aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/exynos/exynos_mixer.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/exynos/exynos_mixer.c')
-rw-r--r--drivers/gpu/drm/exynos/exynos_mixer.c126
1 files changed, 66 insertions, 60 deletions
diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c
index a41c84ee3a2d..820b76234ef4 100644
--- a/drivers/gpu/drm/exynos/exynos_mixer.c
+++ b/drivers/gpu/drm/exynos/exynos_mixer.c
@@ -40,8 +40,6 @@
40#include "exynos_drm_iommu.h" 40#include "exynos_drm_iommu.h"
41#include "exynos_mixer.h" 41#include "exynos_mixer.h"
42 42
43#define get_mixer_manager(dev) platform_get_drvdata(to_platform_device(dev))
44
45#define MIXER_WIN_NR 3 43#define MIXER_WIN_NR 3
46#define MIXER_DEFAULT_WIN 0 44#define MIXER_DEFAULT_WIN 0
47 45
@@ -86,6 +84,7 @@ enum mixer_version_id {
86}; 84};
87 85
88struct mixer_context { 86struct mixer_context {
87 struct exynos_drm_manager manager;
89 struct platform_device *pdev; 88 struct platform_device *pdev;
90 struct device *dev; 89 struct device *dev;
91 struct drm_device *drm_dev; 90 struct drm_device *drm_dev;
@@ -104,6 +103,11 @@ struct mixer_context {
104 atomic_t wait_vsync_event; 103 atomic_t wait_vsync_event;
105}; 104};
106 105
106static inline struct mixer_context *mgr_to_mixer(struct exynos_drm_manager *mgr)
107{
108 return container_of(mgr, struct mixer_context, manager);
109}
110
107struct mixer_drv_data { 111struct mixer_drv_data {
108 enum mixer_version_id version; 112 enum mixer_version_id version;
109 bool is_vp_enabled; 113 bool is_vp_enabled;
@@ -854,7 +858,7 @@ static int mixer_initialize(struct exynos_drm_manager *mgr,
854 struct drm_device *drm_dev) 858 struct drm_device *drm_dev)
855{ 859{
856 int ret; 860 int ret;
857 struct mixer_context *mixer_ctx = mgr->ctx; 861 struct mixer_context *mixer_ctx = mgr_to_mixer(mgr);
858 struct exynos_drm_private *priv; 862 struct exynos_drm_private *priv;
859 priv = drm_dev->dev_private; 863 priv = drm_dev->dev_private;
860 864
@@ -885,7 +889,7 @@ static int mixer_initialize(struct exynos_drm_manager *mgr,
885 889
886static void mixer_mgr_remove(struct exynos_drm_manager *mgr) 890static void mixer_mgr_remove(struct exynos_drm_manager *mgr)
887{ 891{
888 struct mixer_context *mixer_ctx = mgr->ctx; 892 struct mixer_context *mixer_ctx = mgr_to_mixer(mgr);
889 893
890 if (is_drm_iommu_supported(mixer_ctx->drm_dev)) 894 if (is_drm_iommu_supported(mixer_ctx->drm_dev))
891 drm_iommu_detach_device(mixer_ctx->drm_dev, mixer_ctx->dev); 895 drm_iommu_detach_device(mixer_ctx->drm_dev, mixer_ctx->dev);
@@ -893,7 +897,7 @@ static void mixer_mgr_remove(struct exynos_drm_manager *mgr)
893 897
894static int mixer_enable_vblank(struct exynos_drm_manager *mgr) 898static int mixer_enable_vblank(struct exynos_drm_manager *mgr)
895{ 899{
896 struct mixer_context *mixer_ctx = mgr->ctx; 900 struct mixer_context *mixer_ctx = mgr_to_mixer(mgr);
897 struct mixer_resources *res = &mixer_ctx->mixer_res; 901 struct mixer_resources *res = &mixer_ctx->mixer_res;
898 902
899 if (!mixer_ctx->powered) { 903 if (!mixer_ctx->powered) {
@@ -910,7 +914,7 @@ static int mixer_enable_vblank(struct exynos_drm_manager *mgr)
910 914
911static void mixer_disable_vblank(struct exynos_drm_manager *mgr) 915static void mixer_disable_vblank(struct exynos_drm_manager *mgr)
912{ 916{
913 struct mixer_context *mixer_ctx = mgr->ctx; 917 struct mixer_context *mixer_ctx = mgr_to_mixer(mgr);
914 struct mixer_resources *res = &mixer_ctx->mixer_res; 918 struct mixer_resources *res = &mixer_ctx->mixer_res;
915 919
916 /* disable vsync interrupt */ 920 /* disable vsync interrupt */
@@ -920,7 +924,7 @@ static void mixer_disable_vblank(struct exynos_drm_manager *mgr)
920static void mixer_win_mode_set(struct exynos_drm_manager *mgr, 924static void mixer_win_mode_set(struct exynos_drm_manager *mgr,
921 struct exynos_drm_overlay *overlay) 925 struct exynos_drm_overlay *overlay)
922{ 926{
923 struct mixer_context *mixer_ctx = mgr->ctx; 927 struct mixer_context *mixer_ctx = mgr_to_mixer(mgr);
924 struct hdmi_win_data *win_data; 928 struct hdmi_win_data *win_data;
925 int win; 929 int win;
926 930
@@ -971,7 +975,7 @@ static void mixer_win_mode_set(struct exynos_drm_manager *mgr,
971 975
972static void mixer_win_commit(struct exynos_drm_manager *mgr, int zpos) 976static void mixer_win_commit(struct exynos_drm_manager *mgr, int zpos)
973{ 977{
974 struct mixer_context *mixer_ctx = mgr->ctx; 978 struct mixer_context *mixer_ctx = mgr_to_mixer(mgr);
975 int win = zpos == DEFAULT_ZPOS ? MIXER_DEFAULT_WIN : zpos; 979 int win = zpos == DEFAULT_ZPOS ? MIXER_DEFAULT_WIN : zpos;
976 980
977 DRM_DEBUG_KMS("win: %d\n", win); 981 DRM_DEBUG_KMS("win: %d\n", win);
@@ -993,7 +997,7 @@ static void mixer_win_commit(struct exynos_drm_manager *mgr, int zpos)
993 997
994static void mixer_win_disable(struct exynos_drm_manager *mgr, int zpos) 998static void mixer_win_disable(struct exynos_drm_manager *mgr, int zpos)
995{ 999{
996 struct mixer_context *mixer_ctx = mgr->ctx; 1000 struct mixer_context *mixer_ctx = mgr_to_mixer(mgr);
997 struct mixer_resources *res = &mixer_ctx->mixer_res; 1001 struct mixer_resources *res = &mixer_ctx->mixer_res;
998 int win = zpos == DEFAULT_ZPOS ? MIXER_DEFAULT_WIN : zpos; 1002 int win = zpos == DEFAULT_ZPOS ? MIXER_DEFAULT_WIN : zpos;
999 unsigned long flags; 1003 unsigned long flags;
@@ -1021,7 +1025,7 @@ static void mixer_win_disable(struct exynos_drm_manager *mgr, int zpos)
1021 1025
1022static void mixer_wait_for_vblank(struct exynos_drm_manager *mgr) 1026static void mixer_wait_for_vblank(struct exynos_drm_manager *mgr)
1023{ 1027{
1024 struct mixer_context *mixer_ctx = mgr->ctx; 1028 struct mixer_context *mixer_ctx = mgr_to_mixer(mgr);
1025 1029
1026 mutex_lock(&mixer_ctx->mixer_mutex); 1030 mutex_lock(&mixer_ctx->mixer_mutex);
1027 if (!mixer_ctx->powered) { 1031 if (!mixer_ctx->powered) {
@@ -1048,7 +1052,7 @@ static void mixer_wait_for_vblank(struct exynos_drm_manager *mgr)
1048 1052
1049static void mixer_window_suspend(struct exynos_drm_manager *mgr) 1053static void mixer_window_suspend(struct exynos_drm_manager *mgr)
1050{ 1054{
1051 struct mixer_context *ctx = mgr->ctx; 1055 struct mixer_context *ctx = mgr_to_mixer(mgr);
1052 struct hdmi_win_data *win_data; 1056 struct hdmi_win_data *win_data;
1053 int i; 1057 int i;
1054 1058
@@ -1062,7 +1066,7 @@ static void mixer_window_suspend(struct exynos_drm_manager *mgr)
1062 1066
1063static void mixer_window_resume(struct exynos_drm_manager *mgr) 1067static void mixer_window_resume(struct exynos_drm_manager *mgr)
1064{ 1068{
1065 struct mixer_context *ctx = mgr->ctx; 1069 struct mixer_context *ctx = mgr_to_mixer(mgr);
1066 struct hdmi_win_data *win_data; 1070 struct hdmi_win_data *win_data;
1067 int i; 1071 int i;
1068 1072
@@ -1077,7 +1081,7 @@ static void mixer_window_resume(struct exynos_drm_manager *mgr)
1077 1081
1078static void mixer_poweron(struct exynos_drm_manager *mgr) 1082static void mixer_poweron(struct exynos_drm_manager *mgr)
1079{ 1083{
1080 struct mixer_context *ctx = mgr->ctx; 1084 struct mixer_context *ctx = mgr_to_mixer(mgr);
1081 struct mixer_resources *res = &ctx->mixer_res; 1085 struct mixer_resources *res = &ctx->mixer_res;
1082 1086
1083 mutex_lock(&ctx->mixer_mutex); 1087 mutex_lock(&ctx->mixer_mutex);
@@ -1111,7 +1115,7 @@ static void mixer_poweron(struct exynos_drm_manager *mgr)
1111 1115
1112static void mixer_poweroff(struct exynos_drm_manager *mgr) 1116static void mixer_poweroff(struct exynos_drm_manager *mgr)
1113{ 1117{
1114 struct mixer_context *ctx = mgr->ctx; 1118 struct mixer_context *ctx = mgr_to_mixer(mgr);
1115 struct mixer_resources *res = &ctx->mixer_res; 1119 struct mixer_resources *res = &ctx->mixer_res;
1116 1120
1117 mutex_lock(&ctx->mixer_mutex); 1121 mutex_lock(&ctx->mixer_mutex);
@@ -1187,11 +1191,6 @@ static struct exynos_drm_manager_ops mixer_manager_ops = {
1187 .win_disable = mixer_win_disable, 1191 .win_disable = mixer_win_disable,
1188}; 1192};
1189 1193
1190static struct exynos_drm_manager mixer_manager = {
1191 .type = EXYNOS_DISPLAY_TYPE_HDMI,
1192 .ops = &mixer_manager_ops,
1193};
1194
1195static struct mixer_drv_data exynos5420_mxr_drv_data = { 1194static struct mixer_drv_data exynos5420_mxr_drv_data = {
1196 .version = MXR_VER_128_0_0_184, 1195 .version = MXR_VER_128_0_0_184,
1197 .is_vp_enabled = 0, 1196 .is_vp_enabled = 0,
@@ -1249,48 +1248,17 @@ MODULE_DEVICE_TABLE(of, mixer_match_types);
1249 1248
1250static int mixer_bind(struct device *dev, struct device *manager, void *data) 1249static int mixer_bind(struct device *dev, struct device *manager, void *data)
1251{ 1250{
1252 struct platform_device *pdev = to_platform_device(dev); 1251 struct mixer_context *ctx = dev_get_drvdata(dev);
1253 struct drm_device *drm_dev = data; 1252 struct drm_device *drm_dev = data;
1254 struct mixer_context *ctx;
1255 struct mixer_drv_data *drv;
1256 int ret; 1253 int ret;
1257 1254
1258 dev_info(dev, "probe start\n"); 1255 ret = mixer_initialize(&ctx->manager, drm_dev);
1259
1260 ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
1261 if (!ctx) {
1262 DRM_ERROR("failed to alloc mixer context.\n");
1263 return -ENOMEM;
1264 }
1265
1266 mutex_init(&ctx->mixer_mutex);
1267
1268 if (dev->of_node) {
1269 const struct of_device_id *match;
1270 match = of_match_node(mixer_match_types, dev->of_node);
1271 drv = (struct mixer_drv_data *)match->data;
1272 } else {
1273 drv = (struct mixer_drv_data *)
1274 platform_get_device_id(pdev)->driver_data;
1275 }
1276
1277 ctx->pdev = pdev;
1278 ctx->dev = dev;
1279 ctx->vp_enabled = drv->is_vp_enabled;
1280 ctx->has_sclk = drv->has_sclk;
1281 ctx->mxr_ver = drv->version;
1282 init_waitqueue_head(&ctx->wait_vsync_queue);
1283 atomic_set(&ctx->wait_vsync_event, 0);
1284
1285 mixer_manager.ctx = ctx;
1286 ret = mixer_initialize(&mixer_manager, drm_dev);
1287 if (ret) 1256 if (ret)
1288 return ret; 1257 return ret;
1289 1258
1290 platform_set_drvdata(pdev, &mixer_manager); 1259 ret = exynos_drm_crtc_create(&ctx->manager);
1291 ret = exynos_drm_crtc_create(&mixer_manager);
1292 if (ret) { 1260 if (ret) {
1293 mixer_mgr_remove(&mixer_manager); 1261 mixer_mgr_remove(&ctx->manager);
1294 return ret; 1262 return ret;
1295 } 1263 }
1296 1264
@@ -1301,11 +1269,9 @@ static int mixer_bind(struct device *dev, struct device *manager, void *data)
1301 1269
1302static void mixer_unbind(struct device *dev, struct device *master, void *data) 1270static void mixer_unbind(struct device *dev, struct device *master, void *data)
1303{ 1271{
1304 struct exynos_drm_manager *mgr = dev_get_drvdata(dev); 1272 struct mixer_context *ctx = dev_get_drvdata(dev);
1305 1273
1306 dev_info(dev, "remove successful\n"); 1274 mixer_mgr_remove(&ctx->manager);
1307
1308 mixer_mgr_remove(mgr);
1309 1275
1310 pm_runtime_disable(dev); 1276 pm_runtime_disable(dev);
1311} 1277}
@@ -1317,22 +1283,62 @@ static const struct component_ops mixer_component_ops = {
1317 1283
1318static int mixer_probe(struct platform_device *pdev) 1284static int mixer_probe(struct platform_device *pdev)
1319{ 1285{
1286 struct device *dev = &pdev->dev;
1287 struct mixer_drv_data *drv;
1288 struct mixer_context *ctx;
1320 int ret; 1289 int ret;
1321 1290
1291 ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
1292 if (!ctx) {
1293 DRM_ERROR("failed to alloc mixer context.\n");
1294 return -ENOMEM;
1295 }
1296
1297 mutex_init(&ctx->mixer_mutex);
1298
1299 ctx->manager.type = EXYNOS_DISPLAY_TYPE_HDMI;
1300 ctx->manager.ops = &mixer_manager_ops;
1301
1302 if (dev->of_node) {
1303 const struct of_device_id *match;
1304
1305 match = of_match_node(mixer_match_types, dev->of_node);
1306 drv = (struct mixer_drv_data *)match->data;
1307 } else {
1308 drv = (struct mixer_drv_data *)
1309 platform_get_device_id(pdev)->driver_data;
1310 }
1311
1312 ctx->pdev = pdev;
1313 ctx->dev = dev;
1314 ctx->vp_enabled = drv->is_vp_enabled;
1315 ctx->has_sclk = drv->has_sclk;
1316 ctx->mxr_ver = drv->version;
1317 init_waitqueue_head(&ctx->wait_vsync_queue);
1318 atomic_set(&ctx->wait_vsync_event, 0);
1319
1320 platform_set_drvdata(pdev, ctx);
1321
1322 ret = exynos_drm_component_add(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC, 1322 ret = exynos_drm_component_add(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC,
1323 mixer_manager.type); 1323 ctx->manager.type);
1324 if (ret) 1324 if (ret)
1325 return ret; 1325 return ret;
1326 1326
1327 ret = component_add(&pdev->dev, &mixer_component_ops); 1327 ret = component_add(&pdev->dev, &mixer_component_ops);
1328 if (ret) 1328 if (ret) {
1329 exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC); 1329 exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC);
1330 return ret;
1331 }
1332
1333 pm_runtime_enable(dev);
1330 1334
1331 return ret; 1335 return ret;
1332} 1336}
1333 1337
1334static int mixer_remove(struct platform_device *pdev) 1338static int mixer_remove(struct platform_device *pdev)
1335{ 1339{
1340 pm_runtime_disable(&pdev->dev);
1341
1336 component_del(&pdev->dev, &mixer_component_ops); 1342 component_del(&pdev->dev, &mixer_component_ops);
1337 exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC); 1343 exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC);
1338 1344