Skip to content

Commit 96ebb1f

Browse files
committed
drm: hdlcd: Cleanup the atomic plane operations
Harden the plane_check() code to drop attempts at scaling because that is not supported. Make hdlcd_plane_atomic_update() set the pitch and line length registers that correctly reflect the plane's values. And make hdlcd_crtc_mode_set_nofb() a helper function for hdlcd_crtc_enable() rather than an exposed hook. Cc: Daniel Vetter <[email protected]> Signed-off-by: Liviu Dudau <[email protected]>
1 parent 38c8c22 commit 96ebb1f

File tree

2 files changed

+29
-17
lines changed

2 files changed

+29
-17
lines changed

drivers/gpu/drm/arm/hdlcd_crtc.c

Lines changed: 29 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ static void hdlcd_crtc_mode_set_nofb(struct drm_crtc *crtc)
106106
struct hdlcd_drm_private *hdlcd = crtc_to_hdlcd_priv(crtc);
107107
struct drm_display_mode *m = &crtc->state->adjusted_mode;
108108
struct videomode vm;
109-
unsigned int polarities, line_length, err;
109+
unsigned int polarities, err;
110110

111111
vm.vfront_porch = m->crtc_vsync_start - m->crtc_vdisplay;
112112
vm.vback_porch = m->crtc_vtotal - m->crtc_vsync_end;
@@ -122,23 +122,18 @@ static void hdlcd_crtc_mode_set_nofb(struct drm_crtc *crtc)
122122
if (m->flags & DRM_MODE_FLAG_PVSYNC)
123123
polarities |= HDLCD_POLARITY_VSYNC;
124124

125-
line_length = crtc->primary->state->fb->pitches[0];
126-
127125
/* Allow max number of outstanding requests and largest burst size */
128126
hdlcd_write(hdlcd, HDLCD_REG_BUS_OPTIONS,
129127
HDLCD_BUS_MAX_OUTSTAND | HDLCD_BUS_BURST_16);
130128

131-
hdlcd_write(hdlcd, HDLCD_REG_FB_LINE_LENGTH, line_length);
132-
hdlcd_write(hdlcd, HDLCD_REG_FB_LINE_PITCH, line_length);
133-
hdlcd_write(hdlcd, HDLCD_REG_FB_LINE_COUNT, m->crtc_vdisplay - 1);
134129
hdlcd_write(hdlcd, HDLCD_REG_V_DATA, m->crtc_vdisplay - 1);
135130
hdlcd_write(hdlcd, HDLCD_REG_V_BACK_PORCH, vm.vback_porch - 1);
136131
hdlcd_write(hdlcd, HDLCD_REG_V_FRONT_PORCH, vm.vfront_porch - 1);
137132
hdlcd_write(hdlcd, HDLCD_REG_V_SYNC, vm.vsync_len - 1);
133+
hdlcd_write(hdlcd, HDLCD_REG_H_DATA, m->crtc_hdisplay - 1);
138134
hdlcd_write(hdlcd, HDLCD_REG_H_BACK_PORCH, vm.hback_porch - 1);
139135
hdlcd_write(hdlcd, HDLCD_REG_H_FRONT_PORCH, vm.hfront_porch - 1);
140136
hdlcd_write(hdlcd, HDLCD_REG_H_SYNC, vm.hsync_len - 1);
141-
hdlcd_write(hdlcd, HDLCD_REG_H_DATA, m->crtc_hdisplay - 1);
142137
hdlcd_write(hdlcd, HDLCD_REG_POLARITIES, polarities);
143138

144139
err = hdlcd_set_pxl_fmt(crtc);
@@ -153,20 +148,19 @@ static void hdlcd_crtc_enable(struct drm_crtc *crtc)
153148
struct hdlcd_drm_private *hdlcd = crtc_to_hdlcd_priv(crtc);
154149

155150
clk_prepare_enable(hdlcd->clk);
151+
hdlcd_crtc_mode_set_nofb(crtc);
156152
hdlcd_write(hdlcd, HDLCD_REG_COMMAND, 1);
157-
drm_crtc_vblank_on(crtc);
158153
}
159154

