summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/stm/ltdc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/stm/ltdc.c')
-rw-r--r--drivers/gpu/drm/stm/ltdc.c96
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, &ltdc_encoder_funcs,
- DRM_MODE_ENCODER_DPI, NULL);
+ drm_simple_encoder_init(ddev, encoder, DRM_MODE_ENCODER_DPI);
drm_encoder_helper_add(encoder, &ltdc_encoder_helper_funcs);