Add a compatible string for the LCD controller found in the JZ4770 SoC.
Signed-off-by: Paul Cercueil paul@crapouillou.net --- Documentation/devicetree/bindings/display/ingenic,lcd.txt | 1 + 1 file changed, 1 insertion(+)
diff --git a/Documentation/devicetree/bindings/display/ingenic,lcd.txt b/Documentation/devicetree/bindings/display/ingenic,lcd.txt index 7b536c8c6dde..01e3261defb6 100644 --- a/Documentation/devicetree/bindings/display/ingenic,lcd.txt +++ b/Documentation/devicetree/bindings/display/ingenic,lcd.txt @@ -4,6 +4,7 @@ Required properties: - compatible: one of: * ingenic,jz4740-lcd * ingenic,jz4725b-lcd + * ingenic,jz4770-lcd - reg: LCD registers location and length - clocks: LCD pixclock and device clock specifiers. The device clock is only required on the JZ4740.
It is possible that there is no drm_framebuffer associated with a given plane state.
Signed-off-by: Paul Cercueil paul@crapouillou.net --- drivers/gpu/drm/ingenic/ingenic-drm.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-)
diff --git a/drivers/gpu/drm/ingenic/ingenic-drm.c b/drivers/gpu/drm/ingenic/ingenic-drm.c index 2e2ed653e9c6..6dc4b06e7e68 100644 --- a/drivers/gpu/drm/ingenic/ingenic-drm.c +++ b/drivers/gpu/drm/ingenic/ingenic-drm.c @@ -371,14 +371,17 @@ static void ingenic_drm_plane_atomic_update(struct drm_plane *plane, struct ingenic_drm *priv = drm_plane_get_priv(plane); struct drm_plane_state *state = plane->state; unsigned int width, height, cpp; + struct drm_framebuffer *fb = state->fb;
- width = state->crtc->state->adjusted_mode.hdisplay; - height = state->crtc->state->adjusted_mode.vdisplay; - cpp = state->fb->format->cpp[plane->index]; + if (fb) { + width = state->crtc->state->adjusted_mode.hdisplay; + height = state->crtc->state->adjusted_mode.vdisplay; + cpp = fb->format->cpp[plane->index];
- priv->dma_hwdesc->addr = drm_fb_cma_get_gem_addr(state->fb, state, 0); - priv->dma_hwdesc->cmd = width * height * cpp / 4; - priv->dma_hwdesc->cmd |= JZ_LCD_CMD_EOF_IRQ; + priv->dma_hwdesc->addr = drm_fb_cma_get_gem_addr(fb, state, 0); + priv->dma_hwdesc->cmd = width * height * cpp / 4; + priv->dma_hwdesc->cmd |= JZ_LCD_CMD_EOF_IRQ; + } }
static void ingenic_drm_encoder_atomic_mode_set(struct drm_encoder *encoder,
Instead of obtaining the width/height of the framebuffer from the CRTC state, obtain it from the current plane state.
Signed-off-by: Paul Cercueil paul@crapouillou.net --- drivers/gpu/drm/ingenic/ingenic-drm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/ingenic/ingenic-drm.c b/drivers/gpu/drm/ingenic/ingenic-drm.c index 6dc4b06e7e68..7a172271bd63 100644 --- a/drivers/gpu/drm/ingenic/ingenic-drm.c +++ b/drivers/gpu/drm/ingenic/ingenic-drm.c @@ -374,8 +374,8 @@ static void ingenic_drm_plane_atomic_update(struct drm_plane *plane, struct drm_framebuffer *fb = state->fb;
if (fb) { - width = state->crtc->state->adjusted_mode.hdisplay; - height = state->crtc->state->adjusted_mode.vdisplay; + width = state->src_w >> 16; + height = state->src_h >> 16; cpp = fb->format->cpp[plane->index];
priv->dma_hwdesc->addr = drm_fb_cma_get_gem_addr(fb, state, 0);
While the LCD controller can effectively only support a maximum resolution of 800x600, the framebuffer's height can be much higher, since we can change the Y start offset.
Signed-off-by: Paul Cercueil paul@crapouillou.net --- drivers/gpu/drm/ingenic/ingenic-drm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/ingenic/ingenic-drm.c b/drivers/gpu/drm/ingenic/ingenic-drm.c index 7a172271bd63..4538b081b0c5 100644 --- a/drivers/gpu/drm/ingenic/ingenic-drm.c +++ b/drivers/gpu/drm/ingenic/ingenic-drm.c @@ -635,7 +635,7 @@ static int ingenic_drm_probe(struct platform_device *pdev) drm->mode_config.min_width = 0; drm->mode_config.min_height = 0; drm->mode_config.max_width = 800; - drm->mode_config.max_height = 600; + drm->mode_config.max_height = 4095; drm->mode_config.funcs = &ingenic_drm_mode_config_funcs;
base = devm_platform_ioremap_resource(pdev, 0);
Check that the requested display size isn't above the limits supported by the CRTC.
- JZ4750 and older support up to 800x600; - JZ4755 supports up to 1024x576; - JZ4760 and JZ4770 support up to 720p; - JZ4780 supports up to 2k.
Signed-off-by: Paul Cercueil paul@crapouillou.net --- drivers/gpu/drm/ingenic/ingenic-drm.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/ingenic/ingenic-drm.c b/drivers/gpu/drm/ingenic/ingenic-drm.c index 4538b081b0c5..d578c4cb6009 100644 --- a/drivers/gpu/drm/ingenic/ingenic-drm.c +++ b/drivers/gpu/drm/ingenic/ingenic-drm.c @@ -152,6 +152,7 @@ struct ingenic_dma_hwdesc {
struct jz_soc_info { bool needs_dev_clk; + unsigned int max_width, max_height; };
struct ingenic_drm { @@ -163,6 +164,7 @@ struct ingenic_drm { struct device *dev; struct regmap *map; struct clk *lcd_clk, *pix_clk; + const struct jz_soc_info *soc_info;
struct ingenic_dma_hwdesc *dma_hwdesc; dma_addr_t dma_hwdesc_phys; @@ -325,6 +327,10 @@ static int ingenic_drm_crtc_atomic_check(struct drm_crtc *crtc, if (!drm_atomic_crtc_needs_modeset(state)) return 0;
+ if (state->mode.hdisplay > priv->soc_info->max_height || + state->mode.vdisplay > priv->soc_info->max_width) + return -EINVAL; + rate = clk_round_rate(priv->pix_clk, state->adjusted_mode.clock * 1000); if (rate < 0) @@ -619,6 +625,7 @@ static int ingenic_drm_probe(struct platform_device *pdev) if (!priv) return -ENOMEM;
+ priv->soc_info = soc_info; priv->dev = dev; drm = &priv->drm; drm->dev_private = priv; @@ -634,7 +641,7 @@ static int ingenic_drm_probe(struct platform_device *pdev) drm_mode_config_init(drm); drm->mode_config.min_width = 0; drm->mode_config.min_height = 0; - drm->mode_config.max_width = 800; + drm->mode_config.max_width = soc_info->max_width; drm->mode_config.max_height = 4095; drm->mode_config.funcs = &ingenic_drm_mode_config_funcs;
@@ -812,10 +819,14 @@ static int ingenic_drm_remove(struct platform_device *pdev)
static const struct jz_soc_info jz4740_soc_info = { .needs_dev_clk = true, + .max_width = 800, + .max_height = 600, };
static const struct jz_soc_info jz4725b_soc_info = { .needs_dev_clk = false, + .max_width = 800, + .max_height = 600, };
static const struct of_device_id ingenic_drm_of_match[] = {
The LCD controller in the JZ4770 supports up to 720p. While there has been many new features added since the old JZ4740, which are not yet handled here, this driver still works fine.
Signed-off-by: Paul Cercueil paul@crapouillou.net --- drivers/gpu/drm/ingenic/ingenic-drm.c | 7 +++++++ 1 file changed, 7 insertions(+)
diff --git a/drivers/gpu/drm/ingenic/ingenic-drm.c b/drivers/gpu/drm/ingenic/ingenic-drm.c index d578c4cb6009..46d3ce763bb9 100644 --- a/drivers/gpu/drm/ingenic/ingenic-drm.c +++ b/drivers/gpu/drm/ingenic/ingenic-drm.c @@ -829,9 +829,16 @@ static const struct jz_soc_info jz4725b_soc_info = { .max_height = 600, };
+static const struct jz_soc_info jz4770_soc_info = { + .needs_dev_clk = false, + .max_width = 1280, + .max_height = 720, +}; + static const struct of_device_id ingenic_drm_of_match[] = { { .compatible = "ingenic,jz4740-lcd", .data = &jz4740_soc_info }, { .compatible = "ingenic,jz4725b-lcd", .data = &jz4725b_soc_info }, + { .compatible = "ingenic,jz4770-lcd", .data = &jz4770_soc_info }, { /* sentinel */ }, };
On Tue, 19 Nov 2019 15:17:31 +0100, Paul Cercueil wrote:
Add a compatible string for the LCD controller found in the JZ4770 SoC.
Signed-off-by: Paul Cercueil paul@crapouillou.net
Documentation/devicetree/bindings/display/ingenic,lcd.txt | 1 + 1 file changed, 1 insertion(+)
Acked-by: Rob Herring robh@kernel.org
dri-devel@lists.freedesktop.org