160155
static void hdlcd_crtc_disable(struct drm_crtc *crtc)
161156
{
162157
struct hdlcd_drm_private *hdlcd = crtc_to_hdlcd_priv(crtc);
163158

164-
if (!crtc->primary->fb)
159+
if (!crtc->state->active)
165160
return;
166161

167162
hdlcd_write(hdlcd, HDLCD_REG_COMMAND, 0);
168163
clk_disable_unprepare(hdlcd->clk);
169-
drm_crtc_vblank_off(crtc);
170164
}
171165

172166
static int hdlcd_crtc_atomic_check(struct drm_crtc *crtc,
@@ -188,7 +182,6 @@ static int hdlcd_crtc_atomic_check(struct drm_crtc *crtc,
188182
static void hdlcd_crtc_atomic_begin(struct drm_crtc *crtc,
189183
struct drm_crtc_state *state)
190184
{
191-
struct hdlcd_drm_private *hdlcd = crtc_to_hdlcd_priv(crtc);
192185
struct drm_pending_vblank_event *event = crtc->state->event;
193186

194187
if (event) {
@@ -232,6 +225,15 @@ static const struct drm_crtc_helper_funcs hdlcd_crtc_helper_funcs = {
232225
static int hdlcd_plane_atomic_check(struct drm_plane *plane,
233226
struct drm_plane_state *state)
234227
{
228+
u32 src_w, src_h;
229+
230+
src_w = state->src_w >> 16;
231+
src_h = state->src_h >> 16;
232+
233+
/* we can't do any scaling of the plane source */
234+
if ((src_w != state->crtc_w) || (src_h != state->crtc_h))
235+
return -EINVAL;
236+
235237
return 0;
236238
}
237239

@@ -240,20 +242,31 @@ static void hdlcd_plane_atomic_update(struct drm_plane *plane,
240242
{
241243
struct hdlcd_drm_private *hdlcd;
242244
struct drm_gem_cma_object *gem;
245+
unsigned int depth, bpp;
246+
u32 src_w, src_h, dest_w, dest_h;
243247
dma_addr_t scanout_start;
244248

245-
if (!plane->state->crtc || !plane->state->fb)
249+
if (!plane->state->fb)
246250
return;
247251

248-
hdlcd = crtc_to_hdlcd_priv(plane->state->crtc);
252+
drm_fb_get_bpp_depth(plane->state->fb->pixel_format, &depth, &bpp);
253+
src_w = plane->state->src_w >> 16;
254+
src_h = plane->state->src_h >> 16;
255+
dest_w = plane->state->crtc_w;
256+
dest_h = plane->state->crtc_h;
249257
gem = drm_fb_cma_get_gem_obj(plane->state->fb, 0);
250-
scanout_start = gem->paddr;
258+
scanout_start = gem->paddr + plane->state->fb->offsets[0] +
259+
plane->state->crtc_y * plane->state->fb->pitches[0] +
260+
plane->state->crtc_x * bpp / 8;
261+
262+
hdlcd = plane->dev->dev_private;
263+
hdlcd_write(hdlcd, HDLCD_REG_FB_LINE_LENGTH, plane->state->fb->pitches[0]);
264+
hdlcd_write(hdlcd, HDLCD_REG_FB_LINE_PITCH, plane->state->fb->pitches[0]);
265+
hdlcd_write(hdlcd, HDLCD_REG_FB_LINE_COUNT, dest_h - 1);
251266
hdlcd_write(hdlcd, HDLCD_REG_FB_BASE, scanout_start);
252267
}
253268

254269
static const struct drm_plane_helper_funcs hdlcd_plane_helper_funcs = {
255-
.prepare_fb = NULL,
256-
.cleanup_fb = NULL,
257270
.atomic_check = hdlcd_plane_atomic_check,
258271
.atomic_update = hdlcd_plane_atomic_update,
259272
};

drivers/gpu/drm/arm/hdlcd_drv.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ struct hdlcd_drm_private {
99
void __iomem *mmio;
1010
struct clk *clk;
1111
struct drm_fbdev_cma *fbdev;
12-
struct drm_framebuffer *fb;
1312
struct drm_crtc crtc;
1413
struct drm_plane *plane;
1514
struct drm_atomic_state *state;

0 commit comments

Comments
 (0)