diff options
| author | Ajay Kumar <ajaykumar.rs@samsung.com> | 2014-07-31 13:42:14 -0400 |
|---|---|---|
| committer | Thierry Reding <treding@nvidia.com> | 2014-08-06 10:44:16 -0400 |
| commit | 5f1dcd8b7ec8189c2b147cdaa1589d5644c3cef3 (patch) | |
| tree | 515c9198065ff932810886ecfeb532801bbce5be /drivers/gpu/drm | |
| parent | 4deabfa00049465cc1e4ed6fe0b5082bcff98d57 (diff) | |
drm/exynos: dp: Modify driver to support drm_panel
Add drm_panel controls to support powerup/down of the
eDP panel, if one is present at the sink side.
Signed-off-by: Ajay Kumar <ajaykumar.rs@samsung.com>
Acked-by: Inki Dae <inki.dae@samsung.com>
Signed-off-by: Thierry Reding <treding@nvidia.com>
Diffstat (limited to 'drivers/gpu/drm')
| -rw-r--r-- | drivers/gpu/drm/exynos/Kconfig | 1 | ||||
| -rw-r--r-- | drivers/gpu/drm/exynos/exynos_dp_core.c | 88 | ||||
| -rw-r--r-- | drivers/gpu/drm/exynos/exynos_dp_core.h | 3 |
3 files changed, 71 insertions, 21 deletions
diff --git a/drivers/gpu/drm/exynos/Kconfig b/drivers/gpu/drm/exynos/Kconfig index 178d2a9672a8..fd1c070f0297 100644 --- a/drivers/gpu/drm/exynos/Kconfig +++ b/drivers/gpu/drm/exynos/Kconfig | |||
| @@ -52,6 +52,7 @@ config DRM_EXYNOS_DP | |||
| 52 | bool "EXYNOS DRM DP driver support" | 52 | bool "EXYNOS DRM DP driver support" |
| 53 | depends on DRM_EXYNOS_FIMD && ARCH_EXYNOS && (DRM_PTN3460=n || DRM_PTN3460=y || DRM_PTN3460=DRM_EXYNOS) | 53 | depends on DRM_EXYNOS_FIMD && ARCH_EXYNOS && (DRM_PTN3460=n || DRM_PTN3460=y || DRM_PTN3460=DRM_EXYNOS) |
| 54 | default DRM_EXYNOS | 54 | default DRM_EXYNOS |
| 55 | select DRM_PANEL | ||
| 55 | help | 56 | help |
| 56 | This enables support for DP device. | 57 | This enables support for DP device. |
| 57 | 58 | ||
diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.c b/drivers/gpu/drm/exynos/exynos_dp_core.c index c33a9d0a87c1..0d3f88bfeca5 100644 --- a/drivers/gpu/drm/exynos/exynos_dp_core.c +++ b/drivers/gpu/drm/exynos/exynos_dp_core.c | |||
| @@ -16,7 +16,6 @@ | |||
| 16 | #include <linux/clk.h> | 16 | #include <linux/clk.h> |
| 17 | #include <linux/io.h> | 17 | #include <linux/io.h> |
| 18 | #include <linux/interrupt.h> | 18 | #include <linux/interrupt.h> |
| 19 | #include <linux/delay.h> | ||
| 20 | #include <linux/of.h> | 19 | #include <linux/of.h> |
| 21 | #include <linux/of_gpio.h> | 20 | #include <linux/of_gpio.h> |
| 22 | #include <linux/gpio.h> | 21 | #include <linux/gpio.h> |
| @@ -28,6 +27,7 @@ | |||
| 28 | #include <drm/drmP.h> | 27 | #include <drm/drmP.h> |
| 29 | #include <drm/drm_crtc.h> | 28 | #include <drm/drm_crtc.h> |
| 30 | #include <drm/drm_crtc_helper.h> | 29 | #include <drm/drm_crtc_helper.h> |
| 30 | #include <drm/drm_panel.h> | ||
| 31 | #include <drm/bridge/ptn3460.h> | 31 | #include <drm/bridge/ptn3460.h> |
| 32 | 32 | ||
| 33 | #include "exynos_drm_drv.h" | 33 | #include "exynos_drm_drv.h" |
| @@ -41,7 +41,7 @@ struct bridge_init { | |||
| 41 | struct device_node *node; | 41 | struct device_node *node; |
| 42 | }; | 42 | }; |
| 43 | 43 | ||
| 44 | static int exynos_dp_init_dp(struct exynos_dp_device *dp) | 44 | static void exynos_dp_init_dp(struct exynos_dp_device *dp) |
| 45 | { | 45 | { |
| 46 | exynos_dp_reset(dp); | 46 | exynos_dp_reset(dp); |
| 47 | 47 | ||
| @@ -58,8 +58,6 @@ static int exynos_dp_init_dp(struct exynos_dp_device *dp) | |||
| 58 | 58 | ||
| 59 | exynos_dp_init_hpd(dp); | 59 | exynos_dp_init_hpd(dp); |
| 60 | exynos_dp_init_aux(dp); | 60 | exynos_dp_init_aux(dp); |
| 61 | |||
| 62 | return 0; | ||
| 63 | } | 61 | } |
| 64 | 62 | ||
| 65 | static int exynos_dp_detect_hpd(struct exynos_dp_device *dp) | 63 | static int exynos_dp_detect_hpd(struct exynos_dp_device *dp) |
| @@ -887,6 +885,12 @@ static void exynos_dp_commit(struct exynos_drm_display *display) | |||
| 887 | struct exynos_dp_device *dp = display->ctx; | 885 | struct exynos_dp_device *dp = display->ctx; |
| 888 | int ret; | 886 | int ret; |
| 889 | 887 | ||
| 888 | /* Keep the panel disabled while we configure video */ | ||
| 889 | if (dp->panel) { | ||
| 890 | if (drm_panel_disable(dp->panel)) | ||
| 891 | DRM_ERROR("failed to disable the panel\n"); | ||
| 892 | } | ||
| 893 | |||
| 890 | ret = exynos_dp_detect_hpd(dp); | 894 | ret = exynos_dp_detect_hpd(dp); |
| 891 | if (ret) { | 895 | if (ret) { |
| 892 | /* Cable has been disconnected, we're done */ | 896 | /* Cable has been disconnected, we're done */ |
| @@ -917,6 +921,12 @@ static void exynos_dp_commit(struct exynos_drm_display *display) | |||
| 917 | ret = exynos_dp_config_video(dp); | 921 | ret = exynos_dp_config_video(dp); |
| 918 | if (ret) | 922 | if (ret) |
| 919 | dev_err(dp->dev, "unable to config video\n"); | 923 | dev_err(dp->dev, "unable to config video\n"); |
| 924 | |||
| 925 | /* Safe to enable the panel now */ | ||
| 926 | if (dp->panel) { | ||
| 927 | if (drm_panel_enable(dp->panel)) | ||
| 928 | DRM_ERROR("failed to enable the panel\n"); | ||
| 929 | } | ||
| 920 | } | 930 | } |
| 921 | 931 | ||
| 922 | static enum drm_connector_status exynos_dp_detect( | 932 | static enum drm_connector_status exynos_dp_detect( |
| @@ -941,15 +951,18 @@ static int exynos_dp_get_modes(struct drm_connector *connector) | |||
| 941 | struct exynos_dp_device *dp = ctx_from_connector(connector); | 951 | struct exynos_dp_device *dp = ctx_from_connector(connector); |
| 942 | struct drm_display_mode *mode; | 952 | struct drm_display_mode *mode; |
| 943 | 953 | ||
| 954 | if (dp->panel) | ||
| 955 | return drm_panel_get_modes(dp->panel); | ||
| 956 | |||
| 944 | mode = drm_mode_create(connector->dev); | 957 | mode = drm_mode_create(connector->dev); |
| 945 | if (!mode) { | 958 | if (!mode) { |
| 946 | DRM_ERROR("failed to create a new display mode.\n"); | 959 | DRM_ERROR("failed to create a new display mode.\n"); |
| 947 | return 0; | 960 | return 0; |
| 948 | } | 961 | } |
| 949 | 962 | ||
| 950 | drm_display_mode_from_videomode(&dp->panel.vm, mode); | 963 | drm_display_mode_from_videomode(&dp->priv.vm, mode); |
| 951 | mode->width_mm = dp->panel.width_mm; | 964 | mode->width_mm = dp->priv.width_mm; |
| 952 | mode->height_mm = dp->panel.height_mm; | 965 | mode->height_mm = dp->priv.height_mm; |
| 953 | connector->display_info.width_mm = mode->width_mm; | 966 | connector->display_info.width_mm = mode->width_mm; |
| 954 | connector->display_info.height_mm = mode->height_mm; | 967 | connector->display_info.height_mm = mode->height_mm; |
| 955 | 968 | ||
| @@ -1029,7 +1042,10 @@ static int exynos_dp_create_connector(struct exynos_drm_display *display, | |||
| 1029 | drm_sysfs_connector_add(connector); | 1042 | drm_sysfs_connector_add(connector); |
| 1030 | drm_mode_connector_attach_encoder(connector, encoder); | 1043 | drm_mode_connector_attach_encoder(connector, encoder); |
| 1031 | 1044 | ||
| 1032 | return 0; | 1045 | if (dp->panel) |
| 1046 | ret = drm_panel_attach(dp->panel, &dp->connector); | ||
| 1047 | |||
| 1048 | return ret; | ||
| 1033 | } | 1049 | } |
| 1034 | 1050 | ||
| 1035 | static void exynos_dp_phy_init(struct exynos_dp_device *dp) | 1051 | static void exynos_dp_phy_init(struct exynos_dp_device *dp) |
| @@ -1065,6 +1081,13 @@ static void exynos_dp_poweron(struct exynos_drm_display *display) | |||
| 1065 | if (dp->dpms_mode == DRM_MODE_DPMS_ON) | 1081 | if (dp->dpms_mode == DRM_MODE_DPMS_ON) |
| 1066 | return; | 1082 | return; |
| 1067 | 1083 | ||
| 1084 | if (dp->panel) { | ||
| 1085 | if (drm_panel_prepare(dp->panel)) { | ||
| 1086 | DRM_ERROR("failed to setup the panel\n"); | ||
| 1087 | return; | ||
| 1088 | } | ||
| 1089 | } | ||
| 1090 | |||
| 1068 | clk_prepare_enable(dp->clock); | 1091 | clk_prepare_enable(dp->clock); |
| 1069 | exynos_dp_phy_init(dp); | 1092 | exynos_dp_phy_init(dp); |
| 1070 | exynos_dp_init_dp(dp); | 1093 | exynos_dp_init_dp(dp); |
| @@ -1079,10 +1102,22 @@ static void exynos_dp_poweroff(struct exynos_drm_display *display) | |||
| 1079 | if (dp->dpms_mode != DRM_MODE_DPMS_ON) | 1102 | if (dp->dpms_mode != DRM_MODE_DPMS_ON) |
| 1080 | return; | 1103 | return; |
| 1081 | 1104 | ||
| 1105 | if (dp->panel) { | ||
| 1106 | if (drm_panel_disable(dp->panel)) { | ||
| 1107 | DRM_ERROR("failed to disable the panel\n"); | ||
| 1108 | return; | ||
| 1109 | } | ||
| 1110 | } | ||
| 1111 | |||
| 1082 | disable_irq(dp->irq); | 1112 | disable_irq(dp->irq); |
| 1083 | flush_work(&dp->hotplug_work); | 1113 | flush_work(&dp->hotplug_work); |
| 1084 | exynos_dp_phy_exit(dp); | 1114 | exynos_dp_phy_exit(dp); |
| 1085 | clk_disable_unprepare(dp->clock); | 1115 | clk_disable_unprepare(dp->clock); |
| 1116 | |||
| 1117 | if (dp->panel) { | ||
| 1118 | if (drm_panel_unprepare(dp->panel)) | ||
| 1119 | DRM_ERROR("failed to turnoff the panel\n"); | ||
| 1120 | } | ||
| 1086 | } | 1121 | } |
| 1087 | 1122 | ||
| 1088 | static void exynos_dp_dpms(struct exynos_drm_display *display, int mode) | 1123 | static void exynos_dp_dpms(struct exynos_drm_display *display, int mode) |
| @@ -1215,7 +1250,7 @@ static int exynos_dp_dt_parse_panel(struct exynos_dp_device *dp) | |||
| 1215 | { | 1250 | { |
| 1216 | int ret; | 1251 | int ret; |
| 1217 | 1252 | ||
