diff options
author | Dave Airlie <airlied@redhat.com> | 2017-01-26 21:10:24 -0500 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2017-01-26 21:10:24 -0500 |
commit | 3875623c561f9e83181d9621e0a963ed457c4bf6 (patch) | |
tree | 21a2b0bb0bf4822bfe4bd7e16264d48c04b39e72 /drivers/gpu | |
parent | a7e2641aafe261bf70de01ff5fc68dea50468237 (diff) | |
parent | 6f897f51c4181397bf811d260eb7fef8d7ccd14f (diff) |
Merge tag 'drm-misc-next-2017-01-23' of git://anongit.freedesktop.org/git/drm-misc into drm-next
- cleanups&fixes for dw-hdmi bride driver (Laurent)
- updates for adv bridge driver (John Stultz) for nexus
- drm_crtc_from_index helper rollout (Shawn Guo)
- removing drm_framebuffer_unregister_private from drivers&core
- target_vblank (Andrey Grodzovsky)
- misc tiny stuff
* tag 'drm-misc-next-2017-01-23' of git://anongit.freedesktop.org/git/drm-misc: (49 commits)
drm: qxl: Open code teardown function for qxl
drm: qxl: Open code probing sequence for qxl
drm/bridge: adv7511: Re-write the i2c address before EDID probing
drm/bridge: adv7511: Reuse __adv7511_power_on/off() when probing EDID
drm/bridge: adv7511: Rework adv7511_power_on/off() so they can be reused internally
drm/bridge: adv7511: Enable HPD interrupts to support hotplug and improve monitor detection
drm/bridge: adv7511: Switch to using drm_kms_helper_hotplug_event()
drm/bridge: adv7511: Use work_struct to defer hotplug handing to out of irq context
drm: vc4: use crtc helper drm_crtc_from_index()
drm: tegra: use crtc helper drm_crtc_from_index()
drm: nouveau: use crtc helper drm_crtc_from_index()
drm: mediatek: use crtc helper drm_crtc_from_index()
drm: kirin: use crtc helper drm_crtc_from_index()
drm: exynos: use crtc helper drm_crtc_from_index()
dt-bindings: display: dw-hdmi: Clean up DT bindings documentation
drm: bridge: dw-hdmi: Assert SVSRET before resetting the PHY
drm: bridge: dw-hdmi: Fix the name of the PHY reset macros
drm: bridge: dw-hdmi: Define and use macros for PHY register addresses
drm: bridge: dw-hdmi: Detect PHY type at runtime
drm: bridge: dw-hdmi: Handle overflow workaround based on device version
...
Diffstat (limited to 'drivers/gpu')
36 files changed, 778 insertions, 398 deletions
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index 6f3f9e68c218..90bc65d07a35 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig | |||
@@ -138,7 +138,7 @@ config DRM_KMS_CMA_HELPER | |||
138 | 138 | ||
139 | config DRM_VM | 139 | config DRM_VM |
140 | bool | 140 | bool |
141 | depends on DRM | 141 | depends on DRM && MMU |
142 | 142 | ||
143 | source "drivers/gpu/drm/i2c/Kconfig" | 143 | source "drivers/gpu/drm/i2c/Kconfig" |
144 | 144 | ||
@@ -267,7 +267,7 @@ source "drivers/gpu/drm/meson/Kconfig" | |||
267 | 267 | ||
268 | menuconfig DRM_LEGACY | 268 | menuconfig DRM_LEGACY |
269 | bool "Enable legacy drivers (DANGEROUS)" | 269 | bool "Enable legacy drivers (DANGEROUS)" |
270 | depends on DRM | 270 | depends on DRM && MMU |
271 | select DRM_VM | 271 | select DRM_VM |
272 | help | 272 | help |
273 | Enable legacy DRI1 drivers. Those drivers expose unsafe and dangerous | 273 | Enable legacy DRI1 drivers. Those drivers expose unsafe and dangerous |
diff --git a/drivers/gpu/drm/armada/Kconfig b/drivers/gpu/drm/armada/Kconfig index 15f3ecfb16f1..eafaeeb7b5b1 100644 --- a/drivers/gpu/drm/armada/Kconfig +++ b/drivers/gpu/drm/armada/Kconfig | |||
@@ -1,6 +1,6 @@ | |||
1 | config DRM_ARMADA | 1 | config DRM_ARMADA |
2 | tristate "DRM support for Marvell Armada SoCs" | 2 | tristate "DRM support for Marvell Armada SoCs" |
3 | depends on DRM && HAVE_CLK && ARM | 3 | depends on DRM && HAVE_CLK && ARM && MMU |
4 | select DRM_KMS_HELPER | 4 | select DRM_KMS_HELPER |
5 | help | 5 | help |
6 | Support the "LCD" controllers found on the Marvell Armada 510 | 6 | Support the "LCD" controllers found on the Marvell Armada 510 |
diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511.h b/drivers/gpu/drm/bridge/adv7511/adv7511.h index 992d76ce02bb..fe18a5d2d84b 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7511.h +++ b/drivers/gpu/drm/bridge/adv7511/adv7511.h | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <linux/hdmi.h> | 12 | #include <linux/hdmi.h> |
13 | #include <linux/i2c.h> | 13 | #include <linux/i2c.h> |
14 | #include <linux/regmap.h> | 14 | #include <linux/regmap.h> |
15 | #include <linux/regulator/consumer.h> | ||
15 | 16 | ||
16 | #include <drm/drm_crtc_helper.h> | 17 | #include <drm/drm_crtc_helper.h> |
17 | #include <drm/drm_mipi_dsi.h> | 18 | #include <drm/drm_mipi_dsi.h> |
@@ -317,6 +318,8 @@ struct adv7511 { | |||
317 | bool edid_read; | 318 | bool edid_read; |
318 | 319 | ||
319 | wait_queue_head_t wq; | 320 | wait_queue_head_t wq; |
321 | struct work_struct hpd_work; | ||
322 | |||
320 | struct drm_bridge bridge; | 323 | struct drm_bridge bridge; |
321 | struct drm_connector connector; | 324 | struct drm_connector connector; |
322 | 325 | ||
@@ -329,6 +332,9 @@ struct adv7511 { | |||
329 | 332 | ||
330 | struct gpio_desc *gpio_pd; | 333 | struct gpio_desc *gpio_pd; |
331 | 334 | ||
335 | struct regulator_bulk_data *supplies; | ||
336 | unsigned int num_supplies; | ||
337 | |||
332 | /* ADV7533 DSI RX related params */ | 338 | /* ADV7533 DSI RX related params */ |
333 | struct device_node *host_node; | 339 | struct device_node *host_node; |
334 | struct mipi_dsi_device *dsi; | 340 | struct mipi_dsi_device *dsi; |
diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c index 8dba729f6ef9..f75ab6278113 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c +++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | |||
@@ -325,7 +325,7 @@ static void adv7511_set_link_config(struct adv7511 *adv7511, | |||
325 | adv7511->rgb = config->input_colorspace == HDMI_COLORSPACE_RGB; | 325 | adv7511->rgb = config->input_colorspace == HDMI_COLORSPACE_RGB; |
326 | } | 326 | } |
327 | 327 | ||
328 | static void adv7511_power_on(struct adv7511 *adv7511) | 328 | static void __adv7511_power_on(struct adv7511 *adv7511) |
329 | { | 329 | { |
330 | adv7511->current_edid_segment = -1; | 330 | adv7511->current_edid_segment = -1; |
331 | 331 | ||
@@ -338,7 +338,7 @@ static void adv7511_power_on(struct adv7511 *adv7511) | |||
338 | * Still, let's be safe and stick to the documentation. | 338 | * Still, let's be safe and stick to the documentation. |
339 | */ | 339 | */ |
340 | regmap_write(adv7511->regmap, ADV7511_REG_INT_ENABLE(0), | 340 | regmap_write(adv7511->regmap, ADV7511_REG_INT_ENABLE(0), |
341 | ADV7511_INT0_EDID_READY); | 341 | ADV7511_INT0_EDID_READY | ADV7511_INT0_HPD); |
342 | regmap_write(adv7511->regmap, ADV7511_REG_INT_ENABLE(1), | 342 | regmap_write(adv7511->regmap, ADV7511_REG_INT_ENABLE(1), |
343 | ADV7511_INT1_DDC_ERROR); | 343 | ADV7511_INT1_DDC_ERROR); |
344 | } | 344 | } |
@@ -354,6 +354,11 @@ static void adv7511_power_on(struct adv7511 *adv7511) | |||
354 | regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER2, | 354 | regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER2, |
355 | ADV7511_REG_POWER2_HPD_SRC_MASK, | 355 | ADV7511_REG_POWER2_HPD_SRC_MASK, |
356 | ADV7511_REG_POWER2_HPD_SRC_NONE); | 356 | ADV7511_REG_POWER2_HPD_SRC_NONE); |
357 | } | ||
358 | |||
359 | static void adv7511_power_on(struct adv7511 *adv7511) | ||
360 | { | ||
361 | __adv7511_power_on(adv7511); | ||
357 | 362 | ||
358 | /* | 363 | /* |
359 | * Most of the registers are reset during power down or when HPD is low. | 364 | * Most of the registers are reset during power down or when HPD is low. |
@@ -362,21 +367,23 @@ static void adv7511_power_on(struct adv7511 *adv7511) | |||
362 | 367 | ||
363 | if (adv7511->type == ADV7533) | 368 | if (adv7511->type == ADV7533) |
364 | adv7533_dsi_power_on(adv7511); | 369 | adv7533_dsi_power_on(adv7511); |
365 | |||
366 | adv7511->powered = true; | 370 | adv7511->powered = true; |
367 | } | 371 | } |
368 | 372 | ||
369 | static void adv7511_power_off(struct adv7511 *adv7511) | 373 | static void __adv7511_power_off(struct adv7511 *adv7511) |
370 | { | 374 | { |
371 | /* TODO: setup additional power down modes */ | 375 | /* TODO: setup additional power down modes */ |
372 | regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER, | 376 | regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER, |
373 | ADV7511_POWER_POWER_DOWN, | 377 | ADV7511_POWER_POWER_DOWN, |
374 | ADV7511_POWER_POWER_DOWN); | 378 | ADV7511_POWER_POWER_DOWN); |
375 | regcache_mark_dirty(adv7511->regmap); | 379 | regcache_mark_dirty(adv7511->regmap); |
380 | } | ||
376 | 381 | ||
382 | static void adv7511_power_off(struct adv7511 *adv7511) | ||
383 | { | ||
384 | __adv7511_power_off(adv7511); | ||
377 | if (adv7511->type == ADV7533) | 385 | if (adv7511->type == ADV7533) |
378 | adv7533_dsi_power_off(adv7511); | 386 | adv7533_dsi_power_off(adv7511); |
379 | |||
380 | adv7511->powered = false; | 387 | adv7511->powered = false; |
381 | } | 388 | } |
382 | 389 | ||
@@ -402,6 +409,27 @@ static bool adv7511_hpd(struct adv7511 *adv7511) | |||
402 | return false; | 409 | return false; |
403 | } | 410 | } |
404 | 411 | ||
412 | static void adv7511_hpd_work(struct work_struct *work) | ||
413 | { | ||
414 | struct adv7511 *adv7511 = container_of(work, struct adv7511, hpd_work); | ||
415 | enum drm_connector_status status; | ||
416 | unsigned int val; | ||
417 | int ret; | ||
418 | |||
419 | ret = regmap_read(adv7511->regmap, ADV7511_REG_STATUS, &val); | ||
420 | if (ret < 0) | ||
421 | status = connector_status_disconnected; | ||
422 | else if (val & ADV7511_STATUS_HPD) | ||
423 | status = connector_status_connected; | ||
424 | else | ||
425 | status = connector_status_disconnected; | ||
426 | |||
427 | if (adv7511->connector.status != status) { | ||
428 | adv7511->connector.status = status; | ||
429 | drm_kms_helper_hotplug_event(adv7511->connector.dev); | ||
430 | } | ||
431 | } | ||
432 | |||
405 | static int adv7511_irq_process(struct adv7511 *adv7511, bool process_hpd) | 433 | static int adv7511_irq_process(struct adv7511 *adv7511, bool process_hpd) |
406 | { | 434 | { |
407 | unsigned int irq0, irq1; | 435 | unsigned int irq0, irq1; |
@@ -419,7 +447,7 @@ static int adv7511_irq_process(struct adv7511 *adv7511, bool process_hpd) | |||
419 | regmap_write(adv7511->regmap, ADV7511_REG_INT(1), irq1); | 447 | regmap_write(adv7511->regmap, ADV7511_REG_INT(1), irq1); |
420 | 448 | ||
421 | if (process_hpd && irq0 & ADV7511_INT0_HPD && adv7511->bridge.encoder) | 449 | if (process_hpd && irq0 & ADV7511_INT0_HPD && adv7511->bridge.encoder) |
422 | drm_helper_hpd_irq_event(adv7511->connector.dev); | 450 | schedule_work(&adv7511->hpd_work); |
423 | 451 | ||
424 | if (irq0 & ADV7511_INT0_EDID_READY || irq1 & ADV7511_INT1_DDC_ERROR) { | 452 | if (irq0 & ADV7511_INT0_EDID_READY || irq1 & ADV7511_INT1_DDC_ERROR) { |
425 | adv7511->edid_read = true; | 453 | adv7511->edid_read = true; |
@@ -546,23 +574,20 @@ static int adv7511_get_modes(struct adv7511 *adv7511, | |||
546 | 574 | ||
547 | /* Reading the EDID only works if the device is powered */ | 575 | /* Reading the EDID only works if the device is powered */ |
548 | if (!adv7511->powered) { | 576 | if (!adv7511->powered) { |
549 | regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER, | 577 | unsigned int edid_i2c_addr = |
550 | ADV7511_POWER_POWER_DOWN, 0); | 578 | (adv7511->i2c_main->addr << 1) + 4; |
551 | if (adv7511->i2c_main->irq) { | 579 | |
552 | regmap_write(adv7511->regmap, ADV7511_REG_INT_ENABLE(0), | 580 | __adv7511_power_on(adv7511); |
553 | ADV7511_INT0_EDID_READY); | 581 | |
554 | regmap_write(adv7511->regmap, ADV7511_REG_INT_ENABLE(1), | 582 | /* Reset the EDID_I2C_ADDR register as it might be cleared */ |
555 | ADV7511_INT1_DDC_ERROR); | 583 | regmap_write(adv7511->regmap, ADV7511_REG_EDID_I2C_ADDR, |
556 | } | 584 | edid_i2c_addr); |
557 | adv7511->current_edid_segment = -1; | ||
558 | } | 585 | } |
559 | 586 | ||
560 | edid = drm_do_get_edid(connector, adv7511_get_edid_block, adv7511); | 587 | edid = drm_do_get_edid(connector, adv7511_get_edid_block, adv7511); |
561 | 588 | ||
562 | if (!adv7511->powered) | 589 | if (!adv7511->powered) |
563 | regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER, | 590 | __adv7511_power_off(adv7511); |
564 | ADV7511_POWER_POWER_DOWN, | ||
565 | ADV7511_POWER_POWER_DOWN); | ||
566 | 591 | ||
567 | kfree(adv7511->edid); | 592 | kfree(adv7511->edid); |
568 | adv7511->edid = edid; | 593 | adv7511->edid = edid; |
@@ -825,6 +850,10 @@ static int adv7511_bridge_attach(struct drm_bridge *bridge) | |||
825 | if (adv->type == ADV7533) | 850 | if (adv->type == ADV7533) |
826 | ret = adv7533_attach_dsi(adv); | 851 | ret = adv7533_attach_dsi(adv); |
827 | 852 | ||
853 | if (adv->i2c_main->irq) | ||
854 | regmap_write(adv->regmap, ADV7511_REG_INT_ENABLE(0), | ||
855 | ADV7511_INT0_HPD); | ||
856 | |||
828 | return ret; | 857 | return ret; |
829 | } | 858 | } |
830 | 859 | ||
@@ -839,6 +868,58 @@ static struct drm_bridge_funcs adv7511_bridge_funcs = { | |||
839 | * Probe & remove | 868 | * Probe & remove |
840 | */ | 869 | */ |
841 | 870 | ||
871 | static const char * const adv7511_supply_names[] = { | ||
872 | "avdd", | ||
873 | "dvdd", | ||
874 | "pvdd", | ||
875 | "bgvdd", | ||
876 | "dvdd-3v", | ||
877 | }; | ||
878 | |||
879 | static const char * const adv7533_supply_names[] = { | ||
880 | "avdd", | ||
881 | "dvdd", | ||
882 | "pvdd", | ||
883 | "a2vdd", | ||
884 | "v3p3", | ||
885 | "v1p2", | ||
886 | }; | ||
887 | |||
888 | static int adv7511_init_regulators(struct adv7511 *adv) | ||
889 | { | ||
890 | struct device *dev = &adv->i2c_main->dev; | ||
891 | const char * const *supply_names; | ||
892 | unsigned int i; | ||
893 | int ret; | ||
894 | |||
895 | if (adv->type == ADV7511) { | ||
896 | supply_names = adv7511_supply_names; | ||
897 | adv->num_supplies = ARRAY_SIZE(adv7511_supply_names); | ||
898 | } else { | ||
899 | supply_names = adv7533_supply_names; | ||
900 | adv->num_supplies = ARRAY_SIZE(adv7533_supply_names); | ||
901 | } | ||
902 | |||
903 | adv->supplies = devm_kcalloc(dev, adv->num_supplies, | ||
904 | sizeof(*adv->supplies), GFP_KERNEL); | ||
905 | if (!adv->supplies) | ||
906 | return -ENOMEM; | ||
907 | |||
908 | for (i = 0; i < adv->num_supplies; i++) | ||
909 | adv->supplies[i].supply = supply_names[i]; | ||
910 | |||
911 | ret = devm_regulator_bulk_get(dev, adv->num_supplies, adv->supplies); | ||
912 | if (ret) | ||
913 | return ret; | ||
914 | |||
915 | return regulator_bulk_enable(adv->num_supplies, adv->supplies); | ||
916 | } | ||
917 | |||
918 | static void adv7511_uninit_regulators(struct adv7511 *adv) | ||
919 | { | ||
920 | regulator_bulk_disable(adv->num_supplies, adv->supplies); | ||
921 | } | ||
922 | |||
842 | static int adv7511_parse_dt(struct device_node *np, | 923 | static int adv7511_parse_dt(struct device_node *np, |
843 | struct adv7511_link_config *config) | 924 | struct adv7511_link_config *config) |
844 | { | 925 | { |
@@ -939,6 +1020,7 @@ static int adv7511_probe(struct i2c_client *i2c, const struct i2c_device_id *id) | |||
939 | if (!adv7511) | 1020 | if (!adv7511) |
940 | return -ENOMEM; | 1021 | return -ENOMEM; |
941 | 1022 | ||
1023 | adv7511->i2c_main = i2c; | ||
942 | adv7511->powered = false; | 1024 | adv7511->powered = false; |
943 | adv7511->status = connector_status_disconnected; | 1025 | adv7511->status = connector_status_disconnected; |
944 | 1026 | ||
@@ -956,13 +1038,21 @@ static int adv7511_probe(struct i2c_client *i2c, const struct i2c_device_id *id) | |||
956 | if (ret) | 1038 | if (ret) |
957 | return ret; | 1039 | return ret; |
958 | 1040 | ||
1041 | ret = adv7511_init_regulators(adv7511); | ||
1042 | if (ret) { | ||
1043 | dev_err(dev, "failed to init regulators\n"); | ||
1044 | return ret; | ||
1045 | } | ||
1046 | |||
959 | /* | 1047 | /* |
960 | * The power down GPIO is optional. If present, toggle it from active to | 1048 | * The power down GPIO is optional. If present, toggle it from active to |
961 | * inactive to wake up the encoder. | 1049 | * inactive to wake up the encoder. |
962 | */ | 1050 | */ |
963 | adv7511->gpio_pd = devm_gpiod_get_optional(dev, "pd", GPIOD_OUT_HIGH); | 1051 | adv7511->gpio_pd = devm_gpiod_get_optional(dev, "pd", GPIOD_OUT_HIGH); |
964 | if (IS_ERR(adv7511->gpio_pd)) | 1052 | if (IS_ERR(adv7511->gpio_pd)) { |
965 | return PTR_ERR(adv7511->gpio_pd); | 1053 | ret = PTR_ERR(adv7511->gpio_pd); |
1054 | goto uninit_regulators; | ||
1055 | } | ||
966 | 1056 | ||
967 | if (adv7511->gpio_pd) { | 1057 | if (adv7511->gpio_pd) { |
968 | mdelay(5); | 1058 | mdelay(5); |
@@ -970,12 +1060,14 @@ static int adv7511_probe(struct i2c_client *i2c, const struct i2c_device_id *id) | |||
970 | } | 1060 | } |
971 | 1061 | ||
972 | adv7511->regmap = devm_regmap_init_i2c(i2c, &adv7511_regmap_config); | 1062 | adv7511->regmap = devm_regmap_init_i2c(i2c, &adv7511_regmap_config); |
973 | if (IS_ERR(adv7511->regmap)) | 1063 | if (IS_ERR(adv7511->regmap)) { |
974 | return PTR_ERR(adv7511->regmap); | 1064 | ret = PTR_ERR(adv7511->regmap); |
1065 | goto uninit_regulators; | ||
1066 | } | ||
975 | 1067 | ||
976 | ret = regmap_read(adv7511->regmap, ADV7511_REG_CHIP_REVISION, &val); | 1068 | ret = regmap_read(adv7511->regmap, ADV7511_REG_CHIP_REVISION, &val); |
977 | if (ret) | 1069 | if (ret) |
978 | return ret; | 1070 | goto uninit_regulators; |
979 | dev_dbg(dev, "Rev. %d\n", val); | 1071 | dev_dbg(dev, "Rev. %d\n", val); |
980 | 1072 | ||
981 | if (adv7511->type == ADV7511) | 1073 | if (adv7511->type == ADV7511) |
@@ -985,7 +1077,7 @@ static int adv7511_probe(struct i2c_client *i2c, const struct i2c_device_id *id) | |||
985 | else | 1077 | else |
986 | ret = adv7533_patch_registers(adv7511); | 1078 | ret = adv7533_patch_registers(adv7511); |
987 | if (ret) | 1079 | if (ret) |
988 | return ret; | 1080 | goto uninit_regulators; |
989 | 1081 | ||
990 | regmap_write(adv7511->regmap, ADV7511_REG_EDID_I2C_ADDR, edid_i2c_addr); | 1082 | regmap_write(adv7511->regmap, ADV7511_REG_EDID_I2C_ADDR, edid_i2c_addr); |
991 | regmap_write(adv7511->regmap, ADV7511_REG_PACKET_I2C_ADDR, | 1083 | regmap_write(adv7511->regmap, ADV7511_REG_PACKET_I2C_ADDR, |
@@ -995,10 +1087,11 @@ static int adv7511_probe(struct i2c_client *i2c, const struct i2c_device_id *id) | |||
995 | 1087 | ||
996 | adv7511_packet_disable(adv7511, 0xffff); | 1088 | adv7511_packet_disable(adv7511, 0xffff); |
997 | 1089 | ||
998 | adv7511->i2c_main = i2c; | ||
999 | adv7511->i2c_edid = i2c_new_dummy(i2c->adapter, edid_i2c_addr >> 1); | 1090 | adv7511->i2c_edid = i2c_new_dummy(i2c->adapter, edid_i2c_addr >> 1); |
1000 | if (!adv7511->i2c_edid) | 1091 | if (!adv7511->i2c_edid) { |
1001 | return -ENOMEM; | 1092 | ret = -ENOMEM; |
1093 | goto uninit_regulators; | ||
1094 | } | ||
1002 | 1095 | ||
1003 | if (adv7511->type == ADV7533) { | 1096 | if (adv7511->type == ADV7533) { |
1004 | ret = adv7533_init_cec(adv7511); | 1097 | ret = adv7533_init_cec(adv7511); |
@@ -1006,6 +1099,8 @@ static int adv7511_probe(struct i2c_client *i2c, const struct i2c_device_id *id) | |||
1006 | goto err_i2c_unregister_edid; | 1099 | goto err_i2c_unregister_edid; |
1007 | } | 1100 | } |
1008 | 1101 | ||
1102 | INIT_WORK(&adv7511->hpd_work, adv7511_hpd_work); | ||
1103 | |||
1009 | if (i2c->irq) { | 1104 | if (i2c->irq) { |
1010 | init_waitqueue_head(&adv7511->wq); | 1105 | init_waitqueue_head(&adv7511->wq); |
1011 | 1106 | ||
@@ -1045,6 +1140,8 @@ err_unregister_cec: | |||
1045 | adv7533_uninit_cec(adv7511); | 1140 | adv7533_uninit_cec(adv7511); |
1046 | err_i2c_unregister_edid: | 1141 | err_i2c_unregister_edid: |
1047 | i2c_unregister_device(adv7511->i2c_edid); | 1142 | i2c_unregister_device(adv7511->i2c_edid); |
1143 | uninit_regulators: | ||
1144 | adv7511_uninit_regulators(adv7511); | ||
1048 | 1145 | ||
1049 | return ret; | 1146 | return ret; |
1050 | } | 1147 | } |
@@ -1058,6 +1155,8 @@ static int adv7511_remove(struct i2c_client *i2c) | |||
1058 | adv7533_uninit_cec(adv7511); | 1155 | adv7533_uninit_cec(adv7511); |
1059 | } | 1156 | } |
1060 | 1157 | ||
1158 | adv7511_uninit_regulators(adv7511); | ||
1159 | |||
1061 | drm_bridge_remove(&adv7511->bridge); | 1160 | drm_bridge_remove(&adv7511->bridge); |
1062 | 1161 | ||
1063 | adv7511_audio_exit(adv7511); | 1162 | adv7511_audio_exit(adv7511); |
diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c index f5009ae39b89..4fda0717e789 100644 --- a/drivers/gpu/drm/bridge/dw-hdmi.c +++ b/drivers/gpu/drm/bridge/dw-hdmi.c | |||
@@ -113,13 +113,20 @@ struct dw_hdmi_i2c { | |||
113 | bool is_regaddr; | 113 | bool is_regaddr; |
114 | }; | 114 | }; |
115 | 115 | ||
116 | struct dw_hdmi_phy_data { | ||
117 | enum dw_hdmi_phy_type type; | ||
118 | const char *name; | ||
119 | bool has_svsret; | ||
120 | }; | ||
121 | |||
116 | struct dw_hdmi { | 122 | struct dw_hdmi { |
117 | struct drm_connector connector; | 123 | struct drm_connector connector; |
118 | struct drm_encoder *encoder; | 124 | struct drm_bridge bridge; |
119 | struct drm_bridge *bridge; | ||
120 | 125 | ||
121 | struct platform_device *audio; | ||
122 | enum dw_hdmi_devtype dev_type; | 126 | enum dw_hdmi_devtype dev_type; |
127 | unsigned int version; | ||
128 | |||
129 | struct platform_device *audio; | ||
123 | struct device *dev; | 130 | struct device *dev; |
124 | struct clk *isfr_clk; | 131 | struct clk *isfr_clk; |
125 | struct clk *iahb_clk; | 132 | struct clk *iahb_clk; |
@@ -133,7 +140,9 @@ struct dw_hdmi { | |||
133 | u8 edid[HDMI_EDID_LEN]; | 140 | u8 edid[HDMI_EDID_LEN]; |
134 | bool cable_plugin; | 141 | bool cable_plugin; |
135 | 142 | ||
143 | const struct dw_hdmi_phy_data *phy; | ||
136 | bool phy_enabled; | 144 | bool phy_enabled; |
145 | |||
137 | struct drm_display_mode previous_mode; | 146 | struct drm_display_mode previous_mode; |
138 | 147 | ||
139 | struct i2c_adapter *ddc; | 148 | struct i2c_adapter *ddc; |
@@ -868,7 +877,7 @@ static bool hdmi_phy_wait_i2c_done(struct dw_hdmi *hdmi, int msec) | |||
868 | return true; | 877 | return true; |
869 | } | 878 | } |
870 | 879 | ||
871 | static void __hdmi_phy_i2c_write(struct dw_hdmi *hdmi, unsigned short data, | 880 | static void hdmi_phy_i2c_write(struct dw_hdmi *hdmi, unsigned short data, |
872 | unsigned char addr) | 881 | unsigned char addr) |
873 | { | 882 | { |
874 | hdmi_writeb(hdmi, 0xFF, HDMI_IH_I2CMPHY_STAT0); | 883 | hdmi_writeb(hdmi, 0xFF, HDMI_IH_I2CMPHY_STAT0); |
@@ -882,13 +891,6 @@ static void __hdmi_phy_i2c_write(struct dw_hdmi *hdmi, unsigned short data, | |||
882 | hdmi_phy_wait_i2c_done(hdmi, 1000); | 891 | hdmi_phy_wait_i2c_done(hdmi, 1000); |
883 | } | 892 | } |
884 | 893 | ||
885 | static int hdmi_phy_i2c_write(struct dw_hdmi *hdmi, unsigned short data, | ||
886 | unsigned char addr) | ||
887 | { | ||
888 | __hdmi_phy_i2c_write(hdmi, data, addr); | ||
889 | return 0; | ||
890 | } | ||
891 | |||
892 | static void dw_hdmi_phy_enable_powerdown(struct dw_hdmi *hdmi, bool enable) | 894 | static void dw_hdmi_phy_enable_powerdown(struct dw_hdmi *hdmi, bool enable) |
893 | { | 895 | { |
894 | hdmi_mask_writeb(hdmi, !enable, HDMI_PHY_CONF0, | 896 | hdmi_mask_writeb(hdmi, !enable, HDMI_PHY_CONF0, |
@@ -903,11 +905,11 @@ static void dw_hdmi_phy_enable_tmds(struct dw_hdmi *hdmi, u8 enable) | |||
903 | HDMI_PHY_CONF0_ENTMDS_MASK); | 905 | HDMI_PHY_CONF0_ENTMDS_MASK); |
904 | } | 906 | } |
905 | 907 | ||
906 | static void dw_hdmi_phy_enable_spare(struct dw_hdmi *hdmi, u8 enable) | 908 | static void dw_hdmi_phy_enable_svsret(struct dw_hdmi *hdmi, u8 enable) |
907 | { | 909 | { |
908 | hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0, | 910 | hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0, |
909 | HDMI_PHY_CONF0_SPARECTRL_OFFSET, | 911 | HDMI_PHY_CONF0_SVSRET_OFFSET, |
910 | HDMI_PHY_CONF0_SPARECTRL_MASK); | 912 | HDMI_PHY_CONF0_SVSRET_MASK); |
911 | } | 913 | } |
912 | 914 | ||
913 | static void dw_hdmi_phy_gen2_pddq(struct dw_hdmi *hdmi, u8 enable) | 915 | static void dw_hdmi_phy_gen2_pddq(struct dw_hdmi *hdmi, u8 enable) |
@@ -938,34 +940,14 @@ static void dw_hdmi_phy_sel_interface_control(struct dw_hdmi *hdmi, u8 enable) | |||
938 | HDMI_PHY_CONF0_SELDIPIF_MASK); | 940 | HDMI_PHY_CONF0_SELDIPIF_MASK); |
939 | } | 941 | } |
940 | 942 | ||
941 | static int hdmi_phy_configure(struct dw_hdmi *hdmi, unsigned char prep, | 943 | static int hdmi_phy_configure(struct dw_hdmi *hdmi, int cscon) |
942 | unsigned char res, int cscon) | ||
943 | { | 944 | { |
944 | unsigned res_idx; | ||
945 | u8 val, msec; | 945 | u8 val, msec; |
946 | const struct dw_hdmi_plat_data *pdata = hdmi->plat_data; | 946 | const struct dw_hdmi_plat_data *pdata = hdmi->plat_data; |
947 | const struct dw_hdmi_mpll_config *mpll_config = pdata->mpll_cfg; | 947 | const struct dw_hdmi_mpll_config *mpll_config = pdata->mpll_cfg; |
948 | const struct dw_hdmi_curr_ctrl *curr_ctrl = pdata->cur_ctr; | 948 | const struct dw_hdmi_curr_ctrl *curr_ctrl = pdata->cur_ctr; |
949 | const struct dw_hdmi_phy_config *phy_config = pdata->phy_config; | 949 | const struct dw_hdmi_phy_config *phy_config = pdata->phy_config; |
950 | 950 | ||
951 | if (prep) | ||
952 | return -EINVAL; | ||
953 | |||
954 | switch (res) { | ||
955 | case 0: /* color resolution 0 is 8 bit colour depth */ | ||
956 | case 8: | ||
957 | res_idx = DW_HDMI_RES_8; | ||
958 | break; | ||
959 | case 10: | ||
960 | res_idx = DW_HDMI_RES_10; | ||
961 | break; | ||
962 | case 12: | ||
963 | res_idx = DW_HDMI_RES_12; | ||
964 | break; | ||
965 | default: | ||
966 | return -EINVAL; | ||
967 | } | ||
968 | |||
969 | /* PLL/MPLL Cfg - always match on final entry */ | 951 | /* PLL/MPLL Cfg - always match on final entry */ |
970 | for (; mpll_config->mpixelclock != ~0UL; mpll_config++) | 952 | for (; mpll_config->mpixelclock != ~0UL; mpll_config++) |
971 | if (hdmi->hdmi_data.video_mode.mpixelclock <= | 953 | if (hdmi->hdmi_data.video_mode.mpixelclock <= |
@@ -1004,9 +986,13 @@ static int hdmi_phy_configure(struct dw_hdmi *hdmi, unsigned char prep, | |||
1004 | /* gen2 pddq */ | 986 | /* gen2 pddq */ |
1005 | dw_hdmi_phy_gen2_pddq(hdmi, 1); | 987 | dw_hdmi_phy_gen2_pddq(hdmi, 1); |
1006 | 988 | ||
1007 | /* PHY reset */ | 989 | /* Leave low power consumption mode by asserting SVSRET. */ |
1008 | hdmi_writeb(hdmi, HDMI_MC_PHYRSTZ_DEASSERT, HDMI_MC_PHYRSTZ); | 990 | if (hdmi->phy->has_svsret) |
1009 | hdmi_writeb(hdmi, HDMI_MC_PHYRSTZ_ASSERT, HDMI_MC_PHYRSTZ); | 991 | dw_hdmi_phy_enable_svsret(hdmi, 1); |
992 | |||
993 | /* PHY reset. The reset signal is active high on Gen2 PHYs. */ | ||
994 | hdmi_writeb(hdmi, HDMI_MC_PHYRSTZ_PHYRSTZ, HDMI_MC_PHYRSTZ); | ||
995 | hdmi_writeb(hdmi, 0, HDMI_MC_PHYRSTZ); | ||
1010 | 996 | ||
1011 | hdmi_writeb(hdmi, HDMI_MC_HEACPHY_RST_ASSERT, HDMI_MC_HEACPHY_RST); | 997 | hdmi_writeb(hdmi, HDMI_MC_HEACPHY_RST_ASSERT, HDMI_MC_HEACPHY_RST); |
1012 | 998 | ||
@@ -1015,21 +1001,26 @@ static int hdmi_phy_configure(struct dw_hdmi *hdmi, unsigned char prep, | |||
1015 | HDMI_PHY_I2CM_SLAVE_ADDR); | 1001 | HDMI_PHY_I2CM_SLAVE_ADDR); |
1016 | hdmi_phy_test_clear(hdmi, 0); | 1002 | hdmi_phy_test_clear(hdmi, 0); |
1017 | 1003 | ||
1018 | hdmi_phy_i2c_write(hdmi, mpll_config->res[res_idx].cpce, 0x06); | 1004 | hdmi_phy_i2c_write(hdmi, mpll_config->res[0].cpce, |
1019 | hdmi_phy_i2c_write(hdmi, mpll_config->res[res_idx].gmp, 0x15); | 1005 | HDMI_3D_TX_PHY_CPCE_CTRL); |
1020 | 1006 | hdmi_phy_i2c_write(hdmi, mpll_config->res[0].gmp, | |
1021 | /* CURRCTRL */ | 1007 | HDMI_3D_TX_PHY_GMPCTRL); |
1022 | hdmi_phy_i2c_write(hdmi, curr_ctrl->curr[res_idx], 0x10); | 1008 | hdmi_phy_i2c_write(hdmi, curr_ctrl->curr[0], |
1009 | HDMI_3D_TX_PHY_CURRCTRL); | ||
1023 | 1010 | ||
1024 | hdmi_phy_i2c_write(hdmi, 0x0000, 0x13); /* PLLPHBYCTRL */ | 1011 | hdmi_phy_i2c_write(hdmi, 0, HDMI_3D_TX_PHY_PLLPHBYCTRL); |
1025 | hdmi_phy_i2c_write(hdmi, 0x0006, 0x17); | 1012 | hdmi_phy_i2c_write(hdmi, HDMI_3D_TX_PHY_MSM_CTRL_CKO_SEL_FB_CLK, |
1013 | HDMI_3D_TX_PHY_MSM_CTRL); | ||
1026 | 1014 | ||
1027 | hdmi_phy_i2c_write(hdmi, phy_config->term, 0x19); /* TXTERM */ | 1015 | hdmi_phy_i2c_write(hdmi, phy_config->term, HDMI_3D_TX_PHY_TXTERM); |
1028 | hdmi_phy_i2c_write(hdmi, phy_config->sym_ctr, 0x09); /* CKSYMTXCTRL */ | 1016 | hdmi_phy_i2c_write(hdmi, phy_config->sym_ctr, |
1029 | hdmi_phy_i2c_write(hdmi, phy_config->vlev_ctr, 0x0E); /* VLEVCTRL */ | 1017 | HDMI_3D_TX_PHY_CKSYMTXCTRL); |
1018 | hdmi_phy_i2c_write(hdmi, phy_config->vlev_ctr, | ||
1019 | HDMI_3D_TX_PHY_VLEVCTRL); | ||
1030 | 1020 | ||
1031 | /* REMOVE CLK TERM */ | 1021 | /* Override and disable clock termination. */ |
1032 | hdmi_phy_i2c_write(hdmi, 0x8000, 0x05); /* CKCALCTRL */ | 1022 | hdmi_phy_i2c_write(hdmi, HDMI_3D_TX_PHY_CKCALCTRL_OVERRIDE, |
1023 | HDMI_3D_TX_PHY_CKCALCTRL); | ||
1033 | 1024 | ||
1034 | dw_hdmi_phy_enable_powerdown(hdmi, false); | 1025 | dw_hdmi_phy_enable_powerdown(hdmi, false); |
1035 | 1026 | ||
@@ -1041,10 +1032,7 @@ static int hdmi_phy_configure(struct dw_hdmi *hdmi, unsigned char prep, | |||
1041 | dw_hdmi_phy_gen2_txpwron(hdmi, 1); | 1032 | dw_hdmi_phy_gen2_txpwron(hdmi, 1); |
1042 | dw_hdmi_phy_gen2_pddq(hdmi, 0); | 1033 | dw_hdmi_phy_gen2_pddq(hdmi, 0); |
1043 | 1034 | ||
1044 | if (hdmi->dev_type == RK3288_HDMI) | 1035 | /* Wait for PHY PLL lock */ |
1045 | dw_hdmi_phy_enable_spare(hdmi, 1); | ||
1046 | |||
1047 | /*Wait for PHY PLL lock */ | ||
1048 | msec = 5; | 1036 | msec = 5; |
1049 | do { | 1037 | do { |
1050 | val = hdmi_readb(hdmi, HDMI_PHY_STAT0) & HDMI_PHY_TX_PHY_LOCK; | 1038 | val = hdmi_readb(hdmi, HDMI_PHY_STAT0) & HDMI_PHY_TX_PHY_LOCK; |
@@ -1079,7 +1067,7 @@ static int dw_hdmi_phy_init(struct dw_hdmi *hdmi) | |||
1079 | dw_hdmi_phy_enable_powerdown(hdmi, true); | 1067 | dw_hdmi_phy_enable_powerdown(hdmi, true); |
1080 | 1068 | ||
1081 | /* Enable CSC */ | 1069 | /* Enable CSC */ |
1082 | ret = hdmi_phy_configure(hdmi, 0, 8, cscon); | 1070 | ret = hdmi_phy_configure(hdmi, cscon); |
1083 | if (ret) | 1071 | if (ret) |
1084 | return ret; | 1072 | return ret; |
1085 | } | 1073 | } |
@@ -1351,19 +1339,38 @@ static void hdmi_enable_audio_clk(struct dw_hdmi *hdmi) | |||
1351 | /* Workaround to clear the overflow condition */ | 1339 | /* Workaround to clear the overflow condition */ |
1352 | static void dw_hdmi_clear_overflow(struct dw_hdmi *hdmi) | 1340 | static void dw_hdmi_clear_overflow(struct dw_hdmi *hdmi) |
1353 | { | 1341 | { |
1354 | int count; | 1342 | unsigned int count; |
1343 | unsigned int i; | ||
1355 | u8 val; | 1344 | u8 val; |
1356 | 1345 | ||
1357 | /* TMDS software reset */ | 1346 | /* |
1358 | hdmi_writeb(hdmi, (u8)~HDMI_MC_SWRSTZ_TMDSSWRST_REQ, HDMI_MC_SWRSTZ); | 1347 | * Under some circumstances the Frame Composer arithmetic unit can miss |
1348 | * an FC register write due to being busy processing the previous one. | ||
1349 | * The issue can be worked around by issuing a TMDS software reset and | ||
1350 | * then write one of the FC registers several times. | ||
1351 | * | ||
1352 | * The number of iterations matters and depends on the HDMI TX revision | ||
1353 | * (and possibly on the platform). So far only i.MX6Q (v1.30a) and | ||
1354 | * i.MX6DL (v1.31a) have been identified as needing the workaround, with | ||
1355 | * 4 and 1 iterations respectively. | ||
1356 | */ | ||
1359 | 1357 | ||
1360 | val = hdmi_readb(hdmi, HDMI_FC_INVIDCONF); | 1358 | switch (hdmi->version) { |
1361 | if (hdmi->dev_type == IMX6DL_HDMI) { | 1359 | case 0x130a: |
1362 | hdmi_writeb(hdmi, val, HDMI_FC_INVIDCONF); | 1360 | count = 4; |
1361 | break; | ||
1362 | case 0x131a: | ||
1363 | count = 1; | ||
1364 | break; | ||
1365 | default: | ||
1363 | return; | 1366 | return; |
1364 | } | 1367 | } |
1365 | 1368 | ||
1366 | for (count = 0; count < 4; count++) | 1369 | /* TMDS software reset */ |
1370 | hdmi_writeb(hdmi, (u8)~HDMI_MC_SWRSTZ_TMDSSWRST_REQ, HDMI_MC_SWRSTZ); | ||
1371 | |||
1372 | val = hdmi_readb(hdmi, HDMI_FC_INVIDCONF); | ||
1373 | for (i = 0; i < count; i++) | ||
1367 | hdmi_writeb(hdmi, val, HDMI_FC_INVIDCONF); | 1374 | hdmi_writeb(hdmi, val, HDMI_FC_INVIDCONF); |
1368 | } | 1375 | } |
1369 | 1376 | ||
@@ -1586,42 +1593,6 @@ static void dw_hdmi_update_phy_mask(struct dw_hdmi *hdmi) | |||
1586 | hdmi_writeb(hdmi, hdmi->phy_mask, HDMI_PHY_MASK0); | 1593 | hdmi_writeb(hdmi, hdmi->phy_mask, HDMI_PHY_MASK0); |
1587 | } | 1594 | } |
1588 | 1595 | ||
1589 | static void dw_hdmi_bridge_mode_set(struct drm_bridge *bridge, | ||
1590 | struct drm_display_mode *orig_mode, | ||
1591 | struct drm_display_mode *mode) | ||
1592 | { | ||
1593 | struct dw_hdmi *hdmi = bridge->driver_private; | ||
1594 | |||
1595 | mutex_lock(&hdmi->mutex); | ||
1596 | |||
1597 | /* Store the display mode for plugin/DKMS poweron events */ | ||
1598 | memcpy(&hdmi->previous_mode, mode, sizeof(hdmi->previous_mode)); | ||
1599 | |||
1600 | mutex_unlock(&hdmi->mutex); | ||
1601 | } | ||
1602 | |||
1603 | static void dw_hdmi_bridge_disable(struct drm_bridge *bridge) | ||
1604 | { | ||
1605 | struct dw_hdmi *hdmi = bridge->driver_private; | ||
1606 | |||
1607 | mutex_lock(&hdmi->mutex); | ||
1608 | hdmi->disabled = true; | ||
1609 | dw_hdmi_update_power(hdmi); | ||
1610 | dw_hdmi_update_phy_mask(hdmi); | ||
1611 | mutex_unlock(&hdmi->mutex); | ||
1612 | } | ||
1613 | |||
1614 | static void dw_hdmi_bridge_enable(struct drm_bridge *bridge) | ||
1615 | { | ||
1616 | struct dw_hdmi *hdmi = bridge->driver_private; | ||
1617 | |||
1618 | mutex_lock(&hdmi->mutex); | ||
1619 | hdmi->disabled = false; | ||
1620 | dw_hdmi_update_power(hdmi); | ||
1621 | dw_hdmi_update_phy_mask(hdmi); | ||
1622 | mutex_unlock(&hdmi->mutex); | ||
1623 | } | ||
1624 | |||
1625 | static enum drm_connector_status | 1596 | static enum drm_connector_status |
1626 | dw_hdmi_connector_detect(struct drm_connector *connector, bool force) | 1597 | dw_hdmi_connector_detect(struct drm_connector *connector, bool force) |
1627 | { | 1598 | { |
@@ -1714,7 +1685,63 @@ static const struct drm_connector_helper_funcs dw_hdmi_connector_helper_funcs = | |||
1714 | .best_encoder = drm_atomic_helper_best_encoder, | 1685 | .best_encoder = drm_atomic_helper_best_encoder, |
1715 | }; | 1686 | }; |
1716 | 1687 | ||
1688 | static int dw_hdmi_bridge_attach(struct drm_bridge *bridge) | ||
1689 | { | ||
1690 | struct dw_hdmi *hdmi = bridge->driver_private; | ||
1691 | struct drm_encoder *encoder = bridge->encoder; | ||
1692 | struct drm_connector *connector = &hdmi->connector; | ||
1693 | |||
1694 | connector->interlace_allowed = 1; | ||
1695 | connector->polled = DRM_CONNECTOR_POLL_HPD; | ||
1696 | |||
1697 | drm_connector_helper_add(connector, &dw_hdmi_connector_helper_funcs); | ||
1698 | |||
1699 | drm_connector_init(bridge->dev, connector, &dw_hdmi_connector_funcs, | ||
1700 | DRM_MODE_CONNECTOR_HDMIA); | ||
1701 | |||
1702 | drm_mode_connector_attach_encoder(connector, encoder); | ||
1703 | |||
1704 | return 0; | ||
1705 | } | ||
1706 | |||
1707 | static void dw_hdmi_bridge_mode_set(struct drm_bridge *bridge, | ||
1708 | struct drm_display_mode *orig_mode, | ||
1709 | struct drm_display_mode *mode) | ||
1710 | { | ||
1711 | struct dw_hdmi *hdmi = bridge->driver_private; | ||
1712 | |||
1713 | mutex_lock(&hdmi->mutex); | ||
1714 | |||
1715 | /* Store the display mode for plugin/DKMS poweron events */ | ||
1716 | memcpy(&hdmi->previous_mode, mode, sizeof(hdmi->previous_mode)); | ||
1717 | |||
1718 | mutex_unlock(&hdmi->mutex); | ||
1719 | } | ||
1720 | |||
1721 | static void dw_hdmi_bridge_disable(struct drm_bridge *bridge) | ||
1722 | { | ||
1723 | struct dw_hdmi *hdmi = bridge->driver_private; | ||
1724 | |||
1725 | mutex_lock(&hdmi->mutex); | ||
1726 | hdmi->disabled = true; | ||
1727 | dw_hdmi_update_power(hdmi); | ||
1728 | dw_hdmi_update_phy_mask(hdmi); | ||
1729 | mutex_unlock(&hdmi->mutex); | ||
1730 | } | ||
1731 | |||
1732 | static void dw_hdmi_bridge_enable(struct drm_bridge *bridge) | ||
1733 | { | ||
1734 | struct dw_hdmi *hdmi = bridge->driver_private; | ||
1735 | |||
1736 | mutex_lock(&hdmi->mutex); | ||
1737 | hdmi->disabled = false; | ||
1738 | dw_hdmi_update_power(hdmi); | ||
1739 | dw_hdmi_update_phy_mask(hdmi); | ||
1740 | mutex_unlock(&hdmi->mutex); | ||
1741 | } | ||
1742 | |||
1717 | static const struct drm_bridge_funcs dw_hdmi_bridge_funcs = { | 1743 | static const struct drm_bridge_funcs dw_hdmi_bridge_funcs = { |
1744 | .attach = dw_hdmi_bridge_attach, | ||
1718 | .enable = dw_hdmi_bridge_enable, | 1745 | .enable = dw_hdmi_bridge_enable, |
1719 | .disable = dw_hdmi_bridge_disable, | 1746 | .disable = dw_hdmi_bridge_disable, |
1720 | .mode_set = dw_hdmi_bridge_mode_set, | 1747 | .mode_set = dw_hdmi_bridge_mode_set, |
@@ -1816,7 +1843,8 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id) | |||
1816 | if (intr_stat & HDMI_IH_PHY_STAT0_HPD) { | 1843 | if (intr_stat & HDMI_IH_PHY_STAT0_HPD) { |
1817 | dev_dbg(hdmi->dev, "EVENT=%s\n", | 1844 | dev_dbg(hdmi->dev, "EVENT=%s\n", |
1818 | phy_int_pol & HDMI_PHY_HPD ? "plugin" : "plugout"); | 1845 | phy_int_pol & HDMI_PHY_HPD ? "plugin" : "plugout"); |
1819 | drm_helper_hpd_irq_event(hdmi->bridge->dev); | 1846 | if (hdmi->bridge.dev) |
1847 | drm_helper_hpd_irq_event(hdmi->bridge.dev); | ||
1820 | } | 1848 | } |
1821 | 1849 | ||
1822 | hdmi_writeb(hdmi, intr_stat, HDMI_IH_PHY_STAT0); | 1850 | hdmi_writeb(hdmi, intr_stat, HDMI_IH_PHY_STAT0); |
@@ -1826,67 +1854,80 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id) | |||
1826 | return IRQ_HANDLED; | 1854 | return IRQ_HANDLED; |
1827 | } | 1855 | } |
1828 | 1856 | ||
1829 | static int dw_hdmi_register(struct drm_device *drm, struct dw_hdmi *hdmi) | 1857 | static const struct dw_hdmi_phy_data dw_hdmi_phys[] = { |
1830 | { | 1858 | { |
1831 | struct drm_encoder *encoder = hdmi->encoder; | 1859 | .type = DW_HDMI_PHY_DWC_HDMI_TX_PHY, |
1832 | struct drm_bridge *bridge; | 1860 | .name = "DWC HDMI TX PHY", |
1833 | int ret; | 1861 | }, { |
1834 | 1862 | .type = DW_HDMI_PHY_DWC_MHL_PHY_HEAC, | |
1835 | bridge = devm_kzalloc(drm->dev, sizeof(*bridge), GFP_KERNEL); | 1863 | .name = "DWC MHL PHY + HEAC PHY", |
1836 | if (!bridge) { | 1864 | .has_svsret = true, |
1837 | DRM_ERROR("Failed to allocate drm bridge\n"); | 1865 | }, { |
1838 | return -ENOMEM; | 1866 | .type = DW_HDMI_PHY_DWC_MHL_PHY, |
1839 | } | 1867 | .name = "DWC MHL PHY", |
1840 | 1868 | .has_svsret = true, | |
1841 | hdmi->bridge = bridge; | 1869 | }, { |
1842 | bridge->driver_private = hdmi; | 1870 | .type = DW_HDMI_PHY_DWC_HDMI_3D_TX_PHY_HEAC, |
1843 | bridge->funcs = &dw_hdmi_bridge_funcs; | 1871 | .name = "DWC HDMI 3D TX PHY + HEAC PHY", |
1844 | ret = drm_bridge_attach(encoder, bridge, NULL); | 1872 | }, { |
1845 | if (ret) { | 1873 | .type = DW_HDMI_PHY_DWC_HDMI_3D_TX_PHY, |
1846 | DRM_ERROR("Failed to initialize bridge with drm\n"); | 1874 | .name = "DWC HDMI 3D TX PHY", |
1847 | return -EINVAL; | 1875 | }, { |
1876 | .type = DW_HDMI_PHY_DWC_HDMI20_TX_PHY, | ||
1877 | .name = "DWC HDMI 2.0 TX PHY", | ||
1878 | .has_svsret = true, | ||
1848 | } | 1879 | } |
1880 | }; | ||
1849 | 1881 | ||
1850 | hdmi->connector.polled = DRM_CONNECTOR_POLL_HPD; | 1882 | static int dw_hdmi_detect_phy(struct dw_hdmi *hdmi) |
1883 | { | ||
1884 | unsigned int i; | ||
1885 | u8 phy_type; | ||
1851 | 1886 | ||
1852 | drm_connector_helper_add(&hdmi->connector, | 1887 | phy_type = hdmi_readb(hdmi, HDMI_CONFIG2_ID); |
1853 | &dw_hdmi_connector_helper_funcs); | ||
1854 | 1888 | ||
1855 | drm_connector_init(drm, &hdmi->connector, | 1889 | for (i = 0; i < ARRAY_SIZE(dw_hdmi_phys); ++i) { |
1856 | &dw_hdmi_connector_funcs, | 1890 | if (dw_hdmi_phys[i].type == phy_type) { |
1857 | DRM_MODE_CONNECTOR_HDMIA); | 1891 | hdmi->phy = &dw_hdmi_phys[i]; |
1892 | return 0; | ||
1893 | } | ||
1894 | } | ||
1858 | 1895 | ||
1859 | drm_mode_connector_attach_encoder(&hdmi->connector, encoder); | 1896 | if (phy_type == DW_HDMI_PHY_VENDOR_PHY) |
1897 | dev_err(hdmi->dev, "Unsupported vendor HDMI PHY\n"); | ||
1898 | else | ||
1899 | dev_err(hdmi->dev, "Unsupported HDMI PHY type (%02x)\n", | ||
1900 | phy_type); | ||
1860 | 1901 | ||
1861 | return 0; | 1902 | return -ENODEV; |
1862 | } | 1903 | } |
1863 | 1904 | ||
1864 | int dw_hdmi_bind(struct device *dev, struct device *master, | 1905 | static struct dw_hdmi * |
1865 | void *data, struct drm_encoder *encoder, | 1906 | __dw_hdmi_probe(struct platform_device *pdev, |
1866 | struct resource *iores, int irq, | 1907 | const struct dw_hdmi_plat_data *plat_data) |
1867 | const struct dw_hdmi_plat_data *plat_data) | ||
1868 | { | 1908 | { |
1869 | struct drm_device *drm = data; | 1909 | struct device *dev = &pdev->dev; |
1870 | struct device_node *np = dev->of_node; | 1910 | struct device_node *np = dev->of_node; |
1871 | struct platform_device_info pdevinfo; | 1911 | struct platform_device_info pdevinfo; |
1872 | struct device_node *ddc_node; | 1912 | struct device_node *ddc_node; |
1873 | struct dw_hdmi *hdmi; | 1913 | struct dw_hdmi *hdmi; |
1914 | struct resource *iores; | ||
1915 | int irq; | ||
1874 | int ret; | 1916 | int ret; |
1875 | u32 val = 1; | 1917 | u32 val = 1; |
1918 | u8 prod_id0; | ||
1919 | u8 prod_id1; | ||
1876 | u8 config0; | 1920 | u8 config0; |
1877 | u8 config1; | 1921 | u8 config3; |
1878 | 1922 | ||
1879 | hdmi = devm_kzalloc(dev, sizeof(*hdmi), GFP_KERNEL); | 1923 | hdmi = devm_kzalloc(dev, sizeof(*hdmi), GFP_KERNEL); |
1880 | if (!hdmi) | 1924 | if (!hdmi) |
1881 | return -ENOMEM; | 1925 | return ERR_PTR(-ENOMEM); |
1882 | |||
1883 | hdmi->connector.interlace_allowed = 1; | ||
1884 | 1926 | ||
1885 | hdmi->plat_data = plat_data; | 1927 | hdmi->plat_data = plat_data; |
1886 | hdmi->dev = dev; | 1928 | hdmi->dev = dev; |
1887 | hdmi->dev_type = plat_data->dev_type; | 1929 | hdmi->dev_type = plat_data->dev_type; |
1888 | hdmi->sample_rate = 48000; | 1930 | hdmi->sample_rate = 48000; |
1889 | hdmi->encoder = encoder; | ||
1890 | hdmi->disabled = true; | 1931 | hdmi->disabled = true; |
1891 | hdmi->rxsense = true; | 1932 | hdmi->rxsense = true; |
1892 | hdmi->phy_mask = (u8)~(HDMI_PHY_HPD | HDMI_PHY_RX_SENSE); | 1933 | hdmi->phy_mask = (u8)~(HDMI_PHY_HPD | HDMI_PHY_RX_SENSE); |
@@ -1908,7 +1949,7 @@ int dw_hdmi_bind(struct device *dev, struct device *master, | |||
1908 | break; | 1949 | break; |
1909 | default: | 1950 | default: |
1910 | dev_err(dev, "reg-io-width must be 1 or 4\n"); | 1951 | dev_err(dev, "reg-io-width must be 1 or 4\n"); |
1911 | return -EINVAL; | 1952 | return ERR_PTR(-EINVAL); |
1912 | } | 1953 | } |
1913 | 1954 | ||
1914 | ddc_node = of_parse_phandle(np, "ddc-i2c-bus", 0); | 1955 | ddc_node = of_parse_phandle(np, "ddc-i2c-bus", 0); |
@@ -1917,13 +1958,14 @@ int dw_hdmi_bind(struct device *dev, struct device *master, | |||
1917 | of_node_put(ddc_node); | 1958 | of_node_put(ddc_node); |
1918 | if (!hdmi->ddc) { | 1959 | if (!hdmi->ddc) { |
1919 | dev_dbg(hdmi->dev, "failed to read ddc node\n"); | 1960 | dev_dbg(hdmi->dev, "failed to read ddc node\n"); |
1920 | return -EPROBE_DEFER; | 1961 | return ERR_PTR(-EPROBE_DEFER); |
1921 | } | 1962 | } |
1922 | 1963 | ||
1923 | } else { | 1964 | } else { |
1924 | dev_dbg(hdmi->dev, "no ddc property found\n"); | 1965 | dev_dbg(hdmi->dev, "no ddc property found\n"); |
1925 | } | 1966 | } |
1926 | 1967 | ||
1968 | iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
1927 | hdmi->regs = devm_ioremap_resource(dev, iores); | 1969 | hdmi->regs = devm_ioremap_resource(dev, iores); |
1928 | if (IS_ERR(hdmi->regs)) { | 1970 | if (IS_ERR(hdmi->regs)) { |
1929 | ret = PTR_ERR(hdmi->regs); | 1971 | ret = PTR_ERR(hdmi->regs); |
@@ -1957,15 +1999,36 @@ int dw_hdmi_bind(struct device *dev, struct device *master, | |||
1957 | } | 1999 | } |
1958 | 2000 | ||
1959 | /* Product and revision IDs */ | 2001 | /* Product and revision IDs */ |
1960 | dev_info(dev, | 2002 | hdmi->version = (hdmi_readb(hdmi, HDMI_DESIGN_ID) << 8) |
1961 | "Detected HDMI controller 0x%x:0x%x:0x%x:0x%x\n", | 2003 | | (hdmi_readb(hdmi, HDMI_REVISION_ID) << 0); |
1962 | hdmi_readb(hdmi, HDMI_DESIGN_ID), | 2004 | prod_id0 = hdmi_readb(hdmi, HDMI_PRODUCT_ID0); |
1963 | hdmi_readb(hdmi, HDMI_REVISION_ID), | 2005 | prod_id1 = hdmi_readb(hdmi, HDMI_PRODUCT_ID1); |
1964 | hdmi_readb(hdmi, HDMI_PRODUCT_ID0), | 2006 | |
1965 | hdmi_readb(hdmi, HDMI_PRODUCT_ID1)); | 2007 | if (prod_id0 != HDMI_PRODUCT_ID0_HDMI_TX || |
2008 | (prod_id1 & ~HDMI_PRODUCT_ID1_HDCP) != HDMI_PRODUCT_ID1_HDMI_TX) { | ||
2009 | dev_err(dev, "Unsupported HDMI controller (%04x:%02x:%02x)\n", | ||
2010 | hdmi->version, prod_id0, prod_id1); | ||
2011 | ret = -ENODEV; | ||
2012 | goto err_iahb; | ||
2013 | } | ||
2014 | |||
2015 | ret = dw_hdmi_detect_phy(hdmi); | ||
2016 | if (ret < 0) | ||
2017 | goto err_iahb; | ||
2018 | |||
2019 | dev_info(dev, "Detected HDMI TX controller v%x.%03x %s HDCP (%s)\n", | ||
2020 | hdmi->version >> 12, hdmi->version & 0xfff, | ||
2021 | prod_id1 & HDMI_PRODUCT_ID1_HDCP ? "with" : "without", | ||
2022 | hdmi->phy->name); | ||
1966 | 2023 | ||
1967 | initialize_hdmi_ih_mutes(hdmi); | 2024 | initialize_hdmi_ih_mutes(hdmi); |
1968 | 2025 | ||
2026 | irq = platform_get_irq(pdev, 0); | ||
2027 | if (irq < 0) { | ||
2028 | ret = irq; | ||
2029 | goto err_iahb; | ||
2030 | } | ||
2031 | |||
1969 | ret = devm_request_threaded_irq(dev, irq, dw_hdmi_hardirq, | 2032 | ret = devm_request_threaded_irq(dev, irq, dw_hdmi_hardirq, |
1970 | dw_hdmi_irq, IRQF_SHARED, | 2033 | dw_hdmi_irq, IRQF_SHARED, |
1971 | dev_name(dev), hdmi); | 2034 | dev_name(dev), hdmi); |
@@ -1995,11 +2058,11 @@ int dw_hdmi_bind(struct device *dev, struct device *master, | |||
1995 | hdmi_writeb(hdmi, HDMI_IH_PHY_STAT0_HPD | HDMI_IH_PHY_STAT0_RX_SENSE, | 2058 | hdmi_writeb(hdmi, HDMI_IH_PHY_STAT0_HPD | HDMI_IH_PHY_STAT0_RX_SENSE, |
1996 | HDMI_IH_PHY_STAT0); | 2059 | HDMI_IH_PHY_STAT0); |
1997 | 2060 | ||
1998 | ret = dw_hdmi_fb_registered(hdmi); | 2061 | hdmi->bridge.driver_private = hdmi; |
1999 | if (ret) | 2062 | hdmi->bridge.funcs = &dw_hdmi_bridge_funcs; |
2000 | goto err_iahb; | 2063 | hdmi->bridge.of_node = pdev->dev.of_node; |
2001 | 2064 | ||
2002 | ret = dw_hdmi_register(drm, hdmi); | 2065 | ret = dw_hdmi_fb_registered(hdmi); |
2003 | if (ret) | 2066 | if (ret) |
2004 | goto err_iahb; | 2067 | goto err_iahb; |
2005 | 2068 | ||
@@ -2012,9 +2075,9 @@ int dw_hdmi_bind(struct device *dev, struct device *master, | |||
2012 | pdevinfo.id = PLATFORM_DEVID_AUTO; | 2075 | pdevinfo.id = PLATFORM_DEVID_AUTO; |
2013 | 2076 | ||
2014 | config0 = hdmi_readb(hdmi, HDMI_CONFIG0_ID); | 2077 | config0 = hdmi_readb(hdmi, HDMI_CONFIG0_ID); |
2015 | config1 = hdmi_readb(hdmi, HDMI_CONFIG1_ID); | 2078 | config3 = hdmi_readb(hdmi, HDMI_CONFIG3_ID); |
2016 | 2079 | ||
2017 | if (config1 & HDMI_CONFIG1_AHB) { | 2080 | if (config3 & HDMI_CONFIG3_AHBAUDDMA) { |
2018 | struct dw_hdmi_audio_data audio; | 2081 | struct dw_hdmi_audio_data audio; |
2019 | 2082 | ||
2020 | audio.phys = iores->start; | 2083 | audio.phys = iores->start; |
@@ -2046,9 +2109,9 @@ int dw_hdmi_bind(struct device *dev, struct device *master, | |||
2046 | if (hdmi->i2c) | 2109 | if (hdmi->i2c) |
2047 | dw_hdmi_i2c_init(hdmi); | 2110 | dw_hdmi_i2c_init(hdmi); |
2048 | 2111 | ||
2049 | dev_set_drvdata(dev, hdmi); | 2112 | platform_set_drvdata(pdev, hdmi); |
2050 | 2113 | ||
2051 | return 0; | 2114 | return hdmi; |
2052 | 2115 | ||
2053 | err_iahb: | 2116 | err_iahb: |
2054 | if (hdmi->i2c) { | 2117 | if (hdmi->i2c) { |
@@ -2062,14 +2125,11 @@ err_isfr: | |||
2062 | err_res: | 2125 | err_res: |
2063 | i2c_put_adapter(hdmi->ddc); | 2126 | i2c_put_adapter(hdmi->ddc); |
2064 | 2127 | ||
2065 | return ret; | 2128 | return ERR_PTR(ret); |
2066 | } | 2129 | } |
2067 | EXPORT_SYMBOL_GPL(dw_hdmi_bind); | ||
2068 | 2130 | ||
2069 | void dw_hdmi_unbind(struct device *dev, struct device *master, void *data) | 2131 | static void __dw_hdmi_remove(struct dw_hdmi *hdmi) |
2070 | { | 2132 | { |
2071 | struct dw_hdmi *hdmi = dev_get_drvdata(dev); | ||
2072 | |||
2073 | if (hdmi->audio && !IS_ERR(hdmi->audio)) | 2133 | if (hdmi->audio && !IS_ERR(hdmi->audio)) |
2074 | platform_device_unregister(hdmi->audio); | 2134 | platform_device_unregister(hdmi->audio); |
2075 | 2135 | ||
@@ -2084,6 +2144,70 @@ void dw_hdmi_unbind(struct device *dev, struct device *master, void *data) | |||
2084 | else | 2144 | else |
2085 | i2c_put_adapter(hdmi->ddc); | 2145 | i2c_put_adapter(hdmi->ddc); |
2086 | } | 2146 | } |
2147 | |||
2148 | /* ----------------------------------------------------------------------------- | ||
2149 | * Probe/remove API, used from platforms based on the DRM bridge API. | ||
2150 | */ | ||
2151 | int dw_hdmi_probe(struct platform_device *pdev, | ||
2152 | const struct dw_hdmi_plat_data *plat_data) | ||
2153 | { | ||
2154 | struct dw_hdmi *hdmi; | ||
2155 | int ret; | ||
2156 | |||
2157 | hdmi = __dw_hdmi_probe(pdev, plat_data); | ||
2158 | if (IS_ERR(hdmi)) | ||
2159 | return PTR_ERR(hdmi); | ||
2160 | |||
2161 | ret = drm_bridge_add(&hdmi->bridge); | ||
2162 | if (ret < 0) { | ||
2163 | __dw_hdmi_remove(hdmi); | ||
2164 | return ret; | ||
2165 | } | ||
2166 | |||
2167 | return 0; | ||
2168 | } | ||
2169 | EXPORT_SYMBOL_GPL(dw_hdmi_probe); | ||
2170 | |||
2171 | void dw_hdmi_remove(struct platform_device *pdev) | ||
2172 | { | ||
2173 | struct dw_hdmi *hdmi = platform_get_drvdata(pdev); | ||
2174 | |||
2175 | drm_bridge_remove(&hdmi->bridge); | ||
2176 | |||
2177 | __dw_hdmi_remove(hdmi); | ||
2178 | } | ||
2179 | EXPORT_SYMBOL_GPL(dw_hdmi_remove); | ||
2180 | |||
2181 | /* ----------------------------------------------------------------------------- | ||
2182 | * Bind/unbind API, used from platforms based on the component framework. | ||
2183 | */ | ||
2184 | int dw_hdmi_bind(struct platform_device *pdev, struct drm_encoder *encoder, | ||
2185 | const struct dw_hdmi_plat_data *plat_data) | ||
2186 | { | ||
2187 | struct dw_hdmi *hdmi; | ||
2188 | int ret; | ||
2189 | |||
2190 | hdmi = __dw_hdmi_probe(pdev, plat_data); | ||
2191 | if (IS_ERR(hdmi)) | ||
2192 | return PTR_ERR(hdmi); | ||
2193 | |||
2194 | ret = drm_bridge_attach(encoder, &hdmi->bridge, NULL); | ||
2195 | if (ret) { | ||
2196 | dw_hdmi_remove(pdev); | ||
2197 | DRM_ERROR("Failed to initialize bridge with drm\n"); | ||
2198 | return ret; | ||
2199 | } | ||
2200 | |||
2201 | return 0; | ||
2202 | } | ||
2203 | EXPORT_SYMBOL_GPL(dw_hdmi_bind); | ||
2204 | |||
2205 | void dw_hdmi_unbind(struct device *dev) | ||
2206 | { | ||
2207 | struct dw_hdmi *hdmi = dev_get_drvdata(dev); | ||
2208 | |||
2209 | __dw_hdmi_remove(hdmi); | ||
2210 | } | ||
2087 | EXPORT_SYMBOL_GPL(dw_hdmi_unbind); | 2211 | EXPORT_SYMBOL_GPL(dw_hdmi_unbind); |
2088 | 2212 | ||
2089 | MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>"); | 2213 | MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>"); |
diff --git a/drivers/gpu/drm/bridge/dw-hdmi.h b/drivers/gpu/drm/bridge/dw-hdmi.h index 55135bbd0c16..325b0b8ae639 100644 --- a/drivers/gpu/drm/bridge/dw-hdmi.h +++ b/drivers/gpu/drm/bridge/dw-hdmi.h | |||
@@ -545,12 +545,24 @@ | |||
545 | #define HDMI_I2CM_FS_SCL_LCNT_0_ADDR 0x7E12 | 545 | #define HDMI_I2CM_FS_SCL_LCNT_0_ADDR 0x7E12 |
546 | 546 | ||
547 | enum { | 547 | enum { |
548 | /* PRODUCT_ID0 field values */ | ||
549 | HDMI_PRODUCT_ID0_HDMI_TX = 0xa0, | ||
550 | |||
551 | /* PRODUCT_ID1 field values */ | ||
552 | HDMI_PRODUCT_ID1_HDCP = 0xc0, | ||
553 | HDMI_PRODUCT_ID1_HDMI_RX = 0x02, | ||
554 | HDMI_PRODUCT_ID1_HDMI_TX = 0x01, | ||
555 | |||
548 | /* CONFIG0_ID field values */ | 556 | /* CONFIG0_ID field values */ |
549 | HDMI_CONFIG0_I2S = 0x10, | 557 | HDMI_CONFIG0_I2S = 0x10, |
550 | 558 | ||
551 | /* CONFIG1_ID field values */ | 559 | /* CONFIG1_ID field values */ |
552 | HDMI_CONFIG1_AHB = 0x01, | 560 | HDMI_CONFIG1_AHB = 0x01, |
553 | 561 | ||
562 | /* CONFIG3_ID field values */ | ||
563 | HDMI_CONFIG3_AHBAUDDMA = 0x02, | ||
564 | HDMI_CONFIG3_GPAUD = 0x01, | ||
565 | |||
554 | /* IH_FC_INT2 field values */ | 566 | /* IH_FC_INT2 field values */ |
555 | HDMI_IH_FC_INT2_OVERFLOW_MASK = 0x03, | 567 | HDMI_IH_FC_INT2_OVERFLOW_MASK = 0x03, |
556 | HDMI_IH_FC_INT2_LOW_PRIORITY_OVERFLOW = 0x02, | 568 | HDMI_IH_FC_INT2_LOW_PRIORITY_OVERFLOW = 0x02, |
@@ -847,8 +859,8 @@ enum { | |||
847 | HDMI_PHY_CONF0_PDZ_OFFSET = 7, | 859 | HDMI_PHY_CONF0_PDZ_OFFSET = 7, |
848 | HDMI_PHY_CONF0_ENTMDS_MASK = 0x40, | 860 | HDMI_PHY_CONF0_ENTMDS_MASK = 0x40, |
849 | HDMI_PHY_CONF0_ENTMDS_OFFSET = 6, | 861 | HDMI_PHY_CONF0_ENTMDS_OFFSET = 6, |
850 | HDMI_PHY_CONF0_SPARECTRL_MASK = 0x20, | 862 | HDMI_PHY_CONF0_SVSRET_MASK = 0x20, |
851 | HDMI_PHY_CONF0_SPARECTRL_OFFSET = 5, | 863 | HDMI_PHY_CONF0_SVSRET_OFFSET = 5, |
852 | HDMI_PHY_CONF0_GEN2_PDDQ_MASK = 0x10, | 864 | HDMI_PHY_CONF0_GEN2_PDDQ_MASK = 0x10, |
853 | HDMI_PHY_CONF0_GEN2_PDDQ_OFFSET = 4, | 865 | HDMI_PHY_CONF0_GEN2_PDDQ_OFFSET = 4, |
854 | HDMI_PHY_CONF0_GEN2_TXPWRON_MASK = 0x8, | 866 | HDMI_PHY_CONF0_GEN2_TXPWRON_MASK = 0x8, |
@@ -977,8 +989,7 @@ enum { | |||
977 | HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_BYPASS = 0x0, | 989 | HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_BYPASS = 0x0, |
978 | 990 | ||
979 | /* MC_PHYRSTZ field values */ | 991 | /* MC_PHYRSTZ field values */ |
980 | HDMI_MC_PHYRSTZ_ASSERT = 0x0, | 992 | HDMI_MC_PHYRSTZ_PHYRSTZ = 0x01, |
981 | HDMI_MC_PHYRSTZ_DEASSERT = 0x1, | ||
982 | 993 | ||
983 | /* MC_HEACPHY_RST field values */ | 994 | /* MC_HEACPHY_RST field values */ |
984 | HDMI_MC_HEACPHY_RST_ASSERT = 0x1, | 995 | HDMI_MC_HEACPHY_RST_ASSERT = 0x1, |
@@ -1073,4 +1084,70 @@ enum { | |||
1073 | HDMI_I2CM_CTLINT_ARB_MASK = 0x4, | 1084 | HDMI_I2CM_CTLINT_ARB_MASK = 0x4, |
1074 | }; | 1085 | }; |
1075 | 1086 | ||
1087 | /* | ||
1088 | * HDMI 3D TX PHY registers | ||
1089 | */ | ||
1090 | #define HDMI_3D_TX_PHY_PWRCTRL 0x00 | ||
1091 | #define HDMI_3D_TX_PHY_SERDIVCTRL 0x01 | ||
1092 | #define HDMI_3D_TX_PHY_SERCKCTRL 0x02 | ||
1093 | #define HDMI_3D_TX_PHY_SERCKKILLCTRL 0x03 | ||
1094 | #define HDMI_3D_TX_PHY_TXRESCTRL 0x04 | ||
1095 | #define HDMI_3D_TX_PHY_CKCALCTRL 0x05 | ||
1096 | #define HDMI_3D_TX_PHY_CPCE_CTRL 0x06 | ||
1097 | #define HDMI_3D_TX_PHY_TXCLKMEASCTRL 0x07 | ||
1098 | #define HDMI_3D_TX_PHY_TXMEASCTRL 0x08 | ||
1099 | #define HDMI_3D_TX_PHY_CKSYMTXCTRL 0x09 | ||
1100 | #define HDMI_3D_TX_PHY_CMPSEQCTRL 0x0a | ||
1101 | #define HDMI_3D_TX_PHY_CMPPWRCTRL 0x0b | ||
1102 | #define HDMI_3D_TX_PHY_CMPMODECTRL 0x0c | ||
1103 | #define HDMI_3D_TX_PHY_MEASCTRL 0x0d | ||
1104 | #define HDMI_3D_TX_PHY_VLEVCTRL 0x0e | ||
1105 | #define HDMI_3D_TX_PHY_D2ACTRL 0x0f | ||
1106 | #define HDMI_3D_TX_PHY_CURRCTRL 0x10 | ||
1107 | #define HDMI_3D_TX_PHY_DRVANACTRL 0x11 | ||
1108 | #define HDMI_3D_TX_PHY_PLLMEASCTRL 0x12 | ||
1109 | #define HDMI_3D_TX_PHY_PLLPHBYCTRL 0x13 | ||
1110 | #define HDMI_3D_TX_PHY_GRP_CTRL 0x14 | ||
1111 | #define HDMI_3D_TX_PHY_GMPCTRL 0x15 | ||
1112 | #define HDMI_3D_TX_PHY_MPLLMEASCTRL 0x16 | ||
1113 | #define HDMI_3D_TX_PHY_MSM_CTRL 0x17 | ||
1114 | #define HDMI_3D_TX_PHY_SCRPB_STATUS 0x18 | ||
1115 | #define HDMI_3D_TX_PHY_TXTERM 0x19 | ||
1116 | #define HDMI_3D_TX_PHY_PTRPT_ENBL 0x1a | ||
1117 | #define HDMI_3D_TX_PHY_PATTERNGEN 0x1b | ||
1118 | #define HDMI_3D_TX_PHY_SDCAP_MODE 0x1c | ||
1119 | #define HDMI_3D_TX_PHY_SCOPEMODE 0x1d | ||
1120 | #define HDMI_3D_TX_PHY_DIGTXMODE 0x1e | ||
1121 | #define HDMI_3D_TX_PHY_STR_STATUS 0x1f | ||
1122 | #define HDMI_3D_TX_PHY_SCOPECNT0 0x20 | ||
1123 | #define HDMI_3D_TX_PHY_SCOPECNT1 0x21 | ||
1124 | #define HDMI_3D_TX_PHY_SCOPECNT2 0x22 | ||
1125 | #define HDMI_3D_TX_PHY_SCOPECNTCLK 0x23 | ||
1126 | #define HDMI_3D_TX_PHY_SCOPESAMPLE 0x24 | ||
1127 | #define HDMI_3D_TX_PHY_SCOPECNTMSB01 0x25 | ||
1128 | #define HDMI_3D_TX_PHY_SCOPECNTMSB2CK 0x26 | ||
1129 | |||
1130 | /* HDMI_3D_TX_PHY_CKCALCTRL values */ | ||
1131 | #define HDMI_3D_TX_PHY_CKCALCTRL_OVERRIDE BIT(15) | ||
1132 | |||
1133 | /* HDMI_3D_TX_PHY_MSM_CTRL values */ | ||
1134 | #define HDMI_3D_TX_PHY_MSM_CTRL_MPLL_PH_SEL_CK BIT(13) | ||
1135 | #define HDMI_3D_TX_PHY_MSM_CTRL_CKO_SEL_CLK_REF_MPLL (0 << 1) | ||
1136 | #define HDMI_3D_TX_PHY_MSM_CTRL_CKO_SEL_OFF (1 << 1) | ||
1137 | #define HDMI_3D_TX_PHY_MSM_CTRL_CKO_SEL_PCLK (2 << 1) | ||
1138 | #define HDMI_3D_TX_PHY_MSM_CTRL_CKO_SEL_FB_CLK (3 << 1) | ||
1139 | #define HDMI_3D_TX_PHY_MSM_CTRL_SCOPE_CK_SEL BIT(0) | ||
1140 | |||
1141 | /* HDMI_3D_TX_PHY_PTRPT_ENBL values */ | ||
1142 | #define HDMI_3D_TX_PHY_PTRPT_ENBL_OVERRIDE BIT(15) | ||
1143 | #define HDMI_3D_TX_PHY_PTRPT_ENBL_PG_SKIP_BIT2 BIT(8) | ||
1144 | #define HDMI_3D_TX_PHY_PTRPT_ENBL_PG_SKIP_BIT1 BIT(7) | ||
1145 | #define HDMI_3D_TX_PHY_PTRPT_ENBL_PG_SKIP_BIT0 BIT(6) | ||
1146 | #define HDMI_3D_TX_PHY_PTRPT_ENBL_CK_REF_ENB BIT(5) | ||
1147 | #define HDMI_3D_TX_PHY_PTRPT_ENBL_RCAL_ENB BIT(4) | ||
1148 | #define HDMI_3D_TX_PHY_PTRPT_ENBL_TX_CLK_ALIGN_ENB BIT(3) | ||
1149 | #define HDMI_3D_TX_PHY_PTRPT_ENBL_TX_READY BIT(2) | ||
1150 | #define HDMI_3D_TX_PHY_PTRPT_ENBL_CKO_WORD_ENB BIT(1) | ||
1151 | #define HDMI_3D_TX_PHY_PTRPT_ENBL_REFCLK_ENB BIT(0) | ||
1152 | |||
1076 | #endif /* __DW_HDMI_H__ */ | 1153 | #endif /* __DW_HDMI_H__ */ |
diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index 7b71ac48b8a4..b26e3419027e 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c | |||
@@ -2708,6 +2708,44 @@ backoff: | |||
2708 | } | 2708 | } |
2709 | EXPORT_SYMBOL(drm_atomic_helper_connector_set_property); | 2709 | EXPORT_SYMBOL(drm_atomic_helper_connector_set_property); |
2710 | 2710 | ||
2711 | static int page_flip_common( | ||
2712 | struct drm_atomic_state *state, | ||
2713 | struct drm_crtc *crtc, | ||
2714 | struct drm_framebuffer *fb, | ||
2715 | struct drm_pending_vblank_event *event) | ||
2716 | { | ||
2717 | struct drm_plane *plane = crtc->primary; | ||
2718 | struct drm_plane_state *plane_state; | ||
2719 | struct drm_crtc_state *crtc_state; | ||
2720 | int ret = 0; | ||
2721 | |||
2722 | crtc_state = drm_atomic_get_crtc_state(state, crtc); | ||
2723 | if (IS_ERR(crtc_state)) | ||
2724 | return PTR_ERR(crtc_state); | ||
2725 | |||
2726 | crtc_state->event = event; | ||
2727 | |||
2728 | plane_state = drm_atomic_get_plane_state(state, plane); | ||
2729 | if (IS_ERR(plane_state)) | ||
2730 | return PTR_ERR(plane_state); | ||
2731 | |||
2732 | |||
2733 | ret = drm_atomic_set_crtc_for_plane(plane_state, crtc); | ||
2734 | if (ret != 0) | ||
2735 | return ret; | ||
2736 | drm_atomic_set_fb_for_plane(plane_state, fb); | ||
2737 | |||
2738 | /* Make sure we don't accidentally do a full modeset. */ | ||
2739 | state->allow_modeset = false; | ||
2740 | if (!crtc_state->active) { | ||
2741 | DRM_DEBUG_ATOMIC("[CRTC:%d] disabled, rejecting legacy flip\n", | ||
2742 | crtc->base.id); | ||
2743 | return -EINVAL; | ||
2744 | } | ||
2745 | |||
2746 | return ret; | ||
2747 | } | ||
2748 | |||
2711 | /** | 2749 | /** |
2712 | * drm_atomic_helper_page_flip - execute a legacy page flip | 2750 | * drm_atomic_helper_page_flip - execute a legacy page flip |
2713 | * @crtc: DRM crtc | 2751 | * @crtc: DRM crtc |
@@ -2715,7 +2753,8 @@ EXPORT_SYMBOL(drm_atomic_helper_connector_set_property); | |||
2715 | * @event: optional DRM event to signal upon completion | 2753 | * @event: optional DRM event to signal upon completion |
2716 | * @flags: flip flags for non-vblank sync'ed updates | 2754 | * @flags: flip flags for non-vblank sync'ed updates |
2717 | * | 2755 | * |
2718 | * Provides a default page flip implementation using the atomic driver interface. | 2756 | * Provides a default &drm_crtc_funcs.page_flip implementation |
2757 | * using the atomic driver interface. | ||
2719 | * | 2758 | * |
2720 | * Note that for now so called async page flips (i.e. updates which are not | 2759 | * Note that for now so called async page flips (i.e. updates which are not |
2721 | * synchronized to vblank) are not supported, since the atomic interfaces have | 2760 | * synchronized to vblank) are not supported, since the atomic interfaces have |
@@ -2723,6 +2762,9 @@ EXPORT_SYMBOL(drm_atomic_helper_connector_set_property); | |||
2723 | * | 2762 | * |
2724 | * Returns: | 2763 | * Returns: |
2725 | * Returns 0 on success, negative errno numbers on failure. | 2764 | * Returns 0 on success, negative errno numbers on failure. |
2765 | * | ||
2766 | * See also: | ||
2767 | * drm_atomic_helper_page_flip_target() | ||
2726 | */ | 2768 | */ |
2727 | int drm_atomic_helper_page_flip(struct drm_crtc *crtc, | 2769 | int drm_atomic_helper_page_flip(struct drm_crtc *crtc, |
2728 | struct drm_framebuffer *fb, | 2770 | struct drm_framebuffer *fb, |
@@ -2731,8 +2773,6 @@ int drm_atomic_helper_page_flip(struct drm_crtc *crtc, | |||
2731 | { | 2773 | { |
2732 | struct drm_plane *plane = crtc->primary; | 2774 | struct drm_plane *plane = crtc->primary; |
2733 | struct drm_atomic_state *state; | 2775 | struct drm_atomic_state *state; |
2734 | struct drm_plane_state *plane_state; | ||
2735 | struct drm_crtc_state *crtc_state; | ||
2736 | int ret = 0; | 2776 | int ret = 0; |
2737 | 2777 | ||
2738 | if (flags & DRM_MODE_PAGE_FLIP_ASYNC) | 2778 | if (flags & DRM_MODE_PAGE_FLIP_ASYNC) |
@@ -2743,35 +2783,86 @@ int drm_atomic_helper_page_flip(struct drm_crtc *crtc, | |||
2743 | return -ENOMEM; | 2783 | return -ENOMEM; |
2744 | 2784 | ||
2745 | state->acquire_ctx = drm_modeset_legacy_acquire_ctx(crtc); | 2785 | state->acquire_ctx = drm_modeset_legacy_acquire_ctx(crtc); |
2786 | |||
2746 | retry: | 2787 | retry: |
2747 | crtc_state = drm_atomic_get_crtc_state(state, crtc); | 2788 | ret = page_flip_common(state, crtc, fb, event); |
2748 | if (IS_ERR(crtc_state)) { | 2789 | if (ret != 0) |
2749 | ret = PTR_ERR(crtc_state); | ||
2750 | goto fail; | 2790 | goto fail; |
2751 | } | ||
2752 | crtc_state->event = event; | ||
2753 | 2791 | ||
2754 | plane_state = drm_atomic_get_plane_state(state, plane); | 2792 | ret = drm_atomic_nonblocking_commit(state); |
2755 | if (IS_ERR(plane_state)) { | ||
2756 | ret = PTR_ERR(plane_state); | ||
2757 | goto fail; | ||
2758 | } | ||
2759 | 2793 | ||
2760 | ret = drm_atomic_set_crtc_for_plane(plane_state, crtc); | 2794 | fail: |
2795 | if (ret == -EDEADLK) | ||
2796 | goto backoff; | ||
2797 | |||
2798 | drm_atomic_state_put(state); | ||
2799 | return ret; | ||
2800 | |||
2801 | backoff: | ||
2802 | drm_atomic_state_clear(state); | ||
2803 | drm_atomic_legacy_backoff(state); | ||
2804 | |||
2805 | /* | ||
2806 | * Someone might have exchanged the framebuffer while we dropped locks | ||
2807 | * in the backoff code. We need to fix up the fb refcount tracking the | ||
2808 | * core does for us. | ||
2809 | */ | ||
2810 | plane->old_fb = plane->fb; | ||
2811 | |||
2812 | goto retry; | ||
2813 | } | ||
2814 | EXPORT_SYMBOL(drm_atomic_helper_page_flip); | ||
2815 | |||
2816 | /** | ||
2817 | * drm_atomic_helper_page_flip_target - do page flip on target vblank period. | ||
2818 | * @crtc: DRM crtc | ||
2819 | * @fb: DRM framebuffer | ||
2820 | * @event: optional DRM event to signal upon completion | ||
2821 | * @flags: flip flags for non-vblank sync'ed updates | ||
2822 | * @target: specifying the target vblank period when the flip to take effect | ||
2823 | * | ||
2824 | * Provides a default &drm_crtc_funcs.page_flip_target implementation. | ||
2825 | * Similar to drm_atomic_helper_page_flip() with extra parameter to specify | ||
2826 | * target vblank period to flip. | ||
2827 | * | ||
2828 | * Returns: | ||
2829 | * Returns 0 on success, negative errno numbers on failure. | ||
2830 | */ | ||
2831 | int drm_atomic_helper_page_flip_target( | ||
2832 | struct drm_crtc *crtc, | ||
2833 | struct drm_framebuffer *fb, | ||
2834 | struct drm_pending_vblank_event *event, | ||
2835 | uint32_t flags, | ||
2836 | uint32_t target) | ||
2837 | { | ||
2838 | struct drm_plane *plane = crtc->primary; | ||
2839 | struct drm_atomic_state *state; | ||
2840 | struct drm_crtc_state *crtc_state; | ||
2841 | int ret = 0; | ||
2842 | |||
2843 | if (flags & DRM_MODE_PAGE_FLIP_ASYNC) | ||
2844 | return -EINVAL; | ||
2845 | |||
2846 | state = drm_atomic_state_alloc(plane->dev); | ||
2847 | if (!state) | ||
2848 | return -ENOMEM; | ||
2849 | |||
2850 | state->acquire_ctx = drm_modeset_legacy_acquire_ctx(crtc); | ||
2851 | |||
2852 | retry: | ||
2853 | ret = page_flip_common(state, crtc, fb, event); | ||
2761 | if (ret != 0) | 2854 | if (ret != 0) |
2762 | goto fail; | 2855 | goto fail; |
2763 | drm_atomic_set_fb_for_plane(plane_state, fb); | ||
2764 | 2856 | ||
2765 | /* Make sure we don't accidentally do a full modeset. */ | 2857 | crtc_state = drm_atomic_get_existing_crtc_state(state, crtc); |
2766 | state->allow_modeset = false; | 2858 | if (WARN_ON(!crtc_state)) { |
2767 | if (!crtc_state->active) { | ||
2768 | DRM_DEBUG_ATOMIC("[CRTC:%d] disabled, rejecting legacy flip\n", | ||
2769 | crtc->base.id); | ||
2770 | ret = -EINVAL; | 2859 | ret = -EINVAL; |
2771 | goto fail; | 2860 | goto fail; |
2772 | } | 2861 | } |
2862 | crtc_state->target_vblank = target; | ||
2773 | 2863 | ||
2774 | ret = drm_atomic_nonblocking_commit(state); | 2864 | ret = drm_atomic_nonblocking_commit(state); |
2865 | |||
2775 | fail: | 2866 | fail: |
2776 | if (ret == -EDEADLK) | 2867 | if (ret == -EDEADLK) |
2777 | goto backoff; | 2868 | goto backoff; |
@@ -2792,7 +2883,7 @@ backoff: | |||
2792 | 2883 | ||
2793 | goto retry; | 2884 | goto retry; |
2794 | } | 2885 | } |
2795 | EXPORT_SYMBOL(drm_atomic_helper_page_flip); | 2886 | EXPORT_SYMBOL(drm_atomic_helper_page_flip_target); |
2796 | 2887 | ||
2797 | /** | 2888 | /** |
2798 | * drm_atomic_helper_connector_dpms() - connector dpms helper implementation | 2889 | * drm_atomic_helper_connector_dpms() - connector dpms helper implementation |
diff --git a/drivers/gpu/drm/drm_cache.c b/drivers/gpu/drm/drm_cache.c index a7916e5f8864..5066638928ec 100644 --- a/drivers/gpu/drm/drm_cache.c +++ b/drivers/gpu/drm/drm_cache.c | |||
@@ -67,6 +67,14 @@ static void drm_cache_flush_clflush(struct page *pages[], | |||
67 | } | 67 | } |
68 | #endif | 68 | #endif |
69 | 69 | ||
70 | /** | ||
71 | * drm_clflush_pages - Flush dcache lines of a set of pages. | ||
72 | * @pages: List of pages to be flushed. | ||
73 | * @num_pages: Number of pages in the array. | ||
74 | * | ||
75 | * Flush every data cache line entry that points to an address belonging | ||
76 | * to a page in the array. | ||
77 | */ | ||
70 | void | 78 | void |
71 | drm_clflush_pages(struct page *pages[], unsigned long num_pages) | 79 | drm_clflush_pages(struct page *pages[], unsigned long num_pages) |
72 | { | 80 | { |
@@ -101,6 +109,13 @@ drm_clflush_pages(struct page *pages[], unsigned long num_pages) | |||
101 | } | 109 | } |
102 | EXPORT_SYMBOL(drm_clflush_pages); | 110 | EXPORT_SYMBOL(drm_clflush_pages); |
103 | 111 | ||
112 | /** | ||
113 | * drm_clflush_sg - Flush dcache lines pointing to a scather-gather. | ||
114 | * @st: struct sg_table. | ||
115 | * | ||
116 | * Flush every data cache line entry that points to an address in the | ||
117 | * sg. | ||
118 | */ | ||
104 | void | 119 | void |
105 | drm_clflush_sg(struct sg_table *st) | 120 | drm_clflush_sg(struct sg_table *st) |
106 | { | 121 | { |
@@ -125,6 +140,14 @@ drm_clflush_sg(struct sg_table *st) | |||
125 | } | 140 | } |
126 | EXPORT_SYMBOL(drm_clflush_sg); | 141 | EXPORT_SYMBOL(drm_clflush_sg); |
127 | 142 | ||
143 | /** | ||
144 | * drm_clflush_virt_range - Flush dcache lines of a region | ||
145 | * @addr: Initial kernel memory address. | ||
146 | * @length: Region size. | ||
147 | * | ||
148 | * Flush every data cache line entry that points to an address in the | ||
149 | * region requested. | ||
150 | */ | ||
128 | void | 151 | void |
129 | drm_clflush_virt_range(void *addr, unsigned long length) | 152 | drm_clflush_virt_range(void *addr, unsigned long length) |
130 | { | 153 | { |
diff --git a/drivers/gpu/drm/drm_fb_cma_helper.c b/drivers/gpu/drm/drm_fb_cma_helper.c index 20a4011f790d..4364abfb6a71 100644 --- a/drivers/gpu/drm/drm_fb_cma_helper.c +++ b/drivers/gpu/drm/drm_fb_cma_helper.c | |||
@@ -473,8 +473,7 @@ drm_fbdev_cma_create(struct drm_fb_helper *helper, | |||
473 | return 0; | 473 | return 0; |
474 | 474 | ||
475 | err_cma_destroy: | 475 | err_cma_destroy: |
476 | drm_framebuffer_unregister_private(&fbdev_cma->fb->fb); | 476 | drm_framebuffer_remove(&fbdev_cma->fb->fb); |
477 | drm_fb_cma_destroy(&fbdev_cma->fb->fb); | ||
478 | err_fb_info_destroy: | 477 | err_fb_info_destroy: |
479 | drm_fb_helper_release_fbi(helper); | 478 | drm_fb_helper_release_fbi(helper); |
480 | err_gem_free_object: | 479 | err_gem_free_object: |
@@ -574,10 +573,8 @@ void drm_fbdev_cma_fini(struct drm_fbdev_cma *fbdev_cma) | |||
574 | drm_fbdev_cma_defio_fini(fbdev_cma->fb_helper.fbdev); | 573 | drm_fbdev_cma_defio_fini(fbdev_cma->fb_helper.fbdev); |
575 | drm_fb_helper_release_fbi(&fbdev_cma->fb_helper); | 574 | drm_fb_helper_release_fbi(&fbdev_cma->fb_helper); |
576 | 575 | ||
577 | if (fbdev_cma->fb) { | 576 | if (fbdev_cma->fb) |
578 | drm_framebuffer_unregister_private(&fbdev_cma->fb->fb); | 577 | drm_framebuffer_remove(&fbdev_cma->fb->fb); |
579 | drm_fb_cma_destroy(&fbdev_cma->fb->fb); | ||
580 | } | ||
581 | 578 | ||
582 | drm_fb_helper_fini(&fbdev_cma->fb_helper); | 579 | drm_fb_helper_fini(&fbdev_cma->fb_helper); |
583 | kfree(fbdev_cma); | 580 | kfree(fbdev_cma); |
diff --git a/drivers/gpu/drm/etnaviv/Kconfig b/drivers/gpu/drm/etnaviv/Kconfig index 2cde7a5442fb..656c061b439d 100644 --- a/drivers/gpu/drm/etnaviv/Kconfig +++ b/drivers/gpu/drm/etnaviv/Kconfig | |||
@@ -3,6 +3,7 @@ config DRM_ETNAVIV | |||
3 | tristate "ETNAVIV (DRM support for Vivante GPU IP cores)" | 3 | tristate "ETNAVIV (DRM support for Vivante GPU IP cores)" |
4 | depends on DRM | 4 | depends on DRM |
5 | depends on ARCH_MXC || ARCH_DOVE | 5 | depends on ARCH_MXC || ARCH_DOVE |
6 | depends on MMU | ||
6 | select SHMEM | 7 | select SHMEM |
7 | select TMPFS | 8 | select TMPFS |
8 | select IOMMU_API | 9 | select IOMMU_API |
diff --git a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c index c6745a1b8e6a..d69af00bdd6a 100644 --- a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c +++ b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c | |||
@@ -467,7 +467,7 @@ err: | |||
467 | clk_disable_unprepare(ctx->clks[i]); | 467 | clk_disable_unprepare(ctx->clks[i]); |
468 | } | 468 | } |
469 | 469 | ||
470 | static struct exynos_drm_crtc_ops decon_crtc_ops = { | 470 | static const struct exynos_drm_crtc_ops decon_crtc_ops = { |
471 | .enable = decon_enable, | 471 | .enable = decon_enable, |
472 | .disable = decon_disable, | 472 | .disable = decon_disable, |
473 | .enable_vblank = decon_enable_vblank, | 473 | .enable_vblank = decon_enable_vblank, |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.c b/drivers/gpu/drm/exynos/exynos_drm_crtc.c index 2530bf57716a..309c8ee52524 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_crtc.c +++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.c | |||
@@ -109,9 +109,6 @@ static const struct drm_crtc_helper_funcs exynos_crtc_helper_funcs = { | |||
109 | static void exynos_drm_crtc_destroy(struct drm_crtc *crtc) | 109 | static void exynos_drm_crtc_destroy(struct drm_crtc *crtc) |
110 | { | 110 | { |
111 | struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc); | 111 | struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc); |
112 | struct exynos_drm_private *private = crtc->dev->dev_private; | ||
113 | |||
114 | private->crtc[exynos_crtc->pipe] = NULL; | ||
115 | 112 | ||
116 | drm_crtc_cleanup(crtc); | 113 | drm_crtc_cleanup(crtc); |
117 | kfree(exynos_crtc); | 114 | kfree(exynos_crtc); |
@@ -134,7 +131,6 @@ struct exynos_drm_crtc *exynos_drm_crtc_create(struct drm_device *drm_dev, | |||
134 | void *ctx) | 131 | void *ctx) |
135 | { | 132 | { |
136 | struct exynos_drm_crtc *exynos_crtc; | 133 | struct exynos_drm_crtc *exynos_crtc; |
137 | struct exynos_drm_private *private = drm_dev->dev_private; | ||
138 | struct drm_crtc *crtc; | 134 | struct drm_crtc *crtc; |
139 | int ret; | 135 | int ret; |
140 | 136 | ||
@@ -149,8 +145,6 @@ struct exynos_drm_crtc *exynos_drm_crtc_create(struct drm_device *drm_dev, | |||
149 | 145 | ||
150 | crtc = &exynos_crtc->base; | 146 | crtc = &exynos_crtc->base; |
151 | 147 | ||
152 | private->crtc[pipe] = crtc; | ||
153 | |||
154 | ret = drm_crtc_init_with_planes(drm_dev, crtc, plane, NULL, | 148 | ret = drm_crtc_init_with_planes(drm_dev, crtc, plane, NULL, |
155 | &exynos_crtc_funcs, NULL); | 149 | &exynos_crtc_funcs, NULL); |
156 | if (ret < 0) | 150 | if (ret < 0) |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h index 80c4d5b81689..cf6e08cb35a7 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.h +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h | |||
@@ -211,12 +211,6 @@ struct drm_exynos_file_private { | |||
211 | struct exynos_drm_private { | 211 | struct exynos_drm_private { |
212 | struct drm_fb_helper *fb_helper; | 212 | struct drm_fb_helper *fb_helper; |
213 | 213 | ||
214 | /* | ||
215 | * created crtc object would be contained at this array and | ||
216 | * this array is used to be aware of which crtc did it request vblank. | ||
217 | */ | ||
218 | struct drm_crtc *crtc[MAX_CRTC]; | ||
219 | |||
220 | struct device *dma_dev; | 214 | struct device *dma_dev; |
221 | void *mapping; | 215 | void *mapping; |
222 | 216 | ||
@@ -231,9 +225,9 @@ struct exynos_drm_private { | |||
231 | static inline struct exynos_drm_crtc * | 225 | static inline struct exynos_drm_crtc * |
232 | exynos_drm_crtc_from_pipe(struct drm_device *dev, int pipe) | 226 | exynos_drm_crtc_from_pipe(struct drm_device *dev, int pipe) |
233 | { | 227 | { |
234 | struct exynos_drm_private *private = dev->dev_private; | 228 | struct drm_crtc *crtc = drm_crtc_from_index(dev, pipe); |
235 | 229 | ||
236 | return to_exynos_crtc(private->crtc[pipe]); | 230 | return to_exynos_crtc(crtc); |
237 | } | 231 | } |
238 | 232 | ||
239 | static inline struct device *to_dma_dev(struct drm_device *dev) | 233 | static inline struct device *to_dma_dev(struct drm_device *dev) |
diff --git a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c index 307d460ab684..9a0678a33e0d 100644 --- a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c +++ b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c | |||
@@ -304,8 +304,8 @@ static void ade_set_medianoc_qos(struct ade_crtc *acrtc) | |||
304 | 304 | ||
305 | static int ade_enable_vblank(struct drm_device *dev, unsigned int pipe) | 305 | static int ade_enable_vblank(struct drm_device *dev, unsigned int pipe) |
306 | { | 306 | { |
307 | struct kirin_drm_private *priv = dev->dev_private; | 307 | struct drm_crtc *crtc = drm_crtc_from_index(dev, pipe); |
308 | struct ade_crtc *acrtc = to_ade_crtc(priv->crtc[pipe]); | 308 | struct ade_crtc *acrtc = to_ade_crtc(crtc); |
309 | struct ade_hw_ctx *ctx = acrtc->ctx; | 309 | struct ade_hw_ctx *ctx = acrtc->ctx; |
310 | void __iomem *base = ctx->base; | 310 | void __iomem *base = ctx->base; |
311 | 311 | ||
@@ -320,8 +320,8 @@ static int ade_enable_vblank(struct drm_device *dev, unsigned int pipe) | |||
320 | 320 | ||
321 | static void ade_disable_vblank(struct drm_device *dev, unsigned int pipe) | 321 | static void ade_disable_vblank(struct drm_device *dev, unsigned int pipe) |
322 | { | 322 | { |
323 | struct kirin_drm_private *priv = dev->dev_private; | 323 | struct drm_crtc *crtc = drm_crtc_from_index(dev, pipe); |
324 | struct ade_crtc *acrtc = to_ade_crtc(priv->crtc[pipe]); | 324 | struct ade_crtc *acrtc = to_ade_crtc(crtc); |
325 | struct ade_hw_ctx *ctx = acrtc->ctx; | 325 | struct ade_hw_ctx *ctx = acrtc->ctx; |
326 | void __iomem *base = ctx->base; | 326 | void __iomem *base = ctx->base; |
327 | 327 | ||
@@ -575,7 +575,6 @@ static const struct drm_crtc_funcs ade_crtc_funcs = { | |||
575 | static int ade_crtc_init(struct drm_device *dev, struct drm_crtc *crtc, | 575 | static int ade_crtc_init(struct drm_device *dev, struct drm_crtc *crtc, |
576 | struct drm_plane *plane) | 576 | struct drm_plane *plane) |
577 | { | 577 | { |
578 | struct kirin_drm_private *priv = dev->dev_private; | ||
579 | struct device_node *port; | 578 | struct device_node *port; |
580 | int ret; | 579 | int ret; |
581 | 580 | ||
@@ -599,7 +598,6 @@ static int ade_crtc_init(struct drm_device *dev, struct drm_crtc *crtc, | |||
599 | } | 598 | } |
600 | 599 | ||
601 | drm_crtc_helper_add(crtc, &ade_crtc_helper_funcs); | 600 | drm_crtc_helper_add(crtc, &ade_crtc_helper_funcs); |
602 | priv->crtc[drm_crtc_index(crtc)] = crtc; | ||
603 | 601 | ||
604 | return 0; | 602 | return 0; |
605 | } | 603 | } |
diff --git a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.h b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.h index a0bb217c4c64..7f60c64915d9 100644 --- a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.h +++ b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.h | |||
@@ -20,7 +20,6 @@ struct kirin_dc_ops { | |||
20 | }; | 20 | }; |
21 | 21 | ||
22 | struct kirin_drm_private { | 22 | struct kirin_drm_private { |
23 | struct drm_crtc *crtc[MAX_CRTC]; | ||
24 | #ifdef CONFIG_DRM_FBDEV_EMULATION | 23 | #ifdef CONFIG_DRM_FBDEV_EMULATION |
25 | struct drm_fbdev_cma *fbdev; | 24 | struct drm_fbdev_cma *fbdev; |
26 | #endif | 25 | #endif |
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index ead3b6417c54..244628065f94 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -49,6 +49,7 @@ | |||
49 | #include <drm/drm_legacy.h> /* for struct drm_dma_handle */ | 49 | #include <drm/drm_legacy.h> /* for struct drm_dma_handle */ |
50 | #include <drm/drm_gem.h> | 50 | #include <drm/drm_gem.h> |
51 | #include <drm/drm_auth.h> | 51 | #include <drm/drm_auth.h> |
52 | #include <drm/drm_cache.h> | ||
52 | 53 | ||
53 | #include "i915_params.h" | 54 | #include "i915_params.h" |
54 | #include "i915_reg.h" | 55 | #include "i915_reg.h" |
diff --git a/drivers/gpu/drm/imx/dw_hdmi-imx.c b/drivers/gpu/drm/imx/dw_hdmi-imx.c index 359cd2765552..f645275e6e63 100644 --- a/drivers/gpu/drm/imx/dw_hdmi-imx.c +++ b/drivers/gpu/drm/imx/dw_hdmi-imx.c | |||
@@ -207,8 +207,6 @@ static int dw_hdmi_imx_bind(struct device *dev, struct device *master, | |||
207 | struct drm_device *drm = data; | 207 | struct drm_device *drm = data; |
208 | struct drm_encoder *encoder; | 208 | struct drm_encoder *encoder; |
209 | struct imx_hdmi *hdmi; | 209 | struct imx_hdmi *hdmi; |
210 | struct resource *iores; | ||
211 | int irq; | ||
212 | int ret; | 210 | int ret; |
213 | 211 | ||
214 | if (!pdev->dev.of_node) | 212 | if (!pdev->dev.of_node) |
@@ -223,14 +221,6 @@ static int dw_hdmi_imx_bind(struct device *dev, struct device *master, | |||
223 | hdmi->dev = &pdev->dev; | 221 | hdmi->dev = &pdev->dev; |
224 | encoder = &hdmi->encoder; | 222 | encoder = &hdmi->encoder; |
225 | 223 | ||
226 | irq = platform_get_irq(pdev, 0); | ||
227 | if (irq < 0) | ||
228 | return irq; | ||
229 | |||
230 | iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
231 | if (!iores) | ||
232 | return -ENXIO; | ||
233 | |||
234 | encoder->possible_crtcs = drm_of_find_possible_crtcs(drm, dev->of_node); | 224 | encoder->possible_crtcs = drm_of_find_possible_crtcs(drm, dev->of_node); |
235 | /* | 225 | /* |
236 | * If we failed to find the CRTC(s) which this encoder is | 226 | * If we failed to find the CRTC(s) which this encoder is |
@@ -249,7 +239,7 @@ static int dw_hdmi_imx_bind(struct device *dev, struct device *master, | |||
249 | drm_encoder_init(drm, encoder, &dw_hdmi_imx_encoder_funcs, | 239 | drm_encoder_init(drm, encoder, &dw_hdmi_imx_encoder_funcs, |
250 | DRM_MODE_ENCODER_TMDS, NULL); | 240 | DRM_MODE_ENCODER_TMDS, NULL); |
251 | 241 | ||
252 | ret = dw_hdmi_bind(dev, master, data, encoder, iores, irq, plat_data); | 242 | ret = dw_hdmi_bind(pdev, encoder, plat_data); |
253 | 243 | ||
254 | /* | 244 | /* |
255 | * If dw_hdmi_bind() fails we'll never call dw_hdmi_unbind(), | 245 | * If dw_hdmi_bind() fails we'll never call dw_hdmi_unbind(), |
@@ -264,7 +254,7 @@ static int dw_hdmi_imx_bind(struct device *dev, struct device *master, | |||
264 | static void dw_hdmi_imx_unbind(struct device *dev, struct device *master, | 254 | static void dw_hdmi_imx_unbind(struct device *dev, struct device *master, |
265 | void *data) | 255 | void *data) |
266 | { | 256 | { |
267 | return dw_hdmi_unbind(dev, master, data); | 257 | return dw_hdmi_unbind(dev); |
268 | } | 258 | } |
269 | 259 | ||
270 | static const struct component_ops dw_hdmi_imx_ops = { | 260 | static const struct component_ops dw_hdmi_imx_ops = { |
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c index 01a21dd835b5..a73de1e669c2 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c | |||
@@ -170,8 +170,8 @@ static void mtk_drm_crtc_mode_set_nofb(struct drm_crtc *crtc) | |||
170 | 170 | ||
171 | int mtk_drm_crtc_enable_vblank(struct drm_device *drm, unsigned int pipe) | 171 | int mtk_drm_crtc_enable_vblank(struct drm_device *drm, unsigned int pipe) |
172 | { | 172 | { |
173 | struct mtk_drm_private *priv = drm->dev_private; | 173 | struct drm_crtc *crtc = drm_crtc_from_index(drm, pipe); |
174 | struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(priv->crtc[pipe]); | 174 | struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc); |
175 | struct mtk_ddp_comp *ovl = mtk_crtc->ddp_comp[0]; | 175 | struct mtk_ddp_comp *ovl = mtk_crtc->ddp_comp[0]; |
176 | 176 | ||
177 | mtk_ddp_comp_enable_vblank(ovl, &mtk_crtc->base); | 177 | mtk_ddp_comp_enable_vblank(ovl, &mtk_crtc->base); |
@@ -181,8 +181,8 @@ int mtk_drm_crtc_enable_vblank(struct drm_device *drm, unsigned int pipe) | |||
181 | 181 | ||
182 | void mtk_drm_crtc_disable_vblank(struct drm_device *drm, unsigned int pipe) | 182 | void mtk_drm_crtc_disable_vblank(struct drm_device *drm, unsigned int pipe) |
183 | { | 183 | { |
184 | struct mtk_drm_private *priv = drm->dev_private; | 184 | struct drm_crtc *crtc = drm_crtc_from_index(drm, pipe); |
185 | struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(priv->crtc[pipe]); | 185 | struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc); |
186 | struct mtk_ddp_comp *ovl = mtk_crtc->ddp_comp[0]; | 186 | struct mtk_ddp_comp *ovl = mtk_crtc->ddp_comp[0]; |
187 | 187 | ||
188 | mtk_ddp_comp_disable_vblank(ovl); | 188 | mtk_ddp_comp_disable_vblank(ovl); |
@@ -588,7 +588,6 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev, | |||
588 | goto unprepare; | 588 | goto unprepare; |
589 | drm_mode_crtc_set_gamma_size(&mtk_crtc->base, MTK_LUT_SIZE); | 589 | drm_mode_crtc_set_gamma_size(&mtk_crtc->base, MTK_LUT_SIZE); |
590 | drm_crtc_enable_color_mgmt(&mtk_crtc->base, 0, false, MTK_LUT_SIZE); | 590 | drm_crtc_enable_color_mgmt(&mtk_crtc->base, 0, false, MTK_LUT_SIZE); |
591 | priv->crtc[pipe] = &mtk_crtc->base; | ||
592 | priv->num_pipes++; | 591 | priv->num_pipes++; |
593 | 592 | ||
594 | return 0; | 593 | return 0; |
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.h b/drivers/gpu/drm/mediatek/mtk_drm_drv.h index aa9389446785..df322a7a5fcb 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.h +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.h | |||
@@ -32,7 +32,6 @@ struct mtk_drm_private { | |||
32 | struct drm_device *drm; | 32 | struct drm_device *drm; |
33 | struct device *dma_dev; | 33 | struct device *dma_dev; |
34 | 34 | ||
35 | struct drm_crtc *crtc[MAX_CRTC]; | ||
36 | unsigned int num_pipes; | 35 | unsigned int num_pipes; |
37 | 36 | ||
38 | struct device_node *mutex_node; | 37 | struct device_node *mutex_node; |
diff --git a/drivers/gpu/drm/msm/Kconfig b/drivers/gpu/drm/msm/Kconfig index d96b2b6898a3..7f78da695dff 100644 --- a/drivers/gpu/drm/msm/Kconfig +++ b/drivers/gpu/drm/msm/Kconfig | |||
@@ -4,6 +4,7 @@ config DRM_MSM | |||
4 | depends on DRM | 4 | depends on DRM |
5 | depends on ARCH_QCOM || (ARM && COMPILE_TEST) | 5 | depends on ARCH_QCOM || (ARM && COMPILE_TEST) |
6 | depends on OF && COMMON_CLK | 6 | depends on OF && COMMON_CLK |
7 | depends on MMU | ||
7 | select REGULATOR | 8 | select REGULATOR |
8 | select DRM_KMS_HELPER | 9 | select DRM_KMS_HELPER |
9 | select DRM_PANEL | 10 | select DRM_PANEL |
diff --git a/drivers/gpu/drm/msm/msm_fbdev.c b/drivers/gpu/drm/msm/msm_fbdev.c index 5d68ab362d75..f8a587eac6b8 100644 --- a/drivers/gpu/drm/msm/msm_fbdev.c +++ b/drivers/gpu/drm/msm/msm_fbdev.c | |||
@@ -174,10 +174,8 @@ fail_unlock: | |||
174 | fail: | 174 | fail: |
175 | 175 | ||
176 | if (ret) { | 176 | if (ret) { |
177 | if (fb) { | 177 | if (fb) |
178 | drm_framebuffer_unregister_private(fb); | ||
179 | drm_framebuffer_remove(fb); | 178 | drm_framebuffer_remove(fb); |
180 | } | ||
181 | } | 179 | } |
182 | 180 | ||
183 | return ret; | 181 | return ret; |
@@ -247,7 +245,6 @@ void msm_fbdev_free(struct drm_device *dev) | |||
247 | /* this will free the backing object */ | 245 | /* this will free the backing object */ |
248 | if (fbdev->fb) { | 246 | if (fbdev->fb) { |
249 | msm_gem_put_vaddr(fbdev->bo); | 247 | msm_gem_put_vaddr(fbdev->bo); |
250 | drm_framebuffer_unregister_private(fbdev->fb); | ||
251 | drm_framebuffer_remove(fbdev->fb); | 248 | drm_framebuffer_remove(fbdev->fb); |
252 | } | 249 | } |
253 | 250 | ||
diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c index add353e230f4..6b570079d185 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.c +++ b/drivers/gpu/drm/nouveau/nouveau_display.c | |||
@@ -58,27 +58,30 @@ int | |||
58 | nouveau_display_vblank_enable(struct drm_device *dev, unsigned int pipe) | 58 | nouveau_display_vblank_enable(struct drm_device *dev, unsigned int pipe) |
59 | { | 59 | { |
60 | struct drm_crtc *crtc; | 60 | struct drm_crtc *crtc; |
61 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { | 61 | struct nouveau_crtc *nv_crtc; |
62 | struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); | 62 | |
63 | if (nv_crtc->index == pipe) { | 63 | crtc = drm_crtc_from_index(dev, pipe); |
64 | nvif_notify_get(&nv_crtc->vblank); | 64 | if (!crtc) |
65 | return 0; | 65 | return -EINVAL; |
66 | } | 66 | |
67 | } | 67 | nv_crtc = nouveau_crtc(crtc); |
68 | return -EINVAL; | 68 | nvif_notify_get(&nv_crtc->vblank); |
69 | |||
70 | return 0; | ||
69 | } | 71 | } |
70 | 72 | ||
71 | void | 73 | void |
72 | nouveau_display_vblank_disable(struct drm_device *dev, unsigned int pipe) | 74 | nouveau_display_vblank_disable(struct drm_device *dev, unsigned int pipe) |
73 | { | 75 | { |
74 | struct drm_crtc *crtc; | 76 | struct drm_crtc *crtc; |
75 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { | 77 | struct nouveau_crtc *nv_crtc; |
76 | struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); | 78 | |
77 | if (nv_crtc->index == pipe) { | 79 | crtc = drm_crtc_from_index(dev, pipe); |
78 | nvif_notify_put(&nv_crtc->vblank); | 80 | if (!crtc) |
79 | return; | 81 | return; |
80 | } | 82 | |
81 | } | 83 | nv_crtc = nouveau_crtc(crtc); |
84 | nvif_notify_put(&nv_crtc->vblank); | ||
82 | } | 85 | } |
83 | 86 | ||
84 | static inline int | 87 | static inline int |
diff --git a/drivers/gpu/drm/omapdrm/omap_fbdev.c b/drivers/gpu/drm/omapdrm/omap_fbdev.c index aed99a0fc44b..2a839956dae6 100644 --- a/drivers/gpu/drm/omapdrm/omap_fbdev.c +++ b/drivers/gpu/drm/omapdrm/omap_fbdev.c | |||
@@ -225,10 +225,8 @@ fail: | |||
225 | 225 | ||
226 | drm_fb_helper_release_fbi(helper); | 226 | drm_fb_helper_release_fbi(helper); |
227 | 227 | ||
228 | if (fb) { | 228 | if (fb) |
229 | drm_framebuffer_unregister_private(fb); | ||
230 | drm_framebuffer_remove(fb); | 229 | drm_framebuffer_remove(fb); |
231 | } | ||
232 | } | 230 | } |
233 | 231 | ||
234 | return ret; | 232 | return ret; |
@@ -314,10 +312,8 @@ void omap_fbdev_free(struct drm_device *dev) | |||
314 | omap_gem_put_paddr(fbdev->bo); | 312 | omap_gem_put_paddr(fbdev->bo); |
315 | 313 | ||
316 | /* this will free the backing object */ | 314 | /* this will free the backing object */ |
317 | if (fbdev->fb) { | 315 | if (fbdev->fb) |
318 | drm_framebuffer_unregister_private(fbdev->fb); | ||
319 | drm_framebuffer_remove(fbdev->fb); | 316 | drm_framebuffer_remove(fbdev->fb); |
320 | } | ||
321 | 317 | ||
322 | kfree(fbdev); | 318 | kfree(fbdev); |
323 | 319 | ||
diff --git a/drivers/gpu/drm/qxl/qxl_debugfs.c b/drivers/gpu/drm/qxl/qxl_debugfs.c index 241af9131dc8..057b2b547cac 100644 --- a/drivers/gpu/drm/qxl/qxl_debugfs.c +++ b/drivers/gpu/drm/qxl/qxl_debugfs.c | |||
@@ -84,8 +84,18 @@ int | |||
84 | qxl_debugfs_init(struct drm_minor *minor) | 84 | qxl_debugfs_init(struct drm_minor *minor) |
85 | { | 85 | { |
86 | #if defined(CONFIG_DEBUG_FS) | 86 | #if defined(CONFIG_DEBUG_FS) |
87 | int r; | ||
88 | struct qxl_device *dev = | ||
89 | (struct qxl_device *) minor->dev->dev_private; | ||
90 | |||
87 | drm_debugfs_create_files(qxl_debugfs_list, QXL_DEBUGFS_ENTRIES, | 91 | drm_debugfs_create_files(qxl_debugfs_list, QXL_DEBUGFS_ENTRIES, |
88 | minor->debugfs_root, minor); | 92 | minor->debugfs_root, minor); |
93 | |||
94 | r = qxl_ttm_debugfs_init(dev); | ||
95 | if (r) { | ||
96 | DRM_ERROR("Failed to init TTM debugfs\n"); | ||
97 | return r; | ||
98 | } | ||
89 | #endif | 99 | #endif |
90 | return 0; | 100 | return 0; |
91 | } | 101 | } |
diff --git a/drivers/gpu/drm/qxl/qxl_display.c b/drivers/gpu/drm/qxl/qxl_display.c index 659c77742649..416ade8566b7 100644 --- a/drivers/gpu/drm/qxl/qxl_display.c +++ b/drivers/gpu/drm/qxl/qxl_display.c | |||
@@ -1077,7 +1077,6 @@ static int qdev_output_init(struct drm_device *dev, int num_output) | |||
1077 | dev->mode_config.suggested_x_property, 0); | 1077 | dev->mode_config.suggested_x_property, 0); |
1078 | drm_object_attach_property(&connector->base, | 1078 | drm_object_attach_property(&connector->base, |
1079 | dev->mode_config.suggested_y_property, 0); | 1079 | dev->mode_config.suggested_y_property, 0); |
1080 | drm_connector_register(connector); | ||
1081 | return 0; | 1080 | return 0; |
1082 | } | 1081 | } |
1083 | 1082 | ||
diff --git a/drivers/gpu/drm/qxl/qxl_drv.c b/drivers/gpu/drm/qxl/qxl_drv.c index 460bbceae297..6e0f8a2d8ac9 100644 --- a/drivers/gpu/drm/qxl/qxl_drv.c +++ b/drivers/gpu/drm/qxl/qxl_drv.c | |||
@@ -62,20 +62,83 @@ static struct pci_driver qxl_pci_driver; | |||
62 | static int | 62 | static int |
63 | qxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | 63 | qxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) |
64 | { | 64 | { |
65 | struct drm_device *drm; | ||
66 | struct qxl_device *qdev; | ||
67 | int ret; | ||
68 | |||
65 | if (pdev->revision < 4) { | 69 | if (pdev->revision < 4) { |
66 | DRM_ERROR("qxl too old, doesn't support client_monitors_config," | 70 | DRM_ERROR("qxl too old, doesn't support client_monitors_config," |
67 | " use xf86-video-qxl in user mode"); | 71 | " use xf86-video-qxl in user mode"); |
68 | return -EINVAL; /* TODO: ENODEV ? */ | 72 | return -EINVAL; /* TODO: ENODEV ? */ |
69 | } | 73 | } |
70 | return drm_get_pci_dev(pdev, ent, &qxl_driver); | 74 | |
75 | drm = drm_dev_alloc(&qxl_driver, &pdev->dev); | ||
76 | if (IS_ERR(drm)) | ||
77 | return -ENOMEM; | ||
78 | |||
79 | qdev = kzalloc(sizeof(struct qxl_device), GFP_KERNEL); | ||
80 | if (!qdev) { | ||
81 | ret = -ENOMEM; | ||
82 | goto free_drm_device; | ||
83 | } | ||
84 | |||
85 | ret = pci_enable_device(pdev); | ||
86 | if (ret) | ||
87 | goto free_drm_device; | ||
88 | |||
89 | drm->pdev = pdev; | ||
90 | pci_set_drvdata(pdev, drm); | ||
91 | drm->dev_private = qdev; | ||
92 | |||
93 | ret = qxl_device_init(qdev, drm, pdev, ent->driver_data); | ||
94 | if (ret) | ||
95 | goto disable_pci; | ||
96 | |||
97 | ret = drm_vblank_init(drm, 1); | ||
98 | if (ret) | ||
99 | goto unload; | ||
100 | |||
101 | ret = qxl_modeset_init(qdev); | ||
102 | if (ret) | ||
103 | goto vblank_cleanup; | ||
104 | |||
105 | drm_kms_helper_poll_init(qdev->ddev); | ||
106 | |||
107 | /* Complete initialization. */ | ||
108 | ret = drm_dev_register(drm, ent->driver_data); | ||
109 | if (ret) | ||
110 | goto modeset_cleanup; | ||
111 | |||
112 | return 0; | ||
113 | |||
114 | modeset_cleanup: | ||
115 | qxl_modeset_fini(qdev); | ||
116 | vblank_cleanup: | ||
117 | drm_vblank_cleanup(drm); | ||
118 | unload: | ||
119 | qxl_device_fini(qdev); | ||
120 | disable_pci: | ||
121 | pci_disable_device(pdev); | ||
122 | free_drm_device: | ||
123 | kfree(qdev); | ||
124 | kfree(drm); | ||
125 | return ret; | ||
71 | } | 126 | } |
72 | 127 | ||
73 | static void | 128 | static void |
74 | qxl_pci_remove(struct pci_dev *pdev) | 129 | qxl_pci_remove(struct pci_dev *pdev) |
75 | { | 130 | { |
76 | struct drm_device *dev = pci_get_drvdata(pdev); | 131 | struct drm_device *dev = pci_get_drvdata(pdev); |
132 | struct qxl_device *qdev = dev->dev_private; | ||
133 | |||
134 | drm_dev_unregister(dev); | ||
135 | |||
136 | qxl_modeset_fini(qdev); | ||
137 | qxl_device_fini(qdev); | ||
77 | 138 | ||
78 | drm_put_dev(dev); | 139 | dev->dev_private = NULL; |
140 | kfree(qdev); | ||
141 | drm_dev_unref(dev); | ||
79 | } | 142 | } |
80 | 143 | ||
81 | static const struct file_operations qxl_fops = { | 144 | static const struct file_operations qxl_fops = { |
@@ -230,8 +293,6 @@ static struct pci_driver qxl_pci_driver = { | |||
230 | static struct drm_driver qxl_driver = { | 293 | static struct drm_driver qxl_driver = { |
231 | .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_PRIME | | 294 | .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_PRIME | |
232 | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED, | 295 | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED, |
233 | .load = qxl_driver_load, | ||
234 | .unload = qxl_driver_unload, | ||
235 | .get_vblank_counter = qxl_noop_get_vblank_counter, | 296 | .get_vblank_counter = qxl_noop_get_vblank_counter, |
236 | .enable_vblank = qxl_noop_enable_vblank, | 297 | .enable_vblank = qxl_noop_enable_vblank, |
237 | .disable_vblank = qxl_noop_disable_vblank, | 298 | .disable_vblank = qxl_noop_disable_vblank, |
diff --git a/drivers/gpu/drm/qxl/qxl_drv.h b/drivers/gpu/drm/qxl/qxl_drv.h index 883d8639c04e..0d877fa61162 100644 --- a/drivers/gpu/drm/qxl/qxl_drv.h +++ b/drivers/gpu/drm/qxl/qxl_drv.h | |||
@@ -336,8 +336,9 @@ __printf(2,3) void qxl_io_log(struct qxl_device *qdev, const char *fmt, ...); | |||
336 | extern const struct drm_ioctl_desc qxl_ioctls[]; | 336 | extern const struct drm_ioctl_desc qxl_ioctls[]; |
337 | extern int qxl_max_ioctl; | 337 | extern int qxl_max_ioctl; |
338 | 338 | ||
339 | int qxl_driver_load(struct drm_device *dev, unsigned long flags); | 339 | int qxl_device_init(struct qxl_device *qdev, struct drm_device *ddev, |
340 | void qxl_driver_unload(struct drm_device *dev); | 340 | struct pci_dev *pdev, unsigned long flags); |
341 | void qxl_device_fini(struct qxl_device *qdev); | ||
341 | 342 | ||
342 | int qxl_modeset_init(struct qxl_device *qdev); | 343 | int qxl_modeset_init(struct qxl_device *qdev); |
343 | void qxl_modeset_fini(struct qxl_device *qdev); | 344 | void qxl_modeset_fini(struct qxl_device *qdev); |
@@ -531,6 +532,7 @@ int qxl_garbage_collect(struct qxl_device *qdev); | |||
531 | 532 | ||
532 | int qxl_debugfs_init(struct drm_minor *minor); | 533 | int qxl_debugfs_init(struct drm_minor *minor); |
533 | void qxl_debugfs_takedown(struct drm_minor *minor); | 534 | void qxl_debugfs_takedown(struct drm_minor *minor); |
535 | int qxl_ttm_debugfs_init(struct qxl_device *qdev); | ||
534 | 536 | ||
535 | /* qxl_prime.c */ | 537 | /* qxl_prime.c */ |
536 | int qxl_gem_prime_pin(struct drm_gem_object *obj); | 538 | int qxl_gem_prime_pin(struct drm_gem_object *obj); |
diff --git a/drivers/gpu/drm/qxl/qxl_kms.c b/drivers/gpu/drm/qxl/qxl_kms.c index b2491407b616..d0666f5dccd6 100644 --- a/drivers/gpu/drm/qxl/qxl_kms.c +++ b/drivers/gpu/drm/qxl/qxl_kms.c | |||
@@ -115,7 +115,7 @@ static void qxl_gc_work(struct work_struct *work) | |||
115 | qxl_garbage_collect(qdev); | 115 | qxl_garbage_collect(qdev); |
116 | } | 116 | } |
117 | 117 | ||
118 | static int qxl_device_init(struct qxl_device *qdev, | 118 | int qxl_device_init(struct qxl_device *qdev, |
119 | struct drm_device *ddev, | 119 | struct drm_device *ddev, |
120 | struct pci_dev *pdev, | 120 | struct pci_dev *pdev, |
121 | unsigned long flags) | 121 | unsigned long flags) |
@@ -263,7 +263,7 @@ static int qxl_device_init(struct qxl_device *qdev, | |||
263 | return 0; | 263 | return 0; |
264 | } | 264 | } |
265 | 265 | ||
266 | static void qxl_device_fini(struct qxl_device *qdev) | 266 | void qxl_device_fini(struct qxl_device *qdev) |
267 | { | 267 | { |
268 | if (qdev->current_release_bo[0]) | 268 | if (qdev->current_release_bo[0]) |
269 | qxl_bo_unref(&qdev->current_release_bo[0]); | 269 | qxl_bo_unref(&qdev->current_release_bo[0]); |
@@ -284,55 +284,3 @@ static void qxl_device_fini(struct qxl_device *qdev) | |||
284 | qdev->mode_info.num_modes = 0; | 284 | qdev->mode_info.num_modes = 0; |
285 | qxl_debugfs_remove_files(qdev); | 285 | qxl_debugfs_remove_files(qdev); |
286 | } | 286 | } |
287 | |||
288 | void qxl_driver_unload(struct drm_device *dev) | ||
289 | { | ||
290 | struct qxl_device *qdev = dev->dev_private; | ||
291 | |||
292 | if (qdev == NULL) | ||
293 | return; | ||
294 | |||
295 | drm_vblank_cleanup(dev); | ||
296 | |||
297 | qxl_modeset_fini(qdev); | ||
298 | qxl_device_fini(qdev); | ||
299 | |||
300 | kfree(qdev); | ||
301 | dev->dev_private = NULL; | ||
302 | } | ||
303 | |||
304 | int qxl_driver_load(struct drm_device *dev, unsigned long flags) | ||
305 | { | ||
306 | struct qxl_device *qdev; | ||
307 | int r; | ||
308 | |||
309 | qdev = kzalloc(sizeof(struct qxl_device), GFP_KERNEL); | ||
310 | if (qdev == NULL) | ||
311 | return -ENOMEM; | ||
312 | |||
313 | dev->dev_private = qdev; | ||
314 | |||
315 | r = qxl_device_init(qdev, dev, dev->pdev, flags); | ||
316 | if (r) | ||
317 | goto out; | ||
318 | |||
319 | r = drm_vblank_init(dev, 1); | ||
320 | if (r) | ||
321 | goto unload; | ||
322 | |||
323 | r = qxl_modeset_init(qdev); | ||
324 | if (r) | ||
325 | goto unload; | ||
326 | |||
327 | drm_kms_helper_poll_init(qdev->ddev); | ||
328 | |||
329 | return 0; | ||
330 | unload: | ||
331 | qxl_driver_unload(dev); | ||
332 | |||
333 | out: | ||
334 | kfree(qdev); | ||
335 | return r; | ||
336 | } | ||
337 | |||
338 | |||
diff --git a/drivers/gpu/drm/qxl/qxl_ttm.c b/drivers/gpu/drm/qxl/qxl_ttm.c index 1b096c5252ad..bc1c896bc5e1 100644 --- a/drivers/gpu/drm/qxl/qxl_ttm.c +++ b/drivers/gpu/drm/qxl/qxl_ttm.c | |||
@@ -35,7 +35,6 @@ | |||
35 | #include "qxl_object.h" | 35 | #include "qxl_object.h" |
36 | 36 | ||
37 | #include <linux/delay.h> | 37 | #include <linux/delay.h> |
38 | static int qxl_ttm_debugfs_init(struct qxl_device *qdev); | ||
39 | 38 | ||
40 | static struct qxl_device *qxl_get_qdev(struct ttm_bo_device *bdev) | 39 | static struct qxl_device *qxl_get_qdev(struct ttm_bo_device *bdev) |
41 | { | 40 | { |
@@ -436,11 +435,6 @@ int qxl_ttm_init(struct qxl_device *qdev) | |||
436 | ((unsigned)num_io_pages * PAGE_SIZE) / (1024 * 1024)); | 435 | ((unsigned)num_io_pages * PAGE_SIZE) / (1024 * 1024)); |
437 | DRM_INFO("qxl: %uM of Surface memory size\n", | 436 | DRM_INFO("qxl: %uM of Surface memory size\n", |
438 | (unsigned)qdev->surfaceram_size / (1024 * 1024)); | 437 | (unsigned)qdev->surfaceram_size / (1024 * 1024)); |
439 | r = qxl_ttm_debugfs_init(qdev); | ||
440 | if (r) { | ||
441 | DRM_ERROR("Failed to init debugfs\n"); | ||
442 | return r; | ||
443 | } | ||
444 | return 0; | 438 | return 0; |
445 | } | 439 | } |
446 | 440 | ||
@@ -473,7 +467,7 @@ static int qxl_mm_dump_table(struct seq_file *m, void *data) | |||
473 | } | 467 | } |
474 | #endif | 468 | #endif |
475 | 469 | ||
476 | static int qxl_ttm_debugfs_init(struct qxl_device *qdev) | 470 | int qxl_ttm_debugfs_init(struct qxl_device *qdev) |
477 | { | 471 | { |
478 | #if defined(CONFIG_DEBUG_FS) | 472 | #if defined(CONFIG_DEBUG_FS) |
479 | static struct drm_info_list qxl_mem_types_list[QXL_DEBUGFS_MEM_TYPES]; | 473 | static struct drm_info_list qxl_mem_types_list[QXL_DEBUGFS_MEM_TYPES]; |
diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c index 0665fb915579..a6d4a0236e8f 100644 --- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | |||
@@ -257,8 +257,6 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master, | |||
257 | struct drm_device *drm = data; | 257 | struct drm_device *drm = data; |
258 | struct drm_encoder *encoder; | 258 | struct drm_encoder *encoder; |
259 | struct rockchip_hdmi *hdmi; | 259 | struct rockchip_hdmi *hdmi; |
260 | struct resource *iores; | ||
261 | int irq; | ||
262 | int ret; | 260 | int ret; |
263 | 261 | ||
264 | if (!pdev->dev.of_node) | 262 | if (!pdev->dev.of_node) |
@@ -273,14 +271,6 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master, | |||
273 | hdmi->dev = &pdev->dev; | 271 | hdmi->dev = &pdev->dev; |
274 | encoder = &hdmi->encoder; | 272 | encoder = &hdmi->encoder; |
275 | 273 | ||
276 | irq = platform_get_irq(pdev, 0); | ||
277 | if (irq < 0) | ||
278 | return irq; | ||
279 | |||
280 | iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
281 | if (!iores) | ||
282 | return -ENXIO; | ||
283 | |||
284 | encoder->possible_crtcs = drm_of_find_possible_crtcs(drm, dev->of_node); | 274 | encoder->possible_crtcs = drm_of_find_possible_crtcs(drm, dev->of_node); |
285 | /* | 275 | /* |
286 | * If we failed to find the CRTC(s) which this encoder is | 276 | * If we failed to find the CRTC(s) which this encoder is |
@@ -301,7 +291,7 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master, | |||
301 | drm_encoder_init(drm, encoder, &dw_hdmi_rockchip_encoder_funcs, | 291 | drm_encoder_init(drm, encoder, &dw_hdmi_rockchip_encoder_funcs, |
302 | DRM_MODE_ENCODER_TMDS, NULL); | 292 | DRM_MODE_ENCODER_TMDS, NULL); |
303 | 293 | ||
304 | ret = dw_hdmi_bind(dev, master, data, encoder, iores, irq, plat_data); | 294 | ret = dw_hdmi_bind(pdev, encoder, plat_data); |
305 | 295 | ||
306 | /* | 296 | /* |
307 | * If dw_hdmi_bind() fails we'll never call dw_hdmi_unbind(), | 297 | * If dw_hdmi_bind() fails we'll never call dw_hdmi_unbind(), |
@@ -316,7 +306,7 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master, | |||
316 | static void dw_hdmi_rockchip_unbind(struct device *dev, struct device *master, | 306 | static void dw_hdmi_rockchip_unbind(struct device *dev, struct device *master, |
317 | void *data) | 307 | void *data) |
318 | { | 308 | { |
319 | return dw_hdmi_unbind(dev, master, data); | 309 | return dw_hdmi_unbind(dev); |
320 | } | 310 | } |
321 | 311 | ||
322 | static const struct component_ops dw_hdmi_rockchip_ops = { | 312 | static const struct component_ops dw_hdmi_rockchip_ops = { |
diff --git a/drivers/gpu/drm/selftests/test-drm_mm.c b/drivers/gpu/drm/selftests/test-drm_mm.c index 6d2a5cd211f3..6df53e6c1308 100644 --- a/drivers/gpu/drm/selftests/test-drm_mm.c +++ b/drivers/gpu/drm/selftests/test-drm_mm.c | |||
@@ -1274,13 +1274,19 @@ static bool evict_everything(struct drm_mm *mm, | |||
1274 | if (drm_mm_scan_add_block(&scan, &e->node)) | 1274 | if (drm_mm_scan_add_block(&scan, &e->node)) |
1275 | break; | 1275 | break; |
1276 | } | 1276 | } |
1277 | |||
1278 | err = 0; | ||
1277 | list_for_each_entry(e, &evict_list, link) { | 1279 | list_for_each_entry(e, &evict_list, link) { |
1278 | if (!drm_mm_scan_remove_block(&scan, &e->node)) { | 1280 | if (!drm_mm_scan_remove_block(&scan, &e->node)) { |
1279 | pr_err("Node %lld not marked for eviction!\n", | 1281 | if (!err) { |
1280 | e->node.start); | 1282 | pr_err("Node %lld not marked for eviction!\n", |
1281 | list_del(&e->link); | 1283 | e->node.start); |
1284 | err = -EINVAL; | ||
1285 | } | ||
1282 | } | 1286 | } |
1283 | } | 1287 | } |
1288 | if (err) | ||
1289 | return false; | ||
1284 | 1290 | ||
1285 | list_for_each_entry(e, &evict_list, link) | 1291 | list_for_each_entry(e, &evict_list, link) |
1286 | drm_mm_remove_node(&e->node); | 1292 | drm_mm_remove_node(&e->node); |
diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c index 0f4eacb0af4f..2d57f6278db1 100644 --- a/drivers/gpu/drm/tegra/drm.c +++ b/drivers/gpu/drm/tegra/drm.c | |||
@@ -804,23 +804,10 @@ static const struct file_operations tegra_drm_fops = { | |||
804 | .llseek = noop_llseek, | 804 | .llseek = noop_llseek, |
805 | }; | 805 | }; |
806 | 806 | ||
807 | static struct drm_crtc *tegra_crtc_from_pipe(struct drm_device *drm, | ||
808 | unsigned int pipe) | ||
809 | { | ||
810 | struct drm_crtc *crtc; | ||
811 | |||
812 | list_for_each_entry(crtc, &drm->mode_config.crtc_list, head) { | ||
813 | if (pipe == drm_crtc_index(crtc)) | ||
814 | return crtc; | ||
815 | } | ||
816 | |||
817 | return NULL; | ||
818 | } | ||
819 | |||
820 | static u32 tegra_drm_get_vblank_counter(struct drm_device *drm, | 807 | static u32 tegra_drm_get_vblank_counter(struct drm_device *drm, |
821 | unsigned int pipe) | 808 | unsigned int pipe) |
822 | { | 809 | { |
823 | struct drm_crtc *crtc = tegra_crtc_from_pipe(drm, pipe); | 810 | struct drm_crtc *crtc = drm_crtc_from_index(drm, pipe); |
824 | struct tegra_dc *dc = to_tegra_dc(crtc); | 811 | struct tegra_dc *dc = to_tegra_dc(crtc); |
825 | 812 | ||
826 | if (!crtc) | 813 | if (!crtc) |
@@ -831,7 +818,7 @@ static u32 tegra_drm_get_vblank_counter(struct drm_device *drm, | |||
831 | 818 | ||
832 | static int tegra_drm_enable_vblank(struct drm_device *drm, unsigned int pipe) | 819 | static int tegra_drm_enable_vblank(struct drm_device *drm, unsigned int pipe) |
833 | { | 820 | { |
834 | struct drm_crtc *crtc = tegra_crtc_from_pipe(drm, pipe); | 821 | struct drm_crtc *crtc = drm_crtc_from_index(drm, pipe); |
835 | struct tegra_dc *dc = to_tegra_dc(crtc); | 822 | struct tegra_dc *dc = to_tegra_dc(crtc); |
836 | 823 | ||
837 | if (!crtc) | 824 | if (!crtc) |
@@ -844,7 +831,7 @@ static int tegra_drm_enable_vblank(struct drm_device *drm, unsigned int pipe) | |||
844 | 831 | ||
845 | static void tegra_drm_disable_vblank(struct drm_device *drm, unsigned int pipe) | 832 | static void tegra_drm_disable_vblank(struct drm_device *drm, unsigned int pipe) |
846 | { | 833 | { |
847 | struct drm_crtc *crtc = tegra_crtc_from_pipe(drm, pipe); | 834 | struct drm_crtc *crtc = drm_crtc_from_index(drm, pipe); |
848 | struct tegra_dc *dc = to_tegra_dc(crtc); | 835 | struct tegra_dc *dc = to_tegra_dc(crtc); |
849 | 836 | ||
850 | if (crtc) | 837 | if (crtc) |
diff --git a/drivers/gpu/drm/tegra/fb.c b/drivers/gpu/drm/tegra/fb.c index 8df7783cecc2..f896e2ff7d47 100644 --- a/drivers/gpu/drm/tegra/fb.c +++ b/drivers/gpu/drm/tegra/fb.c | |||
@@ -271,8 +271,7 @@ static int tegra_fbdev_probe(struct drm_fb_helper *helper, | |||
271 | return 0; | 271 | return 0; |
272 | 272 | ||
273 | destroy: | 273 | destroy: |
274 | drm_framebuffer_unregister_private(fb); | 274 | drm_framebuffer_remove(fb); |
275 | tegra_fb_destroy(fb); | ||
276 | release: | 275 | release: |
277 | drm_fb_helper_release_fbi(helper); | 276 | drm_fb_helper_release_fbi(helper); |
278 | return err; | 277 | return err; |
@@ -342,10 +341,8 @@ static void tegra_fbdev_exit(struct tegra_fbdev *fbdev) | |||
342 | drm_fb_helper_unregister_fbi(&fbdev->base); | 341 | drm_fb_helper_unregister_fbi(&fbdev->base); |
343 | drm_fb_helper_release_fbi(&fbdev->base); | 342 | drm_fb_helper_release_fbi(&fbdev->base); |
344 | 343 | ||
345 | if (fbdev->fb) { | 344 | if (fbdev->fb) |
346 | drm_framebuffer_unregister_private(&fbdev->fb->base); | ||
347 | drm_framebuffer_remove(&fbdev->fb->base); | 345 | drm_framebuffer_remove(&fbdev->fb->base); |
348 | } | ||
349 | 346 | ||
350 | drm_fb_helper_fini(&fbdev->base); | 347 | drm_fb_helper_fini(&fbdev->base); |
351 | tegra_fbdev_free(fbdev); | 348 | tegra_fbdev_free(fbdev); |
diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c index a0fd3e66bc4b..75b708b36890 100644 --- a/drivers/gpu/drm/vc4/vc4_crtc.c +++ b/drivers/gpu/drm/vc4/vc4_crtc.c | |||
@@ -156,7 +156,8 @@ int vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id, | |||
156 | const struct drm_display_mode *mode) | 156 | const struct drm_display_mode *mode) |
157 | { | 157 | { |
158 | struct vc4_dev *vc4 = to_vc4_dev(dev); | 158 | struct vc4_dev *vc4 = to_vc4_dev(dev); |
159 | struct vc4_crtc *vc4_crtc = vc4->crtc[crtc_id]; | 159 | struct drm_crtc *crtc = drm_crtc_from_index(dev, crtc_id); |
160 | struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); | ||
160 | u32 val; | 161 | u32 val; |
161 | int fifo_lines; | 162 | int fifo_lines; |
162 | int vblank_lines; | 163 | int vblank_lines; |
@@ -272,9 +273,7 @@ int vc4_crtc_get_vblank_timestamp(struct drm_device *dev, unsigned int crtc_id, | |||
272 | int *max_error, struct timeval *vblank_time, | 273 | int *max_error, struct timeval *vblank_time, |
273 | unsigned flags) | 274 | unsigned flags) |
274 | { | 275 | { |
275 | struct vc4_dev *vc4 = to_vc4_dev(dev); | 276 | struct drm_crtc *crtc = drm_crtc_from_index(dev, crtc_id); |
276 | struct vc4_crtc *vc4_crtc = vc4->crtc[crtc_id]; | ||
277 | struct drm_crtc *crtc = &vc4_crtc->base; | ||
278 | struct drm_crtc_state *state = crtc->state; | 277 | struct drm_crtc_state *state = crtc->state; |
279 | 278 | ||
280 | /* Helper routine in DRM core does all the work: */ | 279 | /* Helper routine in DRM core does all the work: */ |
@@ -652,8 +651,8 @@ static void vc4_crtc_atomic_flush(struct drm_crtc *crtc, | |||
652 | 651 | ||
653 | int vc4_enable_vblank(struct drm_device *dev, unsigned int crtc_id) | 652 | int vc4_enable_vblank(struct drm_device *dev, unsigned int crtc_id) |
654 | { | 653 | { |
655 | struct vc4_dev *vc4 = to_vc4_dev(dev); | 654 | struct drm_crtc *crtc = drm_crtc_from_index(dev, crtc_id); |
656 | struct vc4_crtc *vc4_crtc = vc4->crtc[crtc_id]; | 655 | struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); |
657 | 656 | ||
658 | CRTC_WRITE(PV_INTEN, PV_INT_VFP_START); | 657 | CRTC_WRITE(PV_INTEN, PV_INT_VFP_START); |
659 | 658 | ||
@@ -662,8 +661,8 @@ int vc4_enable_vblank(struct drm_device *dev, unsigned int crtc_id) | |||
662 | 661 | ||
663 | void vc4_disable_vblank(struct drm_device *dev, unsigned int crtc_id) | 662 | void vc4_disable_vblank(struct drm_device *dev, unsigned int crtc_id) |
664 | { | 663 | { |
665 | struct vc4_dev *vc4 = to_vc4_dev(dev); | 664 | struct drm_crtc *crtc = drm_crtc_from_index(dev, crtc_id); |
666 | struct vc4_crtc *vc4_crtc = vc4->crtc[crtc_id]; | 665 | struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); |
667 | 666 | ||
668 | CRTC_WRITE(PV_INTEN, 0); | 667 | CRTC_WRITE(PV_INTEN, 0); |
669 | } | 668 | } |
@@ -937,7 +936,6 @@ static int vc4_crtc_bind(struct device *dev, struct device *master, void *data) | |||
937 | { | 936 | { |
938 | struct platform_device *pdev = to_platform_device(dev); | 937 | struct platform_device *pdev = to_platform_device(dev); |
939 | struct drm_device *drm = dev_get_drvdata(master); | 938 | struct drm_device *drm = dev_get_drvdata(master); |
940 | struct vc4_dev *vc4 = to_vc4_dev(drm); | ||
941 | struct vc4_crtc *vc4_crtc; | 939 | struct vc4_crtc *vc4_crtc; |
942 | struct drm_crtc *crtc; | 940 | struct drm_crtc *crtc; |
943 | struct drm_plane *primary_plane, *cursor_plane, *destroy_plane, *temp; | 941 | struct drm_plane *primary_plane, *cursor_plane, *destroy_plane, *temp; |
@@ -975,7 +973,6 @@ static int vc4_crtc_bind(struct device *dev, struct device *master, void *data) | |||
975 | &vc4_crtc_funcs, NULL); | 973 | &vc4_crtc_funcs, NULL); |
976 | drm_crtc_helper_add(crtc, &vc4_crtc_helper_funcs); | 974 | drm_crtc_helper_add(crtc, &vc4_crtc_helper_funcs); |
977 | primary_plane->crtc = crtc; | 975 | primary_plane->crtc = crtc; |
978 | vc4->crtc[drm_crtc_index(crtc)] = vc4_crtc; | ||
979 | vc4_crtc->channel = vc4_crtc->data->hvs_channel; | 976 | vc4_crtc->channel = vc4_crtc->data->hvs_channel; |
980 | drm_mode_crtc_set_gamma_size(crtc, ARRAY_SIZE(vc4_crtc->lut_r)); | 977 | drm_mode_crtc_set_gamma_size(crtc, ARRAY_SIZE(vc4_crtc->lut_r)); |
981 | 978 | ||
diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h index 489956efbff8..affcdeb70aa9 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.h +++ b/drivers/gpu/drm/vc4/vc4_drv.h | |||
@@ -16,7 +16,6 @@ struct vc4_dev { | |||
16 | 16 | ||
17 | struct vc4_hdmi *hdmi; | 17 | struct vc4_hdmi *hdmi; |
18 | struct vc4_hvs *hvs; | 18 | struct vc4_hvs *hvs; |
19 | struct vc4_crtc *crtc[3]; | ||
20 | struct vc4_v3d *v3d; | 19 | struct vc4_v3d *v3d; |
21 | struct vc4_dpi *dpi; | 20 | struct vc4_dpi *dpi; |
22 | struct vc4_vec *vec; | 21 | struct vc4_vec *vec; |
diff --git a/drivers/gpu/drm/vgem/vgem_drv.h b/drivers/gpu/drm/vgem/vgem_drv.h index 1f8798ad329c..cb59c7ab98b9 100644 --- a/drivers/gpu/drm/vgem/vgem_drv.h +++ b/drivers/gpu/drm/vgem/vgem_drv.h | |||
@@ -31,6 +31,7 @@ | |||
31 | 31 | ||
32 | #include <drm/drmP.h> | 32 | #include <drm/drmP.h> |
33 | #include <drm/drm_gem.h> | 33 | #include <drm/drm_gem.h> |
34 | #include <drm/drm_cache.h> | ||
34 | 35 | ||
35 | #include <uapi/drm/vgem_drm.h> | 36 | #include <uapi/drm/vgem_drm.h> |
36 | 37 | ||