aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBeeresh Gopal <gbeeresh@codeaurora.org>2014-12-08 10:48:59 -0500
committerRob Clark <robdclark@gmail.com>2015-02-01 15:30:35 -0500
commitb1b1c74e36b369dceaa0ea98ac543e8c13c720ee (patch)
tree6cac5fb6d36934ca02ea0b9c1c8f162ca1d2eeaa
parentf8d9b5156e966e701cb17c623ffd6ebe35cc3157 (diff)
drm/msm/mdp4: add YUV format support
The patch add support for YUV frame format for MDP4 platform. Signed-off-by: Beeresh Gopal <gbeeresh@codeaurora.org> Signed-off-by: Stephane Viau <sviau@codeaurora.org> Signed-off-by: Rob Clark <robdclark@gmail.com>
-rw-r--r--drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c104
1 files changed, 95 insertions, 9 deletions
diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c
index 1e5ebe83647d..cde25009203a 100644
--- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c
+++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c
@@ -17,6 +17,8 @@
17 17
18#include "mdp4_kms.h" 18#include "mdp4_kms.h"
19 19
20#define DOWN_SCALE_MAX 8
21#define UP_SCALE_MAX 8
20 22
21struct mdp4_plane { 23struct mdp4_plane {
22 struct drm_plane base; 24 struct drm_plane base;
@@ -136,10 +138,6 @@ static void mdp4_plane_set_scanout(struct drm_plane *plane,
136 struct mdp4_plane *mdp4_plane = to_mdp4_plane(plane); 138 struct mdp4_plane *mdp4_plane = to_mdp4_plane(plane);
137 struct mdp4_kms *mdp4_kms = get_kms(plane); 139 struct mdp4_kms *mdp4_kms = get_kms(plane);
138 enum mdp4_pipe pipe = mdp4_plane->pipe; 140 enum mdp4_pipe pipe = mdp4_plane->pipe;
139 uint32_t iova = msm_framebuffer_iova(fb, mdp4_kms->id, 0);
140
141 DBG("%s: set_scanout: %08x (%u)", mdp4_plane->name,
142 iova, fb->pitches[0]);
143 141
144 mdp4_write(mdp4_kms, REG_MDP4_PIPE_SRC_STRIDE_A(pipe), 142 mdp4_write(mdp4_kms, REG_MDP4_PIPE_SRC_STRIDE_A(pipe),
145 MDP4_PIPE_SRC_STRIDE_A_P0(fb->pitches[0]) | 143 MDP4_PIPE_SRC_STRIDE_A_P0(fb->pitches[0]) |
@@ -149,11 +147,45 @@ static void mdp4_plane_set_scanout(struct drm_plane *plane,
149 MDP4_PIPE_SRC_STRIDE_B_P2(fb->pitches[2]) | 147 MDP4_PIPE_SRC_STRIDE_B_P2(fb->pitches[2]) |
150 MDP4_PIPE_SRC_STRIDE_B_P3(fb->pitches[3])); 148 MDP4_PIPE_SRC_STRIDE_B_P3(fb->pitches[3]));
151 149
152 mdp4_write(mdp4_kms, REG_MDP4_PIPE_SRCP0_BASE(pipe), iova); 150 mdp4_write(mdp4_kms, REG_MDP4_PIPE_SRCP0_BASE(pipe),
151 msm_framebuffer_iova(fb, mdp4_kms->id, 0));
152 mdp4_write(mdp4_kms, REG_MDP4_PIPE_SRCP1_BASE(pipe),
153 msm_framebuffer_iova(fb, mdp4_kms->id, 1));
154 mdp4_write(mdp4_kms, REG_MDP4_PIPE_SRCP2_BASE(pipe),
155 msm_framebuffer_iova(fb, mdp4_kms->id, 2));
156 mdp4_write(mdp4_kms, REG_MDP4_PIPE_SRCP3_BASE(pipe),
157 msm_framebuffer_iova(fb, mdp4_kms->id, 3));
153 158
154 plane->fb = fb; 159 plane->fb = fb;
155} 160}
156 161
162static void mdp4_write_csc_config(struct mdp4_kms *mdp4_kms,
163 enum mdp4_pipe pipe, struct csc_cfg *csc)
164{
165 int i;
166
167 for (i = 0; i < ARRAY_SIZE(csc->matrix); i++) {
168 mdp4_write(mdp4_kms, REG_MDP4_PIPE_CSC_MV(pipe, i),
169 csc->matrix[i]);
170 }
171
172 for (i = 0; i < ARRAY_SIZE(csc->post_bias) ; i++) {
173 mdp4_write(mdp4_kms, REG_MDP4_PIPE_CSC_PRE_BV(pipe, i),
174 csc->pre_bias[i]);
175
176 mdp4_write(mdp4_kms, REG_MDP4_PIPE_CSC_POST_BV(pipe, i),
177 csc->post_bias[i]);
178 }
179
180 for (i = 0; i < ARRAY_SIZE(csc->post_clamp) ; i++) {
181 mdp4_write(mdp4_kms, REG_MDP4_PIPE_CSC_PRE_LV(pipe, i),
182 csc->pre_clamp[i]);
183
184 mdp4_write(mdp4_kms, REG_MDP4_PIPE_CSC_POST_LV(pipe, i),
185 csc->post_clamp[i]);
186 }
187}
188
157#define MDP4_VG_PHASE_STEP_DEFAULT 0x20000000 189#define MDP4_VG_PHASE_STEP_DEFAULT 0x20000000
158 190
159static int mdp4_plane_mode_set(struct drm_plane *plane, 191static int mdp4_plane_mode_set(struct drm_plane *plane,
@@ -163,6 +195,7 @@ static int mdp4_plane_mode_set(struct drm_plane *plane,
163 uint32_t src_x, uint32_t src_y, 195 uint32_t src_x, uint32_t src_y,
164 uint32_t src_w, uint32_t src_h) 196 uint32_t src_w, uint32_t src_h)
165{ 197{
198 struct drm_device *dev = plane->dev;
166 struct mdp4_plane *mdp4_plane = to_mdp4_plane(plane); 199 struct mdp4_plane *mdp4_plane = to_mdp4_plane(plane);
167 struct mdp4_kms *mdp4_kms = get_kms(plane); 200 struct mdp4_kms *mdp4_kms = get_kms(plane);
168 enum mdp4_pipe pipe = mdp4_plane->pipe; 201 enum mdp4_pipe pipe = mdp4_plane->pipe;
@@ -186,14 +219,59 @@ static int mdp4_plane_mode_set(struct drm_plane *plane,
186 fb->base.id, src_x, src_y, src_w, src_h, 219 fb->base.id, src_x, src_y, src_w, src_h,
187 crtc->base.id, crtc_x, crtc_y, crtc_w, crtc_h); 220 crtc->base.id, crtc_x, crtc_y, crtc_w, crtc_h);
188 221
222 format = to_mdp_format(msm_framebuffer_format(fb));
223
224 if (src_w > (crtc_w * DOWN_SCALE_MAX)) {
225 dev_err(dev->dev, "Width down scaling exceeds limits!\n");
226 return -ERANGE;
227 }
228
229 if (src_h > (crtc_h * DOWN_SCALE_MAX)) {
230 dev_err(dev->dev, "Height down scaling exceeds limits!\n");
231 return -ERANGE;
232 }
233
234 if (crtc_w > (src_w * UP_SCALE_MAX)) {
235 dev_err(dev->dev, "Width up scaling exceeds limits!\n");
236 return -ERANGE;
237 }
238
239 if (crtc_h > (src_h * UP_SCALE_MAX)) {
240 dev_err(dev->dev, "Height up scaling exceeds limits!\n");
241 return -ERANGE;
242 }
243
189 if (src_w != crtc_w) { 244 if (src_w != crtc_w) {
245 uint32_t sel_unit = SCALE_FIR;
190 op_mode |= MDP4_PIPE_OP_MODE_SCALEX_EN; 246 op_mode |= MDP4_PIPE_OP_MODE_SCALEX_EN;
191 /* TODO calc phasex_step */ 247
248 if (MDP_FORMAT_IS_YUV(format)) {
249 if (crtc_w > src_w)
250 sel_unit = SCALE_PIXEL_RPT;
251 else if (crtc_w <= (src_w / 4))
252 sel_unit = SCALE_MN_PHASE;
253
254 op_mode |= MDP4_PIPE_OP_MODE_SCALEX_UNIT_SEL(sel_unit);
255 phasex_step = mult_frac(MDP4_VG_PHASE_STEP_DEFAULT,
256 src_w, crtc_w);
257 }
192 } 258 }
193 259
194 if (src_h != crtc_h) { 260 if (src_h != crtc_h) {
261 uint32_t sel_unit = SCALE_FIR;
195 op_mode |= MDP4_PIPE_OP_MODE_SCALEY_EN; 262 op_mode |= MDP4_PIPE_OP_MODE_SCALEY_EN;
196 /* TODO calc phasey_step */ 263
264 if (MDP_FORMAT_IS_YUV(format)) {
265
266 if (crtc_h > src_h)
267 sel_unit = SCALE_PIXEL_RPT;
268 else if (crtc_h <= (src_h / 4))
269 sel_unit = SCALE_MN_PHASE;
270
271 op_mode |= MDP4_PIPE_OP_MODE_SCALEY_UNIT_SEL(sel_unit);
272 phasey_step = mult_frac(MDP4_VG_PHASE_STEP_DEFAULT,
273 src_h, crtc_h);
274 }
197 } 275 }
198 276
199 mdp4_write(mdp4_kms, REG_MDP4_PIPE_SRC_SIZE(pipe), 277 mdp4_write(mdp4_kms, REG_MDP4_PIPE_SRC_SIZE(pipe),
@@ -214,8 +292,6 @@ static int mdp4_plane_mode_set(struct drm_plane *plane,
214 292
215 mdp4_plane_set_scanout(plane, fb); 293 mdp4_plane_set_scanout(plane, fb);
216 294
217 format = to_mdp_format(msm_framebuffer_format(fb));
218
219 mdp4_write(mdp4_kms, REG_MDP4_PIPE_SRC_FORMAT(pipe), 295 mdp4_write(mdp4_kms, REG_MDP4_PIPE_SRC_FORMAT(pipe),
220 MDP4_PIPE_SRC_FORMAT_A_BPC(format->bpc_a) | 296 MDP4_PIPE_SRC_FORMAT_A_BPC(format->bpc_a) |
221 MDP4_PIPE_SRC_FORMAT_R_BPC(format->bpc_r) | 297 MDP4_PIPE_SRC_FORMAT_R_BPC(format->bpc_r) |
@@ -224,6 +300,8 @@ static int mdp4_plane_mode_set(struct drm_plane *plane,
224 COND(format->alpha_enable, MDP4_PIPE_SRC_FORMAT_ALPHA_ENABLE) | 300 COND(format->alpha_enable, MDP4_PIPE_SRC_FORMAT_ALPHA_ENABLE) |
225 MDP4_PIPE_SRC_FORMAT_CPP(format->cpp - 1) | 301 MDP4_PIPE_SRC_FORMAT_CPP(format->cpp - 1) |
226 MDP4_PIPE_SRC_FORMAT_UNPACK_COUNT(format->unpack_count - 1) | 302 MDP4_PIPE_SRC_FORMAT_UNPACK_COUNT(format->unpack_count - 1) |
303 MDP4_PIPE_SRC_FORMAT_FETCH_PLANES(format->fetch_type) |
304 MDP4_PIPE_SRC_FORMAT_CHROMA_SAMP(format->chroma_sample) |
227 COND(format->unpack_tight, MDP4_PIPE_SRC_FORMAT_UNPACK_TIGHT)); 305 COND(format->unpack_tight, MDP4_PIPE_SRC_FORMAT_UNPACK_TIGHT));
228 306
229 mdp4_write(mdp4_kms, REG_MDP4_PIPE_SRC_UNPACK(pipe), 307 mdp4_write(mdp4_kms, REG_MDP4_PIPE_SRC_UNPACK(pipe),
@@ -232,6 +310,14 @@ static int mdp4_plane_mode_set(struct drm_plane *plane,
232 MDP4_PIPE_SRC_UNPACK_ELEM2(format->unpack[2]) | 310 MDP4_PIPE_SRC_UNPACK_ELEM2(format->unpack[2]) |
233 MDP4_PIPE_SRC_UNPACK_ELEM3(format->unpack[3])); 311 MDP4_PIPE_SRC_UNPACK_ELEM3(format->unpack[3]));
234 312
313 if (MDP_FORMAT_IS_YUV(format)) {
314 struct csc_cfg *csc = mdp_get_default_csc_cfg(CSC_YUV2RGB);
315
316 op_mode |= MDP4_PIPE_OP_MODE_SRC_YCBCR;
317 op_mode |= MDP4_PIPE_OP_MODE_CSC_EN;
318 mdp4_write_csc_config(mdp4_kms, pipe, csc);
319 }
320
235 mdp4_write(mdp4_kms, REG_MDP4_PIPE_OP_MODE(pipe), op_mode); 321 mdp4_write(mdp4_kms, REG_MDP4_PIPE_OP_MODE(pipe), op_mode);
236 mdp4_write(mdp4_kms, REG_MDP4_PIPE_PHASEX_STEP(pipe), phasex_step); 322 mdp4_write(mdp4_kms, REG_MDP4_PIPE_PHASEX_STEP(pipe), phasex_step);
237 mdp4_write(mdp4_kms, REG_MDP4_PIPE_PHASEY_STEP(pipe), phasey_step); 323 mdp4_write(mdp4_kms, REG_MDP4_PIPE_PHASEY_STEP(pipe), phasey_step);