aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-03-09 22:12:37 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2016-03-09 22:12:37 -0500
commita6e434e9550807164c5ab7bffde59e9e7a4e717b (patch)
treeec24fcf151594b5089fc327648577832fda1ab79
parent8205ff1dc84e0298cd4bc15aa7aeccc35634582c (diff)
parent848819c5447eb318a787467e8435a07c733e16c9 (diff)
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
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_display.c4
-rw-r--r--drivers/gpu/drm/amd/amdgpu/atombios_dp.c20
-rw-r--r--drivers/gpu/drm/i2c/tda998x_drv.c10
-rw-r--r--drivers/gpu/drm/imx/ipuv3-crtc.c2
-rw-r--r--drivers/gpu/drm/imx/ipuv3-plane.c1
-rw-r--r--drivers/gpu/drm/radeon/atombios_dp.c20
-rw-r--r--drivers/gpu/drm/radeon/radeon_display.c4
-rw-r--r--drivers/gpu/drm/radeon/radeon_pm.c5
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c2
-rw-r--r--drivers/gpu/ipu-v3/ipu-common.c31
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)
96 * In practice this won't execute very often unless on very fast 96 * In practice this won't execute very often unless on very fast
97 * machines because the time window for this to happen is very small. 97 * machines because the time window for this to happen is very small.
98 */ 98 */
99 while (amdgpuCrtc->enabled && repcnt--) { 99 while (amdgpuCrtc->enabled && --repcnt) {
100 /* GET_DISTANCE_TO_VBLANKSTART returns distance to real vblank 100 /* GET_DISTANCE_TO_VBLANKSTART returns distance to real vblank
101 * start in hpos, and to the "fudged earlier" vblank start in 101 * start in hpos, and to the "fudged earlier" vblank start in
102 * vpos. 102 * vpos.
@@ -112,13 +112,13 @@ static void amdgpu_flip_work_func(struct work_struct *__work)
112 break; 112 break;
113 113
114 /* Sleep at least until estimated real start of hw vblank */ 114 /* Sleep at least until estimated real start of hw vblank */
115 spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
116 min_udelay = (-hpos + 1) * max(vblank->linedur_ns / 1000, 5); 115 min_udelay = (-hpos + 1) * max(vblank->linedur_ns / 1000, 5);
117 if (min_udelay > vblank->framedur_ns / 2000) { 116 if (min_udelay > vblank->framedur_ns / 2000) {
118 /* Don't wait ridiculously long - something is wrong */ 117 /* Don't wait ridiculously long - something is wrong */
119 repcnt = 0; 118 repcnt = 0;
120 break; 119 break;
121 } 120 }
121 spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
122 usleep_range(min_udelay, 2 * min_udelay); 122 usleep_range(min_udelay, 2 * min_udelay);
123 spin_lock_irqsave(&crtc->dev->event_lock, flags); 123 spin_lock_irqsave(&crtc->dev->event_lock, flags);
124 }; 124 };
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
265 unsigned max_lane_num = drm_dp_max_lane_count(dpcd); 265 unsigned max_lane_num = drm_dp_max_lane_count(dpcd);
266 unsigned lane_num, i, max_pix_clock; 266 unsigned lane_num, i, max_pix_clock;
267 267
268 for (lane_num = 1; lane_num <= max_lane_num; lane_num <<= 1) { 268 if (amdgpu_connector_encoder_get_dp_bridge_encoder_id(connector) ==
269 for (i = 0; i < ARRAY_SIZE(link_rates) && link_rates[i] <= max_link_rate; i++) { 269 ENCODER_OBJECT_ID_NUTMEG) {
270 max_pix_clock = (lane_num * link_rates[i] * 8) / bpp; 270 for (lane_num = 1; lane_num <= max_lane_num; lane_num <<= 1) {
271 max_pix_clock = (lane_num * 270000 * 8) / bpp;
271 if (max_pix_clock >= pix_clock) { 272 if (max_pix_clock >= pix_clock) {
272 *dp_lanes = lane_num; 273 *dp_lanes = lane_num;
273 *dp_rate = link_rates[i]; 274 *dp_rate = 270000;
274 return 0; 275 return 0;
275 } 276 }
276 } 277 }
278 } else {
279 for (lane_num = 1; lane_num <= max_lane_num; lane_num <<= 1) {
280 for (i = 0; i < ARRAY_SIZE(link_rates) && link_rates[i] <= max_link_rate; i++) {
281 max_pix_clock = (lane_num * link_rates[i] * 8) / bpp;
282 if (max_pix_clock >= pix_clock) {
283 *dp_lanes = lane_num;
284 *dp_rate = link_rates[i];
285 return 0;
286 }
287 }
288 }
277 } 289 }
278 290
279 return -EINVAL; 291 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)
1382 drm_connector_cleanup(connector); 1382 drm_connector_cleanup(connector);
1383} 1383}
1384 1384
1385static int tda998x_connector_dpms(struct drm_connector *connector, int mode)
1386{
1387 if (drm_core_check_feature(connector->dev, DRIVER_ATOMIC))
1388 return drm_atomic_helper_connector_dpms(connector, mode);
1389 else
1390 return drm_helper_connector_dpms(connector, mode);
1391}
1392
1385static const struct drm_connector_funcs tda998x_connector_funcs = { 1393static const struct drm_connector_funcs tda998x_connector_funcs = {
1386 .dpms = drm_atomic_helper_connector_dpms, 1394 .dpms = tda998x_connector_dpms,
1387 .reset = drm_atomic_helper_connector_reset, 1395 .reset = drm_atomic_helper_connector_reset,
1388 .fill_modes = drm_helper_probe_single_connector_modes, 1396 .fill_modes = drm_helper_probe_single_connector_modes,
1389 .detect = tda998x_connector_detect, 1397 .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)
64 /* Start DC channel and DI after IDMAC */ 64 /* Start DC channel and DI after IDMAC */
65 ipu_dc_enable_channel(ipu_crtc->dc); 65 ipu_dc_enable_channel(ipu_crtc->dc);
66 ipu_di_enable(ipu_crtc->di); 66 ipu_di_enable(ipu_crtc->di);
67 drm_crtc_vblank_on(&ipu_crtc->base);
67 68
68 ipu_crtc->enabled = 1; 69 ipu_crtc->enabled = 1;
69} 70}
@@ -80,6 +81,7 @@ static void ipu_fb_disable(struct ipu_crtc *ipu_crtc)
80 ipu_di_disable(ipu_crtc->di); 81 ipu_di_disable(ipu_crtc->di);
81 ipu_plane_disable(ipu_crtc->plane[0]); 82 ipu_plane_disable(ipu_crtc->plane[0]);
82 ipu_dc_disable(ipu); 83 ipu_dc_disable(ipu);
84 drm_crtc_vblank_off(&ipu_crtc->base);
83 85
84 ipu_crtc->enabled = 0; 86 ipu_crtc->enabled = 0;
85} 87}
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[] = {
42 DRM_FORMAT_YVYU, 42 DRM_FORMAT_YVYU,
43 DRM_FORMAT_YUV420, 43 DRM_FORMAT_YUV420,
44 DRM_FORMAT_YVU420, 44 DRM_FORMAT_YVU420,
45 DRM_FORMAT_RGB565,
45}; 46};
46 47
47int ipu_plane_irq(struct ipu_plane *ipu_plane) 48int 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,
315 unsigned max_lane_num = drm_dp_max_lane_count(dpcd); 315 unsigned max_lane_num = drm_dp_max_lane_count(dpcd);
316 unsigned lane_num, i, max_pix_clock; 316 unsigned lane_num, i, max_pix_clock;
317 317
318 for (lane_num = 1; lane_num <= max_lane_num; lane_num <<= 1) { 318 if (radeon_connector_encoder_get_dp_bridge_encoder_id(connector) ==
319 for (i = 0; i < ARRAY_SIZE(link_rates) && link_rates[i] <= max_link_rate; i++) { 319 ENCODER_OBJECT_ID_NUTMEG) {
320 max_pix_clock = (lane_num * link_rates[i] * 8) / bpp; 320 for (lane_num = 1; lane_num <= max_lane_num; lane_num <<= 1) {
321 max_pix_clock = (lane_num * 270000 * 8) / bpp;
321 if (max_pix_clock >= pix_clock) { 322 if (max_pix_clock >= pix_clock) {
322 *dp_lanes = lane_num; 323 *dp_lanes = lane_num;
323 *dp_rate = link_rates[i]; 324 *dp_rate = 270000;
324 return 0; 325 return 0;
325 } 326 }
326 } 327 }
328 } else {
329 for (lane_num = 1; lane_num <= max_lane_num; lane_num <<= 1) {
330 for (i = 0; i < ARRAY_SIZE(link_rates) && link_rates[i] <= max_link_rate; i++) {
331 max_pix_clock = (lane_num * link_rates[i] * 8) / bpp;
332 if (max_pix_clock >= pix_clock) {
333 *dp_lanes = lane_num;
334 *dp_rate = link_rates[i];
335 return 0;
336 }
337 }
338 }
327 } 339 }
328 340
329 return -EINVAL; 341 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)
455 * In practice this won't execute very often unless on very fast 455 * In practice this won't execute very often unless on very fast
456 * machines because the time window for this to happen is very small. 456 * machines because the time window for this to happen is very small.
457 */ 457 */
458 while (radeon_crtc->enabled && repcnt--) { 458 while (radeon_crtc->enabled && --repcnt) {
459 /* GET_DISTANCE_TO_VBLANKSTART returns distance to real vblank 459 /* GET_DISTANCE_TO_VBLANKSTART returns distance to real vblank
460 * start in hpos, and to the "fudged earlier" vblank start in 460 * start in hpos, and to the "fudged earlier" vblank start in
461 * vpos. 461 * vpos.
@@ -471,13 +471,13 @@ static void radeon_flip_work_func(struct work_struct *__work)
471 break; 471 break;
472 472
473 /* Sleep at least until estimated real start of hw vblank */ 473 /* Sleep at least until estimated real start of hw vblank */
474 spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
475 min_udelay = (-hpos + 1) * max(vblank->linedur_ns / 1000, 5); 474 min_udelay = (-hpos + 1) * max(vblank->linedur_ns / 1000, 5);
476 if (min_udelay > vblank->framedur_ns / 2000) { 475 if (min_udelay > vblank->framedur_ns / 2000) {
477 /* Don't wait ridiculously long - something is wrong */ 476 /* Don't wait ridiculously long - something is wrong */
478 repcnt = 0; 477 repcnt = 0;
479 break; 478 break;
480 } 479 }
480 spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
481 usleep_range(min_udelay, 2 * min_udelay); 481 usleep_range(min_udelay, 2 * min_udelay);
482 spin_lock_irqsave(&crtc->dev->event_lock, flags); 482 spin_lock_irqsave(&crtc->dev->event_lock, flags);
483 }; 483 };
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:
1079 1079
1080 /* update display watermarks based on new power state */ 1080 /* update display watermarks based on new power state */
1081 radeon_bandwidth_update(rdev); 1081 radeon_bandwidth_update(rdev);
1082 /* update displays */
1083 radeon_dpm_display_configuration_changed(rdev);
1082 1084
1083 /* wait for the rings to drain */ 1085 /* wait for the rings to drain */
1084 for (i = 0; i < RADEON_NUM_RINGS; i++) { 1086 for (i = 0; i < RADEON_NUM_RINGS; i++) {
@@ -1095,9 +1097,6 @@ force:
1095 1097
1096 radeon_dpm_post_set_power_state(rdev); 1098 radeon_dpm_post_set_power_state(rdev);
1097 1099
1098 /* update displays */
1099 radeon_dpm_display_configuration_changed(rdev);
1100
1101 rdev->pm.dpm.current_active_crtcs = rdev->pm.dpm.new_active_crtcs; 1100 rdev->pm.dpm.current_active_crtcs = rdev->pm.dpm.new_active_crtcs;
1102 rdev->pm.dpm.current_active_crtc_count = rdev->pm.dpm.new_active_crtc_count; 1101 rdev->pm.dpm.current_active_crtc_count = rdev->pm.dpm.new_active_crtc_count;
1103 rdev->pm.dpm.single_display = single_display; 1102 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)
563 563
564static const struct drm_connector_funcs vmw_sou_connector_funcs = { 564static const struct drm_connector_funcs vmw_sou_connector_funcs = {
565 .dpms = vmw_du_connector_dpms, 565 .dpms = vmw_du_connector_dpms,
566 .detect = vmw_du_connector_detect,
567 .fill_modes = vmw_du_connector_fill_modes,
566 .set_property = vmw_du_connector_set_property, 568 .set_property = vmw_du_connector_set_property,
567 .destroy = vmw_sou_connector_destroy, 569 .destroy = vmw_sou_connector_destroy,
568}; 570};
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)
1050 for (i = 0; i < ARRAY_SIZE(client_reg); i++) { 1050 for (i = 0; i < ARRAY_SIZE(client_reg); i++) {
1051 const struct ipu_platform_reg *reg = &client_reg[i]; 1051 const struct ipu_platform_reg *reg = &client_reg[i];
1052 struct platform_device *pdev; 1052 struct platform_device *pdev;
1053 struct device_node *of_node;
1054
1055 /* Associate subdevice with the corresponding port node */
1056 of_node = of_graph_get_port_by_id(dev->of_node, i);
1057 if (!of_node) {
1058 dev_info(dev,
1059 "no port@%d node in %s, not using %s%d\n",
1060 i, dev->of_node->full_name,
1061 (i / 2) ? "DI" : "CSI", i % 2);
1062 continue;
1063 }
1053 1064
1054 pdev = platform_device_alloc(reg->name, id++); 1065 pdev = platform_device_alloc(reg->name, id++);
1055 if (!pdev) { 1066 if (!pdev) {
@@ -1057,17 +1068,9 @@ static int ipu_add_client_devices(struct ipu_soc *ipu, unsigned long ipu_base)
1057 goto err_register; 1068 goto err_register;
1058 } 1069 }
1059 1070
1071 pdev->dev.of_node = of_node;
1060 pdev->dev.parent = dev; 1072 pdev->dev.parent = dev;
1061 1073
1062 /* Associate subdevice with the corresponding port node */
1063 pdev->dev.of_node = of_graph_get_port_by_id(dev->of_node, i);
1064 if (!pdev->dev.of_node) {
1065 dev_err(dev, "missing port@%d node in %s\n", i,
1066 dev->of_node->full_name);
1067 ret = -ENODEV;
1068 goto err_register;
1069 }
1070
1071 ret = platform_device_add_data(pdev, &reg->pdata, 1074 ret = platform_device_add_data(pdev, &reg->pdata,
1072 sizeof(reg->pdata)); 1075 sizeof(reg->pdata));
1073 if (!ret) 1076 if (!ret)
@@ -1289,10 +1292,6 @@ static int ipu_probe(struct platform_device *pdev)
1289 ipu->irq_sync = irq_sync; 1292 ipu->irq_sync = irq_sync;
1290 ipu->irq_err = irq_err; 1293 ipu->irq_err = irq_err;
1291 1294
1292 ret = ipu_irq_init(ipu);
1293 if (ret)
1294 goto out_failed_irq;
1295
1296 ret = device_reset(&pdev->dev); 1295 ret = device_reset(&pdev->dev);
1297 if (ret) { 1296 if (ret) {
1298 dev_err(&pdev->dev, "failed to reset: %d\n", ret); 1297 dev_err(&pdev->dev, "failed to reset: %d\n", ret);
@@ -1302,6 +1301,10 @@ static int ipu_probe(struct platform_device *pdev)
1302 if (ret) 1301 if (ret)
1303 goto out_failed_reset; 1302 goto out_failed_reset;
1304 1303
1304 ret = ipu_irq_init(ipu);
1305 if (ret)
1306 goto out_failed_irq;
1307
1305 /* Set MCU_T to divide MCU access window into 2 */ 1308 /* Set MCU_T to divide MCU access window into 2 */
1306 ipu_cm_write(ipu, 0x00400000L | (IPU_MCU_T_DEFAULT << 18), 1309 ipu_cm_write(ipu, 0x00400000L | (IPU_MCU_T_DEFAULT << 18),
1307 IPU_DISP_GEN); 1310 IPU_DISP_GEN);
@@ -1324,9 +1327,9 @@ static int ipu_probe(struct platform_device *pdev)
1324failed_add_clients: 1327failed_add_clients:
1325 ipu_submodules_exit(ipu); 1328 ipu_submodules_exit(ipu);
1326failed_submodules_init: 1329failed_submodules_init:
1327out_failed_reset:
1328 ipu_irq_exit(ipu); 1330 ipu_irq_exit(ipu);
1329out_failed_irq: 1331out_failed_irq:
1332out_failed_reset:
1330 clk_disable_unprepare(ipu->clk); 1333 clk_disable_unprepare(ipu->clk);
1331 return ret; 1334 return ret;
1332} 1335}