Commit 9a45d33c authored by Boris Brezillon's avatar Boris Brezillon

drm/atmel-hlcdc: Simplify the HLCDC layer logic

An HLCDC layers in Atmel's nomenclature is either a DRM plane or a 'Post
Processing Layer' which can be used to output the results of the HLCDC
composition in a memory buffer.

atmel_hlcdc_layer.c was designed to be generic enough to be re-usable in
both cases, but we're not exposing the post-processing layer yet, and
even if we were, I'm not sure the code would provide the necessary tools
to manipulate this kind of layer.

Moreover, the code in atmel_hlcdc_{plane,layer}.c was designed before the
atomic modesetting API, and was trying solve the
check-setting/commit-if-ok/rollback-otherwise problem, which is now
entirely solved by the existing core infrastructure.

And finally, the code in atmel_hlcdc_layer.c is over-complicated compared
to what we really need. This rework is a good excuse to simplify it. Note
that this rework solves an existing resource leak (leading to a -EBUSY
error) which I failed to clearly identify.
Signed-off-by: default avatarBoris Brezillon <boris.brezillon@free-electrons.com>
Acked-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
Reviewed-by: default avatarEric Anholt <eric@anholt.net>
Tested-by: default avatarNicolas Ferre <nicolas.ferre@microchip.com>
parent 6140cf20
atmel-hlcdc-dc-y := atmel_hlcdc_crtc.o \ atmel-hlcdc-dc-y := atmel_hlcdc_crtc.o \
atmel_hlcdc_dc.o \ atmel_hlcdc_dc.o \
atmel_hlcdc_layer.o \
atmel_hlcdc_output.o \ atmel_hlcdc_output.o \
atmel_hlcdc_plane.o atmel_hlcdc_plane.o
......
...@@ -466,8 +466,8 @@ static const struct drm_crtc_funcs atmel_hlcdc_crtc_funcs = { ...@@ -466,8 +466,8 @@ static const struct drm_crtc_funcs atmel_hlcdc_crtc_funcs = {
int atmel_hlcdc_crtc_create(struct drm_device *dev) int atmel_hlcdc_crtc_create(struct drm_device *dev)
{ {
struct atmel_hlcdc_plane *primary = NULL, *cursor = NULL;
struct atmel_hlcdc_dc *dc = dev->dev_private; struct atmel_hlcdc_dc *dc = dev->dev_private;
struct atmel_hlcdc_planes *planes = dc->planes;
struct atmel_hlcdc_crtc *crtc; struct atmel_hlcdc_crtc *crtc;
int ret; int ret;
int i; int i;
...@@ -478,20 +478,41 @@ int atmel_hlcdc_crtc_create(struct drm_device *dev) ...@@ -478,20 +478,41 @@ int atmel_hlcdc_crtc_create(struct drm_device *dev)
crtc->dc = dc; crtc->dc = dc;
ret = drm_crtc_init_with_planes(dev, &crtc->base, for (i = 0; i < ATMEL_HLCDC_MAX_LAYERS; i++) {
&planes->primary->base, if (!dc->layers[i])
planes->cursor ? &planes->cursor->base : NULL, continue;
&atmel_hlcdc_crtc_funcs, NULL);
switch (dc->layers[i]->desc->type) {
case ATMEL_HLCDC_BASE_LAYER:
primary = atmel_hlcdc_layer_to_plane(dc->layers[i]);
break;
case ATMEL_HLCDC_CURSOR_LAYER:
cursor = atmel_hlcdc_layer_to_plane(dc->layers[i]);
break;
default:
break;
}
}
ret = drm_crtc_init_with_planes(dev, &crtc->base, &primary->base,
&cursor->base, &atmel_hlcdc_crtc_funcs,
NULL);
if (ret < 0) if (ret < 0)
goto fail; goto fail;
crtc->id = drm_crtc_index(&crtc->base); crtc->id = drm_crtc_index(&crtc->base);
if (planes->cursor) for (i = 0; i < ATMEL_HLCDC_MAX_LAYERS; i++) {
planes->cursor->base.possible_crtcs = 1 << crtc->id; struct atmel_hlcdc_plane *overlay;
for (i = 0; i < planes->noverlays; i++) if (dc->layers[i] &&
planes->overlays[i]->base.possible_crtcs = 1 << crtc->id; dc->layers[i]->desc->type == ATMEL_HLCDC_OVERLAY_LAYER) {
overlay = atmel_hlcdc_layer_to_plane(dc->layers[i]);
overlay->base.possible_crtcs = 1 << crtc->id;
}
}
drm_crtc_helper_add(&crtc->base, &lcdc_crtc_helper_funcs); drm_crtc_helper_add(&crtc->base, &lcdc_crtc_helper_funcs);
drm_crtc_vblank_reset(&crtc->base); drm_crtc_vblank_reset(&crtc->base);
......
...@@ -36,7 +36,7 @@ static const struct atmel_hlcdc_layer_desc atmel_hlcdc_at91sam9n12_layers[] = { ...@@ -36,7 +36,7 @@ static const struct atmel_hlcdc_layer_desc atmel_hlcdc_at91sam9n12_layers[] = {
.regs_offset = 0x40, .regs_offset = 0x40,
.id = 0, .id = 0,
.type = ATMEL_HLCDC_BASE_LAYER, .type = ATMEL_HLCDC_BASE_LAYER,
.nconfigs = 5, .cfgs_offset = 0x2c,
.layout = { .layout = {
.xstride = { 2 }, .xstride = { 2 },
.default_color = 3, .default_color = 3,
...@@ -65,7 +65,7 @@ static const struct atmel_hlcdc_layer_desc atmel_hlcdc_at91sam9x5_layers[] = { ...@@ -65,7 +65,7 @@ static const struct atmel_hlcdc_layer_desc atmel_hlcdc_at91sam9x5_layers[] = {
.regs_offset = 0x40, .regs_offset = 0x40,
.id = 0, .id = 0,
.type = ATMEL_HLCDC_BASE_LAYER, .type = ATMEL_HLCDC_BASE_LAYER,
.nconfigs = 5, .cfgs_offset = 0x2c,
.layout = { .layout = {
.xstride = { 2 }, .xstride = { 2 },
.default_color = 3, .default_color = 3,
...@@ -80,7 +80,7 @@ static const struct atmel_hlcdc_layer_desc atmel_hlcdc_at91sam9x5_layers[] = { ...@@ -80,7 +80,7 @@ static const struct atmel_hlcdc_layer_desc atmel_hlcdc_at91sam9x5_layers[] = {
.regs_offset = 0x100, .regs_offset = 0x100,
.id = 1, .id = 1,
.type = ATMEL_HLCDC_OVERLAY_LAYER, .type = ATMEL_HLCDC_OVERLAY_LAYER,
.nconfigs = 10, .cfgs_offset = 0x2c,
.layout = { .layout = {
.pos = 2, .pos = 2,
.size = 3, .size = 3,
...@@ -98,7 +98,7 @@ static const struct atmel_hlcdc_layer_desc atmel_hlcdc_at91sam9x5_layers[] = { ...@@ -98,7 +98,7 @@ static const struct atmel_hlcdc_layer_desc atmel_hlcdc_at91sam9x5_layers[] = {
.regs_offset = 0x280, .regs_offset = 0x280,
.id = 2, .id = 2,
.type = ATMEL_HLCDC_OVERLAY_LAYER, .type = ATMEL_HLCDC_OVERLAY_LAYER,
.nconfigs = 17, .cfgs_offset = 0x4c,
.layout = { .layout = {
.pos = 2, .pos = 2,
.size = 3, .size = 3,
...@@ -109,6 +109,7 @@ static const struct atmel_hlcdc_layer_desc atmel_hlcdc_at91sam9x5_layers[] = { ...@@ -109,6 +109,7 @@ static const struct atmel_hlcdc_layer_desc atmel_hlcdc_at91sam9x5_layers[] = {
.chroma_key = 10, .chroma_key = 10,
.chroma_key_mask = 11, .chroma_key_mask = 11,
.general_config = 12, .general_config = 12,
.scaler_config = 13,
.csc = 14, .csc = 14,
}, },
}, },
...@@ -118,9 +119,9 @@ static const struct atmel_hlcdc_layer_desc atmel_hlcdc_at91sam9x5_layers[] = { ...@@ -118,9 +119,9 @@ static const struct atmel_hlcdc_layer_desc atmel_hlcdc_at91sam9x5_layers[] = {
.regs_offset = 0x340, .regs_offset = 0x340,
.id = 3, .id = 3,
.type = ATMEL_HLCDC_CURSOR_LAYER, .type = ATMEL_HLCDC_CURSOR_LAYER,
.nconfigs = 10,
.max_width = 128, .max_width = 128,
.max_height = 128, .max_height = 128,
.cfgs_offset = 0x2c,
.layout = { .layout = {
.pos = 2, .pos = 2,
.size = 3, .size = 3,
...@@ -153,7 +154,7 @@ static const struct atmel_hlcdc_layer_desc atmel_hlcdc_sama5d3_layers[] = { ...@@ -153,7 +154,7 @@ static const struct atmel_hlcdc_layer_desc atmel_hlcdc_sama5d3_layers[] = {
.regs_offset = 0x40, .regs_offset = 0x40,
.id = 0, .id = 0,
.type = ATMEL_HLCDC_BASE_LAYER, .type = ATMEL_HLCDC_BASE_LAYER,
.nconfigs = 7, .cfgs_offset = 0x2c,
.layout = { .layout = {
.xstride = { 2 }, .xstride = { 2 },
.default_color = 3, .default_color = 3,
...@@ -168,7 +169,7 @@ static const struct atmel_hlcdc_layer_desc atmel_hlcdc_sama5d3_layers[] = { ...@@ -168,7 +169,7 @@ static const struct atmel_hlcdc_layer_desc atmel_hlcdc_sama5d3_layers[] = {
.regs_offset = 0x140, .regs_offset = 0x140,
.id = 1, .id = 1,
.type = ATMEL_HLCDC_OVERLAY_LAYER, .type = ATMEL_HLCDC_OVERLAY_LAYER,
.nconfigs = 10, .cfgs_offset = 0x2c,
.layout = { .layout = {
.pos = 2, .pos = 2,
.size = 3, .size = 3,
...@@ -186,7 +187,7 @@ static const struct atmel_hlcdc_layer_desc atmel_hlcdc_sama5d3_layers[] = { ...@@ -186,7 +187,7 @@ static const struct atmel_hlcdc_layer_desc atmel_hlcdc_sama5d3_layers[] = {
.regs_offset = 0x240, .regs_offset = 0x240,
.id = 2, .id = 2,
.type = ATMEL_HLCDC_OVERLAY_LAYER, .type = ATMEL_HLCDC_OVERLAY_LAYER,
.nconfigs = 10, .cfgs_offset = 0x2c,
.layout = { .layout = {
.pos = 2, .pos = 2,
.size = 3, .size = 3,
...@@ -204,7 +205,7 @@ static const struct atmel_hlcdc_layer_desc atmel_hlcdc_sama5d3_layers[] = { ...@@ -204,7 +205,7 @@ static const struct atmel_hlcdc_layer_desc atmel_hlcdc_sama5d3_layers[] = {
.regs_offset = 0x340, .regs_offset = 0x340,
.id = 3, .id = 3,
.type = ATMEL_HLCDC_OVERLAY_LAYER, .type = ATMEL_HLCDC_OVERLAY_LAYER,
.nconfigs = 42, .cfgs_offset = 0x4c,
.layout = { .layout = {
.pos = 2, .pos = 2,
.size = 3, .size = 3,
...@@ -215,6 +216,11 @@ static const struct atmel_hlcdc_layer_desc atmel_hlcdc_sama5d3_layers[] = { ...@@ -215,6 +216,11 @@ static const struct atmel_hlcdc_layer_desc atmel_hlcdc_sama5d3_layers[] = {
.chroma_key = 10, .chroma_key = 10,
.chroma_key_mask = 11, .chroma_key_mask = 11,
.general_config = 12, .general_config = 12,
.scaler_config = 13,
.phicoeffs = {
.x = 17,
.y = 33,
},
.csc = 14, .csc = 14,
}, },
}, },
...@@ -224,9 +230,9 @@ static const struct atmel_hlcdc_layer_desc atmel_hlcdc_sama5d3_layers[] = { ...@@ -224,9 +230,9 @@ static const struct atmel_hlcdc_layer_desc atmel_hlcdc_sama5d3_layers[] = {
.regs_offset = 0x440, .regs_offset = 0x440,
.id = 4, .id = 4,
.type = ATMEL_HLCDC_CURSOR_LAYER, .type = ATMEL_HLCDC_CURSOR_LAYER,
.nconfigs = 10,
.max_width = 128, .max_width = 128,
.max_height = 128, .max_height = 128,
.cfgs_offset = 0x2c,
.layout = { .layout = {
.pos = 2, .pos = 2,
.size = 3, .size = 3,
...@@ -236,6 +242,7 @@ static const struct atmel_hlcdc_layer_desc atmel_hlcdc_sama5d3_layers[] = { ...@@ -236,6 +242,7 @@ static const struct atmel_hlcdc_layer_desc atmel_hlcdc_sama5d3_layers[] = {
.chroma_key = 7, .chroma_key = 7,
.chroma_key_mask = 8, .chroma_key_mask = 8,
.general_config = 9, .general_config = 9,
.scaler_config = 13,
}, },
}, },
}; };
...@@ -260,7 +267,7 @@ static const struct atmel_hlcdc_layer_desc atmel_hlcdc_sama5d4_layers[] = { ...@@ -260,7 +267,7 @@ static const struct atmel_hlcdc_layer_desc atmel_hlcdc_sama5d4_layers[] = {
.regs_offset = 0x40, .regs_offset = 0x40,
.id = 0, .id = 0,
.type = ATMEL_HLCDC_BASE_LAYER, .type = ATMEL_HLCDC_BASE_LAYER,
.nconfigs = 7, .cfgs_offset = 0x2c,
.layout = { .layout = {
.xstride = { 2 }, .xstride = { 2 },
.default_color = 3, .default_color = 3,
...@@ -275,7 +282,7 @@ static const struct atmel_hlcdc_layer_desc atmel_hlcdc_sama5d4_layers[] = { ...@@ -275,7 +282,7 @@ static const struct atmel_hlcdc_layer_desc atmel_hlcdc_sama5d4_layers[] = {
.regs_offset = 0x140, .regs_offset = 0x140,
.id = 1, .id = 1,
.type = ATMEL_HLCDC_OVERLAY_LAYER, .type = ATMEL_HLCDC_OVERLAY_LAYER,
.nconfigs = 10, .cfgs_offset = 0x2c,
.layout = { .layout = {
.pos = 2, .pos = 2,
.size = 3, .size = 3,
...@@ -293,7 +300,7 @@ static const struct atmel_hlcdc_layer_desc atmel_hlcdc_sama5d4_layers[] = { ...@@ -293,7 +300,7 @@ static const struct atmel_hlcdc_layer_desc atmel_hlcdc_sama5d4_layers[] = {
.regs_offset = 0x240, .regs_offset = 0x240,
.id = 2, .id = 2,
.type = ATMEL_HLCDC_OVERLAY_LAYER, .type = ATMEL_HLCDC_OVERLAY_LAYER,
.nconfigs = 10, .cfgs_offset = 0x2c,
.layout = { .layout = {
.pos = 2, .pos = 2,
.size = 3, .size = 3,
...@@ -311,7 +318,7 @@ static const struct atmel_hlcdc_layer_desc atmel_hlcdc_sama5d4_layers[] = { ...@@ -311,7 +318,7 @@ static const struct atmel_hlcdc_layer_desc atmel_hlcdc_sama5d4_layers[] = {
.regs_offset = 0x340, .regs_offset = 0x340,
.id = 3, .id = 3,
.type = ATMEL_HLCDC_OVERLAY_LAYER, .type = ATMEL_HLCDC_OVERLAY_LAYER,
.nconfigs = 42, .cfgs_offset = 0x4c,
.layout = { .layout = {
.pos = 2, .pos = 2,
.size = 3, .size = 3,
...@@ -322,6 +329,11 @@ static const struct atmel_hlcdc_layer_desc atmel_hlcdc_sama5d4_layers[] = { ...@@ -322,6 +329,11 @@ static const struct atmel_hlcdc_layer_desc atmel_hlcdc_sama5d4_layers[] = {
.chroma_key = 10, .chroma_key = 10,
.chroma_key_mask = 11, .chroma_key_mask = 11,
.general_config = 12, .general_config = 12,
.scaler_config = 13,
.phicoeffs = {
.x = 17,
.y = 33,
},
.csc = 14, .csc = 14,
}, },
}, },
...@@ -392,6 +404,17 @@ int atmel_hlcdc_dc_mode_valid(struct atmel_hlcdc_dc *dc, ...@@ -392,6 +404,17 @@ int atmel_hlcdc_dc_mode_valid(struct atmel_hlcdc_dc *dc,
return MODE_OK; return MODE_OK;
} }
static void atmel_hlcdc_layer_irq(struct atmel_hlcdc_layer *layer)
{
if (!layer)
return;
if (layer->desc->type == ATMEL_HLCDC_BASE_LAYER ||
layer->desc->type == ATMEL_HLCDC_OVERLAY_LAYER ||
layer->desc->type == ATMEL_HLCDC_CURSOR_LAYER)
atmel_hlcdc_plane_irq(atmel_hlcdc_layer_to_plane(layer));
}
static irqreturn_t atmel_hlcdc_dc_irq_handler(int irq, void *data) static irqreturn_t atmel_hlcdc_dc_irq_handler(int irq, void *data)
{ {
struct drm_device *dev = data; struct drm_device *dev = data;
...@@ -410,12 +433,8 @@ static irqreturn_t atmel_hlcdc_dc_irq_handler(int irq, void *data) ...@@ -410,12 +433,8 @@ static irqreturn_t atmel_hlcdc_dc_irq_handler(int irq, void *data)
atmel_hlcdc_crtc_irq(dc->crtc); atmel_hlcdc_crtc_irq(dc->crtc);
for (i = 0; i < ATMEL_HLCDC_MAX_LAYERS; i++) { for (i = 0; i < ATMEL_HLCDC_MAX_LAYERS; i++) {
struct atmel_hlcdc_layer *layer = dc->layers[i]; if (ATMEL_HLCDC_LAYER_STATUS(i) & status)
atmel_hlcdc_layer_irq(dc->layers[i]);
if (!(ATMEL_HLCDC_LAYER_STATUS(i) & status) || !layer)
continue;
atmel_hlcdc_layer_irq(layer);
} }
return IRQ_HANDLED; return IRQ_HANDLED;
...@@ -537,9 +556,7 @@ static const struct drm_mode_config_funcs mode_config_funcs = { ...@@ -537,9 +556,7 @@ static const struct drm_mode_config_funcs mode_config_funcs = {
static int atmel_hlcdc_dc_modeset_init(struct drm_device *dev) static int atmel_hlcdc_dc_modeset_init(struct drm_device *dev)
{ {
struct atmel_hlcdc_dc *dc = dev->dev_private; struct atmel_hlcdc_dc *dc = dev->dev_private;
struct atmel_hlcdc_planes *planes;
int ret; int ret;
int i;
drm_mode_config_init(dev); drm_mode_config_init(dev);
...@@ -549,25 +566,12 @@ static int atmel_hlcdc_dc_modeset_init(struct drm_device *dev) ...@@ -549,25 +566,12 @@ static int atmel_hlcdc_dc_modeset_init(struct drm_device *dev)
return ret; return ret;
} }
planes = atmel_hlcdc_create_planes(dev); ret = atmel_hlcdc_create_planes(dev);
if (IS_ERR(planes)) { if (ret) {
dev_err(dev->dev, "failed to create planes\n"); dev_err(dev->dev, "failed to create planes: %d\n", ret);
return PTR_ERR(planes); return ret;
} }
dc->planes = planes;
dc->layers[planes->primary->layer.desc->id] =
&planes->primary->layer;
if (planes->cursor)
dc->layers[planes->cursor->layer.desc->id] =
&planes->cursor->layer;
for (i = 0; i < planes->noverlays; i++)
dc->layers[planes->overlays[i]->layer.desc->id] =
&planes->overlays[i]->layer;
ret = atmel_hlcdc_crtc_create(dev); ret = atmel_hlcdc_crtc_create(dev);
if (ret) { if (ret) {
dev_err(dev->dev, "failed to create crtc\n"); dev_err(dev->dev, "failed to create crtc\n");
......
This diff is collapsed.
This diff is collapsed.
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