aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorSean Paul <seanpaul@chromium.org>2014-01-30 16:19:23 -0500
committerInki Dae <daeinki@gmail.com>2014-03-23 11:36:35 -0400
commit1417f109a82f8a57b46e6789ccf66241bfddf411 (patch)
treec6a9cabe5bdf10765076b85ba7c4d57902eb7dbf /drivers
parent2e4e678aa8a49136a4954dd93e53ac5108977e5c (diff)
drm/exynos: Move display implementation into dp
This patch moves the exynos_drm_display implementation from fimd into the dp driver. This will allow for tighter integration of the dp driver into the exynos drm driver. Signed-off-by: Sean Paul <seanpaul@chromium.org> Signed-off-by: Inki Dae <inki.dae@samsung.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/exynos/exynos_dp_core.c100
-rw-r--r--drivers/gpu/drm/exynos/exynos_dp_core.h4
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_drv.c14
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_drv.h1
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_fimd.c79
5 files changed, 112 insertions, 86 deletions
diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.c b/drivers/gpu/drm/exynos/exynos_dp_core.c
index b3af4962b065..5c261616c06f 100644
--- a/drivers/gpu/drm/exynos/exynos_dp_core.c
+++ b/drivers/gpu/drm/exynos/exynos_dp_core.c
@@ -19,7 +19,12 @@
19#include <linux/delay.h> 19#include <linux/delay.h>
20#include <linux/of.h> 20#include <linux/of.h>
21#include <linux/phy/phy.h> 21#include <linux/phy/phy.h>
22#include <video/of_display_timing.h>
23#include <video/of_videomode.h>
22 24
25#include <drm/drmP.h>
26
27#include "exynos_drm_drv.h"
23#include "exynos_dp_core.h" 28#include "exynos_dp_core.h"
24 29
25static int exynos_dp_init_dp(struct exynos_dp_device *dp) 30static int exynos_dp_init_dp(struct exynos_dp_device *dp)
@@ -892,6 +897,35 @@ static void exynos_dp_hotplug(struct work_struct *work)
892 dev_err(dp->dev, "unable to config video\n"); 897 dev_err(dp->dev, "unable to config video\n");
893} 898}
894 899
900static bool exynos_dp_display_is_connected(struct exynos_drm_display *display)
901{
902 return true;
903}
904
905static void *exynos_dp_get_panel(struct exynos_drm_display *display)
906{
907 struct exynos_dp_device *dp = display->ctx;
908
909 return &dp->panel;
910}
911
912static int exynos_dp_check_mode(struct exynos_drm_display *display,
913 struct drm_display_mode *mode)
914{
915 return 0;
916}
917
918static struct exynos_drm_display_ops exynos_dp_display_ops = {
919 .is_connected = exynos_dp_display_is_connected,
920 .get_panel = exynos_dp_get_panel,
921 .check_mode = exynos_dp_check_mode,
922};
923
924static struct exynos_drm_display exynos_dp_display = {
925 .type = EXYNOS_DISPLAY_TYPE_LCD,
926 .ops = &exynos_dp_display_ops,
927};
928
895static struct video_info *exynos_dp_dt_parse_pdata(struct device *dev) 929static struct video_info *exynos_dp_dt_parse_pdata(struct device *dev)
896{ 930{
897 struct device_node *dp_node = dev->of_node; 931 struct device_node *dp_node = dev->of_node;
@@ -993,6 +1027,19 @@ err:
993 return ret; 1027 return ret;
994} 1028}
995 1029
1030static int exynos_dp_dt_parse_panel(struct exynos_dp_device *dp)
1031{
1032 int ret;
1033
1034 ret = of_get_videomode(dp->dev->of_node, &dp->panel.vm,
1035 OF_USE_NATIVE_MODE);
1036 if (ret) {
1037 DRM_ERROR("failed: of_get_videomode() : %d\n", ret);
1038 return ret;
1039 }
1040 return 0;
1041}
1042
996static void exynos_dp_phy_init(struct exynos_dp_device *dp) 1043static void exynos_dp_phy_init(struct exynos_dp_device *dp)
997{ 1044{
998 if (dp->phy) { 1045 if (dp->phy) {
@@ -1019,6 +1066,28 @@ static void exynos_dp_phy_exit(struct exynos_dp_device *dp)
1019 } 1066 }
1020} 1067}
1021 1068
1069void exynos_dp_poweron(struct exynos_dp_device *dp)
1070{
1071 exynos_dp_phy_init(dp);
1072
1073 clk_prepare_enable(dp->clock);
1074
1075 exynos_dp_init_dp(dp);
1076
1077 enable_irq(dp->irq);
1078}
1079
1080void exynos_dp_poweroff(struct exynos_dp_device *dp)
1081{
1082 disable_irq(dp->irq);
1083
1084 flush_work(&dp->hotplug_work);
1085
1086 exynos_dp_phy_exit(dp);
1087
1088 clk_disable_unprepare(dp->clock);
1089}
1090
1022static int exynos_dp_probe(struct platform_device *pdev) 1091static int exynos_dp_probe(struct platform_device *pdev)
1023{ 1092{
1024 struct resource *res; 1093 struct resource *res;
@@ -1043,6 +1112,10 @@ static int exynos_dp_probe(struct platform_device *pdev)
1043 if (ret) 1112 if (ret)
1044 return ret; 1113 return ret;
1045 1114
1115 ret = exynos_dp_dt_parse_panel(dp);
1116 if (ret)
1117 return ret;
1118
1046 dp->clock = devm_clk_get(&pdev->dev, "dp"); 1119 dp->clock = devm_clk_get(&pdev->dev, "dp");
1047 if (IS_ERR(dp->clock)) { 1120 if (IS_ERR(dp->clock)) {
1048 dev_err(&pdev->dev, "failed to get clock\n"); 1121 dev_err(&pdev->dev, "failed to get clock\n");
@@ -1078,6 +1151,9 @@ static int exynos_dp_probe(struct platform_device *pdev)
1078 1151
1079 platform_set_drvdata(pdev, dp); 1152 platform_set_drvdata(pdev, dp);
1080 1153
1154 exynos_dp_display.ctx = dp;
1155 exynos_drm_display_register(&exynos_dp_display);
1156
1081 return 0; 1157 return 0;
1082} 1158}
1083 1159
@@ -1085,6 +1161,8 @@ static int exynos_dp_remove(struct platform_device *pdev)
1085{ 1161{
1086 struct exynos_dp_device *dp = platform_get_drvdata(pdev); 1162 struct exynos_dp_device *dp = platform_get_drvdata(pdev);
1087 1163
1164 exynos_drm_display_unregister(&exynos_dp_display);
1165
1088 flush_work(&dp->hotplug_work); 1166 flush_work(&dp->hotplug_work);
1089 1167
1090 exynos_dp_phy_exit(dp); 1168 exynos_dp_phy_exit(dp);
@@ -1100,14 +1178,7 @@ static int exynos_dp_suspend(struct device *dev)
1100{ 1178{
1101 struct exynos_dp_device *dp = dev_get_drvdata(dev); 1179 struct exynos_dp_device *dp = dev_get_drvdata(dev);
1102 1180
1103 disable_irq(dp->irq); 1181 exynos_dp_poweroff(dp);
1104
1105 flush_work(&dp->hotplug_work);
1106
1107 exynos_dp_phy_exit(dp);
1108
1109 clk_disable_unprepare(dp->clock);
1110
1111 return 0; 1182 return 0;
1112} 1183}
1113 1184
@@ -1115,14 +1186,7 @@ static int exynos_dp_resume(struct device *dev)
1115{ 1186{
1116 struct exynos_dp_device *dp = dev_get_drvdata(dev); 1187 struct exynos_dp_device *dp = dev_get_drvdata(dev);
1117 1188
1118 exynos_dp_phy_init(dp); 1189 exynos_dp_poweron(dp);
1119
1120 clk_prepare_enable(dp->clock);
1121
1122 exynos_dp_init_dp(dp);
1123
1124 enable_irq(dp->irq);
1125
1126 return 0; 1190 return 0;
1127} 1191}
1128#endif 1192#endif
@@ -1137,7 +1201,7 @@ static const struct of_device_id exynos_dp_match[] = {
1137}; 1201};
1138MODULE_DEVICE_TABLE(of, exynos_dp_match); 1202MODULE_DEVICE_TABLE(of, exynos_dp_match);
1139 1203
1140static struct platform_driver exynos_dp_driver = { 1204struct platform_driver dp_driver = {
1141 .probe = exynos_dp_probe, 1205 .probe = exynos_dp_probe,
1142 .remove = exynos_dp_remove, 1206 .remove = exynos_dp_remove,
1143 .driver = { 1207 .driver = {
@@ -1148,8 +1212,6 @@ static struct platform_driver exynos_dp_driver = {
1148 }, 1212 },
1149}; 1213};
1150 1214
1151module_platform_driver(exynos_dp_driver);
1152
1153MODULE_AUTHOR("Jingoo Han <jg1.han@samsung.com>"); 1215MODULE_AUTHOR("Jingoo Han <jg1.han@samsung.com>");
1154MODULE_DESCRIPTION("Samsung SoC DP Driver"); 1216MODULE_DESCRIPTION("Samsung SoC DP Driver");
1155MODULE_LICENSE("GPL"); 1217MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.h b/drivers/gpu/drm/exynos/exynos_dp_core.h
index 607e36d0c147..4f1414162bbe 100644
--- a/drivers/gpu/drm/exynos/exynos_dp_core.h
+++ b/drivers/gpu/drm/exynos/exynos_dp_core.h
@@ -13,6 +13,8 @@
13#ifndef _EXYNOS_DP_CORE_H 13#ifndef _EXYNOS_DP_CORE_H
14#define _EXYNOS_DP_CORE_H 14#define _EXYNOS_DP_CORE_H
15 15
16#include <drm/exynos_drm.h>
17
16#define DP_TIMEOUT_LOOP_COUNT 100 18#define DP_TIMEOUT_LOOP_COUNT 100
17#define MAX_CR_LOOP 5 19#define MAX_CR_LOOP 5
18#define MAX_EQ_LOOP 5 20#define MAX_EQ_LOOP 5
@@ -152,6 +154,8 @@ struct exynos_dp_device {
152 struct link_train link_train; 154 struct link_train link_train;
153 struct work_struct hotplug_work; 155 struct work_struct hotplug_work;
154 struct phy *phy; 156 struct phy *phy;
157
158 struct exynos_drm_panel_info panel;
155}; 159};
156 160
157/* exynos_dp_reg.c */ 161/* exynos_dp_reg.c */
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c
index d55012594cd9..8619a537e6ff 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c
@@ -357,6 +357,12 @@ static int __init exynos_drm_init(void)
357{ 357{
358 int ret; 358 int ret;
359 359
360#ifdef CONFIG_DRM_EXYNOS_DP
361 ret = platform_driver_register(&dp_driver);
362 if (ret < 0)
363 goto out_dp;
364#endif
365
360#ifdef CONFIG_DRM_EXYNOS_FIMD 366#ifdef CONFIG_DRM_EXYNOS_FIMD
361 ret = platform_driver_register(&fimd_driver); 367 ret = platform_driver_register(&fimd_driver);
362 if (ret < 0) 368 if (ret < 0)
@@ -472,6 +478,10 @@ out_hdmi:
472 platform_driver_unregister(&fimd_driver); 478 platform_driver_unregister(&fimd_driver);
473out_fimd: 479out_fimd:
474#endif 480#endif
481#ifdef CONFIG_DRM_EXYNOS_DP
482 platform_driver_unregister(&dp_driver);
483out_dp:
484#endif
475 return ret; 485 return ret;
476} 486}
477 487
@@ -514,6 +524,10 @@ static void __exit exynos_drm_exit(void)
514#ifdef CONFIG_DRM_EXYNOS_FIMD 524#ifdef CONFIG_DRM_EXYNOS_FIMD
515 platform_driver_unregister(&fimd_driver); 525 platform_driver_unregister(&fimd_driver);
516#endif 526#endif
527
528#ifdef CONFIG_DRM_EXYNOS_DP
529 platform_driver_unregister(&dp_driver);
530#endif
517} 531}
518 532
519module_init(exynos_drm_init); 533module_init(exynos_drm_init);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h
index 81f7de4e2a51..09c158ab53c0 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h
@@ -370,6 +370,7 @@ int exynos_platform_device_ipp_register(void);
370 */ 370 */
371void exynos_platform_device_ipp_unregister(void); 371void exynos_platform_device_ipp_unregister(void);
372 372
373extern struct platform_driver dp_driver;
373extern struct platform_driver fimd_driver; 374extern struct platform_driver fimd_driver;
374extern struct platform_driver hdmi_driver; 375extern struct platform_driver hdmi_driver;
375extern struct platform_driver mixer_driver; 376extern struct platform_driver mixer_driver;
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
index 94195130ef9e..6eb0008e0b62 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
@@ -144,39 +144,6 @@ static inline struct fimd_driver_data *drm_fimd_get_driver_data(
144 return (struct fimd_driver_data *)of_id->data; 144 return (struct fimd_driver_data *)of_id->data;
145} 145}
146 146
147static bool fimd_display_is_connected(struct exynos_drm_display *display)
148{
149 /* TODO. */
150
151 return true;
152}
153
154static void *fimd_get_panel(struct exynos_drm_display *display)
155{
156 struct fimd_context *ctx = display->ctx;
157
158 return &ctx->panel;
159}
160
161static int fimd_check_mode(struct exynos_drm_display *display,
162 struct drm_display_mode *mode)
163{
164 /* TODO. */
165
166 return 0;
167}
168
169static struct exynos_drm_display_ops fimd_display_ops = {
170 .is_connected = fimd_display_is_connected,
171 .get_panel = fimd_get_panel,
172 .check_mode = fimd_check_mode,
173};
174
175static struct exynos_drm_display fimd_display = {
176 .type = EXYNOS_DISPLAY_TYPE_LCD,
177 .ops = &fimd_display_ops,
178};
179
180static int fimd_mgr_initialize(struct exynos_drm_manager *mgr, 147static int fimd_mgr_initialize(struct exynos_drm_manager *mgr,
181 struct drm_device *drm_dev, int pipe) 148 struct drm_device *drm_dev, int pipe)
182{ 149{
@@ -253,7 +220,7 @@ static void fimd_commit(struct exynos_drm_manager *mgr)
253 struct fimd_context *ctx = mgr->ctx; 220 struct fimd_context *ctx = mgr->ctx;
254 struct drm_display_mode *mode = &ctx->mode; 221 struct drm_display_mode *mode = &ctx->mode;
255 struct fimd_driver_data *driver_data; 222 struct fimd_driver_data *driver_data;
256 u32 val, clkdiv; 223 u32 val, clkdiv, vidcon1;
257 int hblank, vblank, vsync_len, vbpd, vfpd, hsync_len, hbpd, hfpd; 224 int hblank, vblank, vsync_len, vbpd, vfpd, hsync_len, hbpd, hfpd;
258 225
259 driver_data = ctx->driver_data; 226 driver_data = ctx->driver_data;
@@ -264,8 +231,13 @@ static void fimd_commit(struct exynos_drm_manager *mgr)
264 if (mode->htotal == 0 || mode->vtotal == 0) 231 if (mode->htotal == 0 || mode->vtotal == 0)
265 return; 232 return;
266 233
267 /* setup polarity values from machine code. */ 234 /* setup polarity values */
268 writel(ctx->vidcon1, ctx->regs + driver_data->timing_base + VIDCON1); 235 vidcon1 = ctx->vidcon1;
236 if (mode->flags & DRM_MODE_FLAG_NVSYNC)
237 vidcon1 |= VIDCON1_INV_VSYNC;
238 if (mode->flags & DRM_MODE_FLAG_NHSYNC)
239 vidcon1 |= VIDCON1_INV_HSYNC;
240 writel(vidcon1, ctx->regs + driver_data->timing_base + VIDCON1);
269 241
270 /* setup vertical timing values. */ 242 /* setup vertical timing values. */
271 vblank = mode->crtc_vblank_end - mode->crtc_vblank_start; 243 vblank = mode->crtc_vblank_end - mode->crtc_vblank_start;
@@ -871,30 +843,6 @@ static int fimd_activate(struct exynos_drm_manager *mgr, bool enable)
871 return 0; 843 return 0;
872} 844}
873 845
874static int fimd_get_platform_data(struct fimd_context *ctx, struct device *dev)
875{
876 struct videomode *vm;
877 int ret;
878
879 vm = &ctx->panel.vm;
880 ret = of_get_videomode(dev->of_node, vm, OF_USE_NATIVE_MODE);
881 if (ret) {
882 DRM_ERROR("failed: of_get_videomode() : %d\n", ret);
883 return ret;
884 }
885
886 if (vm->flags & DISPLAY_FLAGS_VSYNC_LOW)
887 ctx->vidcon1 |= VIDCON1_INV_VSYNC;
888 if (vm->flags & DISPLAY_FLAGS_HSYNC_LOW)
889 ctx->vidcon1 |= VIDCON1_INV_HSYNC;
890 if (vm->flags & DISPLAY_FLAGS_DE_LOW)
891 ctx->vidcon1 |= VIDCON1_INV_VDEN;
892 if (vm->flags & DISPLAY_FLAGS_PIXDATA_NEGEDGE)
893 ctx->vidcon1 |= VIDCON1_INV_VCLK;
894
895 return 0;
896}
897
898static int fimd_probe(struct platform_device *pdev) 846static int fimd_probe(struct platform_device *pdev)
899{ 847{
900 struct device *dev = &pdev->dev; 848 struct device *dev = &pdev->dev;
@@ -912,9 +860,10 @@ static int fimd_probe(struct platform_device *pdev)
912 860
913 ctx->dev = dev; 861 ctx->dev = dev;
914 862
915 ret = fimd_get_platform_data(ctx, dev); 863 if (of_property_read_bool(dev->of_node, "samsung,invert-vden"))
916 if (ret) 864 ctx->vidcon1 |= VIDCON1_INV_VDEN;
917 return ret; 865 if (of_property_read_bool(dev->of_node, "samsung,invert-vclk"))
866 ctx->vidcon1 |= VIDCON1_INV_VCLK;
918 867
919 ctx->bus_clk = devm_clk_get(dev, "fimd"); 868 ctx->bus_clk = devm_clk_get(dev, "fimd");
920 if (IS_ERR(ctx->bus_clk)) { 869 if (IS_ERR(ctx->bus_clk)) {
@@ -956,9 +905,6 @@ static int fimd_probe(struct platform_device *pdev)
956 fimd_manager.ctx = ctx; 905 fimd_manager.ctx = ctx;
957 exynos_drm_manager_register(&fimd_manager); 906 exynos_drm_manager_register(&fimd_manager);
958 907
959 fimd_display.ctx = ctx;
960 exynos_drm_display_register(&fimd_display);
961
962 pm_runtime_enable(dev); 908 pm_runtime_enable(dev);
963 pm_runtime_get_sync(dev); 909 pm_runtime_get_sync(dev);
964 910
@@ -974,7 +920,6 @@ static int fimd_remove(struct platform_device *pdev)
974 struct exynos_drm_manager *mgr = platform_get_drvdata(pdev); 920 struct exynos_drm_manager *mgr = platform_get_drvdata(pdev);
975 struct fimd_context *ctx = mgr->ctx; 921 struct fimd_context *ctx = mgr->ctx;
976 922
977 exynos_drm_display_unregister(&fimd_display);
978 exynos_drm_manager_unregister(&fimd_manager); 923 exynos_drm_manager_unregister(&fimd_manager);
979 924
980 if (ctx->suspended) 925 if (ctx->suspended)