diff options
Diffstat (limited to 'drivers/gpu/drm/stm/ltdc.c')
| -rw-r--r-- | drivers/gpu/drm/stm/ltdc.c | 96 | 
1 files changed, 61 insertions, 35 deletions
| diff --git a/drivers/gpu/drm/stm/ltdc.c b/drivers/gpu/drm/stm/ltdc.c index 7812094f93d6..65c3c79ad1d5 100644 --- a/drivers/gpu/drm/stm/ltdc.c +++ b/drivers/gpu/drm/stm/ltdc.c @@ -26,11 +26,12 @@  #include <drm/drm_device.h>  #include <drm/drm_fb_cma_helper.h>  #include <drm/drm_fourcc.h> +#include <drm/drm_gem_atomic_helper.h>  #include <drm/drm_gem_cma_helper.h> -#include <drm/drm_gem_framebuffer_helper.h>  #include <drm/drm_of.h>  #include <drm/drm_plane_helper.h>  #include <drm/drm_probe_helper.h> +#include <drm/drm_simple_kms_helper.h>  #include <drm/drm_vblank.h>  #include <video/videomode.h> @@ -525,13 +526,42 @@ static void ltdc_crtc_mode_set_nofb(struct drm_crtc *crtc)  {  	struct ltdc_device *ldev = crtc_to_ltdc(crtc);  	struct drm_device *ddev = crtc->dev; +	struct drm_connector_list_iter iter; +	struct drm_connector *connector = NULL; +	struct drm_encoder *encoder = NULL; +	struct drm_bridge *bridge = NULL;  	struct drm_display_mode *mode = &crtc->state->adjusted_mode;  	struct videomode vm;  	u32 hsync, vsync, accum_hbp, accum_vbp, accum_act_w, accum_act_h;  	u32 total_width, total_height; +	u32 bus_flags = 0;  	u32 val;  	int ret; +	/* get encoder from crtc */ +	drm_for_each_encoder(encoder, ddev) +		if (encoder->crtc == crtc) +			break; + +	if (encoder) { +		/* get bridge from encoder */ +		list_for_each_entry(bridge, &encoder->bridge_chain, chain_node) +			if (bridge->encoder == encoder) +				break; + +		/* Get the connector from encoder */ +		drm_connector_list_iter_begin(ddev, &iter); +		drm_for_each_connector_iter(connector, &iter) +			if (connector->encoder == encoder) +				break; +		drm_connector_list_iter_end(&iter); +	} + +	if (bridge && bridge->timings) +		bus_flags = bridge->timings->input_bus_flags; +	else if (connector) +		bus_flags = connector->display_info.bus_flags; +  	if (!pm_runtime_active(ddev->dev)) {  		ret = pm_runtime_get_sync(ddev->dev);  		if (ret) { @@ -567,10 +597,10 @@ static void ltdc_crtc_mode_set_nofb(struct drm_crtc *crtc)  	if (vm.flags & DISPLAY_FLAGS_VSYNC_HIGH)  		val |= GCR_VSPOL; -	if (vm.flags & DISPLAY_FLAGS_DE_LOW) +	if (bus_flags & DRM_BUS_FLAG_DE_LOW)  		val |= GCR_DEPOL; -	if (vm.flags & DISPLAY_FLAGS_PIXDATA_NEGEDGE) +	if (bus_flags & DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE)  		val |= GCR_PCPOL;  	reg_update_bits(ldev->regs, LTDC_GCR, @@ -720,9 +750,11 @@ static const struct drm_crtc_funcs ltdc_crtc_funcs = {   */  static int ltdc_plane_atomic_check(struct drm_plane *plane, -				   struct drm_plane_state *state) +				   struct drm_atomic_state *state)  { -	struct drm_framebuffer *fb = state->fb; +	struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state, +										 plane); +	struct drm_framebuffer *fb = new_plane_state->fb;  	u32 src_w, src_h;  	DRM_DEBUG_DRIVER("\n"); @@ -731,11 +763,11 @@ static int ltdc_plane_atomic_check(struct drm_plane *plane,  		return 0;  	/* convert src_ from 16:16 format */ -	src_w = state->src_w >> 16; -	src_h = state->src_h >> 16; +	src_w = new_plane_state->src_w >> 16; +	src_h = new_plane_state->src_h >> 16;  	/* Reject scaling */ -	if (src_w != state->crtc_w || src_h != state->crtc_h) { +	if (src_w != new_plane_state->crtc_w || src_h != new_plane_state->crtc_h) {  		DRM_ERROR("Scaling is not supported");  		return -EINVAL;  	} @@ -744,36 +776,37 @@ static int ltdc_plane_atomic_check(struct drm_plane *plane,  }  static void ltdc_plane_atomic_update(struct drm_plane *plane, -				     struct drm_plane_state *oldstate) +				     struct drm_atomic_state *state)  {  	struct ltdc_device *ldev = plane_to_ltdc(plane); -	struct drm_plane_state *state = plane->state; -	struct drm_framebuffer *fb = state->fb; +	struct drm_plane_state *newstate = drm_atomic_get_new_plane_state(state, +									  plane); +	struct drm_framebuffer *fb = newstate->fb;  	u32 lofs = plane->index * LAY_OFS; -	u32 x0 = state->crtc_x; -	u32 x1 = state->crtc_x + state->crtc_w - 1; -	u32 y0 = state->crtc_y; -	u32 y1 = state->crtc_y + state->crtc_h - 1; +	u32 x0 = newstate->crtc_x; +	u32 x1 = newstate->crtc_x + newstate->crtc_w - 1; +	u32 y0 = newstate->crtc_y; +	u32 y1 = newstate->crtc_y + newstate->crtc_h - 1;  	u32 src_x, src_y, src_w, src_h;  	u32 val, pitch_in_bytes, line_length, paddr, ahbp, avbp, bpcr;  	enum ltdc_pix_fmt pf; -	if (!state->crtc || !fb) { +	if (!newstate->crtc || !fb) {  		DRM_DEBUG_DRIVER("fb or crtc NULL");  		return;  	}  	/* convert src_ from 16:16 format */ -	src_x = state->src_x >> 16; -	src_y = state->src_y >> 16; -	src_w = state->src_w >> 16; -	src_h = state->src_h >> 16; +	src_x = newstate->src_x >> 16; +	src_y = newstate->src_y >> 16; +	src_w = newstate->src_w >> 16; +	src_h = newstate->src_h >> 16;  	DRM_DEBUG_DRIVER("plane:%d fb:%d (%dx%d)@(%d,%d) -> (%dx%d)@(%d,%d)\n",  			 plane->base.id, fb->base.id,  			 src_w, src_h, src_x, src_y, -			 state->crtc_w, state->crtc_h, -			 state->crtc_x, state->crtc_y); +			 newstate->crtc_w, newstate->crtc_h, +			 newstate->crtc_x, newstate->crtc_y);  	bpcr = reg_read(ldev->regs, LTDC_BPCR);  	ahbp = (bpcr & BPCR_AHBP) >> 16; @@ -832,7 +865,7 @@ static void ltdc_plane_atomic_update(struct drm_plane *plane,  	reg_update_bits(ldev->regs, LTDC_L1CFBLNR + lofs, LXCFBLNR_CFBLN, val);  	/* Sets the FB address */ -	paddr = (u32)drm_fb_cma_get_gem_addr(fb, state, 0); +	paddr = (u32)drm_fb_cma_get_gem_addr(fb, newstate, 0);  	DRM_DEBUG_DRIVER("fb: phys 0x%08x", paddr);  	reg_write(ldev->regs, LTDC_L1CFBAR + lofs, paddr); @@ -858,8 +891,10 @@ static void ltdc_plane_atomic_update(struct drm_plane *plane,  }  static void ltdc_plane_atomic_disable(struct drm_plane *plane, -				      struct drm_plane_state *oldstate) +				      struct drm_atomic_state *state)  { +	struct drm_plane_state *oldstate = drm_atomic_get_old_plane_state(state, +									  plane);  	struct ltdc_device *ldev = plane_to_ltdc(plane);  	u32 lofs = plane->index * LAY_OFS; @@ -911,7 +946,7 @@ static const struct drm_plane_funcs ltdc_plane_funcs = {  };  static const struct drm_plane_helper_funcs ltdc_plane_helper_funcs = { -	.prepare_fb = drm_gem_fb_prepare_fb, +	.prepare_fb = drm_gem_plane_helper_prepare_fb,  	.atomic_check = ltdc_plane_atomic_check,  	.atomic_update = ltdc_plane_atomic_update,  	.atomic_disable = ltdc_plane_atomic_disable, @@ -1020,14 +1055,6 @@ cleanup:  	return ret;  } -/* - * DRM_ENCODER - */ - -static const struct drm_encoder_funcs ltdc_encoder_funcs = { -	.destroy = drm_encoder_cleanup, -}; -  static void ltdc_encoder_disable(struct drm_encoder *encoder)  {  	struct drm_device *ddev = encoder->dev; @@ -1088,8 +1115,7 @@ static int ltdc_encoder_init(struct drm_device *ddev, struct drm_bridge *bridge)  	encoder->possible_crtcs = CRTC_MASK;  	encoder->possible_clones = 0;	/* No cloning support */ -	drm_encoder_init(ddev, encoder, <dc_encoder_funcs, -			 DRM_MODE_ENCODER_DPI, NULL); +	drm_simple_encoder_init(ddev, encoder, DRM_MODE_ENCODER_DPI);  	drm_encoder_helper_add(encoder, <dc_encoder_helper_funcs); | 
