|
@@ -40,8 +40,6 @@
|
|
|
#include "exynos_drm_iommu.h"
|
|
|
#include "exynos_mixer.h"
|
|
|
|
|
|
-#define get_mixer_manager(dev) platform_get_drvdata(to_platform_device(dev))
|
|
|
-
|
|
|
#define MIXER_WIN_NR 3
|
|
|
#define MIXER_DEFAULT_WIN 0
|
|
|
|
|
@@ -86,6 +84,7 @@ enum mixer_version_id {
|
|
|
};
|
|
|
|
|
|
struct mixer_context {
|
|
|
+ struct exynos_drm_manager manager;
|
|
|
struct platform_device *pdev;
|
|
|
struct device *dev;
|
|
|
struct drm_device *drm_dev;
|
|
@@ -1187,11 +1186,6 @@ static struct exynos_drm_manager_ops mixer_manager_ops = {
|
|
|
.win_disable = mixer_win_disable,
|
|
|
};
|
|
|
|
|
|
-static struct exynos_drm_manager mixer_manager = {
|
|
|
- .type = EXYNOS_DISPLAY_TYPE_HDMI,
|
|
|
- .ops = &mixer_manager_ops,
|
|
|
-};
|
|
|
-
|
|
|
static struct mixer_drv_data exynos5420_mxr_drv_data = {
|
|
|
.version = MXR_VER_128_0_0_184,
|
|
|
.is_vp_enabled = 0,
|
|
@@ -1249,48 +1243,17 @@ MODULE_DEVICE_TABLE(of, mixer_match_types);
|
|
|
|
|
|
static int mixer_bind(struct device *dev, struct device *manager, void *data)
|
|
|
{
|
|
|
- struct platform_device *pdev = to_platform_device(dev);
|
|
|
+ struct mixer_context *ctx = dev_get_drvdata(dev);
|
|
|
struct drm_device *drm_dev = data;
|
|
|
- struct mixer_context *ctx;
|
|
|
- struct mixer_drv_data *drv;
|
|
|
int ret;
|
|
|
|
|
|
- dev_info(dev, "probe start\n");
|
|
|
-
|
|
|
- ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
|
|
|
- if (!ctx) {
|
|
|
- DRM_ERROR("failed to alloc mixer context.\n");
|
|
|
- return -ENOMEM;
|
|
|
- }
|
|
|
-
|
|
|
- mutex_init(&ctx->mixer_mutex);
|
|
|
-
|
|
|
- if (dev->of_node) {
|
|
|
- const struct of_device_id *match;
|
|
|
- match = of_match_node(mixer_match_types, dev->of_node);
|
|
|
- drv = (struct mixer_drv_data *)match->data;
|
|
|
- } else {
|
|
|
- drv = (struct mixer_drv_data *)
|
|
|
- platform_get_device_id(pdev)->driver_data;
|
|
|
- }
|
|
|
-
|
|
|
- ctx->pdev = pdev;
|
|
|
- ctx->dev = dev;
|
|
|
- ctx->vp_enabled = drv->is_vp_enabled;
|
|
|
- ctx->has_sclk = drv->has_sclk;
|
|
|
- ctx->mxr_ver = drv->version;
|
|
|
- init_waitqueue_head(&ctx->wait_vsync_queue);
|
|
|
- atomic_set(&ctx->wait_vsync_event, 0);
|
|
|
-
|
|
|
- mixer_manager.ctx = ctx;
|
|
|
- ret = mixer_initialize(&mixer_manager, drm_dev);
|
|
|
+ ret = mixer_initialize(&ctx->manager, drm_dev);
|
|
|
if (ret)
|
|
|
return ret;
|
|
|
|
|
|
- platform_set_drvdata(pdev, &mixer_manager);
|
|
|
- ret = exynos_drm_crtc_create(&mixer_manager);
|
|
|
+ ret = exynos_drm_crtc_create(&ctx->manager);
|
|
|
if (ret) {
|
|
|
- mixer_mgr_remove(&mixer_manager);
|
|
|
+ mixer_mgr_remove(&ctx->manager);
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
@@ -1301,11 +1264,9 @@ static int mixer_bind(struct device *dev, struct device *manager, void *data)
|
|
|
|
|
|
static void mixer_unbind(struct device *dev, struct device *master, void *data)
|
|
|
{
|
|
|
- struct exynos_drm_manager *mgr = dev_get_drvdata(dev);
|
|
|
+ struct mixer_context *ctx = dev_get_drvdata(dev);
|
|
|
|
|
|
- dev_info(dev, "remove successful\n");
|
|
|
-
|
|
|
- mixer_mgr_remove(mgr);
|
|
|
+ mixer_mgr_remove(&ctx->manager);
|
|
|
|
|
|
pm_runtime_disable(dev);
|
|
|
}
|
|
@@ -1317,22 +1278,63 @@ static const struct component_ops mixer_component_ops = {
|
|
|
|
|
|
static int mixer_probe(struct platform_device *pdev)
|
|
|
{
|
|
|
+ struct device *dev = &pdev->dev;
|
|
|
+ struct mixer_drv_data *drv;
|
|
|
+ struct mixer_context *ctx;
|
|
|
int ret;
|
|
|
|
|
|
+ ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
|
|
|
+ if (!ctx) {
|
|
|
+ DRM_ERROR("failed to alloc mixer context.\n");
|
|
|
+ return -ENOMEM;
|
|
|
+ }
|
|
|
+
|
|
|
+ mutex_init(&ctx->mixer_mutex);
|
|
|
+
|
|
|
+ ctx->manager.type = EXYNOS_DISPLAY_TYPE_HDMI;
|
|
|
+ ctx->manager.ops = &mixer_manager_ops;
|
|
|
+
|
|
|
+ if (dev->of_node) {
|
|
|
+ const struct of_device_id *match;
|
|
|
+
|
|
|
+ match = of_match_node(mixer_match_types, dev->of_node);
|
|
|
+ drv = (struct mixer_drv_data *)match->data;
|
|
|
+ } else {
|
|
|
+ drv = (struct mixer_drv_data *)
|
|
|
+ platform_get_device_id(pdev)->driver_data;
|
|
|
+ }
|
|
|
+
|
|
|
+ ctx->pdev = pdev;
|
|
|
+ ctx->dev = dev;
|
|
|
+ ctx->vp_enabled = drv->is_vp_enabled;
|
|
|
+ ctx->has_sclk = drv->has_sclk;
|
|
|
+ ctx->mxr_ver = drv->version;
|
|
|
+ init_waitqueue_head(&ctx->wait_vsync_queue);
|
|
|
+ atomic_set(&ctx->wait_vsync_event, 0);
|
|
|
+ ctx->manager.ctx = ctx;
|
|
|
+
|
|
|
+ platform_set_drvdata(pdev, ctx);
|
|
|
+
|
|
|
ret = exynos_drm_component_add(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC,
|
|
|
- mixer_manager.type);
|
|
|
+ ctx->manager.type);
|
|
|
if (ret)
|
|
|
return ret;
|
|
|
|
|
|
ret = component_add(&pdev->dev, &mixer_component_ops);
|
|
|
- if (ret)
|
|
|
+ if (ret) {
|
|
|
exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC);
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+
|
|
|
+ pm_runtime_enable(dev);
|
|
|
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
static int mixer_remove(struct platform_device *pdev)
|
|
|
{
|
|
|
+ pm_runtime_disable(&pdev->dev);
|
|
|
+
|
|
|
component_del(&pdev->dev, &mixer_component_ops);
|
|
|
exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC);
|
|
|
|