diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-03-10 06:12:37 +0300 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-03-10 06:12:37 +0300 |
commit | a6e434e9550807164c5ab7bffde59e9e7a4e717b (patch) | |
tree | ec24fcf151594b5089fc327648577832fda1ab79 /drivers/gpu | |
parent | 8205ff1dc84e0298cd4bc15aa7aeccc35634582c (diff) | |
parent | 848819c5447eb318a787467e8435a07c733e16c9 (diff) | |
download | linux-a6e434e9550807164c5ab7bffde59e9e7a4e717b.tar.xz |
Merge branch 'drm-fixes' of git://people.freedesktop.org/~airlied/linux
Pull drm fixes from Dave Airlie:
"A few imx fixes I missed from a couple of weeks ago, they still aren't
that big and fix some regression and a fail to boot problem.
Other than that, a couple of regression fixes for radeon/amdgpu, one
regression fix for vmwgfx and one regression fix for tda998x"
* 'drm-fixes' of git://people.freedesktop.org/~airlied/linux:
Revert "drm/radeon/pm: adjust display configuration after powerstate"
drm/amdgpu/dp: add back special handling for NUTMEG
drm/radeon/dp: add back special handling for NUTMEG
drm/i2c: tda998x: Choose between atomic or non atomic dpms helper
drm/vmwgfx: Add back ->detect() and ->fill_modes()
drm/radeon: Fix error handling in radeon_flip_work_func.
drm/amdgpu: Fix error handling in amdgpu_flip_work_func.
drm/imx: Add missing DRM_FORMAT_RGB565 to ipu_plane_formats
drm/imx: notify DRM core about CRTC vblank state
gpu: ipu-v3: Reset IPU before activating IRQ
gpu: ipu-v3: Do not bail out on missing optional port nodes
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_display.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/atombios_dp.c | 20 | ||||
-rw-r--r-- | drivers/gpu/drm/i2c/tda998x_drv.c | 10 | ||||
-rw-r--r-- | drivers/gpu/drm/imx/ipuv3-crtc.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/imx/ipuv3-plane.c | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/atombios_dp.c | 20 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_display.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_pm.c | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c | 2 | ||||
-rw-r--r-- | drivers/gpu/ipu-v3/ipu-common.c | 31 |
10 files changed, 69 insertions, 30 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c index 8297bc319369..1846d65b7285 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c @@ -96,7 +96,7 @@ static void amdgpu_flip_work_func(struct work_struct *__work) * In practice this won't execute very often unless on very fast * machines because the time window for this to happen is very small. */ - while (amdgpuCrtc->enabled && repcnt--) { + while (amdgpuCrtc->enabled && --repcnt) { /* GET_DISTANCE_TO_VBLANKSTART returns distance to real vblank * start in hpos, and to the "fudged earlier" vblank start in * vpos. @@ -112,13 +112,13 @@ static void amdgpu_flip_work_func(struct work_struct *__work) break; /* Sleep at least until estimated real start of hw vblank */ - spin_unlock_irqrestore(&crtc->dev->event_lock, flags); min_udelay = (-hpos + 1) * max(vblank->linedur_ns / 1000, 5); if (min_udelay > vblank->framedur_ns / 2000) { /* Don't wait ridiculously long - something is wrong */ repcnt = 0; break; } + spin_unlock_irqrestore(&crtc->dev->event_lock, flags); usleep_range(min_udelay, 2 * min_udelay); spin_lock_irqsave(&crtc->dev->event_lock, flags); }; diff --git a/drivers/gpu/drm/amd/amdgpu/atombios_dp.c b/drivers/gpu/drm/amd/amdgpu/atombios_dp.c index 21aacc1f45c1..bf731e9f643e 100644 --- a/drivers/gpu/drm/amd/amdgpu/atombios_dp.c +++ b/drivers/gpu/drm/amd/amdgpu/atombios_dp.c @@ -265,15 +265,27 @@ static int amdgpu_atombios_dp_get_dp_link_config(struct drm_connector *connector unsigned max_lane_num = drm_dp_max_lane_count(dpcd); unsigned lane_num, i, max_pix_clock; - for (lane_num = 1; lane_num <= max_lane_num; lane_num <<= 1) { - for (i = 0; i < ARRAY_SIZE(link_rates) && link_rates[i] <= max_link_rate; i++) { - max_pix_clock = (lane_num * link_rates[i] * 8) / bpp; + if (amdgpu_connector_encoder_get_dp_bridge_encoder_id(connector) == + ENCODER_OBJECT_ID_NUTMEG) { + for (lane_num = 1; lane_num <= max_lane_num; lane_num <<= 1) { + max_pix_clock = (lane_num * 270000 * 8) / bpp; if (max_pix_clock >= pix_clock) { *dp_lanes = lane_num; - *dp_rate = link_rates[i]; + *dp_rate = 270000; return 0; } } + } else { + for (lane_num = 1; lane_num <= max_lane_num; lane_num <<= 1) { + for (i = 0; i < ARRAY_SIZE(link_rates) && link_rates[i] <= max_link_rate; i++) { + max_pix_clock = (lane_num * link_rates[i] * 8) / bpp; + if (max_pix_clock >= pix_clock) { + *dp_lanes = lane_num; + *dp_rate = link_rates[i]; + return 0; + } + } + } } return -EINVAL; diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c index 34e38749a817..f8ee740c0e26 100644 --- a/drivers/gpu/drm/i2c/tda998x_drv.c +++ b/drivers/gpu/drm/i2c/tda998x_drv.c @@ -1382,8 +1382,16 @@ static void tda998x_connector_destroy(struct drm_connector *connector) drm_connector_cleanup(connector); } +static int tda998x_connector_dpms(struct drm_connector *connector, int mode) +{ + if (drm_core_check_feature(connector->dev, DRIVER_ATOMIC)) + return drm_atomic_helper_connector_dpms(connector, mode); + else + return drm_helper_connector_dpms(connector, mode); +} + static const struct drm_connector_funcs tda998x_connector_funcs = { - .dpms = drm_atomic_helper_connector_dpms, + .dpms = tda998x_connector_dpms, .reset = drm_atomic_helper_connector_reset, .fill_modes = drm_helper_probe_single_connector_modes, .detect = tda998x_connector_detect, diff --git a/drivers/gpu/drm/imx/ipuv3-crtc.c b/drivers/gpu/drm/imx/ipuv3-crtc.c index 30a57185bdb4..287226311413 100644 --- a/drivers/gpu/drm/imx/ipuv3-crtc.c +++ b/drivers/gpu/drm/imx/ipuv3-crtc.c @@ -64,6 +64,7 @@ static void ipu_fb_enable(struct ipu_crtc *ipu_crtc) /* Start DC channel and DI after IDMAC */ ipu_dc_enable_channel(ipu_crtc->dc); ipu_di_enable(ipu_crtc->di); + drm_crtc_vblank_on(&ipu_crtc->base); ipu_crtc->enabled = 1; } @@ -80,6 +81,7 @@ static void ipu_fb_disable(struct ipu_crtc *ipu_crtc) ipu_di_disable(ipu_crtc->di); ipu_plane_disable(ipu_crtc->plane[0]); ipu_dc_disable(ipu); + drm_crtc_vblank_off(&ipu_crtc->base); ipu_crtc->enabled = 0; } diff --git a/drivers/gpu/drm/imx/ipuv3-plane.c b/drivers/gpu/drm/imx/ipuv3-plane.c index 591ba2f1ae03..26bb1b626fe3 100644 --- a/drivers/gpu/drm/imx/ipuv3-plane.c +++ b/drivers/gpu/drm/imx/ipuv3-plane.c @@ -42,6 +42,7 @@ static const uint32_t ipu_plane_formats[] = { DRM_FORMAT_YVYU, DRM_FORMAT_YUV420, DRM_FORMAT_YVU420, + DRM_FORMAT_RGB565, }; int ipu_plane_irq(struct ipu_plane *ipu_plane) diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c index 44ee72e04df9..6af832545bc5 100644 --- a/drivers/gpu/drm/radeon/atombios_dp.c +++ b/drivers/gpu/drm/radeon/atombios_dp.c @@ -315,15 +315,27 @@ int radeon_dp_get_dp_link_config(struct drm_connector *connector, unsigned max_lane_num = drm_dp_max_lane_count(dpcd); unsigned lane_num, i, max_pix_clock; - for (lane_num = 1; lane_num <= max_lane_num; lane_num <<= 1) { - for (i = 0; i < ARRAY_SIZE(link_rates) && link_rates[i] <= max_link_rate; i++) { - max_pix_clock = (lane_num * link_rates[i] * 8) / bpp; + if (radeon_connector_encoder_get_dp_bridge_encoder_id(connector) == + ENCODER_OBJECT_ID_NUTMEG) { + for (lane_num = 1; lane_num <= max_lane_num; lane_num <<= 1) { + max_pix_clock = (lane_num * 270000 * 8) / bpp; if (max_pix_clock >= pix_clock) { *dp_lanes = lane_num; - *dp_rate = link_rates[i]; + *dp_rate = 270000; return 0; } } + } else { + for (lane_num = 1; lane_num <= max_lane_num; lane_num <<= 1) { + for (i = 0; i < ARRAY_SIZE(link_rates) && link_rates[i] <= max_link_rate; i++) { + max_pix_clock = (lane_num * link_rates[i] * 8) / bpp; + if (max_pix_clock >= pix_clock) { + *dp_lanes = lane_num; + *dp_rate = link_rates[i]; + return 0; + } + } + } } return -EINVAL; diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index 2b9ba03a7c1a..2d9196a447fd 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c @@ -455,7 +455,7 @@ static void radeon_flip_work_func(struct work_struct *__work) * In practice this won't execute very often unless on very fast * machines because the time window for this to happen is very small. */ - while (radeon_crtc->enabled && repcnt--) { + while (radeon_crtc->enabled && --repcnt) { /* GET_DISTANCE_TO_VBLANKSTART returns distance to real vblank * start in hpos, and to the "fudged earlier" vblank start in * vpos. @@ -471,13 +471,13 @@ static void radeon_flip_work_func(struct work_struct *__work) break; /* Sleep at least until estimated real start of hw vblank */ - spin_unlock_irqrestore(&crtc->dev->event_lock, flags); min_udelay = (-hpos + 1) * max(vblank->linedur_ns / 1000, 5); if (min_udelay > vblank->framedur_ns / 2000) { /* Don't wait ridiculously long - something is wrong */ repcnt = 0; break; } + spin_unlock_irqrestore(&crtc->dev->event_lock, flags); usleep_range(min_udelay, 2 * min_udelay); spin_lock_irqsave(&crtc->dev->event_lock, flags); }; diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c index 0f14d897baf9..7a98823bacd1 100644 --- a/drivers/gpu/drm/radeon/radeon_pm.c +++ b/drivers/gpu/drm/radeon/radeon_pm.c @@ -1079,6 +1079,8 @@ force: /* update display watermarks based on new power state */ radeon_bandwidth_update(rdev); + /* update displays */ + radeon_dpm_display_configuration_changed(rdev); /* wait for the rings to drain */ for (i = 0; i < RADEON_NUM_RINGS; i++) { @@ -1095,9 +1097,6 @@ force: radeon_dpm_post_set_power_state(rdev); - /* update displays */ - radeon_dpm_display_configuration_changed(rdev); - rdev->pm.dpm.current_active_crtcs = rdev->pm.dpm.new_active_crtcs; rdev->pm.dpm.current_active_crtc_count = rdev->pm.dpm.new_active_crtc_count; rdev->pm.dpm.single_display = single_display; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c index db082bea8daf..c5a1a08b0449 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c @@ -563,6 +563,8 @@ static void vmw_sou_connector_destroy(struct drm_connector *connector) static const struct drm_connector_funcs vmw_sou_connector_funcs = { .dpms = vmw_du_connector_dpms, + .detect = vmw_du_connector_detect, + .fill_modes = vmw_du_connector_fill_modes, .set_property = vmw_du_connector_set_property, .destroy = vmw_sou_connector_destroy, }; diff --git a/drivers/gpu/ipu-v3/ipu-common.c b/drivers/gpu/ipu-v3/ipu-common.c index f2e13eb8339f..e00db3f510dd 100644 --- a/drivers/gpu/ipu-v3/ipu-common.c +++ b/drivers/gpu/ipu-v3/ipu-common.c @@ -1050,6 +1050,17 @@ static int ipu_add_client_devices(struct ipu_soc *ipu, unsigned long ipu_base) for (i = 0; i < ARRAY_SIZE(client_reg); i++) { const struct ipu_platform_reg *reg = &client_reg[i]; struct platform_device *pdev; + struct device_node *of_node; + + /* Associate subdevice with the corresponding port node */ + of_node = of_graph_get_port_by_id(dev->of_node, i); + if (!of_node) { + dev_info(dev, + "no port@%d node in %s, not using %s%d\n", + i, dev->of_node->full_name, + (i / 2) ? "DI" : "CSI", i % 2); + continue; + } pdev = platform_device_alloc(reg->name, id++); if (!pdev) { @@ -1057,17 +1068,9 @@ static int ipu_add_client_devices(struct ipu_soc *ipu, unsigned long ipu_base) goto err_register; } + pdev->dev.of_node = of_node; pdev->dev.parent = dev; - /* Associate subdevice with the corresponding port node */ - pdev->dev.of_node = of_graph_get_port_by_id(dev->of_node, i); - if (!pdev->dev.of_node) { - dev_err(dev, "missing port@%d node in %s\n", i, - dev->of_node->full_name); - ret = -ENODEV; - goto err_register; - } - ret = platform_device_add_data(pdev, ®->pdata, sizeof(reg->pdata)); if (!ret) @@ -1289,10 +1292,6 @@ static int ipu_probe(struct platform_device *pdev) ipu->irq_sync = irq_sync; ipu->irq_err = irq_err; - ret = ipu_irq_init(ipu); - if (ret) - goto out_failed_irq; - ret = device_reset(&pdev->dev); if (ret) { dev_err(&pdev->dev, "failed to reset: %d\n", ret); @@ -1302,6 +1301,10 @@ static int ipu_probe(struct platform_device *pdev) if (ret) goto out_failed_reset; + ret = ipu_irq_init(ipu); + if (ret) + goto out_failed_irq; + /* Set MCU_T to divide MCU access window into 2 */ ipu_cm_write(ipu, 0x00400000L | (IPU_MCU_T_DEFAULT << 18), IPU_DISP_GEN); @@ -1324,9 +1327,9 @@ static int ipu_probe(struct platform_device *pdev) failed_add_clients: ipu_submodules_exit(ipu); failed_submodules_init: -out_failed_reset: ipu_irq_exit(ipu); out_failed_irq: +out_failed_reset: clk_disable_unprepare(ipu->clk); return ret; } |