@@ -106,7 +106,7 @@ static void hdlcd_crtc_mode_set_nofb(struct drm_crtc *crtc)
106
106
struct hdlcd_drm_private * hdlcd = crtc_to_hdlcd_priv (crtc );
107
107
struct drm_display_mode * m = & crtc -> state -> adjusted_mode ;
108
108
struct videomode vm ;
109
- unsigned int polarities , line_length , err ;
109
+ unsigned int polarities , err ;
110
110
111
111
vm .vfront_porch = m -> crtc_vsync_start - m -> crtc_vdisplay ;
112
112
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)
122
122
if (m -> flags & DRM_MODE_FLAG_PVSYNC )
123
123
polarities |= HDLCD_POLARITY_VSYNC ;
124
124
125
- line_length = crtc -> primary -> state -> fb -> pitches [0 ];
126
-
127
125
/* Allow max number of outstanding requests and largest burst size */
128
126
hdlcd_write (hdlcd , HDLCD_REG_BUS_OPTIONS ,
129
127
HDLCD_BUS_MAX_OUTSTAND | HDLCD_BUS_BURST_16 );
130
128
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 );
134
129
hdlcd_write (hdlcd , HDLCD_REG_V_DATA , m -> crtc_vdisplay - 1 );
135
130
hdlcd_write (hdlcd , HDLCD_REG_V_BACK_PORCH , vm .vback_porch - 1 );
136
131
hdlcd_write (hdlcd , HDLCD_REG_V_FRONT_PORCH , vm .vfront_porch - 1 );
137
132
hdlcd_write (hdlcd , HDLCD_REG_V_SYNC , vm .vsync_len - 1 );
133
+ hdlcd_write (hdlcd , HDLCD_REG_H_DATA , m -> crtc_hdisplay - 1 );
138
134
hdlcd_write (hdlcd , HDLCD_REG_H_BACK_PORCH , vm .hback_porch - 1 );
139
135
hdlcd_write (hdlcd , HDLCD_REG_H_FRONT_PORCH , vm .hfront_porch - 1 );
140
136
hdlcd_write (hdlcd , HDLCD_REG_H_SYNC , vm .hsync_len - 1 );
141
- hdlcd_write (hdlcd , HDLCD_REG_H_DATA , m -> crtc_hdisplay - 1 );
142
137
hdlcd_write (hdlcd , HDLCD_REG_POLARITIES , polarities );
143
138
144
139
err = hdlcd_set_pxl_fmt (crtc );
@@ -153,20 +148,19 @@ static void hdlcd_crtc_enable(struct drm_crtc *crtc)
153
148
struct hdlcd_drm_private * hdlcd = crtc_to_hdlcd_priv (crtc );
154
149
155
150
clk_prepare_enable (hdlcd -> clk );
151
+ hdlcd_crtc_mode_set_nofb (crtc );
156
152
hdlcd_write (hdlcd , HDLCD_REG_COMMAND , 1 );
157
- drm_crtc_vblank_on (crtc );
158
153
}
159
154
160
155
static void hdlcd_crtc_disable (struct drm_crtc * crtc )
161
156
{
162
157
struct hdlcd_drm_private * hdlcd = crtc_to_hdlcd_priv (crtc );
163
158
164
- if (!crtc -> primary -> fb )
159
+ if (!crtc -> state -> active )
165
160
return ;
166
161
167
162
hdlcd_write (hdlcd , HDLCD_REG_COMMAND , 0 );
168
163
clk_disable_unprepare (hdlcd -> clk );
169
- drm_crtc_vblank_off (crtc );
170
164
}
171
165
172
166
static int hdlcd_crtc_atomic_check (struct drm_crtc * crtc ,
@@ -188,7 +182,6 @@ static int hdlcd_crtc_atomic_check(struct drm_crtc *crtc,
188
182
static void hdlcd_crtc_atomic_begin (struct drm_crtc * crtc ,
189
183
struct drm_crtc_state * state )
190
184
{
191
- struct hdlcd_drm_private * hdlcd = crtc_to_hdlcd_priv (crtc );
192
185
struct drm_pending_vblank_event * event = crtc -> state -> event ;
193
186
194
187
if (event ) {
@@ -232,6 +225,15 @@ static const struct drm_crtc_helper_funcs hdlcd_crtc_helper_funcs = {
232
225
static int hdlcd_plane_atomic_check (struct drm_plane * plane ,
233
226
struct drm_plane_state * state )
234
227
{
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
+
235
237
return 0 ;
236
238
}
237
239
@@ -240,20 +242,31 @@ static void hdlcd_plane_atomic_update(struct drm_plane *plane,
240
242
{
241
243
struct hdlcd_drm_private * hdlcd ;
242
244
struct drm_gem_cma_object * gem ;
245
+ unsigned int depth , bpp ;
246
+ u32 src_w , src_h , dest_w , dest_h ;
243
247
dma_addr_t scanout_start ;
244
248
245
- if (!plane -> state -> crtc || ! plane -> state -> fb )
249
+ if (!plane -> state -> fb )
246
250
return ;
247
251
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 ;
249
257
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 );
251
266
hdlcd_write (hdlcd , HDLCD_REG_FB_BASE , scanout_start );
252
267
}
253
268
254
269
static const struct drm_plane_helper_funcs hdlcd_plane_helper_funcs = {
255
- .prepare_fb = NULL ,
256
- .cleanup_fb = NULL ,
257
270
.atomic_check = hdlcd_plane_atomic_check ,
258
271
.atomic_update = hdlcd_plane_atomic_update ,
259
272
};
0 commit comments