blob: 49b8d5b84351e815ecb63c338cacbd23709d170b [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
Narendra Muppalla1b0b3352015-09-29 10:16:51 -070013#include "sde_hwio.h"
14#include "sde_hw_catalog.h"
15#include "sde_hw_lm.h"
Clarence Ipe78efb72016-06-24 18:35:21 -040016#include "sde_hw_sspp.h"
Narendra Muppalla1b0b3352015-09-29 10:16:51 -070017
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
Clarence Ipe78efb72016-06-24 18:35:21 -040065#define SSPP_VIG_OP_MODE 0x0
Narendra Muppalla1b0b3352015-09-29 10:16:51 -070066
Clarence Ipe78efb72016-06-24 18:35:21 -040067/* SDE_SSPP_SCALER_QSEED2 */
Narendra Muppalla1b0b3352015-09-29 10:16:51 -070068#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
Narendra Muppalla1b0b3352015-09-29 10:16:51 -070079/*
80 * MDP Solid fill configuration
81 * argb8888
82 */
83#define SSPP_SOLID_FILL 0x4037ff
84
Clarence Ipe78efb72016-06-24 18:35:21 -040085/*
86 * Definitions for ViG op modes
87 */
88#define VIG_OP_CSC_DST_DATAFMT BIT(19)
89#define VIG_OP_CSC_SRC_DATAFMT BIT(18)
90#define VIG_OP_CSC_EN BIT(17)
91#define VIG_OP_MEM_PROT_CONT BIT(15)
92#define VIG_OP_MEM_PROT_VAL BIT(14)
93#define VIG_OP_MEM_PROT_SAT BIT(13)
94#define VIG_OP_MEM_PROT_HUE BIT(12)
95#define VIG_OP_HIST BIT(8)
96#define VIG_OP_SKY_COL BIT(7)
97#define VIG_OP_FOIL BIT(6)
98#define VIG_OP_SKIN_COL BIT(5)
99#define VIG_OP_PA_EN BIT(4)
100#define VIG_OP_PA_SAT_ZERO_EXP BIT(2)
101#define VIG_OP_MEM_PROT_BLEND BIT(1)
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700102
103static inline int _sspp_subblk_offset(struct sde_hw_pipe *ctx,
104 int s_id,
105 u32 *idx)
106{
107 int rc = 0;
108 const struct sde_sspp_sub_blks *sblk = ctx->cap->sblk;
109
Clarence Ipe78efb72016-06-24 18:35:21 -0400110 if (!ctx)
111 return -EINVAL;
112
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700113 switch (s_id) {
114 case SDE_SSPP_SRC:
115 *idx = sblk->src_blk.base;
116 break;
Clarence Ipe78efb72016-06-24 18:35:21 -0400117 case SDE_SSPP_SCALER_QSEED2:
118 case SDE_SSPP_SCALER_QSEED3:
119 case SDE_SSPP_SCALER_RGB:
120 *idx = sblk->scaler_blk.base;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700121 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;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700136 }
137
138 return rc;
139}
140
141static void _sspp_setup_opmode(struct sde_hw_pipe *ctx,
Clarence Ipe78efb72016-06-24 18:35:21 -0400142 u32 mask, u8 en)
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700143{
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700144 u32 idx;
145 u32 opmode;
146
Clarence Ipe78efb72016-06-24 18:35:21 -0400147 if (!_sspp_subblk_offset(ctx, SDE_SSPP_SCALER_QSEED2, &idx) &&
148 (test_bit(SDE_SSPP_CSC, &ctx->cap->features) ||
149 test_bit(SDE_SSPP_PA_V1, &ctx->cap->features))) {
150 opmode = SDE_REG_READ(&ctx->hw, SSPP_VIG_OP_MODE + idx);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700151
Clarence Ipe78efb72016-06-24 18:35:21 -0400152 if (en)
153 opmode |= mask;
154 else
155 opmode &= ~mask;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700156
Clarence Ipe78efb72016-06-24 18:35:21 -0400157 SDE_REG_WRITE(&ctx->hw, SSPP_VIG_OP_MODE + idx, opmode);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700158 }
159}
160/**
161 * Setup source pixel format, flip,
162 */
163static void sde_hw_sspp_setup_format(struct sde_hw_pipe *ctx,
164 struct sde_hw_pipe_cfg *cfg,
165 u32 flags)
166{
Clarence Ipe78efb72016-06-24 18:35:21 -0400167 struct sde_hw_blk_reg_map *c;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700168 struct sde_mdp_format_params *fmt;
169 u32 chroma_samp, unpack, src_format;
170 u32 secure = 0;
171 u32 opmode = 0;
172 u32 idx;
173
Clarence Ipe78efb72016-06-24 18:35:21 -0400174 if (_sspp_subblk_offset(ctx, SDE_SSPP_SRC, &idx) || !cfg)
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700175 return;
176
Clarence Ipe78efb72016-06-24 18:35:21 -0400177 c = &ctx->hw;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700178 opmode = SDE_REG_READ(c, SSPP_SRC_OP_MODE + idx);
179
180 /* format info */
181 fmt = cfg->src.format;
182 if (WARN_ON(!fmt))
183 return;
184
185 if (flags & SDE_SSPP_SECURE_OVERLAY_SESSION)
186 secure = 0xF;
187
188 if (flags & SDE_SSPP_FLIP_LR)
189 opmode |= MDSS_MDP_OP_FLIP_LR;
190 if (flags & SDE_SSPP_FLIP_UD)
191 opmode |= MDSS_MDP_OP_FLIP_UD;
192
193 chroma_samp = fmt->chroma_sample;
194 if (flags & SDE_SSPP_SOURCE_ROTATED_90) {
195 if (chroma_samp == SDE_MDP_CHROMA_H2V1)
196 chroma_samp = SDE_MDP_CHROMA_H1V2;
197 else if (chroma_samp == SDE_MDP_CHROMA_H1V2)
198 chroma_samp = SDE_MDP_CHROMA_H2V1;
199 }
200
201 src_format = (chroma_samp << 23) | (fmt->fetch_planes << 19) |
202 (fmt->bits[C3_ALPHA] << 6) | (fmt->bits[C2_R_Cr] << 4) |
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400203 (fmt->bits[C1_B_Cb] << 2) | (fmt->bits[C0_G_Y] << 0);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700204
205 if (flags & SDE_SSPP_ROT_90)
206 src_format |= BIT(11); /* ROT90 */
207
208 if (fmt->alpha_enable &&
209 fmt->fetch_planes != SDE_MDP_PLANE_INTERLEAVED)
210 src_format |= BIT(8); /* SRCC3_EN */
211
212 unpack = (fmt->element[3] << 24) | (fmt->element[2] << 16) |
213 (fmt->element[1] << 8) | (fmt->element[0] << 0);
214 src_format |= ((fmt->unpack_count - 1) << 12) |
215 (fmt->unpack_tight << 17) |
216 (fmt->unpack_align_msb << 18) |
217 ((fmt->bpp - 1) << 9);
218
219 if (fmt->fetch_mode != SDE_MDP_FETCH_LINEAR) {
220 opmode |= MDSS_MDP_OP_BWC_EN;
221 src_format |= (fmt->fetch_mode & 3) << 30; /*FRAME_FORMAT */
222 SDE_REG_WRITE(c, SSPP_FETCH_CONFIG,
223 SDE_MDP_FETCH_CONFIG_RESET_VALUE |
224 ctx->highest_bank_bit << 18);
225 }
226
Clarence Ipe78efb72016-06-24 18:35:21 -0400227 opmode |= MDSS_MDP_OP_PE_OVERRIDE;
228
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700229 /* if this is YUV pixel format, enable CSC */
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400230 if (fmt->is_yuv)
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700231 src_format |= BIT(15);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700232
Clarence Ipe78efb72016-06-24 18:35:21 -0400233 /* update scaler opmode, if appropriate */
234 _sspp_setup_opmode(ctx,
235 VIG_OP_CSC_EN | VIG_OP_CSC_SRC_DATAFMT, fmt->is_yuv);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700236
237 SDE_REG_WRITE(c, SSPP_SRC_FORMAT + idx, src_format);
238 SDE_REG_WRITE(c, SSPP_SRC_UNPACK_PATTERN + idx, unpack);
239 SDE_REG_WRITE(c, SSPP_SRC_OP_MODE + idx, opmode);
240 SDE_REG_WRITE(c, SSPP_SRC_ADDR_SW_STATUS + idx, secure);
241
242 /* clear previous UBWC error */
243 SDE_REG_WRITE(c, SSPP_UBWC_ERROR_STATUS + idx, BIT(31));
244}
245
246static void sde_hw_sspp_setup_pe_config(struct sde_hw_pipe *ctx,
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700247 struct sde_hw_pixel_ext *pe_ext)
248{
Clarence Ipe78efb72016-06-24 18:35:21 -0400249 struct sde_hw_blk_reg_map *c;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700250 u8 color;
251 u32 lr_pe[4], tb_pe[4], tot_req_pixels[4];
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400252 const u32 bytemask = 0xff;
253 const u32 shortmask = 0xffff;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700254 u32 idx;
255
Clarence Ipe78efb72016-06-24 18:35:21 -0400256 if (_sspp_subblk_offset(ctx, SDE_SSPP_SRC, &idx) || !pe_ext)
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700257 return;
258
Clarence Ipe78efb72016-06-24 18:35:21 -0400259 c = &ctx->hw;
260
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700261 /* program SW pixel extension override for all pipes*/
Clarence Ipe78efb72016-06-24 18:35:21 -0400262 for (color = 0; color < SDE_MAX_PLANES; color++) {
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700263 /* color 2 has the same set of registers as color 1 */
264 if (color == 2)
265 continue;
266
267 lr_pe[color] = ((pe_ext->right_ftch[color] & bytemask) << 24)|
268 ((pe_ext->right_rpt[color] & bytemask) << 16)|
269 ((pe_ext->left_ftch[color] & bytemask) << 8)|
270 (pe_ext->left_rpt[color] & bytemask);
271
272 tb_pe[color] = ((pe_ext->btm_ftch[color] & bytemask) << 24)|
273 ((pe_ext->btm_rpt[color] & bytemask) << 16)|
274 ((pe_ext->top_ftch[color] & bytemask) << 8)|
275 (pe_ext->top_rpt[color] & bytemask);
276
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400277 tot_req_pixels[color] = (((pe_ext->roi_h[color] +
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700278 pe_ext->num_ext_pxls_top[color] +
279 pe_ext->num_ext_pxls_btm[color]) & shortmask) << 16) |
280 ((pe_ext->roi_w[color] +
281 pe_ext->num_ext_pxls_left[color] +
282 pe_ext->num_ext_pxls_right[color]) & shortmask);
283 }
284
285 /* color 0 */
286 SDE_REG_WRITE(c, SSPP_SW_PIX_EXT_C0_LR + idx, lr_pe[0]);
287 SDE_REG_WRITE(c, SSPP_SW_PIX_EXT_C0_TB + idx, tb_pe[0]);
288 SDE_REG_WRITE(c, SSPP_SW_PIX_EXT_C0_REQ_PIXELS + idx,
289 tot_req_pixels[0]);
290
291 /* color 1 and color 2 */
292 SDE_REG_WRITE(c, SSPP_SW_PIX_EXT_C1C2_LR + idx, lr_pe[1]);
293 SDE_REG_WRITE(c, SSPP_SW_PIX_EXT_C1C2_TB + idx, tb_pe[1]);
294 SDE_REG_WRITE(c, SSPP_SW_PIX_EXT_C1C2_REQ_PIXELS + idx,
295 tot_req_pixels[1]);
296
297 /* color 3 */
298 SDE_REG_WRITE(c, SSPP_SW_PIX_EXT_C3_LR + idx, lr_pe[3]);
299 SDE_REG_WRITE(c, SSPP_SW_PIX_EXT_C3_TB + idx, lr_pe[3]);
300 SDE_REG_WRITE(c, SSPP_SW_PIX_EXT_C3_REQ_PIXELS + idx,
301 tot_req_pixels[3]);
302}
303
Clarence Ipe78efb72016-06-24 18:35:21 -0400304static void _sde_hw_sspp_setup_scaler(struct sde_hw_pipe *ctx,
305 struct sde_hw_pixel_ext *pe)
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700306{
Clarence Ipe78efb72016-06-24 18:35:21 -0400307 struct sde_hw_blk_reg_map *c;
308 int config_h = 0x0;
309 int config_v = 0x0;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700310 u32 idx;
311
Clarence Ipe78efb72016-06-24 18:35:21 -0400312 if (_sspp_subblk_offset(ctx, SDE_SSPP_SCALER_QSEED2, &idx) || !pe)
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700313 return;
314
Clarence Ipe78efb72016-06-24 18:35:21 -0400315 c = &ctx->hw;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700316
Clarence Ipe78efb72016-06-24 18:35:21 -0400317 /* enable scaler(s) if valid filter set */
318 if (pe->horz_filter[SDE_SSPP_COMP_0] < SDE_MDP_SCALE_FILTER_MAX)
319 config_h |= pe->horz_filter[SDE_SSPP_COMP_0] << 8;
320 if (pe->horz_filter[SDE_SSPP_COMP_1_2] < SDE_MDP_SCALE_FILTER_MAX)
321 config_h |= pe->horz_filter[SDE_SSPP_COMP_1_2] << 12;
322 if (pe->horz_filter[SDE_SSPP_COMP_3] < SDE_MDP_SCALE_FILTER_MAX)
323 config_h |= pe->horz_filter[SDE_SSPP_COMP_3] << 16;
324
325 if (config_h)
326 config_h |= BIT(0);
327
328 if (pe->vert_filter[SDE_SSPP_COMP_0] < SDE_MDP_SCALE_FILTER_MAX)
329 config_v |= pe->vert_filter[SDE_SSPP_COMP_0] << 10;
330 if (pe->vert_filter[SDE_SSPP_COMP_1_2] < SDE_MDP_SCALE_FILTER_MAX)
331 config_v |= pe->vert_filter[SDE_SSPP_COMP_1_2] << 14;
332 if (pe->vert_filter[SDE_SSPP_COMP_3] < SDE_MDP_SCALE_FILTER_MAX)
333 config_v |= pe->vert_filter[SDE_SSPP_COMP_3] << 18;
334
335 if (config_v)
336 config_v |= BIT(1);
337
338 SDE_REG_WRITE(c, SCALE_CONFIG + idx, config_h | config_v);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700339 SDE_REG_WRITE(c, COMP0_3_INIT_PHASE_X + idx,
Clarence Ipe78efb72016-06-24 18:35:21 -0400340 pe->init_phase_x[SDE_SSPP_COMP_0]);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700341 SDE_REG_WRITE(c, COMP0_3_INIT_PHASE_Y + idx,
Clarence Ipe78efb72016-06-24 18:35:21 -0400342 pe->init_phase_y[SDE_SSPP_COMP_0]);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700343 SDE_REG_WRITE(c, COMP0_3_PHASE_STEP_X + idx,
Clarence Ipe78efb72016-06-24 18:35:21 -0400344 pe->phase_step_x[SDE_SSPP_COMP_0]);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700345 SDE_REG_WRITE(c, COMP0_3_PHASE_STEP_Y + idx,
Clarence Ipe78efb72016-06-24 18:35:21 -0400346 pe->phase_step_y[SDE_SSPP_COMP_0]);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700347
348 SDE_REG_WRITE(c, COMP1_2_INIT_PHASE_X + idx,
Clarence Ipe78efb72016-06-24 18:35:21 -0400349 pe->init_phase_x[SDE_SSPP_COMP_1_2]);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700350 SDE_REG_WRITE(c, COMP1_2_INIT_PHASE_Y + idx,
Clarence Ipe78efb72016-06-24 18:35:21 -0400351 pe->init_phase_y[SDE_SSPP_COMP_1_2]);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700352 SDE_REG_WRITE(c, COMP1_2_PHASE_STEP_X + idx,
Clarence Ipe78efb72016-06-24 18:35:21 -0400353 pe->phase_step_x[SDE_SSPP_COMP_1_2]);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700354 SDE_REG_WRITE(c, COMP1_2_PHASE_STEP_Y + idx,
Clarence Ipe78efb72016-06-24 18:35:21 -0400355 pe->phase_step_y[SDE_SSPP_COMP_1_2]);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700356}
357
358/**
359 * sde_hw_sspp_setup_rects()
360 */
361static void sde_hw_sspp_setup_rects(struct sde_hw_pipe *ctx,
362 struct sde_hw_pipe_cfg *cfg,
363 struct sde_hw_pixel_ext *pe_ext)
364{
Clarence Ipe78efb72016-06-24 18:35:21 -0400365 struct sde_hw_blk_reg_map *c;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700366 u32 src_size, src_xy, dst_size, dst_xy, ystride0, ystride1;
367 u32 decimation = 0;
368 u32 idx;
369
Clarence Ipe78efb72016-06-24 18:35:21 -0400370 if (_sspp_subblk_offset(ctx, SDE_SSPP_SRC, &idx) || !cfg)
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700371 return;
372
Clarence Ipe78efb72016-06-24 18:35:21 -0400373 c = &ctx->hw;
374
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700375 /* program pixel extension override */
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400376 if (pe_ext)
Clarence Ipe78efb72016-06-24 18:35:21 -0400377 sde_hw_sspp_setup_pe_config(ctx, pe_ext);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700378
379 /* src and dest rect programming */
380 src_xy = (cfg->src_rect.y << 16) |
381 (cfg->src_rect.x);
382 src_size = (cfg->src_rect.h << 16) |
383 (cfg->src_rect.w);
384 dst_xy = (cfg->dst_rect.y << 16) |
385 (cfg->dst_rect.x);
386 dst_size = (cfg->dst_rect.h << 16) |
387 (cfg->dst_rect.w);
388
389 ystride0 = (cfg->src.ystride[0]) |
390 (cfg->src.ystride[1] << 16);
391 ystride1 = (cfg->src.ystride[2]) |
392 (cfg->src.ystride[3] << 16);
393
Clarence Ipe78efb72016-06-24 18:35:21 -0400394 /* program scaler, phase registers, if pipes supporting scaling */
395 if (ctx->cap->features & SDE_SSPP_SCALER) {
396 /* program decimation */
397 decimation = ((1 << cfg->horz_decimation) - 1) << 8;
398 decimation |= ((1 << cfg->vert_decimation) - 1);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700399
Clarence Ipe78efb72016-06-24 18:35:21 -0400400 _sde_hw_sspp_setup_scaler(ctx, pe_ext);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700401 }
402
403 /* Rectangle Register programming */
404 SDE_REG_WRITE(c, SSPP_SRC_SIZE + idx, src_size);
405 SDE_REG_WRITE(c, SSPP_SRC_XY + idx, src_xy);
406 SDE_REG_WRITE(c, SSPP_OUT_SIZE + idx, dst_size);
407 SDE_REG_WRITE(c, SSPP_OUT_XY + idx, dst_xy);
408
409 SDE_REG_WRITE(c, SSPP_SRC_YSTRIDE0 + idx, ystride0);
410 SDE_REG_WRITE(c, SSPP_SRC_YSTRIDE1 + idx, ystride1);
411 SDE_REG_WRITE(c, SSPP_DECIMATION_CONFIG + idx, decimation);
412}
413
414static void sde_hw_sspp_setup_sourceaddress(struct sde_hw_pipe *ctx,
415 struct sde_hw_pipe_cfg *cfg)
416{
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700417 int i;
418 u32 idx;
419
420 if (_sspp_subblk_offset(ctx, SDE_SSPP_SRC, &idx))
421 return;
422
423 for (i = 0; i < cfg->src.num_planes; i++)
Clarence Ipe78efb72016-06-24 18:35:21 -0400424 SDE_REG_WRITE(&ctx->hw, SSPP_SRC0_ADDR + idx + i*0x4,
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700425 cfg->addr.plane[i]);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700426}
427
Clarence Ipe78efb72016-06-24 18:35:21 -0400428static void sde_hw_sspp_setup_csc(struct sde_hw_pipe *ctx,
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700429 struct sde_csc_cfg *data)
430{
Clarence Ipe78efb72016-06-24 18:35:21 -0400431 u32 idx;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700432
Clarence Ipe78efb72016-06-24 18:35:21 -0400433 if (_sspp_subblk_offset(ctx, SDE_SSPP_CSC, &idx) || !data)
434 return;
435
436 sde_hw_csc_setup(&ctx->hw, idx, data);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700437}
438
439static void sde_hw_sspp_setup_sharpening(struct sde_hw_pipe *ctx,
440 struct sde_hw_sharp_cfg *cfg)
441{
Clarence Ipe78efb72016-06-24 18:35:21 -0400442 struct sde_hw_blk_reg_map *c;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700443 u32 idx;
444
Clarence Ipe78efb72016-06-24 18:35:21 -0400445 if (_sspp_subblk_offset(ctx, SDE_SSPP_SCALER_QSEED2, &idx) || !cfg)
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700446 return;
447
Clarence Ipe78efb72016-06-24 18:35:21 -0400448 c = &ctx->hw;
449
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700450 SDE_REG_WRITE(c, VIG_0_QSEED2_SHARP + idx, cfg->strength);
451 SDE_REG_WRITE(c, VIG_0_QSEED2_SHARP + idx + 0x4, cfg->edge_thr);
452 SDE_REG_WRITE(c, VIG_0_QSEED2_SHARP + idx + 0x8, cfg->smooth_thr);
453 SDE_REG_WRITE(c, VIG_0_QSEED2_SHARP + idx + 0xC, cfg->noise_thr);
454}
455
456static void sde_hw_sspp_setup_solidfill(struct sde_hw_pipe *ctx,
457 u32 const_color,
458 u32 flags)
459{
Clarence Ipe78efb72016-06-24 18:35:21 -0400460 struct sde_hw_blk_reg_map *c;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700461 u32 secure = 0;
462 u32 unpack, src_format, opmode = 0;
463 u32 idx;
464
465 if (_sspp_subblk_offset(ctx, SDE_SSPP_SRC, &idx))
466 return;
467
Clarence Ipe78efb72016-06-24 18:35:21 -0400468 c = &ctx->hw;
469
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700470 /* format info */
471 src_format = SSPP_SOLID_FILL;
472 unpack = (C3_ALPHA << 24) | (C2_R_Cr << 16) |
473 (C1_B_Cb << 8) | (C0_G_Y << 0);
474 secure = (flags & SDE_SSPP_SECURE_OVERLAY_SESSION) ? 0xF : 0x00;
475 opmode = MDSS_MDP_OP_PE_OVERRIDE;
476
477 SDE_REG_WRITE(c, SSPP_SRC_FORMAT + idx, src_format);
478 SDE_REG_WRITE(c, SSPP_SRC_UNPACK_PATTERN + idx, unpack);
479 SDE_REG_WRITE(c, SSPP_SRC_ADDR_SW_STATUS + idx, secure);
480 SDE_REG_WRITE(c, SSPP_SRC_CONSTANT_COLOR + idx, const_color);
481 SDE_REG_WRITE(c, SSPP_SRC_OP_MODE + idx, opmode);
482}
483
484static void sde_hw_sspp_setup_histogram_v1(struct sde_hw_pipe *ctx,
Clarence Ipe78efb72016-06-24 18:35:21 -0400485 void *cfg)
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700486{
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700487}
488
489static void sde_hw_sspp_setup_memcolor(struct sde_hw_pipe *ctx,
490 u32 memcolortype, u8 en)
491{
492}
493
494static void sde_hw_sspp_setup_igc(struct sde_hw_pipe *ctx)
495{
496}
497
498void sde_sspp_setup_pa(struct sde_hw_pipe *c)
499{
500}
501
502static void sde_hw_sspp_setup_danger_safe(struct sde_hw_pipe *ctx,
503 u32 danger_lut, u32 safe_lut)
504{
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700505 u32 idx;
506
507 if (_sspp_subblk_offset(ctx, SDE_SSPP_SRC, &idx))
508 return;
509
Clarence Ipe78efb72016-06-24 18:35:21 -0400510 SDE_REG_WRITE(&ctx->hw, SSPP_DANGER_LUT + idx, danger_lut);
511 SDE_REG_WRITE(&ctx->hw, SSPP_SAFE_LUT + idx, safe_lut);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700512}
513
514static void sde_hw_sspp_qseed2_coeff(void *ctx)
515{
516}
517
518static void _setup_layer_ops(struct sde_hw_sspp_ops *ops,
519 unsigned long features)
520{
521 if (test_bit(SDE_SSPP_SRC, &features)) {
522 ops->setup_sourceformat = sde_hw_sspp_setup_format;
523 ops->setup_rects = sde_hw_sspp_setup_rects;
524 ops->setup_sourceaddress = sde_hw_sspp_setup_sourceaddress;
525 ops->setup_solidfill = sde_hw_sspp_setup_solidfill;
526 ops->setup_danger_safe = sde_hw_sspp_setup_danger_safe;
527 }
528 if (test_bit(SDE_SSPP_CSC, &features))
Clarence Ipe78efb72016-06-24 18:35:21 -0400529 ops->setup_csc = sde_hw_sspp_setup_csc;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700530
531 if (test_bit(SDE_SSPP_PA_V1, &features)) {
532 ops->setup_sharpening = sde_hw_sspp_setup_sharpening;
533 ops->setup_pa_memcolor = sde_hw_sspp_setup_memcolor;
534 }
535 if (test_bit(SDE_SSPP_HIST_V1, &features))
536 ops->setup_histogram = sde_hw_sspp_setup_histogram_v1;
537
538 if (test_bit(SDE_SSPP_IGC, &features))
539 ops->setup_igc = sde_hw_sspp_setup_igc;
540}
541
542static struct sde_sspp_cfg *_sspp_offset(enum sde_sspp sspp,
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700543 void __iomem *addr,
Clarence Ipe78efb72016-06-24 18:35:21 -0400544 struct sde_mdss_cfg *catalog,
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700545 struct sde_hw_blk_reg_map *b)
546{
547 int i;
548
Clarence Ipe78efb72016-06-24 18:35:21 -0400549 if ((sspp < SSPP_MAX) && catalog && addr && b) {
550 for (i = 0; i < catalog->sspp_count; i++) {
551 if (sspp == catalog->sspp[i].id) {
552 b->base_off = addr;
553 b->blk_off = catalog->sspp[i].base;
554 b->hwversion = catalog->hwversion;
555 return &catalog->sspp[i];
556 }
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700557 }
558 }
559
560 return ERR_PTR(-ENOMEM);
561}
562
563struct sde_hw_pipe *sde_hw_sspp_init(enum sde_sspp idx,
564 void __iomem *addr,
Clarence Ipe78efb72016-06-24 18:35:21 -0400565 struct sde_mdss_cfg *catalog)
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700566{
Clarence Ipe78efb72016-06-24 18:35:21 -0400567 struct sde_hw_pipe *ctx;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700568 struct sde_sspp_cfg *cfg;
569
Clarence Ipe78efb72016-06-24 18:35:21 -0400570 ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
571 if (!ctx)
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700572 return ERR_PTR(-ENOMEM);
573
Clarence Ipe78efb72016-06-24 18:35:21 -0400574 cfg = _sspp_offset(idx, addr, catalog, &ctx->hw);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700575 if (IS_ERR_OR_NULL(cfg)) {
Clarence Ipe78efb72016-06-24 18:35:21 -0400576 kfree(ctx);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700577 return ERR_PTR(-EINVAL);
578 }
579
580 /* Assign ops */
Clarence Ipe78efb72016-06-24 18:35:21 -0400581 ctx->idx = idx;
582 ctx->cap = cfg;
583 _setup_layer_ops(&ctx->ops, ctx->cap->features);
584 ctx->highest_bank_bit = catalog->mdp[0].highest_bank_bit;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700585
586 /*
587 * Perform any default initialization for the sspp blocks
588 */
Clarence Ipe78efb72016-06-24 18:35:21 -0400589 if (test_bit(SDE_SSPP_SCALER_QSEED2, &cfg->features))
590 sde_hw_sspp_qseed2_coeff(ctx);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700591
Clarence Ipe78efb72016-06-24 18:35:21 -0400592 if (test_bit(SDE_MDP_PANIC_PER_PIPE, &catalog->mdp[0].features))
593 sde_hw_sspp_setup_danger_safe(ctx,
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700594 cfg->sblk->danger_lut,
595 cfg->sblk->safe_lut);
596
Clarence Ipe78efb72016-06-24 18:35:21 -0400597 return ctx;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700598}
599
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400600void sde_hw_sspp_destroy(struct sde_hw_pipe *ctx)
601{
602 kfree(ctx);
603}
604