28
28
#define PP_FBC_BUDGET_CTL 0x038
29
29
#define PP_FBC_LOSSY_MODE 0x03C
30
30
31
+ #define PP_DITHER_EN 0x000
32
+ #define PP_DITHER_BITDEPTH 0x004
33
+ #define PP_DITHER_MATRIX 0x008
34
+
35
+ #define DITHER_DEPTH_MAP_INDEX 9
36
+
37
+ static u32 dither_depth_map [DITHER_DEPTH_MAP_INDEX ] = {
38
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 2
39
+ };
40
+
31
41
static const struct dpu_pingpong_cfg * _pingpong_offset (enum dpu_pingpong pp ,
32
42
const struct dpu_mdss_cfg * m ,
33
43
void __iomem * addr ,
@@ -49,6 +59,37 @@ static const struct dpu_pingpong_cfg *_pingpong_offset(enum dpu_pingpong pp,
49
59
return ERR_PTR (- EINVAL );
50
60
}
51
61
62
+ static void dpu_hw_pp_setup_dither (struct dpu_hw_pingpong * pp ,
63
+ struct dpu_hw_dither_cfg * cfg )
64
+ {
65
+ struct dpu_hw_blk_reg_map * c ;
66
+ u32 i , base , data = 0 ;
67
+
68
+ c = & pp -> hw ;
69
+ base = pp -> caps -> sblk -> dither .base ;
70
+ if (!cfg ) {
71
+ DPU_REG_WRITE (c , base + PP_DITHER_EN , 0 );
72
+ return ;
73
+ }
74
+
75
+ data = dither_depth_map [cfg -> c0_bitdepth ] & REG_MASK (2 );
76
+ data |= (dither_depth_map [cfg -> c1_bitdepth ] & REG_MASK (2 )) << 2 ;
77
+ data |= (dither_depth_map [cfg -> c2_bitdepth ] & REG_MASK (2 )) << 4 ;
78
+ data |= (dither_depth_map [cfg -> c3_bitdepth ] & REG_MASK (2 )) << 6 ;
79
+ data |= (cfg -> temporal_en ) ? (1 << 8 ) : 0 ;
80
+
81
+ DPU_REG_WRITE (c , base + PP_DITHER_BITDEPTH , data );
82
+
83
+ for (i = 0 ; i < DITHER_MATRIX_SZ - 3 ; i += 4 ) {
84
+ data = (cfg -> matrix [i ] & REG_MASK (4 )) |
85
+ ((cfg -> matrix [i + 1 ] & REG_MASK (4 )) << 4 ) |
86
+ ((cfg -> matrix [i + 2 ] & REG_MASK (4 )) << 8 ) |
87
+ ((cfg -> matrix [i + 3 ] & REG_MASK (4 )) << 12 );
88
+ DPU_REG_WRITE (c , base + PP_DITHER_MATRIX + i , data );
89
+ }
90
+ DPU_REG_WRITE (c , base + PP_DITHER_EN , 1 );
91
+ }
92
+
52
93
static int dpu_hw_pp_setup_te_config (struct dpu_hw_pingpong * pp ,
53
94
struct dpu_hw_tear_check * te )
54
95
{
@@ -180,15 +221,19 @@ static u32 dpu_hw_pp_get_line_count(struct dpu_hw_pingpong *pp)
180
221
return line ;
181
222
}
182
223
183
- static void _setup_pingpong_ops (struct dpu_hw_pingpong_ops * ops ,
184
- const struct dpu_pingpong_cfg * hw_cap )
224
+ static void _setup_pingpong_ops (struct dpu_hw_pingpong * c ,
225
+ unsigned long features )
185
226
{
186
- ops -> setup_tearcheck = dpu_hw_pp_setup_te_config ;
187
- ops -> enable_tearcheck = dpu_hw_pp_enable_te ;
188
- ops -> connect_external_te = dpu_hw_pp_connect_external_te ;
189
- ops -> get_vsync_info = dpu_hw_pp_get_vsync_info ;
190
- ops -> poll_timeout_wr_ptr = dpu_hw_pp_poll_timeout_wr_ptr ;
191
- ops -> get_line_count = dpu_hw_pp_get_line_count ;
227
+ c -> ops .setup_tearcheck = dpu_hw_pp_setup_te_config ;
228
+ c -> ops .enable_tearcheck = dpu_hw_pp_enable_te ;
229
+ c -> ops .connect_external_te = dpu_hw_pp_connect_external_te ;
230
+ c -> ops .get_vsync_info = dpu_hw_pp_get_vsync_info ;
231
+ c -> ops .poll_timeout_wr_ptr = dpu_hw_pp_poll_timeout_wr_ptr ;
232
+ c -> ops .get_line_count = dpu_hw_pp_get_line_count ;
233
+
234
+ if (test_bit (DPU_PINGPONG_DITHER , & features ) &&
235
+ IS_SC7180_TARGET (c -> hw .hwversion ))
236
+ c -> ops .setup_dither = dpu_hw_pp_setup_dither ;
192
237
};
193
238
194
239
static struct dpu_hw_blk_ops dpu_hw_ops ;
@@ -212,7 +257,7 @@ struct dpu_hw_pingpong *dpu_hw_pingpong_init(enum dpu_pingpong idx,
212
257
213
258
c -> idx = idx ;
214
259
c -> caps = cfg ;
215
- _setup_pingpong_ops (& c -> ops , c -> caps );
260
+ _setup_pingpong_ops (c , c -> caps -> features );
216
261
217
262
dpu_hw_blk_init (& c -> base , DPU_HW_BLK_PINGPONG , idx , & dpu_hw_ops );
218
263
0 commit comments