Commit 9037d4b9 authored by Dave Airlie's avatar Dave Airlie
parents 2989b3ce b06078de
...@@ -14,6 +14,7 @@ Required properties: ...@@ -14,6 +14,7 @@ Required properties:
- compatible : Shall contain one or more of - compatible : Shall contain one or more of
- "renesas,r8a7795-hdmi" for R8A7795 (R-Car H3) compatible HDMI TX - "renesas,r8a7795-hdmi" for R8A7795 (R-Car H3) compatible HDMI TX
- "renesas,r8a7796-hdmi" for R8A7796 (R-Car M3-W) compatible HDMI TX - "renesas,r8a7796-hdmi" for R8A7796 (R-Car M3-W) compatible HDMI TX
- "renesas,r8a77965-hdmi" for R8A77965 (R-Car M3-N) compatible HDMI TX
- "renesas,rcar-gen3-hdmi" for the generic R-Car Gen3 compatible HDMI TX - "renesas,rcar-gen3-hdmi" for the generic R-Car Gen3 compatible HDMI TX
When compatible with generic versions, nodes must list the SoC-specific When compatible with generic versions, nodes must list the SoC-specific
......
...@@ -13,6 +13,7 @@ Required Properties: ...@@ -13,6 +13,7 @@ Required Properties:
- "renesas,du-r8a7794" for R8A7794 (R-Car E2) compatible DU - "renesas,du-r8a7794" for R8A7794 (R-Car E2) compatible DU
- "renesas,du-r8a7795" for R8A7795 (R-Car H3) compatible DU - "renesas,du-r8a7795" for R8A7795 (R-Car H3) compatible DU
- "renesas,du-r8a7796" for R8A7796 (R-Car M3-W) compatible DU - "renesas,du-r8a7796" for R8A7796 (R-Car M3-W) compatible DU
- "renesas,du-r8a77965" for R8A77965 (R-Car M3-N) compatible DU
- "renesas,du-r8a77970" for R8A77970 (R-Car V3M) compatible DU - "renesas,du-r8a77970" for R8A77970 (R-Car V3M) compatible DU
- "renesas,du-r8a77995" for R8A77995 (R-Car D3) compatible DU - "renesas,du-r8a77995" for R8A77995 (R-Car D3) compatible DU
...@@ -59,6 +60,7 @@ corresponding to each DU output. ...@@ -59,6 +60,7 @@ corresponding to each DU output.
R8A7794 (R-Car E2) DPAD 0 DPAD 1 - - R8A7794 (R-Car E2) DPAD 0 DPAD 1 - -
R8A7795 (R-Car H3) DPAD 0 HDMI 0 HDMI 1 LVDS 0 R8A7795 (R-Car H3) DPAD 0 HDMI 0 HDMI 1 LVDS 0
R8A7796 (R-Car M3-W) DPAD 0 HDMI 0 LVDS 0 - R8A7796 (R-Car M3-W) DPAD 0 HDMI 0 LVDS 0 -
R8A77965 (R-Car M3-N) DPAD 0 HDMI 0 LVDS 0 -
R8A77970 (R-Car V3M) DPAD 0 LVDS 0 - - R8A77970 (R-Car V3M) DPAD 0 LVDS 0 - -
R8A77995 (R-Car D3) DPAD 0 LVDS 0 LVDS 1 - R8A77995 (R-Car D3) DPAD 0 LVDS 0 LVDS 1 -
......
...@@ -767,7 +767,8 @@ static irqreturn_t rcar_du_crtc_irq(int irq, void *arg) ...@@ -767,7 +767,8 @@ static irqreturn_t rcar_du_crtc_irq(int irq, void *arg)
* Initialization * Initialization
*/ */
int rcar_du_crtc_create(struct rcar_du_group *rgrp, unsigned int index) int rcar_du_crtc_create(struct rcar_du_group *rgrp, unsigned int swindex,
unsigned int hwindex)
{ {
static const unsigned int mmio_offsets[] = { static const unsigned int mmio_offsets[] = {
DU0_REG_OFFSET, DU1_REG_OFFSET, DU2_REG_OFFSET, DU3_REG_OFFSET DU0_REG_OFFSET, DU1_REG_OFFSET, DU2_REG_OFFSET, DU3_REG_OFFSET
...@@ -775,7 +776,7 @@ int rcar_du_crtc_create(struct rcar_du_group *rgrp, unsigned int index) ...@@ -775,7 +776,7 @@ int rcar_du_crtc_create(struct rcar_du_group *rgrp, unsigned int index)
struct rcar_du_device *rcdu = rgrp->dev; struct rcar_du_device *rcdu = rgrp->dev;
struct platform_device *pdev = to_platform_device(rcdu->dev); struct platform_device *pdev = to_platform_device(rcdu->dev);
struct rcar_du_crtc *rcrtc = &rcdu->crtcs[index]; struct rcar_du_crtc *rcrtc = &rcdu->crtcs[swindex];
struct drm_crtc *crtc = &rcrtc->crtc; struct drm_crtc *crtc = &rcrtc->crtc;
struct drm_plane *primary; struct drm_plane *primary;
unsigned int irqflags; unsigned int irqflags;
...@@ -787,7 +788,7 @@ int rcar_du_crtc_create(struct rcar_du_group *rgrp, unsigned int index) ...@@ -787,7 +788,7 @@ int rcar_du_crtc_create(struct rcar_du_group *rgrp, unsigned int index)
/* Get the CRTC clock and the optional external clock. */ /* Get the CRTC clock and the optional external clock. */
if (rcar_du_has(rcdu, RCAR_DU_FEATURE_CRTC_IRQ_CLOCK)) { if (rcar_du_has(rcdu, RCAR_DU_FEATURE_CRTC_IRQ_CLOCK)) {
sprintf(clk_name, "du.%u", index); sprintf(clk_name, "du.%u", hwindex);
name = clk_name; name = clk_name;
} else { } else {
name = NULL; name = NULL;
...@@ -795,16 +796,16 @@ int rcar_du_crtc_create(struct rcar_du_group *rgrp, unsigned int index) ...@@ -795,16 +796,16 @@ int rcar_du_crtc_create(struct rcar_du_group *rgrp, unsigned int index)
rcrtc->clock = devm_clk_get(rcdu->dev, name); rcrtc->clock = devm_clk_get(rcdu->dev, name);
if (IS_ERR(rcrtc->clock)) { if (IS_ERR(rcrtc->clock)) {
dev_err(rcdu->dev, "no clock for CRTC %u\n", index); dev_err(rcdu->dev, "no clock for DU channel %u\n", hwindex);
return PTR_ERR(rcrtc->clock); return PTR_ERR(rcrtc->clock);
} }
sprintf(clk_name, "dclkin.%u", index); sprintf(clk_name, "dclkin.%u", hwindex);
clk = devm_clk_get(rcdu->dev, clk_name); clk = devm_clk_get(rcdu->dev, clk_name);
if (!IS_ERR(clk)) { if (!IS_ERR(clk)) {
rcrtc->extclock = clk; rcrtc->extclock = clk;
} else if (PTR_ERR(rcrtc->clock) == -EPROBE_DEFER) { } else if (PTR_ERR(rcrtc->clock) == -EPROBE_DEFER) {
dev_info(rcdu->dev, "can't get external clock %u\n", index); dev_info(rcdu->dev, "can't get external clock %u\n", hwindex);
return -EPROBE_DEFER; return -EPROBE_DEFER;
} }
...@@ -813,13 +814,13 @@ int rcar_du_crtc_create(struct rcar_du_group *rgrp, unsigned int index) ...@@ -813,13 +814,13 @@ int rcar_du_crtc_create(struct rcar_du_group *rgrp, unsigned int index)
spin_lock_init(&rcrtc->vblank_lock); spin_lock_init(&rcrtc->vblank_lock);
rcrtc->group = rgrp; rcrtc->group = rgrp;
rcrtc->mmio_offset = mmio_offsets[index]; rcrtc->mmio_offset = mmio_offsets[hwindex];
rcrtc->index = index; rcrtc->index = hwindex;
if (rcar_du_has(rcdu, RCAR_DU_FEATURE_VSP1_SOURCE)) if (rcar_du_has(rcdu, RCAR_DU_FEATURE_VSP1_SOURCE))
primary = &rcrtc->vsp->planes[rcrtc->vsp_pipe].plane; primary = &rcrtc->vsp->planes[rcrtc->vsp_pipe].plane;
else else
primary = &rgrp->planes[index % 2].plane; primary = &rgrp->planes[swindex % 2].plane;
ret = drm_crtc_init_with_planes(rcdu->ddev, crtc, primary, ret = drm_crtc_init_with_planes(rcdu->ddev, crtc, primary,
NULL, &crtc_funcs, NULL); NULL, &crtc_funcs, NULL);
...@@ -833,7 +834,8 @@ int rcar_du_crtc_create(struct rcar_du_group *rgrp, unsigned int index) ...@@ -833,7 +834,8 @@ int rcar_du_crtc_create(struct rcar_du_group *rgrp, unsigned int index)
/* Register the interrupt handler. */ /* Register the interrupt handler. */
if (rcar_du_has(rcdu, RCAR_DU_FEATURE_CRTC_IRQ_CLOCK)) { if (rcar_du_has(rcdu, RCAR_DU_FEATURE_CRTC_IRQ_CLOCK)) {
irq = platform_get_irq(pdev, index); /* The IRQ's are associated with the CRTC (sw)index. */
irq = platform_get_irq(pdev, swindex);
irqflags = 0; irqflags = 0;
} else { } else {
irq = platform_get_irq(pdev, 0); irq = platform_get_irq(pdev, 0);
...@@ -841,7 +843,7 @@ int rcar_du_crtc_create(struct rcar_du_group *rgrp, unsigned int index) ...@@ -841,7 +843,7 @@ int rcar_du_crtc_create(struct rcar_du_group *rgrp, unsigned int index)
} }
if (irq < 0) { if (irq < 0) {
dev_err(rcdu->dev, "no IRQ for CRTC %u\n", index); dev_err(rcdu->dev, "no IRQ for CRTC %u\n", swindex);
return irq; return irq;
} }
...@@ -849,7 +851,7 @@ int rcar_du_crtc_create(struct rcar_du_group *rgrp, unsigned int index) ...@@ -849,7 +851,7 @@ int rcar_du_crtc_create(struct rcar_du_group *rgrp, unsigned int index)
dev_name(rcdu->dev), rcrtc); dev_name(rcdu->dev), rcrtc);
if (ret < 0) { if (ret < 0) {
dev_err(rcdu->dev, dev_err(rcdu->dev,
"failed to register IRQ for CRTC %u\n", index); "failed to register IRQ for CRTC %u\n", swindex);
return ret; return ret;
} }
......
...@@ -80,7 +80,8 @@ enum rcar_du_output { ...@@ -80,7 +80,8 @@ enum rcar_du_output {
RCAR_DU_OUTPUT_MAX, RCAR_DU_OUTPUT_MAX,
}; };
int rcar_du_crtc_create(struct rcar_du_group *rgrp, unsigned int index); int rcar_du_crtc_create(struct rcar_du_group *rgrp, unsigned int swindex,
unsigned int hwindex);
void rcar_du_crtc_suspend(struct rcar_du_crtc *rcrtc); void rcar_du_crtc_suspend(struct rcar_du_crtc *rcrtc);
void rcar_du_crtc_resume(struct rcar_du_crtc *rcrtc); void rcar_du_crtc_resume(struct rcar_du_crtc *rcrtc);
......
...@@ -40,7 +40,7 @@ static const struct rcar_du_device_info rzg1_du_r8a7743_info = { ...@@ -40,7 +40,7 @@ static const struct rcar_du_device_info rzg1_du_r8a7743_info = {
.gen = 2, .gen = 2,
.features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK .features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
| RCAR_DU_FEATURE_EXT_CTRL_REGS, | RCAR_DU_FEATURE_EXT_CTRL_REGS,
.num_crtcs = 2, .channels_mask = BIT(1) | BIT(0),
.routes = { .routes = {
/* /*
* R8A7743 has one RGB output and one LVDS output * R8A7743 has one RGB output and one LVDS output
...@@ -61,7 +61,7 @@ static const struct rcar_du_device_info rzg1_du_r8a7745_info = { ...@@ -61,7 +61,7 @@ static const struct rcar_du_device_info rzg1_du_r8a7745_info = {
.gen = 2, .gen = 2,
.features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK .features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
| RCAR_DU_FEATURE_EXT_CTRL_REGS, | RCAR_DU_FEATURE_EXT_CTRL_REGS,
.num_crtcs = 2, .channels_mask = BIT(1) | BIT(0),
.routes = { .routes = {
/* /*
* R8A7745 has two RGB outputs * R8A7745 has two RGB outputs
...@@ -80,7 +80,7 @@ static const struct rcar_du_device_info rzg1_du_r8a7745_info = { ...@@ -80,7 +80,7 @@ static const struct rcar_du_device_info rzg1_du_r8a7745_info = {
static const struct rcar_du_device_info rcar_du_r8a7779_info = { static const struct rcar_du_device_info rcar_du_r8a7779_info = {
.gen = 2, .gen = 2,
.features = 0, .features = 0,
.num_crtcs = 2, .channels_mask = BIT(1) | BIT(0),
.routes = { .routes = {
/* /*
* R8A7779 has two RGB outputs and one (currently unsupported) * R8A7779 has two RGB outputs and one (currently unsupported)
...@@ -102,7 +102,7 @@ static const struct rcar_du_device_info rcar_du_r8a7790_info = { ...@@ -102,7 +102,7 @@ static const struct rcar_du_device_info rcar_du_r8a7790_info = {
.features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK .features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
| RCAR_DU_FEATURE_EXT_CTRL_REGS, | RCAR_DU_FEATURE_EXT_CTRL_REGS,
.quirks = RCAR_DU_QUIRK_ALIGN_128B, .quirks = RCAR_DU_QUIRK_ALIGN_128B,
.num_crtcs = 3, .channels_mask = BIT(2) | BIT(1) | BIT(0),
.routes = { .routes = {
/* /*
* R8A7790 has one RGB output, two LVDS outputs and one * R8A7790 has one RGB output, two LVDS outputs and one
...@@ -129,7 +129,7 @@ static const struct rcar_du_device_info rcar_du_r8a7791_info = { ...@@ -129,7 +129,7 @@ static const struct rcar_du_device_info rcar_du_r8a7791_info = {
.gen = 2, .gen = 2,
.features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK .features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
| RCAR_DU_FEATURE_EXT_CTRL_REGS, | RCAR_DU_FEATURE_EXT_CTRL_REGS,
.num_crtcs = 2, .channels_mask = BIT(1) | BIT(0),
.routes = { .routes = {
/* /*
* R8A779[13] has one RGB output, one LVDS output and one * R8A779[13] has one RGB output, one LVDS output and one
...@@ -151,7 +151,7 @@ static const struct rcar_du_device_info rcar_du_r8a7792_info = { ...@@ -151,7 +151,7 @@ static const struct rcar_du_device_info rcar_du_r8a7792_info = {
.gen = 2, .gen = 2,
.features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK .features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
| RCAR_DU_FEATURE_EXT_CTRL_REGS, | RCAR_DU_FEATURE_EXT_CTRL_REGS,
.num_crtcs = 2, .channels_mask = BIT(1) | BIT(0),
.routes = { .routes = {
/* R8A7792 has two RGB outputs. */ /* R8A7792 has two RGB outputs. */
[RCAR_DU_OUTPUT_DPAD0] = { [RCAR_DU_OUTPUT_DPAD0] = {
...@@ -169,7 +169,7 @@ static const struct rcar_du_device_info rcar_du_r8a7794_info = { ...@@ -169,7 +169,7 @@ static const struct rcar_du_device_info rcar_du_r8a7794_info = {
.gen = 2, .gen = 2,
.features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK .features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
| RCAR_DU_FEATURE_EXT_CTRL_REGS, | RCAR_DU_FEATURE_EXT_CTRL_REGS,
.num_crtcs = 2, .channels_mask = BIT(1) | BIT(0),
.routes = { .routes = {
/* /*
* R8A7794 has two RGB outputs and one (currently unsupported) * R8A7794 has two RGB outputs and one (currently unsupported)
...@@ -191,7 +191,7 @@ static const struct rcar_du_device_info rcar_du_r8a7795_info = { ...@@ -191,7 +191,7 @@ static const struct rcar_du_device_info rcar_du_r8a7795_info = {
.features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK .features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
| RCAR_DU_FEATURE_EXT_CTRL_REGS | RCAR_DU_FEATURE_EXT_CTRL_REGS
| RCAR_DU_FEATURE_VSP1_SOURCE, | RCAR_DU_FEATURE_VSP1_SOURCE,
.num_crtcs = 4, .channels_mask = BIT(3) | BIT(2) | BIT(1) | BIT(0),
.routes = { .routes = {
/* /*
* R8A7795 has one RGB output, two HDMI outputs and one * R8A7795 has one RGB output, two HDMI outputs and one
...@@ -215,7 +215,7 @@ static const struct rcar_du_device_info rcar_du_r8a7795_info = { ...@@ -215,7 +215,7 @@ static const struct rcar_du_device_info rcar_du_r8a7795_info = {
}, },
}, },
.num_lvds = 1, .num_lvds = 1,
.dpll_ch = BIT(1) | BIT(2), .dpll_ch = BIT(2) | BIT(1),
}; };
static const struct rcar_du_device_info rcar_du_r8a7796_info = { static const struct rcar_du_device_info rcar_du_r8a7796_info = {
...@@ -223,7 +223,7 @@ static const struct rcar_du_device_info rcar_du_r8a7796_info = { ...@@ -223,7 +223,7 @@ static const struct rcar_du_device_info rcar_du_r8a7796_info = {
.features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK .features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
| RCAR_DU_FEATURE_EXT_CTRL_REGS | RCAR_DU_FEATURE_EXT_CTRL_REGS
| RCAR_DU_FEATURE_VSP1_SOURCE, | RCAR_DU_FEATURE_VSP1_SOURCE,
.num_crtcs = 3, .channels_mask = BIT(2) | BIT(1) | BIT(0),
.routes = { .routes = {
/* /*
* R8A7796 has one RGB output, one LVDS output and one HDMI * R8A7796 has one RGB output, one LVDS output and one HDMI
...@@ -246,12 +246,40 @@ static const struct rcar_du_device_info rcar_du_r8a7796_info = { ...@@ -246,12 +246,40 @@ static const struct rcar_du_device_info rcar_du_r8a7796_info = {
.dpll_ch = BIT(1), .dpll_ch = BIT(1),
}; };
static const struct rcar_du_device_info rcar_du_r8a77965_info = {
.gen = 3,
.features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
| RCAR_DU_FEATURE_EXT_CTRL_REGS
| RCAR_DU_FEATURE_VSP1_SOURCE,
.channels_mask = BIT(3) | BIT(1) | BIT(0),
.routes = {
/*
* R8A77965 has one RGB output, one LVDS output and one HDMI
* output.
*/
[RCAR_DU_OUTPUT_DPAD0] = {
.possible_crtcs = BIT(2),
.port = 0,
},
[RCAR_DU_OUTPUT_HDMI0] = {
.possible_crtcs = BIT(1),
.port = 1,
},
[RCAR_DU_OUTPUT_LVDS0] = {
.possible_crtcs = BIT(0),
.port = 2,
},
},
.num_lvds = 1,
.dpll_ch = BIT(1),
};
static const struct rcar_du_device_info rcar_du_r8a77970_info = { static const struct rcar_du_device_info rcar_du_r8a77970_info = {
.gen = 3, .gen = 3,
.features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK .features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
| RCAR_DU_FEATURE_EXT_CTRL_REGS | RCAR_DU_FEATURE_EXT_CTRL_REGS
| RCAR_DU_FEATURE_VSP1_SOURCE, | RCAR_DU_FEATURE_VSP1_SOURCE,
.num_crtcs = 1, .channels_mask = BIT(0),
.routes = { .routes = {
/* R8A77970 has one RGB output and one LVDS output. */ /* R8A77970 has one RGB output and one LVDS output. */
[RCAR_DU_OUTPUT_DPAD0] = { [RCAR_DU_OUTPUT_DPAD0] = {
...@@ -277,6 +305,7 @@ static const struct of_device_id rcar_du_of_table[] = { ...@@ -277,6 +305,7 @@ static const struct of_device_id rcar_du_of_table[] = {
{ .compatible = "renesas,du-r8a7794", .data = &rcar_du_r8a7794_info }, { .compatible = "renesas,du-r8a7794", .data = &rcar_du_r8a7794_info },
{ .compatible = "renesas,du-r8a7795", .data = &rcar_du_r8a7795_info }, { .compatible = "renesas,du-r8a7795", .data = &rcar_du_r8a7795_info },
{ .compatible = "renesas,du-r8a7796", .data = &rcar_du_r8a7796_info }, { .compatible = "renesas,du-r8a7796", .data = &rcar_du_r8a7796_info },
{ .compatible = "renesas,du-r8a77965", .data = &rcar_du_r8a77965_info },
{ .compatible = "renesas,du-r8a77970", .data = &rcar_du_r8a77970_info }, { .compatible = "renesas,du-r8a77970", .data = &rcar_du_r8a77970_info },
{ } { }
}; };
......
...@@ -52,7 +52,7 @@ struct rcar_du_output_routing { ...@@ -52,7 +52,7 @@ struct rcar_du_output_routing {
* @gen: device generation (2 or 3) * @gen: device generation (2 or 3)
* @features: device features (RCAR_DU_FEATURE_*) * @features: device features (RCAR_DU_FEATURE_*)
* @quirks: device quirks (RCAR_DU_QUIRK_*) * @quirks: device quirks (RCAR_DU_QUIRK_*)
* @num_crtcs: total number of CRTCs * @channels_mask: bit mask of available DU channels
* @routes: array of CRTC to output routes, indexed by output (RCAR_DU_OUTPUT_*) * @routes: array of CRTC to output routes, indexed by output (RCAR_DU_OUTPUT_*)
* @num_lvds: number of internal LVDS encoders * @num_lvds: number of internal LVDS encoders
*/ */
...@@ -60,7 +60,7 @@ struct rcar_du_device_info { ...@@ -60,7 +60,7 @@ struct rcar_du_device_info {
unsigned int gen; unsigned int gen;
unsigned int features; unsigned int features;
unsigned int quirks; unsigned int quirks;
unsigned int num_crtcs; unsigned int channels_mask;
struct rcar_du_output_routing routes[RCAR_DU_OUTPUT_MAX]; struct rcar_du_output_routing routes[RCAR_DU_OUTPUT_MAX];
unsigned int num_lvds; unsigned int num_lvds;
unsigned int dpll_ch; unsigned int dpll_ch;
......
...@@ -46,10 +46,13 @@ void rcar_du_group_write(struct rcar_du_group *rgrp, u32 reg, u32 data) ...@@ -46,10 +46,13 @@ void rcar_du_group_write(struct rcar_du_group *rgrp, u32 reg, u32 data)
static void rcar_du_group_setup_pins(struct rcar_du_group *rgrp) static void rcar_du_group_setup_pins(struct rcar_du_group *rgrp)
{ {
u32 defr6 = DEFR6_CODE | DEFR6_ODPM12_DISP; u32 defr6 = DEFR6_CODE;
if (rgrp->num_crtcs > 1) if (rgrp->channels_mask & BIT(0))
defr6 |= DEFR6_ODPM22_DISP; defr6 |= DEFR6_ODPM02_DISP;
if (rgrp->channels_mask & BIT(1))
defr6 |= DEFR6_ODPM12_DISP;
rcar_du_group_write(rgrp, DEFR6, defr6); rcar_du_group_write(rgrp, DEFR6, defr6);
} }
...@@ -80,10 +83,11 @@ static void rcar_du_group_setup_defr8(struct rcar_du_group *rgrp) ...@@ -80,10 +83,11 @@ static void rcar_du_group_setup_defr8(struct rcar_du_group *rgrp)
* On Gen3 VSPD routing can't be configured, but DPAD routing * On Gen3 VSPD routing can't be configured, but DPAD routing
* needs to be set despite having a single option available. * needs to be set despite having a single option available.
*/ */
u32 crtc = ffs(possible_crtcs) - 1; unsigned int rgb_crtc = ffs(possible_crtcs) - 1;
struct rcar_du_crtc *crtc = &rcdu->crtcs[rgb_crtc];
if (crtc / 2 == rgrp->index) if (crtc->index / 2 == rgrp->index)
defr8 |= DEFR8_DRGBS_DU(crtc); defr8 |= DEFR8_DRGBS_DU(crtc->index);
} }
rcar_du_group_write(rgrp, DEFR8, defr8); rcar_du_group_write(rgrp, DEFR8, defr8);
......
...@@ -25,6 +25,7 @@ struct rcar_du_device; ...@@ -25,6 +25,7 @@ struct rcar_du_device;
* @dev: the DU device * @dev: the DU device
* @mmio_offset: registers offset in the device memory map * @mmio_offset: registers offset in the device memory map
* @index: group index * @index: group index
* @channels_mask: bitmask of populated DU channels in this group
* @num_crtcs: number of CRTCs in this group (1 or 2) * @num_crtcs: number of CRTCs in this group (1 or 2)
* @use_count: number of users of the group (rcar_du_group_(get|put)) * @use_count: number of users of the group (rcar_du_group_(get|put))
* @used_crtcs: number of CRTCs currently in use * @used_crtcs: number of CRTCs currently in use
...@@ -39,6 +40,7 @@ struct rcar_du_group { ...@@ -39,6 +40,7 @@ struct rcar_du_group {
unsigned int mmio_offset; unsigned int mmio_offset;
unsigned int index; unsigned int index;
unsigned int channels_mask;
unsigned int num_crtcs; unsigned int num_crtcs;
unsigned int use_count; unsigned int use_count;
unsigned int used_crtcs; unsigned int used_crtcs;
......
...@@ -428,7 +428,7 @@ static int rcar_du_vsps_init(struct rcar_du_device *rcdu) ...@@ -428,7 +428,7 @@ static int rcar_du_vsps_init(struct rcar_du_device *rcdu)
struct { struct {
struct device_node *np; struct device_node *np;
unsigned int crtcs_mask; unsigned int crtcs_mask;
} vsps[RCAR_DU_MAX_VSPS] = { { 0, }, }; } vsps[RCAR_DU_MAX_VSPS] = { { NULL, }, };
unsigned int vsps_count = 0; unsigned int vsps_count = 0;
unsigned int cells; unsigned int cells;
unsigned int i; unsigned int i;
...@@ -507,6 +507,8 @@ int rcar_du_modeset_init(struct rcar_du_device *rcdu) ...@@ -507,6 +507,8 @@ int rcar_du_modeset_init(struct rcar_du_device *rcdu)
struct drm_fbdev_cma *fbdev; struct drm_fbdev_cma *fbdev;
unsigned int num_encoders; unsigned int num_encoders;
unsigned int num_groups; unsigned int num_groups;
unsigned int swindex;
unsigned int hwindex;
unsigned int i; unsigned int i;
int ret; int ret;
...@@ -520,7 +522,7 @@ int rcar_du_modeset_init(struct rcar_du_device *rcdu) ...@@ -520,7 +522,7 @@ int rcar_du_modeset_init(struct rcar_du_device *rcdu)
dev->mode_config.funcs = &rcar_du_mode_config_funcs; dev->mode_config.funcs = &rcar_du_mode_config_funcs;
dev->mode_config.helper_private = &rcar_du_mode_config_helper; dev->mode_config.helper_private = &rcar_du_mode_config_helper;
rcdu->num_crtcs = rcdu->info->num_crtcs; rcdu->num_crtcs = hweight8(rcdu->info->channels_mask);
ret = rcar_du_properties_init(rcdu); ret = rcar_du_properties_init(rcdu);
if (ret < 0) if (ret < 0)
...@@ -530,7 +532,7 @@ int rcar_du_modeset_init(struct rcar_du_device *rcdu) ...@@ -530,7 +532,7 @@ int rcar_du_modeset_init(struct rcar_du_device *rcdu)
* Initialize vertical blanking interrupts handling. Start with vblank * Initialize vertical blanking interrupts handling. Start with vblank
* disabled for all CRTCs. * disabled for all CRTCs.
*/ */
ret = drm_vblank_init(dev, (1 << rcdu->info->num_crtcs) - 1); ret = drm_vblank_init(dev, (1 << rcdu->num_crtcs) - 1);
if (ret < 0) if (ret < 0)
return ret; return ret;
...@@ -545,7 +547,10 @@ int rcar_du_modeset_init(struct rcar_du_device *rcdu) ...@@ -545,7 +547,10 @@ int rcar_du_modeset_init(struct rcar_du_device *rcdu)
rgrp->dev = rcdu; rgrp->dev = rcdu;
rgrp->mmio_offset = mmio_offsets[i]; rgrp->mmio_offset = mmio_offsets[i];
rgrp->index = i; rgrp->index = i;
rgrp->num_crtcs = min(rcdu->num_crtcs - 2 * i, 2U); /* Extract the channel mask for this group only. */
rgrp->channels_mask = (rcdu->info->channels_mask >> (2 * i))
& GENMASK(1, 0);
rgrp->num_crtcs = hweight8(rgrp->channels_mask);
/* /*
* If we have more than one CRTCs in this group pre-associate * If we have more than one CRTCs in this group pre-associate
...@@ -572,10 +577,16 @@ int rcar_du_modeset_init(struct rcar_du_device *rcdu) ...@@ -572,10 +577,16 @@ int rcar_du_modeset_init(struct rcar_du_device *rcdu)
} }
/* Create the CRTCs. */ /* Create the CRTCs. */
for (i = 0; i < rcdu->num_crtcs; ++i) { for (swindex = 0, hwindex = 0; swindex < rcdu->num_crtcs; ++hwindex) {
struct rcar_du_group *rgrp = &rcdu->groups[i / 2]; struct rcar_du_group *rgrp;
/* Skip unpopulated DU channels. */
if (!(rcdu->info->channels_mask & BIT(hwindex)))
continue;
rgrp = &rcdu->groups[hwindex / 2];
ret = rcar_du_crtc_create(rgrp, i); ret = rcar_du_crtc_create(rgrp, swindex++, hwindex);
if (ret < 0) if (ret < 0)
return ret; return ret;
} }
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include "rcar_du_crtc.h" #include "rcar_du_crtc.h"
#include "rcar_du_drv.h" #include "rcar_du_drv.h"
#include "rcar_du_of.h"
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
* Generic Overlay Handling * Generic Overlay Handling
......
...@@ -187,14 +187,14 @@ ...@@ -187,14 +187,14 @@
#define DEFR6 0x000e8 #define DEFR6 0x000e8
#define DEFR6_CODE (0x7778 << 16) #define DEFR6_CODE (0x7778 << 16)
#define DEFR6_ODPM22_DSMR (0 << 10) #define DEFR6_ODPM12_DSMR (0 << 10)
#define DEFR6_ODPM22_DISP (2 << 10) #define DEFR6_ODPM12_DISP (2 << 10)
#define DEFR6_ODPM22_CDE (3 << 10) #define DEFR6_ODPM12_CDE (3 << 10)
#define DEFR6_ODPM22_MASK (3 << 10) #define DEFR6_ODPM12_MASK (3 << 10)
#define DEFR6_ODPM12_DSMR (0 << 8) #define DEFR6_ODPM02_DSMR (0 << 8)
#define DEFR6_ODPM12_DISP (2 << 8) #define DEFR6_ODPM02_DISP (2 << 8)
#define DEFR6_ODPM12_CDE (3 << 8) #define DEFR6_ODPM02_CDE (3 << 8)
#define DEFR6_ODPM12_MASK (3 << 8) #define DEFR6_ODPM02_MASK (3 << 8)
#define DEFR6_TCNE1 (1 << 6) #define DEFR6_TCNE1 (1 << 6)
#define DEFR6_TCNE0 (1 << 4) #define DEFR6_TCNE0 (1 << 4)
#define DEFR6_MLOS1 (1 << 2) #define DEFR6_MLOS1 (1 << 2)
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include <drm/drm_crtc_helper.h> #include <drm/drm_crtc_helper.h>
#include <drm/drm_fb_cma_helper.h> #include <drm/drm_fb_cma_helper.h>
#include <drm/drm_gem_cma_helper.h> #include <drm/drm_gem_cma_helper.h>
#include <drm/drm_gem_framebuffer_helper.h>
#include <drm/drm_plane_helper.h> #include <drm/drm_plane_helper.h>
#include <linux/bitops.h> #include <linux/bitops.h>
...@@ -237,6 +238,10 @@ static int rcar_du_vsp_plane_prepare_fb(struct drm_plane *plane, ...@@ -237,6 +238,10 @@ static int rcar_du_vsp_plane_prepare_fb(struct drm_plane *plane,
} }
} }
ret = drm_gem_fb_prepare_fb(plane, state);
if (ret)
goto fail;
return 0; return 0;
fail: fail:
...@@ -299,18 +304,17 @@ static const struct drm_plane_helper_funcs rcar_du_vsp_plane_helper_funcs = { ...@@ -299,18 +304,17 @@ static const struct drm_plane_helper_funcs rcar_du_vsp_plane_helper_funcs = {
static struct drm_plane_state * static struct drm_plane_state *
rcar_du_vsp_plane_atomic_duplicate_state(struct drm_plane *plane) rcar_du_vsp_plane_atomic_duplicate_state(struct drm_plane *plane)
{ {
struct rcar_du_vsp_plane_state *state;
struct rcar_du_vsp_plane_state *copy; struct rcar_du_vsp_plane_state *copy;
if (WARN_ON(!plane->state)) if (WARN_ON(!plane->state))
return NULL; return NULL;
state = to_rcar_vsp_plane_state(plane->state); copy = kzalloc(sizeof(*copy), GFP_KERNEL);
copy = kmemdup(state, sizeof(*state), GFP_KERNEL);
if (copy == NULL) if (copy == NULL)
return NULL; return NULL;
__drm_atomic_helper_plane_duplicate_state(plane, &copy->state); __drm_atomic_helper_plane_duplicate_state(plane, &copy->state);
copy->alpha = to_rcar_vsp_plane_state(plane->state)->alpha;
return &copy->state; return &copy->state;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment