diff options
author | Dave Airlie <airlied@redhat.com> | 2016-11-16 09:39:21 +1000 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2016-11-16 09:39:21 +1000 |
commit | 1a3865d64a0d8151c7fe23f4b57a587615ccc5bb (patch) | |
tree | c3ad147281f48e85c59d23559485f0e9408ecea7 /drivers/gpu/drm | |
parent | d8c1abd968f1c880ad8ce4ecf7df55489f8c69a1 (diff) | |
parent | 85e8f8d175caa6a39f4c4e11dd4d0ab038f43324 (diff) |
Merge branch 'drm/next/du' of git://linuxtv.org/pinchartl/media into drm-next
rcar-du -next branch.
* 'drm/next/du' of git://linuxtv.org/pinchartl/media:
drm: rcar-du: Fix LVDS start sequence on Gen3
drm: rcar-du: Fix H/V sync signal polarity configuration
drm: rcar-du: Fix display timing controller parameter
drm: rcar-du: Fix dot clock routing configuration
drm: rcar-du: Add R8A7796 support
drm: rcar-du: Add R8A7792 support
drm: rcar-du: Simplify and fix probe error handling
drm: rcar-du: Fix crash in encoder failure error path
drm: rcar-du: Remove memory allocation error message
drm: rcar-du: Remove test for impossible error condition
drm: rcar-du: Bring HDMI encoder comments in line with the driver
drm: rcar-du: Constify node argument to rcar_du_lvds_connector_init()
video: of: Constify node argument to display timing functions
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r-- | drivers/gpu/drm/rcar-du/rcar_du_crtc.c | 6 | ||||
-rw-r--r-- | drivers/gpu/drm/rcar-du/rcar_du_drv.c | 83 | ||||
-rw-r--r-- | drivers/gpu/drm/rcar-du/rcar_du_group.c | 22 | ||||
-rw-r--r-- | drivers/gpu/drm/rcar-du/rcar_du_hdmienc.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/rcar-du/rcar_du_kms.c | 17 | ||||
-rw-r--r-- | drivers/gpu/drm/rcar-du/rcar_du_lvdscon.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/rcar-du/rcar_du_lvdscon.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/rcar-du/rcar_du_lvdsenc.c | 19 |
8 files changed, 98 insertions, 57 deletions
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c index 7316fc7fa0bd..a2ec6d8796a0 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c +++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c @@ -149,8 +149,8 @@ static void rcar_du_crtc_set_display_timing(struct rcar_du_crtc *rcrtc) rcar_du_group_write(rcrtc->group, rcrtc->index % 2 ? OTAR2 : OTAR, 0); /* Signal polarities */ - value = ((mode->flags & DRM_MODE_FLAG_PVSYNC) ? 0 : DSMR_VSL) - | ((mode->flags & DRM_MODE_FLAG_PHSYNC) ? 0 : DSMR_HSL) + value = ((mode->flags & DRM_MODE_FLAG_PVSYNC) ? DSMR_VSL : 0) + | ((mode->flags & DRM_MODE_FLAG_PHSYNC) ? DSMR_HSL : 0) | DSMR_DIPM_DISP | DSMR_CSPM; rcar_du_crtc_write(rcrtc, DSMR, value); @@ -172,7 +172,7 @@ static void rcar_du_crtc_set_display_timing(struct rcar_du_crtc *rcrtc) mode->crtc_vsync_start - 1); rcar_du_crtc_write(rcrtc, VCR, mode->crtc_vtotal - 1); - rcar_du_crtc_write(rcrtc, DESR, mode->htotal - mode->hsync_start); + rcar_du_crtc_write(rcrtc, DESR, mode->htotal - mode->hsync_start - 1); rcar_du_crtc_write(rcrtc, DEWR, mode->hdisplay); } diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.c b/drivers/gpu/drm/rcar-du/rcar_du_drv.c index 68fd167d7313..c05e00872778 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_drv.c +++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.c @@ -110,6 +110,27 @@ static const struct rcar_du_device_info rcar_du_r8a7791_info = { .num_lvds = 1, }; +static const struct rcar_du_device_info rcar_du_r8a7792_info = { + .gen = 2, + .features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK + | RCAR_DU_FEATURE_EXT_CTRL_REGS, + .num_crtcs = 2, + .routes = { + /* R8A7792 has two RGB outputs. */ + [RCAR_DU_OUTPUT_DPAD0] = { + .possible_crtcs = BIT(0), + .encoder_type = DRM_MODE_ENCODER_NONE, + .port = 0, + }, + [RCAR_DU_OUTPUT_DPAD1] = { + .possible_crtcs = BIT(1), + .encoder_type = DRM_MODE_ENCODER_NONE, + .port = 1, + }, + }, + .num_lvds = 0, +}; + static const struct rcar_du_device_info rcar_du_r8a7794_info = { .gen = 2, .features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK @@ -157,13 +178,39 @@ static const struct rcar_du_device_info rcar_du_r8a7795_info = { .num_lvds = 1, }; +static const struct rcar_du_device_info rcar_du_r8a7796_info = { + .gen = 3, + .features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK + | RCAR_DU_FEATURE_EXT_CTRL_REGS + | RCAR_DU_FEATURE_VSP1_SOURCE, + .num_crtcs = 3, + .routes = { + /* R8A7796 has one RGB output, one LVDS output and one + * (currently unsupported) HDMI output. + */ + [RCAR_DU_OUTPUT_DPAD0] = { + .possible_crtcs = BIT(2), + .encoder_type = DRM_MODE_ENCODER_NONE, + .port = 0, + }, + [RCAR_DU_OUTPUT_LVDS0] = { + .possible_crtcs = BIT(0), + .encoder_type = DRM_MODE_ENCODER_LVDS, + .port = 2, + }, + }, + .num_lvds = 1, +}; + static const struct of_device_id rcar_du_of_table[] = { { .compatible = "renesas,du-r8a7779", .data = &rcar_du_r8a7779_info }, { .compatible = "renesas,du-r8a7790", .data = &rcar_du_r8a7790_info }, { .compatible = "renesas,du-r8a7791", .data = &rcar_du_r8a7791_info }, + { .compatible = "renesas,du-r8a7792", .data = &rcar_du_r8a7792_info }, { .compatible = "renesas,du-r8a7793", .data = &rcar_du_r8a7791_info }, { .compatible = "renesas,du-r8a7794", .data = &rcar_du_r8a7794_info }, { .compatible = "renesas,du-r8a7795", .data = &rcar_du_r8a7795_info }, + { .compatible = "renesas,du-r8a7796", .data = &rcar_du_r8a7796_info }, { } }; @@ -283,7 +330,6 @@ static int rcar_du_remove(struct platform_device *pdev) drm_kms_helper_poll_fini(ddev); drm_mode_config_cleanup(ddev); - drm_vblank_cleanup(ddev); drm_dev_unref(ddev); @@ -292,18 +338,12 @@ static int rcar_du_remove(struct platform_device *pdev) static int rcar_du_probe(struct platform_device *pdev) { - struct device_node *np = pdev->dev.of_node; struct rcar_du_device *rcdu; struct drm_device *ddev; struct resource *mem; int ret; - if (np == NULL) { - dev_err(&pdev->dev, "no device tree node\n"); - return -ENODEV; - } - - /* Allocate and initialize the DRM and R-Car device structures. */ + /* Allocate and initialize the R-Car device structure. */ rcdu = devm_kzalloc(&pdev->dev, sizeof(*rcdu), GFP_KERNEL); if (rcdu == NULL) return -ENOMEM; @@ -313,31 +353,22 @@ static int rcar_du_probe(struct platform_device *pdev) rcdu->dev = &pdev->dev; rcdu->info = of_match_device(rcar_du_of_table, rcdu->dev)->data; - ddev = drm_dev_alloc(&rcar_du_driver, &pdev->dev); - if (IS_ERR(ddev)) - return PTR_ERR(ddev); - - rcdu->ddev = ddev; - ddev->dev_private = rcdu; - platform_set_drvdata(pdev, rcdu); /* I/O resources */ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); rcdu->mmio = devm_ioremap_resource(&pdev->dev, mem); - if (IS_ERR(rcdu->mmio)) { - ret = PTR_ERR(rcdu->mmio); - goto error; - } - - /* Initialize vertical blanking interrupts handling. Start with vblank - * disabled for all CRTCs. - */ - ret = drm_vblank_init(ddev, (1 << rcdu->info->num_crtcs) - 1); - if (ret < 0) - goto error; + if (IS_ERR(rcdu->mmio)) + return PTR_ERR(rcdu->mmio); /* DRM/KMS objects */ + ddev = drm_dev_alloc(&rcar_du_driver, &pdev->dev); + if (IS_ERR(ddev)) + return PTR_ERR(ddev); + + rcdu->ddev = ddev; + ddev->dev_private = rcdu; + ret = rcar_du_modeset_init(rcdu); if (ret < 0) { if (ret != -EPROBE_DEFER) diff --git a/drivers/gpu/drm/rcar-du/rcar_du_group.c b/drivers/gpu/drm/rcar-du/rcar_du_group.c index 33b2fc53da3e..64738fca96d0 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_group.c +++ b/drivers/gpu/drm/rcar-du/rcar_du_group.c @@ -105,16 +105,20 @@ static void rcar_du_group_setup(struct rcar_du_group *rgrp) if (rcar_du_has(rgrp->dev, RCAR_DU_FEATURE_EXT_CTRL_REGS)) { rcar_du_group_setup_defr8(rgrp); - /* Configure input dot clock routing. We currently hardcode the - * configuration to routing DOTCLKINn to DUn. + /* + * Configure input dot clock routing. We currently hardcode the + * configuration to routing DOTCLKINn to DUn. Register fields + * depend on the DU generation, but the resulting value is 0 in + * all cases. + * + * On Gen2 a single register in the first group controls dot + * clock selection for all channels, while on Gen3 dot clocks + * are setup through per-group registers, only available when + * the group has two channels. */ - rcar_du_group_write(rgrp, DIDSR, DIDSR_CODE | - DIDSR_LCDS_DCLKIN(2) | - DIDSR_LCDS_DCLKIN(1) | - DIDSR_LCDS_DCLKIN(0) | - DIDSR_PDCS_CLK(2, 0) | - DIDSR_PDCS_CLK(1, 0) | - DIDSR_PDCS_CLK(0, 0)); + if ((rcdu->info->gen < 3 && rgrp->index == 0) || + (rcdu->info->gen == 3 && rgrp->num_crtcs > 1)) + rcar_du_group_write(rgrp, DIDSR, DIDSR_CODE); } if (rcdu->info->gen >= 3) diff --git a/drivers/gpu/drm/rcar-du/rcar_du_hdmienc.c b/drivers/gpu/drm/rcar-du/rcar_du_hdmienc.c index e03004f4588d..f9515f53cc5b 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_hdmienc.c +++ b/drivers/gpu/drm/rcar-du/rcar_du_hdmienc.c @@ -108,7 +108,7 @@ int rcar_du_hdmienc_init(struct rcar_du_device *rcdu, if (hdmienc == NULL) return -ENOMEM; - /* Locate drm bridge from the hdmi encoder DT node */ + /* Locate the DRM bridge from the HDMI encoder DT node. */ bridge = of_drm_find_bridge(np); if (!bridge) return -EPROBE_DEFER; @@ -123,7 +123,7 @@ int rcar_du_hdmienc_init(struct rcar_du_device *rcdu, renc->hdmi = hdmienc; hdmienc->renc = renc; - /* Link drm_bridge to encoder */ + /* Link the bridge to the encoder. */ bridge->encoder = encoder; encoder->bridge = bridge; diff --git a/drivers/gpu/drm/rcar-du/rcar_du_kms.c b/drivers/gpu/drm/rcar-du/rcar_du_kms.c index 4220d621f55f..b5d3f16cfa12 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_kms.c +++ b/drivers/gpu/drm/rcar-du/rcar_du_kms.c @@ -454,13 +454,13 @@ static int rcar_du_encoders_init_one(struct rcar_du_device *rcdu, } ret = rcar_du_encoder_init(rcdu, enc_type, output, encoder, connector); - of_node_put(encoder); - of_node_put(connector); - if (ret && ret != -EPROBE_DEFER) dev_warn(rcdu->dev, - "failed to initialize encoder %s (%d), skipping\n", - encoder->full_name, ret); + "failed to initialize encoder %s on output %u (%d), skipping\n", + of_node_full_name(encoder), output, ret); + + of_node_put(encoder); + of_node_put(connector); return ret; } @@ -568,6 +568,13 @@ int rcar_du_modeset_init(struct rcar_du_device *rcdu) if (ret < 0) return ret; + /* Initialize vertical blanking interrupts handling. Start with vblank + * disabled for all CRTCs. + */ + ret = drm_vblank_init(dev, (1 << rcdu->info->num_crtcs) - 1); + if (ret < 0) + return ret; + /* Initialize the groups. */ num_groups = DIV_ROUND_UP(rcdu->num_crtcs, 2); diff --git a/drivers/gpu/drm/rcar-du/rcar_du_lvdscon.c b/drivers/gpu/drm/rcar-du/rcar_du_lvdscon.c index 6afd0af312ba..64e9f0b86e58 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_lvdscon.c +++ b/drivers/gpu/drm/rcar-du/rcar_du_lvdscon.c @@ -79,7 +79,7 @@ static const struct drm_connector_funcs connector_funcs = { int rcar_du_lvds_connector_init(struct rcar_du_device *rcdu, struct rcar_du_encoder *renc, - /* TODO const */ struct device_node *np) + const struct device_node *np) { struct drm_encoder *encoder = rcar_encoder_to_drm_encoder(renc); struct rcar_du_lvds_connector *lvdscon; diff --git a/drivers/gpu/drm/rcar-du/rcar_du_lvdscon.h b/drivers/gpu/drm/rcar-du/rcar_du_lvdscon.h index d4881ee0be7e..639071dd235c 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_lvdscon.h +++ b/drivers/gpu/drm/rcar-du/rcar_du_lvdscon.h @@ -19,6 +19,6 @@ struct rcar_du_encoder; int rcar_du_lvds_connector_init(struct rcar_du_device *rcdu, struct rcar_du_encoder *renc, - struct device_node *np); + const struct device_node *np); #endif /* __RCAR_DU_LVDSCON_H__ */ diff --git a/drivers/gpu/drm/rcar-du/rcar_du_lvdsenc.c b/drivers/gpu/drm/rcar-du/rcar_du_lvdsenc.c index ef3a50321ecc..e3a4985f6f3f 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_lvdsenc.c +++ b/drivers/gpu/drm/rcar-du/rcar_du_lvdsenc.c @@ -104,7 +104,14 @@ static void rcar_du_lvdsenc_start_gen3(struct rcar_du_lvdsenc *lvds, rcar_lvds_write(lvds, LVDPLLCR, pllcr); - /* Turn the PLL on, set it to LVDS normal mode, wait for the startup + /* Turn all the channels on. */ + rcar_lvds_write(lvds, LVDCR1, + LVDCR1_CHSTBY_GEN3(3) | LVDCR1_CHSTBY_GEN3(2) | + LVDCR1_CHSTBY_GEN3(1) | LVDCR1_CHSTBY_GEN3(0) | + LVDCR1_CLKSTBY_GEN3); + + /* + * Turn the PLL on, set it to LVDS normal mode, wait for the startup * delay and turn the output on. */ lvdcr0 = LVDCR0_PLLON; @@ -117,12 +124,6 @@ static void rcar_du_lvdsenc_start_gen3(struct rcar_du_lvdsenc *lvds, lvdcr0 |= LVDCR0_LVRES; rcar_lvds_write(lvds, LVDCR0, lvdcr0); - - /* Turn all the channels on. */ - rcar_lvds_write(lvds, LVDCR1, - LVDCR1_CHSTBY_GEN3(3) | LVDCR1_CHSTBY_GEN3(2) | - LVDCR1_CHSTBY_GEN3(1) | LVDCR1_CHSTBY_GEN3(0) | - LVDCR1_CLKSTBY_GEN3); } static int rcar_du_lvdsenc_start(struct rcar_du_lvdsenc *lvds, @@ -241,10 +242,8 @@ int rcar_du_lvdsenc_init(struct rcar_du_device *rcdu) for (i = 0; i < rcdu->info->num_lvds; ++i) { lvds = devm_kzalloc(&pdev->dev, sizeof(*lvds), GFP_KERNEL); - if (lvds == NULL) { - dev_err(&pdev->dev, "failed to allocate private data\n"); + if (lvds == NULL) return -ENOMEM; - } lvds->dev = rcdu; lvds->index = i; |