drm/exynos: separate dpi from fimd
The patch separates dpi related routines from fimd. Changelog v2: - Rename ctx->dpi to ctx->display Signed-off-by: Andrzej Hajda <a.hajda@samsung.com> Signed-off-by: Inki Dae <inki.dae@samsung.com>
This commit is contained in:
parent
d1afe7d453
commit
000cc9204e
|
@ -40,20 +40,10 @@ exynos_dpi_detect(struct drm_connector *connector, bool force)
|
||||||
{
|
{
|
||||||
struct exynos_dpi *ctx = connector_to_dpi(connector);
|
struct exynos_dpi *ctx = connector_to_dpi(connector);
|
||||||
|
|
||||||
/* panels supported only by boot-loader are always connected */
|
if (!ctx->panel->connector)
|
||||||
if (!ctx->panel_node)
|
drm_panel_attach(ctx->panel, &ctx->connector);
|
||||||
return connector_status_connected;
|
|
||||||
|
|
||||||
if (!ctx->panel) {
|
return connector_status_connected;
|
||||||
ctx->panel = of_drm_find_panel(ctx->panel_node);
|
|
||||||
if (ctx->panel)
|
|
||||||
drm_panel_attach(ctx->panel, &ctx->connector);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ctx->panel)
|
|
||||||
return connector_status_connected;
|
|
||||||
|
|
||||||
return connector_status_disconnected;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void exynos_dpi_connector_destroy(struct drm_connector *connector)
|
static void exynos_dpi_connector_destroy(struct drm_connector *connector)
|
||||||
|
@ -284,8 +274,10 @@ static int exynos_dpi_parse_dt(struct exynos_dpi *ctx)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
ret = of_get_videomode(dn, vm, 0);
|
ret = of_get_videomode(dn, vm, 0);
|
||||||
if (ret < 0)
|
if (ret < 0) {
|
||||||
|
devm_kfree(dev, vm);
|
||||||
return ret;
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
ctx->vm = vm;
|
ctx->vm = vm;
|
||||||
|
|
||||||
|
@ -298,27 +290,35 @@ static int exynos_dpi_parse_dt(struct exynos_dpi *ctx)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int exynos_dpi_probe(struct drm_device *drm_dev, struct device *dev)
|
struct exynos_drm_display *exynos_dpi_probe(struct device *dev)
|
||||||
{
|
{
|
||||||
struct exynos_dpi *ctx;
|
struct exynos_dpi *ctx;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
|
ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
|
||||||
if (!ctx)
|
if (!ctx)
|
||||||
return -ENOMEM;
|
return NULL;
|
||||||
|
|
||||||
ctx->dev = dev;
|
ctx->dev = dev;
|
||||||
exynos_dpi_display.ctx = ctx;
|
exynos_dpi_display.ctx = ctx;
|
||||||
ctx->dpms_mode = DRM_MODE_DPMS_OFF;
|
ctx->dpms_mode = DRM_MODE_DPMS_OFF;
|
||||||
|
|
||||||
ret = exynos_dpi_parse_dt(ctx);
|
ret = exynos_dpi_parse_dt(ctx);
|
||||||
if (ret < 0)
|
if (ret < 0) {
|
||||||
return ret;
|
devm_kfree(dev, ctx);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
return exynos_drm_create_enc_conn(drm_dev, &exynos_dpi_display);
|
if (ctx->panel_node) {
|
||||||
|
ctx->panel = of_drm_find_panel(ctx->panel_node);
|
||||||
|
if (!ctx->panel)
|
||||||
|
return ERR_PTR(-EPROBE_DEFER);
|
||||||
|
}
|
||||||
|
|
||||||
|
return &exynos_dpi_display;
|
||||||
}
|
}
|
||||||
|
|
||||||
int exynos_dpi_remove(struct drm_device *drm_dev, struct device *dev)
|
int exynos_dpi_remove(struct device *dev)
|
||||||
{
|
{
|
||||||
struct drm_encoder *encoder = exynos_dpi_display.encoder;
|
struct drm_encoder *encoder = exynos_dpi_display.encoder;
|
||||||
struct exynos_dpi *ctx = exynos_dpi_display.ctx;
|
struct exynos_dpi *ctx = exynos_dpi_display.ctx;
|
||||||
|
|
|
@ -332,17 +332,12 @@ int exynos_platform_device_ipp_register(void);
|
||||||
void exynos_platform_device_ipp_unregister(void);
|
void exynos_platform_device_ipp_unregister(void);
|
||||||
|
|
||||||
#ifdef CONFIG_DRM_EXYNOS_DPI
|
#ifdef CONFIG_DRM_EXYNOS_DPI
|
||||||
int exynos_dpi_probe(struct drm_device *drm_dev, struct device *dev);
|
struct exynos_drm_display * exynos_dpi_probe(struct device *dev);
|
||||||
int exynos_dpi_remove(struct drm_device *drm_dev, struct device *dev);
|
int exynos_dpi_remove(struct device *dev);
|
||||||
struct device_node *exynos_dpi_of_find_panel_node(struct device *dev);
|
|
||||||
#else
|
#else
|
||||||
static inline int exynos_dpi_probe(struct drm_device *drm_dev,
|
static inline struct exynos_drm_display *
|
||||||
struct device *dev) { return 0; }
|
exynos_dpi_probe(struct device *dev) { return 0; }
|
||||||
static inline int exynos_dpi_remove(struct drm_device *drm_dev,
|
static inline int exynos_dpi_remove(struct device *dev) { return 0; }
|
||||||
struct device *dev) { return 0; }
|
|
||||||
static inline struct device_node
|
|
||||||
*exynos_dpi_of_find_panel_node(struct device *dev)
|
|
||||||
{ return NULL; }
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -24,7 +24,6 @@
|
||||||
#include <video/of_display_timing.h>
|
#include <video/of_display_timing.h>
|
||||||
#include <video/of_videomode.h>
|
#include <video/of_videomode.h>
|
||||||
#include <video/samsung_fimd.h>
|
#include <video/samsung_fimd.h>
|
||||||
#include <drm/drm_panel.h>
|
|
||||||
#include <drm/exynos_drm.h>
|
#include <drm/exynos_drm.h>
|
||||||
|
|
||||||
#include "exynos_drm_drv.h"
|
#include "exynos_drm_drv.h"
|
||||||
|
@ -124,6 +123,7 @@ struct fimd_context {
|
||||||
|
|
||||||
struct exynos_drm_panel_info panel;
|
struct exynos_drm_panel_info panel;
|
||||||
struct fimd_driver_data *driver_data;
|
struct fimd_driver_data *driver_data;
|
||||||
|
struct exynos_drm_display *display;
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct of_device_id fimd_driver_dt_match[] = {
|
static const struct of_device_id fimd_driver_dt_match[] = {
|
||||||
|
@ -882,12 +882,49 @@ out:
|
||||||
|
|
||||||
static int fimd_bind(struct device *dev, struct device *master, void *data)
|
static int fimd_bind(struct device *dev, struct device *master, void *data)
|
||||||
{
|
{
|
||||||
struct platform_device *pdev = to_platform_device(dev);
|
struct fimd_context *ctx = fimd_manager.ctx;
|
||||||
struct drm_device *drm_dev = data;
|
struct drm_device *drm_dev = data;
|
||||||
struct fimd_context *ctx;
|
|
||||||
struct device_node *dn;
|
|
||||||
struct resource *res;
|
|
||||||
int win;
|
int win;
|
||||||
|
|
||||||
|
fimd_mgr_initialize(&fimd_manager, drm_dev);
|
||||||
|
exynos_drm_crtc_create(&fimd_manager);
|
||||||
|
if (ctx->display)
|
||||||
|
exynos_drm_create_enc_conn(drm_dev, ctx->display);
|
||||||
|
|
||||||
|
for (win = 0; win < WINDOWS_NR; win++)
|
||||||
|
fimd_clear_win(ctx, win);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void fimd_unbind(struct device *dev, struct device *master,
|
||||||
|
void *data)
|
||||||
|
{
|
||||||
|
struct exynos_drm_manager *mgr = dev_get_drvdata(dev);
|
||||||
|
struct fimd_context *ctx = fimd_manager.ctx;
|
||||||
|
struct drm_crtc *crtc = mgr->crtc;
|
||||||
|
|
||||||
|
fimd_dpms(mgr, DRM_MODE_DPMS_OFF);
|
||||||
|
|
||||||
|
if (ctx->display)
|
||||||
|
exynos_dpi_remove(dev);
|
||||||
|
|
||||||
|
fimd_mgr_remove(mgr);
|
||||||
|
|
||||||
|
crtc->funcs->destroy(crtc);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct component_ops fimd_component_ops = {
|
||||||
|
.bind = fimd_bind,
|
||||||
|
.unbind = fimd_unbind,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int fimd_probe(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
struct device *dev = &pdev->dev;
|
||||||
|
struct fimd_context *ctx;
|
||||||
|
struct resource *res;
|
||||||
int ret = -EINVAL;
|
int ret = -EINVAL;
|
||||||
|
|
||||||
if (!dev->of_node)
|
if (!dev->of_node)
|
||||||
|
@ -943,68 +980,10 @@ static int fimd_bind(struct device *dev, struct device *master, void *data)
|
||||||
platform_set_drvdata(pdev, &fimd_manager);
|
platform_set_drvdata(pdev, &fimd_manager);
|
||||||
|
|
||||||
fimd_manager.ctx = ctx;
|
fimd_manager.ctx = ctx;
|
||||||
fimd_mgr_initialize(&fimd_manager, drm_dev);
|
|
||||||
|
|
||||||
exynos_drm_crtc_create(&fimd_manager);
|
ctx->display = exynos_dpi_probe(dev);
|
||||||
|
if (IS_ERR(ctx->display))
|
||||||
dn = exynos_dpi_of_find_panel_node(&pdev->dev);
|
return PTR_ERR(ctx->display);
|
||||||
if (dn) {
|
|
||||||
/*
|
|
||||||
* It should be called after exynos_drm_crtc_create call
|
|
||||||
* because exynos_dpi_probe call will try to find same lcd
|
|
||||||
* type of manager to setup possible_crtcs.
|
|
||||||
*/
|
|
||||||
exynos_dpi_probe(drm_dev, dev);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (win = 0; win < WINDOWS_NR; win++)
|
|
||||||
fimd_clear_win(ctx, win);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void fimd_unbind(struct device *dev, struct device *master,
|
|
||||||
void *data)
|
|
||||||
{
|
|
||||||
struct exynos_drm_manager *mgr = dev_get_drvdata(dev);
|
|
||||||
struct drm_crtc *crtc = mgr->crtc;
|
|
||||||
struct device_node *dn;
|
|
||||||
|
|
||||||
fimd_dpms(mgr, DRM_MODE_DPMS_OFF);
|
|
||||||
|
|
||||||
dn = exynos_dpi_of_find_panel_node(dev);
|
|
||||||
if (dn)
|
|
||||||
exynos_dpi_remove(mgr->drm_dev, dev);
|
|
||||||
|
|
||||||
fimd_mgr_remove(mgr);
|
|
||||||
|
|
||||||
crtc->funcs->destroy(crtc);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct component_ops fimd_component_ops = {
|
|
||||||
.bind = fimd_bind,
|
|
||||||
.unbind = fimd_unbind,
|
|
||||||
};
|
|
||||||
|
|
||||||
static int fimd_probe(struct platform_device *pdev)
|
|
||||||
{
|
|
||||||
struct device_node *dn;
|
|
||||||
|
|
||||||
/* Check if fimd node has port node. */
|
|
||||||
dn = exynos_dpi_of_find_panel_node(&pdev->dev);
|
|
||||||
if (dn) {
|
|
||||||
struct drm_panel *panel;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Do not bind if there is the port node but a drm_panel
|
|
||||||
* isn't added to panel_list yet.
|
|
||||||
* In this case, fimd_probe will be called by defered probe
|
|
||||||
* again after the drm_panel is added to panel_list.
|
|
||||||
*/
|
|
||||||
panel = of_drm_find_panel(dn);
|
|
||||||
if (!panel)
|
|
||||||
return -EPROBE_DEFER;
|
|
||||||
}
|
|
||||||
|
|
||||||
pm_runtime_enable(&pdev->dev);
|
pm_runtime_enable(&pdev->dev);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue