Commit ebab87ab authored by Boris Brezillon's avatar Boris Brezillon

drm: atmel-hlcdc: route DMA accesses through AHB interfaces

In relation with the actuall bandwidth consumed on a DMA Source interface,
choose the less used one for a created plane.
Signed-off-by: default avatarBoris Brezillon <boris.brezillon@free-electrons.com>
Tested-by: default avatarNicolas Ferre <nicolas.ferre@atmel.com>
parent 5ac44c8b
...@@ -319,7 +319,11 @@ static int atmel_hlcdc_crtc_atomic_check(struct drm_crtc *c, ...@@ -319,7 +319,11 @@ static int atmel_hlcdc_crtc_atomic_check(struct drm_crtc *c,
if (ret) if (ret)
return ret; return ret;
return atmel_hlcdc_plane_prepare_disc_area(s); ret = atmel_hlcdc_plane_prepare_disc_area(s);
if (ret)
return ret;
return atmel_hlcdc_plane_prepare_ahb_routing(s);
} }
static void atmel_hlcdc_crtc_atomic_begin(struct drm_crtc *c, static void atmel_hlcdc_crtc_atomic_begin(struct drm_crtc *c,
......
...@@ -163,6 +163,7 @@ struct atmel_hlcdc_planes * ...@@ -163,6 +163,7 @@ struct atmel_hlcdc_planes *
atmel_hlcdc_create_planes(struct drm_device *dev); atmel_hlcdc_create_planes(struct drm_device *dev);
int atmel_hlcdc_plane_prepare_disc_area(struct drm_crtc_state *c_state); int atmel_hlcdc_plane_prepare_disc_area(struct drm_crtc_state *c_state);
int atmel_hlcdc_plane_prepare_ahb_routing(struct drm_crtc_state *c_state);
void atmel_hlcdc_crtc_irq(struct drm_crtc *c); void atmel_hlcdc_crtc_irq(struct drm_crtc *c);
......
...@@ -59,6 +59,8 @@ struct atmel_hlcdc_plane_state { ...@@ -59,6 +59,8 @@ struct atmel_hlcdc_plane_state {
int disc_w; int disc_w;
int disc_h; int disc_h;
int ahb_id;
/* These fields are private and should not be touched */ /* These fields are private and should not be touched */
int bpp[ATMEL_HLCDC_MAX_PLANES]; int bpp[ATMEL_HLCDC_MAX_PLANES];
unsigned int offsets[ATMEL_HLCDC_MAX_PLANES]; unsigned int offsets[ATMEL_HLCDC_MAX_PLANES];
...@@ -361,8 +363,10 @@ atmel_hlcdc_plane_update_general_settings(struct atmel_hlcdc_plane *plane, ...@@ -361,8 +363,10 @@ atmel_hlcdc_plane_update_general_settings(struct atmel_hlcdc_plane *plane,
atmel_hlcdc_layer_update_cfg(&plane->layer, atmel_hlcdc_layer_update_cfg(&plane->layer,
ATMEL_HLCDC_LAYER_DMA_CFG_ID, ATMEL_HLCDC_LAYER_DMA_CFG_ID,
ATMEL_HLCDC_LAYER_DMA_BLEN_MASK, ATMEL_HLCDC_LAYER_DMA_BLEN_MASK |
ATMEL_HLCDC_LAYER_DMA_BLEN_INCR16); ATMEL_HLCDC_LAYER_DMA_SIF,
ATMEL_HLCDC_LAYER_DMA_BLEN_INCR16 |
state->ahb_id);
atmel_hlcdc_layer_update_cfg(&plane->layer, layout->general_config, atmel_hlcdc_layer_update_cfg(&plane->layer, layout->general_config,
ATMEL_HLCDC_LAYER_ITER2BL | ATMEL_HLCDC_LAYER_ITER2BL |
...@@ -437,6 +441,41 @@ static void atmel_hlcdc_plane_update_buffers(struct atmel_hlcdc_plane *plane, ...@@ -437,6 +441,41 @@ static void atmel_hlcdc_plane_update_buffers(struct atmel_hlcdc_plane *plane,
} }
} }
int atmel_hlcdc_plane_prepare_ahb_routing(struct drm_crtc_state *c_state)
{
unsigned int ahb_load[2] = { };
struct drm_plane *plane;
drm_atomic_crtc_state_for_each_plane(plane, c_state) {
struct atmel_hlcdc_plane_state *plane_state;
struct drm_plane_state *plane_s;
unsigned int pixels, load = 0;
int i;
plane_s = drm_atomic_get_plane_state(c_state->state, plane);
if (IS_ERR(plane_s))
return PTR_ERR(plane_s);
plane_state =
drm_plane_state_to_atmel_hlcdc_plane_state(plane_s);
pixels = (plane_state->src_w * plane_state->src_h) -
(plane_state->disc_w * plane_state->disc_h);
for (i = 0; i < plane_state->nplanes; i++)
load += pixels * plane_state->bpp[i];
if (ahb_load[0] <= ahb_load[1])
plane_state->ahb_id = 0;
else
plane_state->ahb_id = 1;
ahb_load[plane_state->ahb_id] += load;
}
return 0;
}
int int
atmel_hlcdc_plane_prepare_disc_area(struct drm_crtc_state *c_state) atmel_hlcdc_plane_prepare_disc_area(struct drm_crtc_state *c_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