blob: 19cedd3aba22d8f92a73c324df2414bcabeb9752 [file] [log] [blame]
Narendra Muppalla1b0b3352015-09-29 10:16:51 -07001/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 */
12
13#include "sde_hw_sspp.h"
14#include "sde_hwio.h"
15#include "sde_hw_catalog.h"
16#include "sde_hw_lm.h"
17
18#define SDE_MDP_FETCH_CONFIG_RESET_VALUE 0x00000087
19
20/* SDE_SSPP_SRC */
21#define SSPP_SRC_SIZE 0x00
22#define SSPP_SRC_XY 0x08
23#define SSPP_OUT_SIZE 0x0c
24#define SSPP_OUT_XY 0x10
25#define SSPP_SRC0_ADDR 0x14
26#define SSPP_SRC1_ADDR 0x18
27#define SSPP_SRC2_ADDR 0x1C
28#define SSPP_SRC3_ADDR 0x20
29#define SSPP_SRC_YSTRIDE0 0x24
30#define SSPP_SRC_YSTRIDE1 0x28
31#define SSPP_SRC_FORMAT 0x30
32#define SSPP_SRC_UNPACK_PATTERN 0x34
33#define SSPP_SRC_OP_MODE 0x38
34#define MDSS_MDP_OP_DEINTERLACE BIT(22)
35
36#define MDSS_MDP_OP_DEINTERLACE_ODD BIT(23)
37#define MDSS_MDP_OP_IGC_ROM_1 BIT(18)
38#define MDSS_MDP_OP_IGC_ROM_0 BIT(17)
39#define MDSS_MDP_OP_IGC_EN BIT(16)
40#define MDSS_MDP_OP_FLIP_UD BIT(14)
41#define MDSS_MDP_OP_FLIP_LR BIT(13)
42#define MDSS_MDP_OP_BWC_EN BIT(0)
43#define MDSS_MDP_OP_PE_OVERRIDE BIT(31)
44#define MDSS_MDP_OP_BWC_LOSSLESS (0 << 1)
45#define MDSS_MDP_OP_BWC_Q_HIGH (1 << 1)
46#define MDSS_MDP_OP_BWC_Q_MED (2 << 1)
47
48#define SSPP_SRC_CONSTANT_COLOR 0x3c
49#define SSPP_FETCH_CONFIG 0x048
50#define SSPP_DANGER_LUT 0x60
51#define SSPP_SAFE_LUT 0x64
52#define SSPP_CREQ_LUT 0x68
53#define SSPP_DECIMATION_CONFIG 0xB4
54#define SSPP_SRC_ADDR_SW_STATUS 0x70
55#define SSPP_SW_PIX_EXT_C0_LR 0x100
56#define SSPP_SW_PIX_EXT_C0_TB 0x104
57#define SSPP_SW_PIX_EXT_C0_REQ_PIXELS 0x108
58#define SSPP_SW_PIX_EXT_C1C2_LR 0x110
59#define SSPP_SW_PIX_EXT_C1C2_TB 0x114
60#define SSPP_SW_PIX_EXT_C1C2_REQ_PIXELS 0x118
61#define SSPP_SW_PIX_EXT_C3_LR 0x120
62#define SSPP_SW_PIX_EXT_C3_TB 0x124
63#define SSPP_SW_PIX_EXT_C3_REQ_PIXELS 0x128
64#define SSPP_UBWC_ERROR_STATUS 0x138
65#define SSPP_VIG_OP_MODE 0x200
66
67/* SDE_SSPP_SCALAR_QSEED2 */
68#define SCALE_CONFIG 0x04
69#define COMP0_3_PHASE_STEP_X 0x10
70#define COMP0_3_PHASE_STEP_Y 0x14
71#define COMP1_2_PHASE_STEP_X 0x18
72#define COMP1_2_PHASE_STEP_Y 0x1c
73#define COMP0_3_INIT_PHASE_X 0x20
74#define COMP0_3_INIT_PHASE_Y 0x24
75#define COMP1_2_INIT_PHASE_X 0x28
76#define COMP1_2_INIT_PHASE_Y 0x2C
77#define VIG_0_QSEED2_SHARP 0x30
78
79#define VIG_0_CSC_1_MATRIX_COEFF_0 0x20
80#define VIG_0_CSC_1_COMP_0_PRE_CLAMP 0x34
81#define VIG_0_CSC_1_COMP_0_POST_CLAMP 0x40
82#define VIG_0_CSC_1_COMP_0_PRE_BIAS 0x4C
83#define VIG_0_CSC_1_COMP_0_POST_BIAS 0x60
84
85/*
86 * MDP Solid fill configuration
87 * argb8888
88 */
89#define SSPP_SOLID_FILL 0x4037ff
90
91enum {
92 CSC = 0x1,
93 PA,
94 HIST,
95 SKIN_COL,
96 FOIL,
97 SKY_COL,
98 MEM_PROT_HUE,
99 MEM_PROT_SAT,
100 MEM_PROT_VAL,
101 MEM_PROT_CONT,
102 MEM_PROT_BLEND,
103 PA_SAT_ADJ
104};
105
106static inline int _sspp_subblk_offset(struct sde_hw_pipe *ctx,
107 int s_id,
108 u32 *idx)
109{
110 int rc = 0;
111 const struct sde_sspp_sub_blks *sblk = ctx->cap->sblk;
112
113 switch (s_id) {
114 case SDE_SSPP_SRC:
115 *idx = sblk->src_blk.base;
116 break;
117 case SDE_SSPP_SCALAR_QSEED2:
118 case SDE_SSPP_SCALAR_QSEED3:
119 case SDE_SSPP_SCALAR_RGB:
120 *idx = sblk->scalar_blk.base;
121 break;
122 case SDE_SSPP_CSC:
123 *idx = sblk->csc_blk.base;
124 break;
125 case SDE_SSPP_PA_V1:
126 *idx = sblk->pa_blk.base;
127 break;
128 case SDE_SSPP_HIST_V1:
129 *idx = sblk->hist_lut.base;
130 break;
131 case SDE_SSPP_PCC:
132 *idx = sblk->pcc_blk.base;
133 break;
134 default:
135 rc = -EINVAL;
136 pr_err("Unsupported SSPP sub-blk for this hw\n");
137 }
138
139 return rc;
140}
141
142static void _sspp_setup_opmode(struct sde_hw_pipe *ctx,
143 u32 op, u8 en)
144{
145 struct sde_hw_blk_reg_map *c = &ctx->hw;
146 u32 idx;
147 u32 opmode;
148
149 if (ctx->cap->features == SDE_SSPP_PA_V1) {
150
151 if (_sspp_subblk_offset(ctx, SDE_SSPP_SRC, &idx))
152 return;
153
154 opmode = SDE_REG_READ(c, SSPP_VIG_OP_MODE + idx);
155
156 /* ops */
157 switch (op) {
158 case CSC:
159 if (en)
160 /* CSC_1_EN and CSC_SRC_DATA_FORMAT*/
161 opmode |= BIT(18) | BIT(17);
162 else
163 opmode &= ~BIT(17);
164 break;
165 default:
166 pr_err(" Unsupported operation\n");
167 }
168 SDE_REG_WRITE(c, SSPP_VIG_OP_MODE + idx, opmode);
169 }
170}
171/**
172 * Setup source pixel format, flip,
173 */
174static void sde_hw_sspp_setup_format(struct sde_hw_pipe *ctx,
175 struct sde_hw_pipe_cfg *cfg,
176 u32 flags)
177{
178 struct sde_hw_blk_reg_map *c = &ctx->hw;
179 struct sde_mdp_format_params *fmt;
180 u32 chroma_samp, unpack, src_format;
181 u32 secure = 0;
182 u32 opmode = 0;
183 u32 idx;
184
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400185 if (_sspp_subblk_offset(ctx, SDE_SSPP_SRC, &idx))
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700186 return;
187
188 opmode = SDE_REG_READ(c, SSPP_SRC_OP_MODE + idx);
189
190 /* format info */
191 fmt = cfg->src.format;
192 if (WARN_ON(!fmt))
193 return;
194
195 if (flags & SDE_SSPP_SECURE_OVERLAY_SESSION)
196 secure = 0xF;
197
198 if (flags & SDE_SSPP_FLIP_LR)
199 opmode |= MDSS_MDP_OP_FLIP_LR;
200 if (flags & SDE_SSPP_FLIP_UD)
201 opmode |= MDSS_MDP_OP_FLIP_UD;
202
203 chroma_samp = fmt->chroma_sample;
204 if (flags & SDE_SSPP_SOURCE_ROTATED_90) {
205 if (chroma_samp == SDE_MDP_CHROMA_H2V1)
206 chroma_samp = SDE_MDP_CHROMA_H1V2;
207 else if (chroma_samp == SDE_MDP_CHROMA_H1V2)
208 chroma_samp = SDE_MDP_CHROMA_H2V1;
209 }
210
211 src_format = (chroma_samp << 23) | (fmt->fetch_planes << 19) |
212 (fmt->bits[C3_ALPHA] << 6) | (fmt->bits[C2_R_Cr] << 4) |
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400213 (fmt->bits[C1_B_Cb] << 2) | (fmt->bits[C0_G_Y] << 0);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700214
215 if (flags & SDE_SSPP_ROT_90)
216 src_format |= BIT(11); /* ROT90 */
217
218 if (fmt->alpha_enable &&
219 fmt->fetch_planes != SDE_MDP_PLANE_INTERLEAVED)
220 src_format |= BIT(8); /* SRCC3_EN */
221
222 unpack = (fmt->element[3] << 24) | (fmt->element[2] << 16) |
223 (fmt->element[1] << 8) | (fmt->element[0] << 0);
224 src_format |= ((fmt->unpack_count - 1) << 12) |
225 (fmt->unpack_tight << 17) |
226 (fmt->unpack_align_msb << 18) |
227 ((fmt->bpp - 1) << 9);
228
229 if (fmt->fetch_mode != SDE_MDP_FETCH_LINEAR) {
230 opmode |= MDSS_MDP_OP_BWC_EN;
231 src_format |= (fmt->fetch_mode & 3) << 30; /*FRAME_FORMAT */
232 SDE_REG_WRITE(c, SSPP_FETCH_CONFIG,
233 SDE_MDP_FETCH_CONFIG_RESET_VALUE |
234 ctx->highest_bank_bit << 18);
235 }
236
237 /* if this is YUV pixel format, enable CSC */
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400238 if (fmt->is_yuv)
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700239 src_format |= BIT(15);
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400240 _sspp_setup_opmode(ctx, CSC, fmt->is_yuv);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700241
242 opmode |= MDSS_MDP_OP_PE_OVERRIDE;
243
244 SDE_REG_WRITE(c, SSPP_SRC_FORMAT + idx, src_format);
245 SDE_REG_WRITE(c, SSPP_SRC_UNPACK_PATTERN + idx, unpack);
246 SDE_REG_WRITE(c, SSPP_SRC_OP_MODE + idx, opmode);
247 SDE_REG_WRITE(c, SSPP_SRC_ADDR_SW_STATUS + idx, secure);
248
249 /* clear previous UBWC error */
250 SDE_REG_WRITE(c, SSPP_UBWC_ERROR_STATUS + idx, BIT(31));
251}
252
253static void sde_hw_sspp_setup_pe_config(struct sde_hw_pipe *ctx,
254 struct sde_hw_pipe_cfg *cfg,
255 struct sde_hw_pixel_ext *pe_ext)
256{
257 struct sde_hw_blk_reg_map *c = &ctx->hw;
258 u8 color;
259 u32 lr_pe[4], tb_pe[4], tot_req_pixels[4];
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400260 const u32 bytemask = 0xff;
261 const u32 shortmask = 0xffff;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700262 u32 idx;
263
264 if (_sspp_subblk_offset(ctx, SDE_SSPP_SRC, &idx))
265 return;
266
267 /* program SW pixel extension override for all pipes*/
268 for (color = 0; color < 4; color++) {
269 /* color 2 has the same set of registers as color 1 */
270 if (color == 2)
271 continue;
272
273 lr_pe[color] = ((pe_ext->right_ftch[color] & bytemask) << 24)|
274 ((pe_ext->right_rpt[color] & bytemask) << 16)|
275 ((pe_ext->left_ftch[color] & bytemask) << 8)|
276 (pe_ext->left_rpt[color] & bytemask);
277
278 tb_pe[color] = ((pe_ext->btm_ftch[color] & bytemask) << 24)|
279 ((pe_ext->btm_rpt[color] & bytemask) << 16)|
280 ((pe_ext->top_ftch[color] & bytemask) << 8)|
281 (pe_ext->top_rpt[color] & bytemask);
282
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400283 tot_req_pixels[color] = (((pe_ext->roi_h[color] +
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700284 pe_ext->num_ext_pxls_top[color] +
285 pe_ext->num_ext_pxls_btm[color]) & shortmask) << 16) |
286 ((pe_ext->roi_w[color] +
287 pe_ext->num_ext_pxls_left[color] +
288 pe_ext->num_ext_pxls_right[color]) & shortmask);
289 }
290
291 /* color 0 */
292 SDE_REG_WRITE(c, SSPP_SW_PIX_EXT_C0_LR + idx, lr_pe[0]);
293 SDE_REG_WRITE(c, SSPP_SW_PIX_EXT_C0_TB + idx, tb_pe[0]);
294 SDE_REG_WRITE(c, SSPP_SW_PIX_EXT_C0_REQ_PIXELS + idx,
295 tot_req_pixels[0]);
296
297 /* color 1 and color 2 */
298 SDE_REG_WRITE(c, SSPP_SW_PIX_EXT_C1C2_LR + idx, lr_pe[1]);
299 SDE_REG_WRITE(c, SSPP_SW_PIX_EXT_C1C2_TB + idx, tb_pe[1]);
300 SDE_REG_WRITE(c, SSPP_SW_PIX_EXT_C1C2_REQ_PIXELS + idx,
301 tot_req_pixels[1]);
302
303 /* color 3 */
304 SDE_REG_WRITE(c, SSPP_SW_PIX_EXT_C3_LR + idx, lr_pe[3]);
305 SDE_REG_WRITE(c, SSPP_SW_PIX_EXT_C3_TB + idx, lr_pe[3]);
306 SDE_REG_WRITE(c, SSPP_SW_PIX_EXT_C3_REQ_PIXELS + idx,
307 tot_req_pixels[3]);
308}
309
310static void sde_hw_sspp_setup_scalar(struct sde_hw_pipe *ctx,
311 struct sde_hw_pixel_ext *pe_ext)
312{
313 struct sde_hw_blk_reg_map *c = &ctx->hw;
314 int scale_config;
315 const u8 mask = 0x3;
316 u32 idx;
317
318 if (_sspp_subblk_offset(ctx, SDE_SSPP_SCALAR_QSEED2, &idx))
319 return;
320
321 scale_config = BIT(0) | BIT(1);
322 /* RGB/YUV config */
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400323 scale_config |= (pe_ext->horz_filter[SDE_SSPP_COMP_LUMA] & mask) << 8;
324 scale_config |= (pe_ext->vert_filter[SDE_SSPP_COMP_LUMA] & mask) << 10;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700325 /* Aplha config*/
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400326 scale_config |= (pe_ext->horz_filter[SDE_SSPP_COMP_ALPHA] & mask) << 16;
327 scale_config |= (pe_ext->vert_filter[SDE_SSPP_COMP_ALPHA] & mask) << 18;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700328
329 SDE_REG_WRITE(c, SCALE_CONFIG + idx, scale_config);
330 SDE_REG_WRITE(c, COMP0_3_INIT_PHASE_X + idx,
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400331 pe_ext->init_phase_x[SDE_SSPP_COMP_LUMA]);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700332 SDE_REG_WRITE(c, COMP0_3_INIT_PHASE_Y + idx,
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400333 pe_ext->init_phase_y[SDE_SSPP_COMP_LUMA]);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700334 SDE_REG_WRITE(c, COMP0_3_PHASE_STEP_X + idx,
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400335 pe_ext->phase_step_x[SDE_SSPP_COMP_LUMA]);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700336 SDE_REG_WRITE(c, COMP0_3_PHASE_STEP_Y + idx,
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400337 pe_ext->phase_step_y[SDE_SSPP_COMP_LUMA]);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700338
339 SDE_REG_WRITE(c, COMP1_2_INIT_PHASE_X + idx,
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400340 pe_ext->init_phase_x[SDE_SSPP_COMP_CHROMA]);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700341 SDE_REG_WRITE(c, COMP1_2_INIT_PHASE_Y + idx,
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400342 pe_ext->init_phase_y[SDE_SSPP_COMP_CHROMA]);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700343 SDE_REG_WRITE(c, COMP1_2_PHASE_STEP_X + idx,
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400344 pe_ext->phase_step_x[SDE_SSPP_COMP_CHROMA]);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700345 SDE_REG_WRITE(c, COMP1_2_PHASE_STEP_Y + idx,
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400346 pe_ext->phase_step_y[SDE_SSPP_COMP_CHROMA]);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700347}
348
349/**
350 * sde_hw_sspp_setup_rects()
351 */
352static void sde_hw_sspp_setup_rects(struct sde_hw_pipe *ctx,
353 struct sde_hw_pipe_cfg *cfg,
354 struct sde_hw_pixel_ext *pe_ext)
355{
356 struct sde_hw_blk_reg_map *c = &ctx->hw;
357 u32 src_size, src_xy, dst_size, dst_xy, ystride0, ystride1;
358 u32 decimation = 0;
359 u32 idx;
360
361 if (_sspp_subblk_offset(ctx, SDE_SSPP_SRC, &idx))
362 return;
363
364 /* program pixel extension override */
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400365 if (pe_ext)
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700366 sde_hw_sspp_setup_pe_config(ctx, cfg, pe_ext);
367
368 /* src and dest rect programming */
369 src_xy = (cfg->src_rect.y << 16) |
370 (cfg->src_rect.x);
371 src_size = (cfg->src_rect.h << 16) |
372 (cfg->src_rect.w);
373 dst_xy = (cfg->dst_rect.y << 16) |
374 (cfg->dst_rect.x);
375 dst_size = (cfg->dst_rect.h << 16) |
376 (cfg->dst_rect.w);
377
378 ystride0 = (cfg->src.ystride[0]) |
379 (cfg->src.ystride[1] << 16);
380 ystride1 = (cfg->src.ystride[2]) |
381 (cfg->src.ystride[3] << 16);
382
383 /* program scalar, phase registers, if pipes supporting scaling */
384 if (src_size != dst_size) {
385 if (test_bit(SDE_SSPP_SCALAR_RGB, &ctx->cap->features) ||
386 test_bit(SDE_SSPP_SCALAR_QSEED2, &ctx->cap->features)) {
387 /* program decimation */
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400388 decimation = ((1 << cfg->horz_decimation) - 1) << 8;
389 decimation |= ((1 << cfg->vert_decimation) - 1);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700390
391 sde_hw_sspp_setup_scalar(ctx, pe_ext);
392 }
393 }
394
395 /* Rectangle Register programming */
396 SDE_REG_WRITE(c, SSPP_SRC_SIZE + idx, src_size);
397 SDE_REG_WRITE(c, SSPP_SRC_XY + idx, src_xy);
398 SDE_REG_WRITE(c, SSPP_OUT_SIZE + idx, dst_size);
399 SDE_REG_WRITE(c, SSPP_OUT_XY + idx, dst_xy);
400
401 SDE_REG_WRITE(c, SSPP_SRC_YSTRIDE0 + idx, ystride0);
402 SDE_REG_WRITE(c, SSPP_SRC_YSTRIDE1 + idx, ystride1);
403 SDE_REG_WRITE(c, SSPP_DECIMATION_CONFIG + idx, decimation);
404}
405
406static void sde_hw_sspp_setup_sourceaddress(struct sde_hw_pipe *ctx,
407 struct sde_hw_pipe_cfg *cfg)
408{
409 struct sde_hw_blk_reg_map *c = &ctx->hw;
410 int i;
411 u32 idx;
412
413 if (_sspp_subblk_offset(ctx, SDE_SSPP_SRC, &idx))
414 return;
415
416 for (i = 0; i < cfg->src.num_planes; i++)
Abhijit Kulkarni94954d52016-06-24 18:27:48 -0400417 SDE_REG_WRITE(c, SSPP_SRC0_ADDR + idx + i*0x4,
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700418 cfg->addr.plane[i]);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700419}
420
421static void sde_hw_sspp_setup_csc_8bit(struct sde_hw_pipe *ctx,
422 struct sde_csc_cfg *data)
423{
424 struct sde_hw_blk_reg_map *c = &ctx->hw;
425
426 sde_hw_csc_setup(c, VIG_0_CSC_1_MATRIX_COEFF_0, data);
427}
428
429static void sde_hw_sspp_setup_sharpening(struct sde_hw_pipe *ctx,
430 struct sde_hw_sharp_cfg *cfg)
431{
432 struct sde_hw_blk_reg_map *c = &ctx->hw;
433 u32 idx;
434
435 if (_sspp_subblk_offset(ctx, SDE_SSPP_SRC, &idx))
436 return;
437
438 SDE_REG_WRITE(c, VIG_0_QSEED2_SHARP + idx, cfg->strength);
439 SDE_REG_WRITE(c, VIG_0_QSEED2_SHARP + idx + 0x4, cfg->edge_thr);
440 SDE_REG_WRITE(c, VIG_0_QSEED2_SHARP + idx + 0x8, cfg->smooth_thr);
441 SDE_REG_WRITE(c, VIG_0_QSEED2_SHARP + idx + 0xC, cfg->noise_thr);
442}
443
444static void sde_hw_sspp_setup_solidfill(struct sde_hw_pipe *ctx,
445 u32 const_color,
446 u32 flags)
447{
448 struct sde_hw_blk_reg_map *c = &ctx->hw;
449 u32 secure = 0;
450 u32 unpack, src_format, opmode = 0;
451 u32 idx;
452
453 if (_sspp_subblk_offset(ctx, SDE_SSPP_SRC, &idx))
454 return;
455
456 /* format info */
457 src_format = SSPP_SOLID_FILL;
458 unpack = (C3_ALPHA << 24) | (C2_R_Cr << 16) |
459 (C1_B_Cb << 8) | (C0_G_Y << 0);
460 secure = (flags & SDE_SSPP_SECURE_OVERLAY_SESSION) ? 0xF : 0x00;
461 opmode = MDSS_MDP_OP_PE_OVERRIDE;
462
463 SDE_REG_WRITE(c, SSPP_SRC_FORMAT + idx, src_format);
464 SDE_REG_WRITE(c, SSPP_SRC_UNPACK_PATTERN + idx, unpack);
465 SDE_REG_WRITE(c, SSPP_SRC_ADDR_SW_STATUS + idx, secure);
466 SDE_REG_WRITE(c, SSPP_SRC_CONSTANT_COLOR + idx, const_color);
467 SDE_REG_WRITE(c, SSPP_SRC_OP_MODE + idx, opmode);
468}
469
470static void sde_hw_sspp_setup_histogram_v1(struct sde_hw_pipe *ctx,
471 void *cfg)
472{
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700473}
474
475static void sde_hw_sspp_setup_memcolor(struct sde_hw_pipe *ctx,
476 u32 memcolortype, u8 en)
477{
478}
479
480static void sde_hw_sspp_setup_igc(struct sde_hw_pipe *ctx)
481{
482}
483
484void sde_sspp_setup_pa(struct sde_hw_pipe *c)
485{
486}
487
488static void sde_hw_sspp_setup_danger_safe(struct sde_hw_pipe *ctx,
489 u32 danger_lut, u32 safe_lut)
490{
491 struct sde_hw_blk_reg_map *c = &ctx->hw;
492 u32 idx;
493
494 if (_sspp_subblk_offset(ctx, SDE_SSPP_SRC, &idx))
495 return;
496
497 SDE_REG_WRITE(c, SSPP_DANGER_LUT + idx, danger_lut);
498 SDE_REG_WRITE(c, SSPP_SAFE_LUT + idx, safe_lut);
499}
500
501static void sde_hw_sspp_qseed2_coeff(void *ctx)
502{
503}
504
505static void _setup_layer_ops(struct sde_hw_sspp_ops *ops,
506 unsigned long features)
507{
508 if (test_bit(SDE_SSPP_SRC, &features)) {
509 ops->setup_sourceformat = sde_hw_sspp_setup_format;
510 ops->setup_rects = sde_hw_sspp_setup_rects;
511 ops->setup_sourceaddress = sde_hw_sspp_setup_sourceaddress;
512 ops->setup_solidfill = sde_hw_sspp_setup_solidfill;
513 ops->setup_danger_safe = sde_hw_sspp_setup_danger_safe;
514 }
515 if (test_bit(SDE_SSPP_CSC, &features))
516 ops->setup_csc = sde_hw_sspp_setup_csc_8bit;
517
518 if (test_bit(SDE_SSPP_PA_V1, &features)) {
519 ops->setup_sharpening = sde_hw_sspp_setup_sharpening;
520 ops->setup_pa_memcolor = sde_hw_sspp_setup_memcolor;
521 }
522 if (test_bit(SDE_SSPP_HIST_V1, &features))
523 ops->setup_histogram = sde_hw_sspp_setup_histogram_v1;
524
525 if (test_bit(SDE_SSPP_IGC, &features))
526 ops->setup_igc = sde_hw_sspp_setup_igc;
527}
528
529static struct sde_sspp_cfg *_sspp_offset(enum sde_sspp sspp,
530 struct sde_mdss_cfg *m,
531 void __iomem *addr,
532 struct sde_hw_blk_reg_map *b)
533{
534 int i;
535
536 for (i = 0; i < m->sspp_count; i++) {
537 if (sspp == m->sspp[i].id) {
538 b->base_off = addr;
539 b->blk_off = m->sspp[i].base;
540 b->hwversion = m->hwversion;
541 return &m->sspp[i];
542 }
543 }
544
545 return ERR_PTR(-ENOMEM);
546}
547
548struct sde_hw_pipe *sde_hw_sspp_init(enum sde_sspp idx,
549 void __iomem *addr,
550 struct sde_mdss_cfg *m)
551{
552 struct sde_hw_pipe *c;
553 struct sde_sspp_cfg *cfg;
554
555 c = kzalloc(sizeof(*c), GFP_KERNEL);
556 if (!c)
557 return ERR_PTR(-ENOMEM);
558
559 cfg = _sspp_offset(idx, m, addr, &c->hw);
560 if (IS_ERR_OR_NULL(cfg)) {
561 kfree(c);
562 return ERR_PTR(-EINVAL);
563 }
564
565 /* Assign ops */
566 c->idx = idx;
567 c->cap = cfg;
568 _setup_layer_ops(&c->ops, c->cap->features);
569 c->highest_bank_bit = m->mdp[0].highest_bank_bit;
570
571 /*
572 * Perform any default initialization for the sspp blocks
573 */
574 if (test_bit(SDE_SSPP_SCALAR_QSEED2, &cfg->features))
575 sde_hw_sspp_qseed2_coeff(c);
576
577 if (test_bit(SDE_MDP_PANIC_PER_PIPE, &m->mdp[0].features))
578 sde_hw_sspp_setup_danger_safe(c,
579 cfg->sblk->danger_lut,
580 cfg->sblk->safe_lut);
581
582 return c;
583}
584
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400585void sde_hw_sspp_destroy(struct sde_hw_pipe *ctx)
586{
587 kfree(ctx);
588}
589