diff options
author | Dave Airlie <airlied@redhat.com> | 2017-11-30 18:09:30 -0500 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2017-11-30 18:09:30 -0500 |
commit | e4b2eb13e0b13217d3bd1923d61572a45b78fccb (patch) | |
tree | b194658488de1841f07d546b22175ca6ff58fabf | |
parent | 43f462f1c2e111d2882b48baeeff774ae42e7c56 (diff) | |
parent | 4dbd6c03fbf88299c573d676838896c6e06aade2 (diff) |
Merge tag 'drm-misc-fixes-2017-11-30' of git://anongit.freedesktop.org/drm/drm-misc into drm-fixes
drm-misc-fixes for -rc2
- big pile of bridge driver (mostly tc358767), all handled by Archit
and Andrez
- rockchip dsi fix
- atomic helper regression fix for spurious -EBUSY (Maarten)
- fix deferred fbdev fallout (Maarten)
* tag 'drm-misc-fixes-2017-11-30' of git://anongit.freedesktop.org/drm/drm-misc:
drm/bridge: tc358767: fix 1-lane behavior
drm/bridge: tc358767: fix AUXDATAn registers access
drm/bridge: tc358767: fix timing calculations
drm/bridge: tc358767: fix DP0_MISC register set
drm/bridge: tc358767: filter out too high modes
drm/bridge: tc358767: do no fail on hi-res displays
drm/bridge: Fix lvds-encoder since the panel_bridge rework.
drm/bridge: synopsys/dw-hdmi: Enable cec clock
drm/bridge: adv7511/33: Fix adv7511_cec_init() failure handling
drm/fb_helper: Disable all crtc's when initial setup fails.
drm/atomic: make drm_atomic_helper_wait_for_vblanks more agressive
drm/rockchip: dw-mipi-dsi: fix possible un-balanced runtime PM enable
-rw-r--r-- | drivers/gpu/drm/bridge/adv7511/adv7511.h | 13 | ||||
-rw-r--r-- | drivers/gpu/drm/bridge/adv7511/adv7511_cec.c | 32 | ||||
-rw-r--r-- | drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 17 | ||||
-rw-r--r-- | drivers/gpu/drm/bridge/lvds-encoder.c | 48 | ||||
-rw-r--r-- | drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 25 | ||||
-rw-r--r-- | drivers/gpu/drm/bridge/tc358767.c | 73 | ||||
-rw-r--r-- | drivers/gpu/drm/drm_atomic_helper.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/drm_fb_helper.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 3 |
9 files changed, 149 insertions, 68 deletions
diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511.h b/drivers/gpu/drm/bridge/adv7511/adv7511.h index b4efcbabf7f7..d034b2cb5eee 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7511.h +++ b/drivers/gpu/drm/bridge/adv7511/adv7511.h | |||
@@ -372,9 +372,18 @@ struct adv7511 { | |||
372 | }; | 372 | }; |
373 | 373 | ||
374 | #ifdef CONFIG_DRM_I2C_ADV7511_CEC | 374 | #ifdef CONFIG_DRM_I2C_ADV7511_CEC |
375 | int adv7511_cec_init(struct device *dev, struct adv7511 *adv7511, | 375 | int adv7511_cec_init(struct device *dev, struct adv7511 *adv7511); |
376 | unsigned int offset); | ||
377 | void adv7511_cec_irq_process(struct adv7511 *adv7511, unsigned int irq1); | 376 | void adv7511_cec_irq_process(struct adv7511 *adv7511, unsigned int irq1); |
377 | #else | ||
378 | static inline int adv7511_cec_init(struct device *dev, struct adv7511 *adv7511) | ||
379 | { | ||
380 | unsigned int offset = adv7511->type == ADV7533 ? | ||
381 | ADV7533_REG_CEC_OFFSET : 0; | ||
382 | |||
383 | regmap_write(adv7511->regmap, ADV7511_REG_CEC_CTRL + offset, | ||
384 | ADV7511_CEC_CTRL_POWER_DOWN); | ||
385 | return 0; | ||
386 | } | ||
378 | #endif | 387 | #endif |
379 | 388 | ||
380 | #ifdef CONFIG_DRM_I2C_ADV7533 | 389 | #ifdef CONFIG_DRM_I2C_ADV7533 |
diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_cec.c b/drivers/gpu/drm/bridge/adv7511/adv7511_cec.c index b33d730e4d73..a20a45c0b353 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7511_cec.c +++ b/drivers/gpu/drm/bridge/adv7511/adv7511_cec.c | |||
@@ -300,18 +300,21 @@ static int adv7511_cec_parse_dt(struct device *dev, struct adv7511 *adv7511) | |||
300 | return 0; | 300 | return 0; |
301 | } | 301 | } |
302 | 302 | ||
303 | int adv7511_cec_init(struct device *dev, struct adv7511 *adv7511, | 303 | int adv7511_cec_init(struct device *dev, struct adv7511 *adv7511) |
304 | unsigned int offset) | ||
305 | { | 304 | { |
305 | unsigned int offset = adv7511->type == ADV7533 ? | ||
306 | ADV7533_REG_CEC_OFFSET : 0; | ||
306 | int ret = adv7511_cec_parse_dt(dev, adv7511); | 307 | int ret = adv7511_cec_parse_dt(dev, adv7511); |
307 | 308 | ||
308 | if (ret) | 309 | if (ret) |
309 | return ret; | 310 | goto err_cec_parse_dt; |
310 | 311 | ||
311 | adv7511->cec_adap = cec_allocate_adapter(&adv7511_cec_adap_ops, | 312 | adv7511->cec_adap = cec_allocate_adapter(&adv7511_cec_adap_ops, |
312 | adv7511, dev_name(dev), CEC_CAP_DEFAULTS, ADV7511_MAX_ADDRS); | 313 | adv7511, dev_name(dev), CEC_CAP_DEFAULTS, ADV7511_MAX_ADDRS); |
313 | if (IS_ERR(adv7511->cec_adap)) | 314 | if (IS_ERR(adv7511->cec_adap)) { |
314 | return PTR_ERR(adv7511->cec_adap); | 315 | ret = PTR_ERR(adv7511->cec_adap); |
316 | goto err_cec_alloc; | ||
317 | } | ||
315 | 318 | ||
316 | regmap_write(adv7511->regmap, ADV7511_REG_CEC_CTRL + offset, 0); | 319 | regmap_write(adv7511->regmap, ADV7511_REG_CEC_CTRL + offset, 0); |
317 | /* cec soft reset */ | 320 | /* cec soft reset */ |
@@ -329,9 +332,18 @@ int adv7511_cec_init(struct device *dev, struct adv7511 *adv7511, | |||
329 | ((adv7511->cec_clk_freq / 750000) - 1) << 2); | 332 | ((adv7511->cec_clk_freq / 750000) - 1) << 2); |
330 | 333 | ||
331 | ret = cec_register_adapter(adv7511->cec_adap, dev); | 334 | ret = cec_register_adapter(adv7511->cec_adap, dev); |
332 | if (ret) { | 335 | if (ret) |
333 | cec_delete_adapter(adv7511->cec_adap); | 336 | goto err_cec_register; |
334 | adv7511->cec_adap = NULL; | 337 | return 0; |
335 | } | 338 | |
336 | return ret; | 339 | err_cec_register: |
340 | cec_delete_adapter(adv7511->cec_adap); | ||
341 | adv7511->cec_adap = NULL; | ||
342 | err_cec_alloc: | ||
343 | dev_info(dev, "Initializing CEC failed with error %d, disabling CEC\n", | ||
344 | ret); | ||
345 | err_cec_parse_dt: | ||
346 | regmap_write(adv7511->regmap, ADV7511_REG_CEC_CTRL + offset, | ||
347 | ADV7511_CEC_CTRL_POWER_DOWN); | ||
348 | return ret == -EPROBE_DEFER ? ret : 0; | ||
337 | } | 349 | } |
diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c index 0e14f1572d05..efa29db5fc2b 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c +++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | |||
@@ -1084,7 +1084,6 @@ static int adv7511_probe(struct i2c_client *i2c, const struct i2c_device_id *id) | |||
1084 | struct device *dev = &i2c->dev; | 1084 | struct device *dev = &i2c->dev; |
1085 | unsigned int main_i2c_addr = i2c->addr << 1; | 1085 | unsigned int main_i2c_addr = i2c->addr << 1; |
1086 | unsigned int edid_i2c_addr = main_i2c_addr + 4; | 1086 | unsigned int edid_i2c_addr = main_i2c_addr + 4; |
1087 | unsigned int offset; | ||
1088 | unsigned int val; | 1087 | unsigned int val; |
1089 | int ret; | 1088 | int ret; |
1090 | 1089 | ||
@@ -1192,24 +1191,16 @@ static int adv7511_probe(struct i2c_client *i2c, const struct i2c_device_id *id) | |||
1192 | if (adv7511->type == ADV7511) | 1191 | if (adv7511->type == ADV7511) |
1193 | adv7511_set_link_config(adv7511, &link_config); | 1192 | adv7511_set_link_config(adv7511, &link_config); |
1194 | 1193 | ||
1194 | ret = adv7511_cec_init(dev, adv7511); | ||
1195 | if (ret) | ||
1196 | goto err_unregister_cec; | ||
1197 | |||
1195 | adv7511->bridge.funcs = &adv7511_bridge_funcs; | 1198 | adv7511->bridge.funcs = &adv7511_bridge_funcs; |
1196 | adv7511->bridge.of_node = dev->of_node; | 1199 | adv7511->bridge.of_node = dev->of_node; |
1197 | 1200 | ||
1198 | drm_bridge_add(&adv7511->bridge); | 1201 | drm_bridge_add(&adv7511->bridge); |
1199 | 1202 | ||
1200 | adv7511_audio_init(dev, adv7511); | 1203 | adv7511_audio_init(dev, adv7511); |
1201 | |||
1202 | offset = adv7511->type == ADV7533 ? ADV7533_REG_CEC_OFFSET : 0; | ||
1203 | |||
1204 | #ifdef CONFIG_DRM_I2C_ADV7511_CEC | ||
1205 | ret = adv7511_cec_init(dev, adv7511, offset); | ||
1206 | if (ret) | ||
1207 | goto err_unregister_cec; | ||
1208 | #else | ||
1209 | regmap_write(adv7511->regmap, ADV7511_REG_CEC_CTRL + offset, | ||
1210 | ADV7511_CEC_CTRL_POWER_DOWN); | ||
1211 | #endif | ||
1212 | |||
1213 | return 0; | 1204 | return 0; |
1214 | 1205 | ||
1215 | err_unregister_cec: | 1206 | err_unregister_cec: |
diff --git a/drivers/gpu/drm/bridge/lvds-encoder.c b/drivers/gpu/drm/bridge/lvds-encoder.c index 0903ba574f61..75b0d3f6e4de 100644 --- a/drivers/gpu/drm/bridge/lvds-encoder.c +++ b/drivers/gpu/drm/bridge/lvds-encoder.c | |||
@@ -13,13 +13,37 @@ | |||
13 | 13 | ||
14 | #include <linux/of_graph.h> | 14 | #include <linux/of_graph.h> |
15 | 15 | ||
16 | struct lvds_encoder { | ||
17 | struct drm_bridge bridge; | ||
18 | struct drm_bridge *panel_bridge; | ||
19 | }; | ||
20 | |||
21 | static int lvds_encoder_attach(struct drm_bridge *bridge) | ||
22 | { | ||
23 | struct lvds_encoder *lvds_encoder = container_of(bridge, | ||
24 | struct lvds_encoder, | ||
25 | bridge); | ||
26 | |||
27 | return drm_bridge_attach(bridge->encoder, lvds_encoder->panel_bridge, | ||
28 | bridge); | ||
29 | } | ||
30 | |||
31 | static struct drm_bridge_funcs funcs = { | ||
32 | .attach = lvds_encoder_attach, | ||
33 | }; | ||
34 | |||
16 | static int lvds_encoder_probe(struct platform_device *pdev) | 35 | static int lvds_encoder_probe(struct platform_device *pdev) |
17 | { | 36 | { |
18 | struct device_node *port; | 37 | struct device_node *port; |
19 | struct device_node *endpoint; | 38 | struct device_node *endpoint; |
20 | struct device_node *panel_node; | 39 | struct device_node *panel_node; |
21 | struct drm_panel *panel; | 40 | struct drm_panel *panel; |
22 | struct drm_bridge *bridge; | 41 | struct lvds_encoder *lvds_encoder; |
42 | |||
43 | lvds_encoder = devm_kzalloc(&pdev->dev, sizeof(*lvds_encoder), | ||
44 | GFP_KERNEL); | ||
45 | if (!lvds_encoder) | ||
46 | return -ENOMEM; | ||
23 | 47 | ||
24 | /* Locate the panel DT node. */ | 48 | /* Locate the panel DT node. */ |
25 | port = of_graph_get_port_by_id(pdev->dev.of_node, 1); | 49 | port = of_graph_get_port_by_id(pdev->dev.of_node, 1); |
@@ -49,20 +73,30 @@ static int lvds_encoder_probe(struct platform_device *pdev) | |||
49 | return -EPROBE_DEFER; | 73 | return -EPROBE_DEFER; |
50 | } | 74 | } |
51 | 75 | ||
52 | bridge = drm_panel_bridge_add(panel, DRM_MODE_CONNECTOR_LVDS); | 76 | lvds_encoder->panel_bridge = |
53 | if (IS_ERR(bridge)) | 77 | devm_drm_panel_bridge_add(&pdev->dev, |
54 | return PTR_ERR(bridge); | 78 | panel, DRM_MODE_CONNECTOR_LVDS); |
79 | if (IS_ERR(lvds_encoder->panel_bridge)) | ||
80 | return PTR_ERR(lvds_encoder->panel_bridge); | ||
81 | |||
82 | /* The panel_bridge bridge is attached to the panel's of_node, | ||
83 | * but we need a bridge attached to our of_node for our user | ||
84 | * to look up. | ||
85 | */ | ||
86 | lvds_encoder->bridge.of_node = pdev->dev.of_node; | ||
87 | lvds_encoder->bridge.funcs = &funcs; | ||
88 | drm_bridge_add(&lvds_encoder->bridge); | ||
55 | 89 | ||
56 | platform_set_drvdata(pdev, bridge); | 90 | platform_set_drvdata(pdev, lvds_encoder); |
57 | 91 | ||
58 | return 0; | 92 | return 0; |
59 | } | 93 | } |
60 | 94 | ||
61 | static int lvds_encoder_remove(struct platform_device *pdev) | 95 | static int lvds_encoder_remove(struct platform_device *pdev) |
62 | { | 96 | { |
63 | struct drm_bridge *bridge = platform_get_drvdata(pdev); | 97 | struct lvds_encoder *lvds_encoder = platform_get_drvdata(pdev); |
64 | 98 | ||
65 | drm_bridge_remove(bridge); | 99 | drm_bridge_remove(&lvds_encoder->bridge); |
66 | 100 | ||
67 | return 0; | 101 | return 0; |
68 | } | 102 | } |
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c index bf14214fa464..b72259bf6e2f 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | |||
@@ -138,6 +138,7 @@ struct dw_hdmi { | |||
138 | struct device *dev; | 138 | struct device *dev; |
139 | struct clk *isfr_clk; | 139 | struct clk *isfr_clk; |
140 | struct clk *iahb_clk; | 140 | struct clk *iahb_clk; |
141 | struct clk *cec_clk; | ||
141 | struct dw_hdmi_i2c *i2c; | 142 | struct dw_hdmi_i2c *i2c; |
142 | 143 | ||
143 | struct hdmi_data_info hdmi_data; | 144 | struct hdmi_data_info hdmi_data; |
@@ -2382,6 +2383,26 @@ __dw_hdmi_probe(struct platform_device *pdev, | |||
2382 | goto err_isfr; | 2383 | goto err_isfr; |
2383 | } | 2384 | } |
2384 | 2385 | ||
2386 | hdmi->cec_clk = devm_clk_get(hdmi->dev, "cec"); | ||
2387 | if (PTR_ERR(hdmi->cec_clk) == -ENOENT) { | ||
2388 | hdmi->cec_clk = NULL; | ||
2389 | } else if (IS_ERR(hdmi->cec_clk)) { | ||
2390 | ret = PTR_ERR(hdmi->cec_clk); | ||
2391 | if (ret != -EPROBE_DEFER) | ||
2392 | dev_err(hdmi->dev, "Cannot get HDMI cec clock: %d\n", | ||
2393 | ret); | ||
2394 | |||
2395 | hdmi->cec_clk = NULL; | ||
2396 | goto err_iahb; | ||
2397 | } else { | ||
2398 | ret = clk_prepare_enable(hdmi->cec_clk); | ||
2399 | if (ret) { | ||
2400 | dev_err(hdmi->dev, "Cannot enable HDMI cec clock: %d\n", | ||
2401 | ret); | ||
2402 | goto err_iahb; | ||
2403 | } | ||
2404 | } | ||
2405 | |||
2385 | /* Product and revision IDs */ | 2406 | /* Product and revision IDs */ |
2386 | hdmi->version = (hdmi_readb(hdmi, HDMI_DESIGN_ID) << 8) | 2407 | hdmi->version = (hdmi_readb(hdmi, HDMI_DESIGN_ID) << 8) |
2387 | | (hdmi_readb(hdmi, HDMI_REVISION_ID) << 0); | 2408 | | (hdmi_readb(hdmi, HDMI_REVISION_ID) << 0); |
@@ -2518,6 +2539,8 @@ err_iahb: | |||
2518 | cec_notifier_put(hdmi->cec_notifier); | 2539 | cec_notifier_put(hdmi->cec_notifier); |
2519 | 2540 | ||
2520 | clk_disable_unprepare(hdmi->iahb_clk); | 2541 | clk_disable_unprepare(hdmi->iahb_clk); |
2542 | if (hdmi->cec_clk) | ||
2543 | clk_disable_unprepare(hdmi->cec_clk); | ||
2521 | err_isfr: | 2544 | err_isfr: |
2522 | clk_disable_unprepare(hdmi->isfr_clk); | 2545 | clk_disable_unprepare(hdmi->isfr_clk); |
2523 | err_res: | 2546 | err_res: |
@@ -2541,6 +2564,8 @@ static void __dw_hdmi_remove(struct dw_hdmi *hdmi) | |||
2541 | 2564 | ||
2542 | clk_disable_unprepare(hdmi->iahb_clk); | 2565 | clk_disable_unprepare(hdmi->iahb_clk); |
2543 | clk_disable_unprepare(hdmi->isfr_clk); | 2566 | clk_disable_unprepare(hdmi->isfr_clk); |
2567 | if (hdmi->cec_clk) | ||
2568 | clk_disable_unprepare(hdmi->cec_clk); | ||
2544 | 2569 | ||
2545 | if (hdmi->i2c) | 2570 | if (hdmi->i2c) |
2546 | i2c_del_adapter(&hdmi->i2c->adap); | 2571 | i2c_del_adapter(&hdmi->i2c->adap); |
diff --git a/drivers/gpu/drm/bridge/tc358767.c b/drivers/gpu/drm/bridge/tc358767.c index 8571cfd877c5..8636e7eeb731 100644 --- a/drivers/gpu/drm/bridge/tc358767.c +++ b/drivers/gpu/drm/bridge/tc358767.c | |||
@@ -97,7 +97,7 @@ | |||
97 | #define DP0_ACTIVEVAL 0x0650 | 97 | #define DP0_ACTIVEVAL 0x0650 |
98 | #define DP0_SYNCVAL 0x0654 | 98 | #define DP0_SYNCVAL 0x0654 |
99 | #define DP0_MISC 0x0658 | 99 | #define DP0_MISC 0x0658 |
100 | #define TU_SIZE_RECOMMENDED (0x3f << 16) /* LSCLK cycles per TU */ | 100 | #define TU_SIZE_RECOMMENDED (63) /* LSCLK cycles per TU */ |
101 | #define BPC_6 (0 << 5) | 101 | #define BPC_6 (0 << 5) |
102 | #define BPC_8 (1 << 5) | 102 | #define BPC_8 (1 << 5) |
103 | 103 | ||
@@ -318,7 +318,7 @@ static ssize_t tc_aux_transfer(struct drm_dp_aux *aux, | |||
318 | tmp = (tmp << 8) | buf[i]; | 318 | tmp = (tmp << 8) | buf[i]; |
319 | i++; | 319 | i++; |
320 | if (((i % 4) == 0) || (i == size)) { | 320 | if (((i % 4) == 0) || (i == size)) { |
321 | tc_write(DP0_AUXWDATA(i >> 2), tmp); | 321 | tc_write(DP0_AUXWDATA((i - 1) >> 2), tmp); |
322 | tmp = 0; | 322 | tmp = 0; |
323 | } | 323 | } |
324 | } | 324 | } |
@@ -603,8 +603,15 @@ static int tc_get_display_props(struct tc_data *tc) | |||
603 | ret = drm_dp_link_probe(&tc->aux, &tc->link.base); | 603 | ret = drm_dp_link_probe(&tc->aux, &tc->link.base); |
604 | if (ret < 0) | 604 | if (ret < 0) |
605 | goto err_dpcd_read; | 605 | goto err_dpcd_read; |
606 | if ((tc->link.base.rate != 162000) && (tc->link.base.rate != 270000)) | 606 | if (tc->link.base.rate != 162000 && tc->link.base.rate != 270000) { |
607 | goto err_dpcd_inval; | 607 | dev_dbg(tc->dev, "Falling to 2.7 Gbps rate\n"); |
608 | tc->link.base.rate = 270000; | ||
609 | } | ||
610 | |||
611 | if (tc->link.base.num_lanes > 2) { | ||
612 | dev_dbg(tc->dev, "Falling to 2 lanes\n"); | ||
613 | tc->link.base.num_lanes = 2; | ||
614 | } | ||
608 | 615 | ||
609 | ret = drm_dp_dpcd_readb(&tc->aux, DP_MAX_DOWNSPREAD, tmp); | 616 | ret = drm_dp_dpcd_readb(&tc->aux, DP_MAX_DOWNSPREAD, tmp); |
610 | if (ret < 0) | 617 | if (ret < 0) |
@@ -637,9 +644,6 @@ static int tc_get_display_props(struct tc_data *tc) | |||
637 | err_dpcd_read: | 644 | err_dpcd_read: |
638 | dev_err(tc->dev, "failed to read DPCD: %d\n", ret); | 645 | dev_err(tc->dev, "failed to read DPCD: %d\n", ret); |
639 | return ret; | 646 | return ret; |
640 | err_dpcd_inval: | ||
641 | dev_err(tc->dev, "invalid DPCD\n"); | ||
642 | return -EINVAL; | ||
643 | } | 647 | } |
644 | 648 | ||
645 | static int tc_set_video_mode(struct tc_data *tc, struct drm_display_mode *mode) | 649 | static int tc_set_video_mode(struct tc_data *tc, struct drm_display_mode *mode) |
@@ -655,6 +659,14 @@ static int tc_set_video_mode(struct tc_data *tc, struct drm_display_mode *mode) | |||
655 | int lower_margin = mode->vsync_start - mode->vdisplay; | 659 | int lower_margin = mode->vsync_start - mode->vdisplay; |
656 | int vsync_len = mode->vsync_end - mode->vsync_start; | 660 | int vsync_len = mode->vsync_end - mode->vsync_start; |
657 | 661 | ||
662 | /* | ||
663 | * Recommended maximum number of symbols transferred in a transfer unit: | ||
664 | * DIV_ROUND_UP((input active video bandwidth in bytes) * tu_size, | ||
665 | * (output active video bandwidth in bytes)) | ||
666 | * Must be less than tu_size. | ||
667 | */ | ||
668 | max_tu_symbol = TU_SIZE_RECOMMENDED - 1; | ||
669 | |||
658 | dev_dbg(tc->dev, "set mode %dx%d\n", | 670 | dev_dbg(tc->dev, "set mode %dx%d\n", |
659 | mode->hdisplay, mode->vdisplay); | 671 | mode->hdisplay, mode->vdisplay); |
660 | dev_dbg(tc->dev, "H margin %d,%d sync %d\n", | 672 | dev_dbg(tc->dev, "H margin %d,%d sync %d\n", |
@@ -664,13 +676,18 @@ static int tc_set_video_mode(struct tc_data *tc, struct drm_display_mode *mode) | |||
664 | dev_dbg(tc->dev, "total: %dx%d\n", mode->htotal, mode->vtotal); | 676 | dev_dbg(tc->dev, "total: %dx%d\n", mode->htotal, mode->vtotal); |
665 | 677 | ||
666 | 678 | ||
667 | /* LCD Ctl Frame Size */ | 679 | /* |
668 | tc_write(VPCTRL0, (0x40 << 20) /* VSDELAY */ | | 680 | * LCD Ctl Frame Size |
681 | * datasheet is not clear of vsdelay in case of DPI | ||
682 | * assume we do not need any delay when DPI is a source of | ||
683 | * sync signals | ||
684 | */ | ||
685 | tc_write(VPCTRL0, (0 << 20) /* VSDELAY */ | | ||
669 | OPXLFMT_RGB888 | FRMSYNC_DISABLED | MSF_DISABLED); | 686 | OPXLFMT_RGB888 | FRMSYNC_DISABLED | MSF_DISABLED); |
670 | tc_write(HTIM01, (left_margin << 16) | /* H back porch */ | 687 | tc_write(HTIM01, (ALIGN(left_margin, 2) << 16) | /* H back porch */ |
671 | (hsync_len << 0)); /* Hsync */ | 688 | (ALIGN(hsync_len, 2) << 0)); /* Hsync */ |
672 | tc_write(HTIM02, (right_margin << 16) | /* H front porch */ | 689 | tc_write(HTIM02, (ALIGN(right_margin, 2) << 16) | /* H front porch */ |
673 | (mode->hdisplay << 0)); /* width */ | 690 | (ALIGN(mode->hdisplay, 2) << 0)); /* width */ |
674 | tc_write(VTIM01, (upper_margin << 16) | /* V back porch */ | 691 | tc_write(VTIM01, (upper_margin << 16) | /* V back porch */ |
675 | (vsync_len << 0)); /* Vsync */ | 692 | (vsync_len << 0)); /* Vsync */ |
676 | tc_write(VTIM02, (lower_margin << 16) | /* V front porch */ | 693 | tc_write(VTIM02, (lower_margin << 16) | /* V front porch */ |
@@ -689,7 +706,7 @@ static int tc_set_video_mode(struct tc_data *tc, struct drm_display_mode *mode) | |||
689 | /* DP Main Stream Attributes */ | 706 | /* DP Main Stream Attributes */ |
690 | vid_sync_dly = hsync_len + left_margin + mode->hdisplay; | 707 | vid_sync_dly = hsync_len + left_margin + mode->hdisplay; |
691 | tc_write(DP0_VIDSYNCDELAY, | 708 | tc_write(DP0_VIDSYNCDELAY, |
692 | (0x003e << 16) | /* thresh_dly */ | 709 | (max_tu_symbol << 16) | /* thresh_dly */ |
693 | (vid_sync_dly << 0)); | 710 | (vid_sync_dly << 0)); |
694 | 711 | ||
695 | tc_write(DP0_TOTALVAL, (mode->vtotal << 16) | (mode->htotal)); | 712 | tc_write(DP0_TOTALVAL, (mode->vtotal << 16) | (mode->htotal)); |
@@ -705,14 +722,8 @@ static int tc_set_video_mode(struct tc_data *tc, struct drm_display_mode *mode) | |||
705 | tc_write(DPIPXLFMT, VS_POL_ACTIVE_LOW | HS_POL_ACTIVE_LOW | | 722 | tc_write(DPIPXLFMT, VS_POL_ACTIVE_LOW | HS_POL_ACTIVE_LOW | |
706 | DE_POL_ACTIVE_HIGH | SUB_CFG_TYPE_CONFIG1 | DPI_BPP_RGB888); | 723 | DE_POL_ACTIVE_HIGH | SUB_CFG_TYPE_CONFIG1 | DPI_BPP_RGB888); |
707 | 724 | ||
708 | /* | 725 | tc_write(DP0_MISC, (max_tu_symbol << 23) | (TU_SIZE_RECOMMENDED << 16) | |
709 | * Recommended maximum number of symbols transferred in a transfer unit: | 726 | BPC_8); |
710 | * DIV_ROUND_UP((input active video bandwidth in bytes) * tu_size, | ||
711 | * (output active video bandwidth in bytes)) | ||
712 | * Must be less than tu_size. | ||
713 | */ | ||
714 | max_tu_symbol = TU_SIZE_RECOMMENDED - 1; | ||
715 | tc_write(DP0_MISC, (max_tu_symbol << 23) | TU_SIZE_RECOMMENDED | BPC_8); | ||
716 | 727 | ||
717 | return 0; | 728 | return 0; |
718 | err: | 729 | err: |
@@ -808,8 +819,6 @@ static int tc_main_link_setup(struct tc_data *tc) | |||
808 | unsigned int rate; | 819 | unsigned int rate; |
809 | u32 dp_phy_ctrl; | 820 | u32 dp_phy_ctrl; |
810 | int timeout; | 821 | int timeout; |
811 | bool aligned; | ||
812 | bool ready; | ||
813 | u32 value; | 822 | u32 value; |
814 | int ret; | 823 | int ret; |
815 | u8 tmp[8]; | 824 | u8 tmp[8]; |
@@ -954,16 +963,15 @@ static int tc_main_link_setup(struct tc_data *tc) | |||
954 | ret = drm_dp_dpcd_read_link_status(aux, tmp + 2); | 963 | ret = drm_dp_dpcd_read_link_status(aux, tmp + 2); |
955 | if (ret < 0) | 964 | if (ret < 0) |
956 | goto err_dpcd_read; | 965 | goto err_dpcd_read; |
957 | ready = (tmp[2] == ((DP_CHANNEL_EQ_BITS << 4) | /* Lane1 */ | 966 | } while ((--timeout) && |
958 | DP_CHANNEL_EQ_BITS)); /* Lane0 */ | 967 | !(drm_dp_channel_eq_ok(tmp + 2, tc->link.base.num_lanes))); |
959 | aligned = tmp[4] & DP_INTERLANE_ALIGN_DONE; | ||
960 | } while ((--timeout) && !(ready && aligned)); | ||
961 | 968 | ||
962 | if (timeout == 0) { | 969 | if (timeout == 0) { |
963 | /* Read DPCD 0x200-0x201 */ | 970 | /* Read DPCD 0x200-0x201 */ |
964 | ret = drm_dp_dpcd_read(aux, DP_SINK_COUNT, tmp, 2); | 971 | ret = drm_dp_dpcd_read(aux, DP_SINK_COUNT, tmp, 2); |
965 | if (ret < 0) | 972 | if (ret < 0) |
966 | goto err_dpcd_read; | 973 | goto err_dpcd_read; |
974 | dev_err(dev, "channel(s) EQ not ok\n"); | ||
967 | dev_info(dev, "0x0200 SINK_COUNT: 0x%02x\n", tmp[0]); | 975 | dev_info(dev, "0x0200 SINK_COUNT: 0x%02x\n", tmp[0]); |
968 | dev_info(dev, "0x0201 DEVICE_SERVICE_IRQ_VECTOR: 0x%02x\n", | 976 | dev_info(dev, "0x0201 DEVICE_SERVICE_IRQ_VECTOR: 0x%02x\n", |
969 | tmp[1]); | 977 | tmp[1]); |
@@ -974,10 +982,6 @@ static int tc_main_link_setup(struct tc_data *tc) | |||
974 | dev_info(dev, "0x0206 ADJUST_REQUEST_LANE0_1: 0x%02x\n", | 982 | dev_info(dev, "0x0206 ADJUST_REQUEST_LANE0_1: 0x%02x\n", |
975 | tmp[6]); | 983 | tmp[6]); |
976 | 984 | ||
977 | if (!ready) | ||
978 | dev_err(dev, "Lane0/1 not ready\n"); | ||
979 | if (!aligned) | ||
980 | dev_err(dev, "Lane0/1 not aligned\n"); | ||
981 | return -EAGAIN; | 985 | return -EAGAIN; |
982 | } | 986 | } |
983 | 987 | ||
@@ -1099,7 +1103,10 @@ static bool tc_bridge_mode_fixup(struct drm_bridge *bridge, | |||
1099 | static int tc_connector_mode_valid(struct drm_connector *connector, | 1103 | static int tc_connector_mode_valid(struct drm_connector *connector, |
1100 | struct drm_display_mode *mode) | 1104 | struct drm_display_mode *mode) |
1101 | { | 1105 | { |
1102 | /* Accept any mode */ | 1106 | /* DPI interface clock limitation: upto 154 MHz */ |
1107 | if (mode->clock > 154000) | ||
1108 | return MODE_CLOCK_HIGH; | ||
1109 | |||
1103 | return MODE_OK; | 1110 | return MODE_OK; |
1104 | } | 1111 | } |
1105 | 1112 | ||
diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index 71d712f1b56a..b16f1d69a0bb 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c | |||
@@ -1225,7 +1225,7 @@ drm_atomic_helper_wait_for_vblanks(struct drm_device *dev, | |||
1225 | return; | 1225 | return; |
1226 | 1226 | ||
1227 | for_each_oldnew_crtc_in_state(old_state, crtc, old_crtc_state, new_crtc_state, i) { | 1227 | for_each_oldnew_crtc_in_state(old_state, crtc, old_crtc_state, new_crtc_state, i) { |
1228 | if (!new_crtc_state->active || !new_crtc_state->planes_changed) | 1228 | if (!new_crtc_state->active) |
1229 | continue; | 1229 | continue; |
1230 | 1230 | ||
1231 | ret = drm_crtc_vblank_get(crtc); | 1231 | ret = drm_crtc_vblank_get(crtc); |
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 07374008f146..e56166334455 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c | |||
@@ -1809,6 +1809,10 @@ static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper, | |||
1809 | 1809 | ||
1810 | if (crtc_count == 0 || sizes.fb_width == -1 || sizes.fb_height == -1) { | 1810 | if (crtc_count == 0 || sizes.fb_width == -1 || sizes.fb_height == -1) { |
1811 | DRM_INFO("Cannot find any crtc or sizes\n"); | 1811 | DRM_INFO("Cannot find any crtc or sizes\n"); |
1812 | |||
1813 | /* First time: disable all crtc's.. */ | ||
1814 | if (!fb_helper->deferred_setup && !READ_ONCE(fb_helper->dev->master)) | ||
1815 | restore_fbdev_mode(fb_helper); | ||
1812 | return -EAGAIN; | 1816 | return -EAGAIN; |
1813 | } | 1817 | } |
1814 | 1818 | ||
diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c index b15755b6129c..b1fe0639227e 100644 --- a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c +++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c | |||
@@ -1285,8 +1285,6 @@ static int dw_mipi_dsi_bind(struct device *dev, struct device *master, | |||
1285 | goto err_pllref; | 1285 | goto err_pllref; |
1286 | } | 1286 | } |
1287 | 1287 | ||
1288 | pm_runtime_enable(dev); | ||
1289 | |||
1290 | dsi->dsi_host.ops = &dw_mipi_dsi_host_ops; | 1288 | dsi->dsi_host.ops = &dw_mipi_dsi_host_ops; |
1291 | dsi->dsi_host.dev = dev; | 1289 | dsi->dsi_host.dev = dev; |
1292 | ret = mipi_dsi_host_register(&dsi->dsi_host); | 1290 | ret = mipi_dsi_host_register(&dsi->dsi_host); |
@@ -1301,6 +1299,7 @@ static int dw_mipi_dsi_bind(struct device *dev, struct device *master, | |||
1301 | } | 1299 | } |
1302 | 1300 | ||
1303 | dev_set_drvdata(dev, dsi); | 1301 | dev_set_drvdata(dev, dsi); |
1302 | pm_runtime_enable(dev); | ||
1304 | return 0; | 1303 | return 0; |
1305 | 1304 | ||
1306 | err_mipi_dsi_host: | 1305 | err_mipi_dsi_host: |