blob: 400a5539ce8ba940ca41f10ea435bfcf24ae0fab [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
Lloyd Atkinson9a673492016-07-05 11:41:57 -040018#define SDE_FETCH_CONFIG_RESET_VALUE 0x00000087
Narendra Muppalla1b0b3352015-09-29 10:16:51 -070019
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/*
Clarence Ipe78efb72016-06-24 18:35:21 -040080 * Definitions for ViG op modes
81 */
82#define VIG_OP_CSC_DST_DATAFMT BIT(19)
83#define VIG_OP_CSC_SRC_DATAFMT BIT(18)
84#define VIG_OP_CSC_EN BIT(17)
85#define VIG_OP_MEM_PROT_CONT BIT(15)
86#define VIG_OP_MEM_PROT_VAL BIT(14)
87#define VIG_OP_MEM_PROT_SAT BIT(13)
88#define VIG_OP_MEM_PROT_HUE BIT(12)
89#define VIG_OP_HIST BIT(8)
90#define VIG_OP_SKY_COL BIT(7)
91#define VIG_OP_FOIL BIT(6)
92#define VIG_OP_SKIN_COL BIT(5)
93#define VIG_OP_PA_EN BIT(4)
94#define VIG_OP_PA_SAT_ZERO_EXP BIT(2)
95#define VIG_OP_MEM_PROT_BLEND BIT(1)
Narendra Muppalla1b0b3352015-09-29 10:16:51 -070096
97static inline int _sspp_subblk_offset(struct sde_hw_pipe *ctx,
98 int s_id,
99 u32 *idx)
100{
101 int rc = 0;
102 const struct sde_sspp_sub_blks *sblk = ctx->cap->sblk;
103
Clarence Ipe78efb72016-06-24 18:35:21 -0400104 if (!ctx)
105 return -EINVAL;
106
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700107 switch (s_id) {
108 case SDE_SSPP_SRC:
109 *idx = sblk->src_blk.base;
110 break;
Clarence Ipe78efb72016-06-24 18:35:21 -0400111 case SDE_SSPP_SCALER_QSEED2:
112 case SDE_SSPP_SCALER_QSEED3:
113 case SDE_SSPP_SCALER_RGB:
114 *idx = sblk->scaler_blk.base;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700115 break;
116 case SDE_SSPP_CSC:
117 *idx = sblk->csc_blk.base;
118 break;
119 case SDE_SSPP_PA_V1:
120 *idx = sblk->pa_blk.base;
121 break;
122 case SDE_SSPP_HIST_V1:
123 *idx = sblk->hist_lut.base;
124 break;
125 case SDE_SSPP_PCC:
126 *idx = sblk->pcc_blk.base;
127 break;
128 default:
129 rc = -EINVAL;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700130 }
131
132 return rc;
133}
134
135static void _sspp_setup_opmode(struct sde_hw_pipe *ctx,
Clarence Ipe78efb72016-06-24 18:35:21 -0400136 u32 mask, u8 en)
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700137{
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700138 u32 idx;
139 u32 opmode;
140
Clarence Ipe78efb72016-06-24 18:35:21 -0400141 if (!_sspp_subblk_offset(ctx, SDE_SSPP_SCALER_QSEED2, &idx) &&
142 (test_bit(SDE_SSPP_CSC, &ctx->cap->features) ||
143 test_bit(SDE_SSPP_PA_V1, &ctx->cap->features))) {
144 opmode = SDE_REG_READ(&ctx->hw, SSPP_VIG_OP_MODE + idx);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700145
Clarence Ipe78efb72016-06-24 18:35:21 -0400146 if (en)
147 opmode |= mask;
148 else
149 opmode &= ~mask;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700150
Clarence Ipe78efb72016-06-24 18:35:21 -0400151 SDE_REG_WRITE(&ctx->hw, SSPP_VIG_OP_MODE + idx, opmode);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700152 }
153}
154/**
155 * Setup source pixel format, flip,
156 */
157static void sde_hw_sspp_setup_format(struct sde_hw_pipe *ctx,
Lloyd Atkinson9a673492016-07-05 11:41:57 -0400158 const struct sde_format *fmt, u32 flags)
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700159{
Clarence Ipe78efb72016-06-24 18:35:21 -0400160 struct sde_hw_blk_reg_map *c;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700161 u32 chroma_samp, unpack, src_format;
162 u32 secure = 0;
163 u32 opmode = 0;
164 u32 idx;
165
Clarence Ipcb410d42016-06-26 22:52:33 -0400166 if (_sspp_subblk_offset(ctx, SDE_SSPP_SRC, &idx) || !fmt)
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700167 return;
168
Clarence Ipe78efb72016-06-24 18:35:21 -0400169 c = &ctx->hw;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700170 opmode = SDE_REG_READ(c, SSPP_SRC_OP_MODE + idx);
Clarence Ip5e2a9222016-06-26 22:38:24 -0400171 opmode &= ~(MDSS_MDP_OP_FLIP_LR | MDSS_MDP_OP_FLIP_UD |
172 MDSS_MDP_OP_BWC_EN | MDSS_MDP_OP_PE_OVERRIDE);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700173
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700174 if (flags & SDE_SSPP_SECURE_OVERLAY_SESSION)
175 secure = 0xF;
176
177 if (flags & SDE_SSPP_FLIP_LR)
178 opmode |= MDSS_MDP_OP_FLIP_LR;
179 if (flags & SDE_SSPP_FLIP_UD)
180 opmode |= MDSS_MDP_OP_FLIP_UD;
181
182 chroma_samp = fmt->chroma_sample;
183 if (flags & SDE_SSPP_SOURCE_ROTATED_90) {
Lloyd Atkinson9a673492016-07-05 11:41:57 -0400184 if (chroma_samp == SDE_CHROMA_H2V1)
185 chroma_samp = SDE_CHROMA_H1V2;
186 else if (chroma_samp == SDE_CHROMA_H1V2)
187 chroma_samp = SDE_CHROMA_H2V1;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700188 }
189
190 src_format = (chroma_samp << 23) | (fmt->fetch_planes << 19) |
191 (fmt->bits[C3_ALPHA] << 6) | (fmt->bits[C2_R_Cr] << 4) |
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400192 (fmt->bits[C1_B_Cb] << 2) | (fmt->bits[C0_G_Y] << 0);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700193
194 if (flags & SDE_SSPP_ROT_90)
195 src_format |= BIT(11); /* ROT90 */
196
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400197 if (fmt->alpha_enable && fmt->fetch_planes == SDE_PLANE_INTERLEAVED)
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700198 src_format |= BIT(8); /* SRCC3_EN */
199
Clarence Ipcb410d42016-06-26 22:52:33 -0400200 if (flags & SDE_SSPP_SOLID_FILL)
201 src_format |= BIT(22);
202
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700203 unpack = (fmt->element[3] << 24) | (fmt->element[2] << 16) |
204 (fmt->element[1] << 8) | (fmt->element[0] << 0);
205 src_format |= ((fmt->unpack_count - 1) << 12) |
206 (fmt->unpack_tight << 17) |
207 (fmt->unpack_align_msb << 18) |
208 ((fmt->bpp - 1) << 9);
209
Lloyd Atkinson9a673492016-07-05 11:41:57 -0400210 if (fmt->fetch_mode != SDE_FETCH_LINEAR) {
Clarence Ipcb410d42016-06-26 22:52:33 -0400211 if (SDE_FORMAT_IS_UBWC(fmt))
212 opmode |= MDSS_MDP_OP_BWC_EN;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700213 src_format |= (fmt->fetch_mode & 3) << 30; /*FRAME_FORMAT */
214 SDE_REG_WRITE(c, SSPP_FETCH_CONFIG,
Lloyd Atkinson9a673492016-07-05 11:41:57 -0400215 SDE_FETCH_CONFIG_RESET_VALUE |
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700216 ctx->highest_bank_bit << 18);
217 }
218
Clarence Ipe78efb72016-06-24 18:35:21 -0400219 opmode |= MDSS_MDP_OP_PE_OVERRIDE;
220
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700221 /* if this is YUV pixel format, enable CSC */
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400222 if (SDE_FORMAT_IS_YUV(fmt))
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700223 src_format |= BIT(15);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700224
Clarence Ipe78efb72016-06-24 18:35:21 -0400225 /* update scaler opmode, if appropriate */
226 _sspp_setup_opmode(ctx,
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400227 VIG_OP_CSC_EN | VIG_OP_CSC_SRC_DATAFMT, SDE_FORMAT_IS_YUV(fmt));
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700228
229 SDE_REG_WRITE(c, SSPP_SRC_FORMAT + idx, src_format);
230 SDE_REG_WRITE(c, SSPP_SRC_UNPACK_PATTERN + idx, unpack);
231 SDE_REG_WRITE(c, SSPP_SRC_OP_MODE + idx, opmode);
232 SDE_REG_WRITE(c, SSPP_SRC_ADDR_SW_STATUS + idx, secure);
233
234 /* clear previous UBWC error */
235 SDE_REG_WRITE(c, SSPP_UBWC_ERROR_STATUS + idx, BIT(31));
236}
237
238static void sde_hw_sspp_setup_pe_config(struct sde_hw_pipe *ctx,
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700239 struct sde_hw_pixel_ext *pe_ext)
240{
Clarence Ipe78efb72016-06-24 18:35:21 -0400241 struct sde_hw_blk_reg_map *c;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700242 u8 color;
243 u32 lr_pe[4], tb_pe[4], tot_req_pixels[4];
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400244 const u32 bytemask = 0xff;
245 const u32 shortmask = 0xffff;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700246 u32 idx;
247
Clarence Ipe78efb72016-06-24 18:35:21 -0400248 if (_sspp_subblk_offset(ctx, SDE_SSPP_SRC, &idx) || !pe_ext)
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700249 return;
250
Clarence Ipe78efb72016-06-24 18:35:21 -0400251 c = &ctx->hw;
252
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700253 /* program SW pixel extension override for all pipes*/
Clarence Ipe78efb72016-06-24 18:35:21 -0400254 for (color = 0; color < SDE_MAX_PLANES; color++) {
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700255 /* color 2 has the same set of registers as color 1 */
256 if (color == 2)
257 continue;
258
259 lr_pe[color] = ((pe_ext->right_ftch[color] & bytemask) << 24)|
260 ((pe_ext->right_rpt[color] & bytemask) << 16)|
261 ((pe_ext->left_ftch[color] & bytemask) << 8)|
262 (pe_ext->left_rpt[color] & bytemask);
263
264 tb_pe[color] = ((pe_ext->btm_ftch[color] & bytemask) << 24)|
265 ((pe_ext->btm_rpt[color] & bytemask) << 16)|
266 ((pe_ext->top_ftch[color] & bytemask) << 8)|
267 (pe_ext->top_rpt[color] & bytemask);
268
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400269 tot_req_pixels[color] = (((pe_ext->roi_h[color] +
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700270 pe_ext->num_ext_pxls_top[color] +
271 pe_ext->num_ext_pxls_btm[color]) & shortmask) << 16) |
272 ((pe_ext->roi_w[color] +
273 pe_ext->num_ext_pxls_left[color] +
274 pe_ext->num_ext_pxls_right[color]) & shortmask);
275 }
276
277 /* color 0 */
278 SDE_REG_WRITE(c, SSPP_SW_PIX_EXT_C0_LR + idx, lr_pe[0]);
279 SDE_REG_WRITE(c, SSPP_SW_PIX_EXT_C0_TB + idx, tb_pe[0]);
280 SDE_REG_WRITE(c, SSPP_SW_PIX_EXT_C0_REQ_PIXELS + idx,
281 tot_req_pixels[0]);
282
283 /* color 1 and color 2 */
284 SDE_REG_WRITE(c, SSPP_SW_PIX_EXT_C1C2_LR + idx, lr_pe[1]);
285 SDE_REG_WRITE(c, SSPP_SW_PIX_EXT_C1C2_TB + idx, tb_pe[1]);
286 SDE_REG_WRITE(c, SSPP_SW_PIX_EXT_C1C2_REQ_PIXELS + idx,
287 tot_req_pixels[1]);
288
289 /* color 3 */
290 SDE_REG_WRITE(c, SSPP_SW_PIX_EXT_C3_LR + idx, lr_pe[3]);
291 SDE_REG_WRITE(c, SSPP_SW_PIX_EXT_C3_TB + idx, lr_pe[3]);
292 SDE_REG_WRITE(c, SSPP_SW_PIX_EXT_C3_REQ_PIXELS + idx,
293 tot_req_pixels[3]);
294}
295
Clarence Ipe78efb72016-06-24 18:35:21 -0400296static void _sde_hw_sspp_setup_scaler(struct sde_hw_pipe *ctx,
297 struct sde_hw_pixel_ext *pe)
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700298{
Clarence Ipe78efb72016-06-24 18:35:21 -0400299 struct sde_hw_blk_reg_map *c;
300 int config_h = 0x0;
301 int config_v = 0x0;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700302 u32 idx;
303
Clarence Ipe78efb72016-06-24 18:35:21 -0400304 if (_sspp_subblk_offset(ctx, SDE_SSPP_SCALER_QSEED2, &idx) || !pe)
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700305 return;
306
Clarence Ipe78efb72016-06-24 18:35:21 -0400307 c = &ctx->hw;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700308
Clarence Ipe78efb72016-06-24 18:35:21 -0400309 /* enable scaler(s) if valid filter set */
Lloyd Atkinson9a673492016-07-05 11:41:57 -0400310 if (pe->horz_filter[SDE_SSPP_COMP_0] < SDE_SCALE_FILTER_MAX)
Clarence Ipe78efb72016-06-24 18:35:21 -0400311 config_h |= pe->horz_filter[SDE_SSPP_COMP_0] << 8;
Lloyd Atkinson9a673492016-07-05 11:41:57 -0400312 if (pe->horz_filter[SDE_SSPP_COMP_1_2] < SDE_SCALE_FILTER_MAX)
Clarence Ipe78efb72016-06-24 18:35:21 -0400313 config_h |= pe->horz_filter[SDE_SSPP_COMP_1_2] << 12;
Lloyd Atkinson9a673492016-07-05 11:41:57 -0400314 if (pe->horz_filter[SDE_SSPP_COMP_3] < SDE_SCALE_FILTER_MAX)
Clarence Ipe78efb72016-06-24 18:35:21 -0400315 config_h |= pe->horz_filter[SDE_SSPP_COMP_3] << 16;
316
317 if (config_h)
318 config_h |= BIT(0);
319
Lloyd Atkinson9a673492016-07-05 11:41:57 -0400320 if (pe->vert_filter[SDE_SSPP_COMP_0] < SDE_SCALE_FILTER_MAX)
Clarence Ipe78efb72016-06-24 18:35:21 -0400321 config_v |= pe->vert_filter[SDE_SSPP_COMP_0] << 10;
Lloyd Atkinson9a673492016-07-05 11:41:57 -0400322 if (pe->vert_filter[SDE_SSPP_COMP_1_2] < SDE_SCALE_FILTER_MAX)
Clarence Ipe78efb72016-06-24 18:35:21 -0400323 config_v |= pe->vert_filter[SDE_SSPP_COMP_1_2] << 14;
Lloyd Atkinson9a673492016-07-05 11:41:57 -0400324 if (pe->vert_filter[SDE_SSPP_COMP_3] < SDE_SCALE_FILTER_MAX)
Clarence Ipe78efb72016-06-24 18:35:21 -0400325 config_v |= pe->vert_filter[SDE_SSPP_COMP_3] << 18;
326
327 if (config_v)
328 config_v |= BIT(1);
329
330 SDE_REG_WRITE(c, SCALE_CONFIG + idx, config_h | config_v);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700331 SDE_REG_WRITE(c, COMP0_3_INIT_PHASE_X + idx,
Clarence Ipe78efb72016-06-24 18:35:21 -0400332 pe->init_phase_x[SDE_SSPP_COMP_0]);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700333 SDE_REG_WRITE(c, COMP0_3_INIT_PHASE_Y + idx,
Clarence Ipe78efb72016-06-24 18:35:21 -0400334 pe->init_phase_y[SDE_SSPP_COMP_0]);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700335 SDE_REG_WRITE(c, COMP0_3_PHASE_STEP_X + idx,
Clarence Ipe78efb72016-06-24 18:35:21 -0400336 pe->phase_step_x[SDE_SSPP_COMP_0]);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700337 SDE_REG_WRITE(c, COMP0_3_PHASE_STEP_Y + idx,
Clarence Ipe78efb72016-06-24 18:35:21 -0400338 pe->phase_step_y[SDE_SSPP_COMP_0]);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700339
340 SDE_REG_WRITE(c, COMP1_2_INIT_PHASE_X + idx,
Clarence Ipe78efb72016-06-24 18:35:21 -0400341 pe->init_phase_x[SDE_SSPP_COMP_1_2]);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700342 SDE_REG_WRITE(c, COMP1_2_INIT_PHASE_Y + idx,
Clarence Ipe78efb72016-06-24 18:35:21 -0400343 pe->init_phase_y[SDE_SSPP_COMP_1_2]);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700344 SDE_REG_WRITE(c, COMP1_2_PHASE_STEP_X + idx,
Clarence Ipe78efb72016-06-24 18:35:21 -0400345 pe->phase_step_x[SDE_SSPP_COMP_1_2]);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700346 SDE_REG_WRITE(c, COMP1_2_PHASE_STEP_Y + idx,
Clarence Ipe78efb72016-06-24 18:35:21 -0400347 pe->phase_step_y[SDE_SSPP_COMP_1_2]);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700348}
349
350/**
351 * sde_hw_sspp_setup_rects()
352 */
353static void sde_hw_sspp_setup_rects(struct sde_hw_pipe *ctx,
354 struct sde_hw_pipe_cfg *cfg,
355 struct sde_hw_pixel_ext *pe_ext)
356{
Clarence Ipe78efb72016-06-24 18:35:21 -0400357 struct sde_hw_blk_reg_map *c;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700358 u32 src_size, src_xy, dst_size, dst_xy, ystride0, ystride1;
359 u32 decimation = 0;
360 u32 idx;
361
Clarence Ipe78efb72016-06-24 18:35:21 -0400362 if (_sspp_subblk_offset(ctx, SDE_SSPP_SRC, &idx) || !cfg)
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700363 return;
364
Clarence Ipe78efb72016-06-24 18:35:21 -0400365 c = &ctx->hw;
366
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700367 /* program pixel extension override */
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400368 if (pe_ext)
Clarence Ipe78efb72016-06-24 18:35:21 -0400369 sde_hw_sspp_setup_pe_config(ctx, pe_ext);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700370
371 /* src and dest rect programming */
Clarence Ipcb410d42016-06-26 22:52:33 -0400372 src_xy = (cfg->src_rect.y << 16) | (cfg->src_rect.x);
373 src_size = (cfg->src_rect.h << 16) | (cfg->src_rect.w);
374 dst_xy = (cfg->dst_rect.y << 16) | (cfg->dst_rect.x);
375 dst_size = (cfg->dst_rect.h << 16) | (cfg->dst_rect.w);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700376
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400377 ystride0 = (cfg->layout.plane_pitch[0]) |
378 (cfg->layout.plane_pitch[1] << 16);
379 ystride1 = (cfg->layout.plane_pitch[2]) |
380 (cfg->layout.plane_pitch[3] << 16);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700381
Clarence Ipe78efb72016-06-24 18:35:21 -0400382 /* program scaler, phase registers, if pipes supporting scaling */
383 if (ctx->cap->features & SDE_SSPP_SCALER) {
384 /* program decimation */
385 decimation = ((1 << cfg->horz_decimation) - 1) << 8;
386 decimation |= ((1 << cfg->vert_decimation) - 1);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700387
Clarence Ipe78efb72016-06-24 18:35:21 -0400388 _sde_hw_sspp_setup_scaler(ctx, pe_ext);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700389 }
390
Clarence Ipcb410d42016-06-26 22:52:33 -0400391 /* rectangle register programming */
392 SDE_REG_WRITE(c, SSPP_SRC_SIZE + idx, src_size);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700393 SDE_REG_WRITE(c, SSPP_SRC_XY + idx, src_xy);
394 SDE_REG_WRITE(c, SSPP_OUT_SIZE + idx, dst_size);
395 SDE_REG_WRITE(c, SSPP_OUT_XY + idx, dst_xy);
396
397 SDE_REG_WRITE(c, SSPP_SRC_YSTRIDE0 + idx, ystride0);
398 SDE_REG_WRITE(c, SSPP_SRC_YSTRIDE1 + idx, ystride1);
399 SDE_REG_WRITE(c, SSPP_DECIMATION_CONFIG + idx, decimation);
400}
401
402static void sde_hw_sspp_setup_sourceaddress(struct sde_hw_pipe *ctx,
403 struct sde_hw_pipe_cfg *cfg)
404{
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700405 int i;
406 u32 idx;
407
408 if (_sspp_subblk_offset(ctx, SDE_SSPP_SRC, &idx))
409 return;
410
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400411 for (i = 0; i < ARRAY_SIZE(cfg->layout.plane_addr); i++)
412 SDE_REG_WRITE(&ctx->hw, SSPP_SRC0_ADDR + idx + i * 0x4,
413 cfg->layout.plane_addr[i]);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700414}
415
Clarence Ipe78efb72016-06-24 18:35:21 -0400416static void sde_hw_sspp_setup_csc(struct sde_hw_pipe *ctx,
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700417 struct sde_csc_cfg *data)
418{
Clarence Ipe78efb72016-06-24 18:35:21 -0400419 u32 idx;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700420
Clarence Ipe78efb72016-06-24 18:35:21 -0400421 if (_sspp_subblk_offset(ctx, SDE_SSPP_CSC, &idx) || !data)
422 return;
423
424 sde_hw_csc_setup(&ctx->hw, idx, data);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700425}
426
427static void sde_hw_sspp_setup_sharpening(struct sde_hw_pipe *ctx,
428 struct sde_hw_sharp_cfg *cfg)
429{
Clarence Ipe78efb72016-06-24 18:35:21 -0400430 struct sde_hw_blk_reg_map *c;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700431 u32 idx;
432
Clarence Ip4c1d9772016-06-26 09:35:38 -0400433 if (_sspp_subblk_offset(ctx, SDE_SSPP_SCALER_QSEED2, &idx) || !cfg ||
434 !test_bit(SDE_SSPP_SCALER_QSEED2, &ctx->cap->features))
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700435 return;
436
Clarence Ipe78efb72016-06-24 18:35:21 -0400437 c = &ctx->hw;
438
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700439 SDE_REG_WRITE(c, VIG_0_QSEED2_SHARP + idx, cfg->strength);
440 SDE_REG_WRITE(c, VIG_0_QSEED2_SHARP + idx + 0x4, cfg->edge_thr);
441 SDE_REG_WRITE(c, VIG_0_QSEED2_SHARP + idx + 0x8, cfg->smooth_thr);
442 SDE_REG_WRITE(c, VIG_0_QSEED2_SHARP + idx + 0xC, cfg->noise_thr);
443}
444
Clarence Ipcb410d42016-06-26 22:52:33 -0400445static void sde_hw_sspp_setup_solidfill(struct sde_hw_pipe *ctx, u32 color)
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700446{
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700447 u32 idx;
448
449 if (_sspp_subblk_offset(ctx, SDE_SSPP_SRC, &idx))
450 return;
451
Clarence Ipcb410d42016-06-26 22:52:33 -0400452 SDE_REG_WRITE(&ctx->hw, SSPP_SRC_CONSTANT_COLOR + idx, color);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700453}
454
455static void sde_hw_sspp_setup_histogram_v1(struct sde_hw_pipe *ctx,
Clarence Ipe78efb72016-06-24 18:35:21 -0400456 void *cfg)
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700457{
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700458}
459
460static void sde_hw_sspp_setup_memcolor(struct sde_hw_pipe *ctx,
461 u32 memcolortype, u8 en)
462{
463}
464
465static void sde_hw_sspp_setup_igc(struct sde_hw_pipe *ctx)
466{
467}
468
469void sde_sspp_setup_pa(struct sde_hw_pipe *c)
470{
471}
472
473static void sde_hw_sspp_setup_danger_safe(struct sde_hw_pipe *ctx,
474 u32 danger_lut, u32 safe_lut)
475{
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700476 u32 idx;
477
478 if (_sspp_subblk_offset(ctx, SDE_SSPP_SRC, &idx))
479 return;
480
Clarence Ipe78efb72016-06-24 18:35:21 -0400481 SDE_REG_WRITE(&ctx->hw, SSPP_DANGER_LUT + idx, danger_lut);
482 SDE_REG_WRITE(&ctx->hw, SSPP_SAFE_LUT + idx, safe_lut);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700483}
484
485static void sde_hw_sspp_qseed2_coeff(void *ctx)
486{
487}
488
489static void _setup_layer_ops(struct sde_hw_sspp_ops *ops,
490 unsigned long features)
491{
492 if (test_bit(SDE_SSPP_SRC, &features)) {
Clarence Ip4c1d9772016-06-26 09:35:38 -0400493 ops->setup_format = sde_hw_sspp_setup_format;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700494 ops->setup_rects = sde_hw_sspp_setup_rects;
495 ops->setup_sourceaddress = sde_hw_sspp_setup_sourceaddress;
496 ops->setup_solidfill = sde_hw_sspp_setup_solidfill;
497 ops->setup_danger_safe = sde_hw_sspp_setup_danger_safe;
498 }
499 if (test_bit(SDE_SSPP_CSC, &features))
Clarence Ipe78efb72016-06-24 18:35:21 -0400500 ops->setup_csc = sde_hw_sspp_setup_csc;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700501
502 if (test_bit(SDE_SSPP_PA_V1, &features)) {
503 ops->setup_sharpening = sde_hw_sspp_setup_sharpening;
504 ops->setup_pa_memcolor = sde_hw_sspp_setup_memcolor;
505 }
506 if (test_bit(SDE_SSPP_HIST_V1, &features))
507 ops->setup_histogram = sde_hw_sspp_setup_histogram_v1;
508
509 if (test_bit(SDE_SSPP_IGC, &features))
510 ops->setup_igc = sde_hw_sspp_setup_igc;
511}
512
513static struct sde_sspp_cfg *_sspp_offset(enum sde_sspp sspp,
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700514 void __iomem *addr,
Clarence Ipe78efb72016-06-24 18:35:21 -0400515 struct sde_mdss_cfg *catalog,
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700516 struct sde_hw_blk_reg_map *b)
517{
518 int i;
519
Clarence Ipe78efb72016-06-24 18:35:21 -0400520 if ((sspp < SSPP_MAX) && catalog && addr && b) {
521 for (i = 0; i < catalog->sspp_count; i++) {
522 if (sspp == catalog->sspp[i].id) {
523 b->base_off = addr;
524 b->blk_off = catalog->sspp[i].base;
525 b->hwversion = catalog->hwversion;
Clarence Ip4ce59322016-06-26 22:27:51 -0400526 b->log_mask = SDE_DBG_MASK_SSPP;
Clarence Ipe78efb72016-06-24 18:35:21 -0400527 return &catalog->sspp[i];
528 }
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700529 }
530 }
531
532 return ERR_PTR(-ENOMEM);
533}
534
535struct sde_hw_pipe *sde_hw_sspp_init(enum sde_sspp idx,
536 void __iomem *addr,
Clarence Ipe78efb72016-06-24 18:35:21 -0400537 struct sde_mdss_cfg *catalog)
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700538{
Clarence Ipe78efb72016-06-24 18:35:21 -0400539 struct sde_hw_pipe *ctx;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700540 struct sde_sspp_cfg *cfg;
541
Clarence Ipe78efb72016-06-24 18:35:21 -0400542 ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
543 if (!ctx)
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700544 return ERR_PTR(-ENOMEM);
545
Clarence Ipe78efb72016-06-24 18:35:21 -0400546 cfg = _sspp_offset(idx, addr, catalog, &ctx->hw);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700547 if (IS_ERR_OR_NULL(cfg)) {
Clarence Ipe78efb72016-06-24 18:35:21 -0400548 kfree(ctx);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700549 return ERR_PTR(-EINVAL);
550 }
551
552 /* Assign ops */
Clarence Ipe78efb72016-06-24 18:35:21 -0400553 ctx->idx = idx;
554 ctx->cap = cfg;
555 _setup_layer_ops(&ctx->ops, ctx->cap->features);
556 ctx->highest_bank_bit = catalog->mdp[0].highest_bank_bit;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700557
558 /*
559 * Perform any default initialization for the sspp blocks
560 */
Clarence Ipe78efb72016-06-24 18:35:21 -0400561 if (test_bit(SDE_SSPP_SCALER_QSEED2, &cfg->features))
562 sde_hw_sspp_qseed2_coeff(ctx);
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700563
Clarence Ipe78efb72016-06-24 18:35:21 -0400564 if (test_bit(SDE_MDP_PANIC_PER_PIPE, &catalog->mdp[0].features))
565 sde_hw_sspp_setup_danger_safe(ctx,
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700566 cfg->sblk->danger_lut,
567 cfg->sblk->safe_lut);
568
Clarence Ipe78efb72016-06-24 18:35:21 -0400569 return ctx;
Narendra Muppalla1b0b3352015-09-29 10:16:51 -0700570}
571
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400572void sde_hw_sspp_destroy(struct sde_hw_pipe *ctx)
573{
574 kfree(ctx);
575}
576