mirror of https://gitee.com/openkylin/linux.git
drm/meson: Use optional canvas provider
This is the first step into converting the meson/drm driver to use the canvas module. If a canvas provider node is detected in DT, use it. Otherwise, fall back to what is currently being done. Signed-off-by: Maxime Jourdan <mjourdan@baylibre.com> Reviewed-by: Neil Armstrong <narmstrong@baylibre.com> [narmstrong: added back priv in meson_drv_unbind()] Signed-off-by: Neil Armstrong <narmstrong@baylibre.com> Link: https://patchwork.freedesktop.org/patch/msgid/20181105104508.23090-3-mjourdan@baylibre.com
This commit is contained in:
parent
2b80b98b72
commit
66cae477c3
|
@ -7,6 +7,7 @@ config DRM_MESON
|
||||||
select DRM_GEM_CMA_HELPER
|
select DRM_GEM_CMA_HELPER
|
||||||
select VIDEOMODE_HELPERS
|
select VIDEOMODE_HELPERS
|
||||||
select REGMAP_MMIO
|
select REGMAP_MMIO
|
||||||
|
select MESON_CANVAS
|
||||||
|
|
||||||
config DRM_MESON_DW_HDMI
|
config DRM_MESON_DW_HDMI
|
||||||
tristate "HDMI Synopsys Controller support for Amlogic Meson Display"
|
tristate "HDMI Synopsys Controller support for Amlogic Meson Display"
|
||||||
|
|
|
@ -193,10 +193,16 @@ void meson_crtc_irq(struct meson_drm *priv)
|
||||||
} else
|
} else
|
||||||
meson_vpp_disable_interlace_vscaler_osd1(priv);
|
meson_vpp_disable_interlace_vscaler_osd1(priv);
|
||||||
|
|
||||||
meson_canvas_setup(priv, MESON_CANVAS_ID_OSD1,
|
if (priv->canvas)
|
||||||
priv->viu.osd1_addr, priv->viu.osd1_stride,
|
meson_canvas_config(priv->canvas, priv->canvas_id_osd1,
|
||||||
priv->viu.osd1_height, MESON_CANVAS_WRAP_NONE,
|
priv->viu.osd1_addr, priv->viu.osd1_stride,
|
||||||
MESON_CANVAS_BLKMODE_LINEAR);
|
priv->viu.osd1_height, MESON_CANVAS_WRAP_NONE,
|
||||||
|
MESON_CANVAS_BLKMODE_LINEAR, 0);
|
||||||
|
else
|
||||||
|
meson_canvas_setup(priv, MESON_CANVAS_ID_OSD1,
|
||||||
|
priv->viu.osd1_addr, priv->viu.osd1_stride,
|
||||||
|
priv->viu.osd1_height, MESON_CANVAS_WRAP_NONE,
|
||||||
|
MESON_CANVAS_BLKMODE_LINEAR);
|
||||||
|
|
||||||
/* Enable OSD1 */
|
/* Enable OSD1 */
|
||||||
writel_bits_relaxed(VPP_OSD1_POSTBLEND, VPP_OSD1_POSTBLEND,
|
writel_bits_relaxed(VPP_OSD1_POSTBLEND, VPP_OSD1_POSTBLEND,
|
||||||
|
|
|
@ -208,24 +208,33 @@ static int meson_drv_bind_master(struct device *dev, bool has_components)
|
||||||
goto free_drm;
|
goto free_drm;
|
||||||
}
|
}
|
||||||
|
|
||||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dmc");
|
priv->canvas = meson_canvas_get(dev);
|
||||||
if (!res) {
|
if (!IS_ERR(priv->canvas)) {
|
||||||
ret = -EINVAL;
|
ret = meson_canvas_alloc(priv->canvas, &priv->canvas_id_osd1);
|
||||||
goto free_drm;
|
if (ret)
|
||||||
}
|
goto free_drm;
|
||||||
/* Simply ioremap since it may be a shared register zone */
|
} else {
|
||||||
regs = devm_ioremap(dev, res->start, resource_size(res));
|
priv->canvas = NULL;
|
||||||
if (!regs) {
|
|
||||||
ret = -EADDRNOTAVAIL;
|
|
||||||
goto free_drm;
|
|
||||||
}
|
|
||||||
|
|
||||||
priv->dmc = devm_regmap_init_mmio(dev, regs,
|
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dmc");
|
||||||
&meson_regmap_config);
|
if (!res) {
|
||||||
if (IS_ERR(priv->dmc)) {
|
ret = -EINVAL;
|
||||||
dev_err(&pdev->dev, "Couldn't create the DMC regmap\n");
|
goto free_drm;
|
||||||
ret = PTR_ERR(priv->dmc);
|
}
|
||||||
goto free_drm;
|
/* Simply ioremap since it may be a shared register zone */
|
||||||
|
regs = devm_ioremap(dev, res->start, resource_size(res));
|
||||||
|
if (!regs) {
|
||||||
|
ret = -EADDRNOTAVAIL;
|
||||||
|
goto free_drm;
|
||||||
|
}
|
||||||
|
|
||||||
|
priv->dmc = devm_regmap_init_mmio(dev, regs,
|
||||||
|
&meson_regmap_config);
|
||||||
|
if (IS_ERR(priv->dmc)) {
|
||||||
|
dev_err(&pdev->dev, "Couldn't create the DMC regmap\n");
|
||||||
|
ret = PTR_ERR(priv->dmc);
|
||||||
|
goto free_drm;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
priv->vsync_irq = platform_get_irq(pdev, 0);
|
priv->vsync_irq = platform_get_irq(pdev, 0);
|
||||||
|
@ -300,6 +309,10 @@ static int meson_drv_bind(struct device *dev)
|
||||||
static void meson_drv_unbind(struct device *dev)
|
static void meson_drv_unbind(struct device *dev)
|
||||||
{
|
{
|
||||||
struct drm_device *drm = dev_get_drvdata(dev);
|
struct drm_device *drm = dev_get_drvdata(dev);
|
||||||
|
struct meson_drm *priv = drm->dev_private;
|
||||||
|
|
||||||
|
if (priv->canvas)
|
||||||
|
meson_canvas_free(priv->canvas, priv->canvas_id_osd1);
|
||||||
|
|
||||||
drm_dev_unregister(drm);
|
drm_dev_unregister(drm);
|
||||||
drm_kms_helper_poll_fini(drm);
|
drm_kms_helper_poll_fini(drm);
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
#include <linux/regmap.h>
|
#include <linux/regmap.h>
|
||||||
#include <linux/of.h>
|
#include <linux/of.h>
|
||||||
|
#include <linux/soc/amlogic/meson-canvas.h>
|
||||||
#include <drm/drmP.h>
|
#include <drm/drmP.h>
|
||||||
|
|
||||||
struct meson_drm {
|
struct meson_drm {
|
||||||
|
@ -31,6 +32,9 @@ struct meson_drm {
|
||||||
struct regmap *dmc;
|
struct regmap *dmc;
|
||||||
int vsync_irq;
|
int vsync_irq;
|
||||||
|
|
||||||
|
struct meson_canvas *canvas;
|
||||||
|
u8 canvas_id_osd1;
|
||||||
|
|
||||||
struct drm_device *drm;
|
struct drm_device *drm;
|
||||||
struct drm_crtc *crtc;
|
struct drm_crtc *crtc;
|
||||||
struct drm_plane *primary_plane;
|
struct drm_plane *primary_plane;
|
||||||
|
|
|
@ -90,6 +90,7 @@ static void meson_plane_atomic_update(struct drm_plane *plane,
|
||||||
.y2 = state->crtc_y + state->crtc_h,
|
.y2 = state->crtc_y + state->crtc_h,
|
||||||
};
|
};
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
u8 canvas_id_osd1;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Update Coordinates
|
* Update Coordinates
|
||||||
|
@ -104,8 +105,13 @@ static void meson_plane_atomic_update(struct drm_plane *plane,
|
||||||
(0xFF << OSD_GLOBAL_ALPHA_SHIFT) |
|
(0xFF << OSD_GLOBAL_ALPHA_SHIFT) |
|
||||||
OSD_BLK0_ENABLE;
|
OSD_BLK0_ENABLE;
|
||||||
|
|
||||||
|
if (priv->canvas)
|
||||||
|
canvas_id_osd1 = priv->canvas_id_osd1;
|
||||||
|
else
|
||||||
|
canvas_id_osd1 = MESON_CANVAS_ID_OSD1;
|
||||||
|
|
||||||
/* Set up BLK0 to point to the right canvas */
|
/* Set up BLK0 to point to the right canvas */
|
||||||
priv->viu.osd1_blk0_cfg[0] = ((MESON_CANVAS_ID_OSD1 << OSD_CANVAS_SEL) |
|
priv->viu.osd1_blk0_cfg[0] = ((canvas_id_osd1 << OSD_CANVAS_SEL) |
|
||||||
OSD_ENDIANNESS_LE);
|
OSD_ENDIANNESS_LE);
|
||||||
|
|
||||||
/* On GXBB, Use the old non-HDR RGB2YUV converter */
|
/* On GXBB, Use the old non-HDR RGB2YUV converter */
|
||||||
|
|
Loading…
Reference in New Issue