1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (c) 2016 MediaTek Inc.
4 * Author: Ming Hsiu Tsai <minghsiu.tsai@mediatek.com>
5 * Rick Chang <rick.chang@mediatek.com>
9 #include <linux/kernel.h>
10 #include <media/videobuf2-core.h>
12 #include "mtk_jpeg_hw.h"
14 #define MTK_JPEG_DUNUM_MASK(val) (((val) - 1) & 0x3)
17 MTK_JPEG_COLOR_420
= 0x00221111,
18 MTK_JPEG_COLOR_422
= 0x00211111,
19 MTK_JPEG_COLOR_444
= 0x00111111,
20 MTK_JPEG_COLOR_422V
= 0x00121111,
21 MTK_JPEG_COLOR_422X2
= 0x00412121,
22 MTK_JPEG_COLOR_422VX2
= 0x00222121,
23 MTK_JPEG_COLOR_400
= 0x00110000
26 static inline int mtk_jpeg_verify_align(u32 val
, int align
, u32 reg
)
28 if (val
& (align
- 1)) {
29 pr_err("mtk-jpeg: write reg %x without %d align\n", reg
, align
);
36 static int mtk_jpeg_decide_format(struct mtk_jpeg_dec_param
*param
)
38 param
->src_color
= (param
->sampling_w
[0] << 20) |
39 (param
->sampling_h
[0] << 16) |
40 (param
->sampling_w
[1] << 12) |
41 (param
->sampling_h
[1] << 8) |
42 (param
->sampling_w
[2] << 4) |
43 (param
->sampling_h
[2]);
46 switch (param
->src_color
) {
47 case MTK_JPEG_COLOR_444
:
49 param
->dst_fourcc
= V4L2_PIX_FMT_YUV422M
;
51 case MTK_JPEG_COLOR_422X2
:
52 case MTK_JPEG_COLOR_422
:
53 param
->dst_fourcc
= V4L2_PIX_FMT_YUV422M
;
55 case MTK_JPEG_COLOR_422V
:
56 case MTK_JPEG_COLOR_422VX2
:
58 param
->dst_fourcc
= V4L2_PIX_FMT_YUV420M
;
60 case MTK_JPEG_COLOR_420
:
61 param
->dst_fourcc
= V4L2_PIX_FMT_YUV420M
;
63 case MTK_JPEG_COLOR_400
:
64 param
->dst_fourcc
= V4L2_PIX_FMT_GREY
;
67 param
->dst_fourcc
= 0;
74 static void mtk_jpeg_calc_mcu(struct mtk_jpeg_dec_param
*param
)
76 u32 factor_w
, factor_h
;
79 factor_w
= 2 + param
->sampling_w
[0];
80 factor_h
= 2 + param
->sampling_h
[0];
81 param
->mcu_w
= (param
->pic_w
+ (1 << factor_w
) - 1) >> factor_w
;
82 param
->mcu_h
= (param
->pic_h
+ (1 << factor_h
) - 1) >> factor_h
;
83 param
->total_mcu
= param
->mcu_w
* param
->mcu_h
;
84 param
->unit_num
= ((param
->pic_w
+ 7) >> 3) * ((param
->pic_h
+ 7) >> 3);
86 for (i
= 0; i
< MTK_JPEG_COMP_MAX
; i
++) {
87 param
->blk_comp
[i
] = 0;
88 if (i
>= param
->comp_num
)
90 param
->blk_comp
[i
] = param
->sampling_w
[i
] *
92 param
->blk_num
+= param
->blk_comp
[i
];
95 param
->membership
= 0;
96 for (i
= 0, blk
= 0, comp
= 0; i
< MTK_JPEG_BLOCK_MAX
; i
++) {
97 if (i
< param
->blk_num
&& comp
< param
->comp_num
) {
100 tmp
= (0x04 + (comp
& 0x3));
101 param
->membership
|= tmp
<< (i
* 3);
102 if (++blk
== param
->blk_comp
[comp
]) {
107 param
->membership
|= 7 << (i
* 3);
112 static void mtk_jpeg_calc_dma_group(struct mtk_jpeg_dec_param
*param
)
116 if (param
->src_color
== MTK_JPEG_COLOR_444
&&
117 param
->dst_fourcc
== V4L2_PIX_FMT_YUV422M
)
119 else if (param
->src_color
== MTK_JPEG_COLOR_422V
&&
120 param
->dst_fourcc
== V4L2_PIX_FMT_YUV420M
)
122 else if (param
->src_color
== MTK_JPEG_COLOR_422X2
&&
123 param
->dst_fourcc
== V4L2_PIX_FMT_YUV422M
)
125 else if (param
->src_color
== MTK_JPEG_COLOR_400
||
126 (param
->src_color
& 0x0FFFF) == 0)
129 param
->dma_mcu
= 1 << factor_mcu
;
130 param
->dma_group
= param
->mcu_w
/ param
->dma_mcu
;
131 param
->dma_last_mcu
= param
->mcu_w
% param
->dma_mcu
;
132 if (param
->dma_last_mcu
)
135 param
->dma_last_mcu
= param
->dma_mcu
;
138 static int mtk_jpeg_calc_dst_size(struct mtk_jpeg_dec_param
*param
)
145 brz_w
[1] = param
->uv_brz_w
;
148 for (i
= 0; i
< param
->comp_num
; i
++) {
152 padding_w
= param
->mcu_w
* MTK_JPEG_DCTSIZE
*
153 param
->sampling_w
[i
];
154 /* output format is 420/422 */
155 param
->comp_w
[i
] = padding_w
>> brz_w
[i
];
156 param
->comp_w
[i
] = mtk_jpeg_align(param
->comp_w
[i
],
158 param
->img_stride
[i
] = i
? mtk_jpeg_align(param
->comp_w
[i
], 16)
159 : mtk_jpeg_align(param
->comp_w
[i
], 32);
160 ds_row_h
[i
] = (MTK_JPEG_DCTSIZE
* param
->sampling_h
[i
]);
162 param
->dec_w
= param
->img_stride
[0];
163 param
->dec_h
= ds_row_h
[0] * param
->mcu_h
;
165 for (i
= 0; i
< MTK_JPEG_COMP_MAX
; i
++) {
166 /* They must be equal in frame mode. */
167 param
->mem_stride
[i
] = param
->img_stride
[i
];
168 param
->comp_size
[i
] = param
->mem_stride
[i
] * ds_row_h
[i
] *
172 param
->y_size
= param
->comp_size
[0];
173 param
->uv_size
= param
->comp_size
[1];
174 param
->dec_size
= param
->y_size
+ (param
->uv_size
<< 1);
179 int mtk_jpeg_dec_fill_param(struct mtk_jpeg_dec_param
*param
)
181 if (mtk_jpeg_decide_format(param
))
184 mtk_jpeg_calc_mcu(param
);
185 mtk_jpeg_calc_dma_group(param
);
186 if (mtk_jpeg_calc_dst_size(param
))
192 u32
mtk_jpeg_dec_get_int_status(void __iomem
*base
)
196 ret
= readl(base
+ JPGDEC_REG_INTERRUPT_STATUS
) & BIT_INQST_MASK_ALLIRQ
;
198 writel(ret
, base
+ JPGDEC_REG_INTERRUPT_STATUS
);
203 u32
mtk_jpeg_dec_enum_result(u32 irq_result
)
205 if (irq_result
& BIT_INQST_MASK_EOF
)
206 return MTK_JPEG_DEC_RESULT_EOF_DONE
;
207 if (irq_result
& BIT_INQST_MASK_PAUSE
)
208 return MTK_JPEG_DEC_RESULT_PAUSE
;
209 if (irq_result
& BIT_INQST_MASK_UNDERFLOW
)
210 return MTK_JPEG_DEC_RESULT_UNDERFLOW
;
211 if (irq_result
& BIT_INQST_MASK_OVERFLOW
)
212 return MTK_JPEG_DEC_RESULT_OVERFLOW
;
213 if (irq_result
& BIT_INQST_MASK_ERROR_BS
)
214 return MTK_JPEG_DEC_RESULT_ERROR_BS
;
216 return MTK_JPEG_DEC_RESULT_ERROR_UNKNOWN
;
219 void mtk_jpeg_dec_start(void __iomem
*base
)
221 writel(0, base
+ JPGDEC_REG_TRIG
);
224 static void mtk_jpeg_dec_soft_reset(void __iomem
*base
)
226 writel(0x0000FFFF, base
+ JPGDEC_REG_INTERRUPT_STATUS
);
227 writel(0x00, base
+ JPGDEC_REG_RESET
);
228 writel(0x01, base
+ JPGDEC_REG_RESET
);
231 static void mtk_jpeg_dec_hard_reset(void __iomem
*base
)
233 writel(0x00, base
+ JPGDEC_REG_RESET
);
234 writel(0x10, base
+ JPGDEC_REG_RESET
);
237 void mtk_jpeg_dec_reset(void __iomem
*base
)
239 mtk_jpeg_dec_soft_reset(base
);
240 mtk_jpeg_dec_hard_reset(base
);
243 static void mtk_jpeg_dec_set_brz_factor(void __iomem
*base
, u8 yscale_w
,
244 u8 yscale_h
, u8 uvscale_w
, u8 uvscale_h
)
248 val
= (uvscale_h
<< 12) | (uvscale_w
<< 8) |
249 (yscale_h
<< 4) | yscale_w
;
250 writel(val
, base
+ JPGDEC_REG_BRZ_FACTOR
);
253 static void mtk_jpeg_dec_set_dst_bank0(void __iomem
*base
, u32 addr_y
,
254 u32 addr_u
, u32 addr_v
)
256 mtk_jpeg_verify_align(addr_y
, 16, JPGDEC_REG_DEST_ADDR0_Y
);
257 writel(addr_y
, base
+ JPGDEC_REG_DEST_ADDR0_Y
);
258 mtk_jpeg_verify_align(addr_u
, 16, JPGDEC_REG_DEST_ADDR0_U
);
259 writel(addr_u
, base
+ JPGDEC_REG_DEST_ADDR0_U
);
260 mtk_jpeg_verify_align(addr_v
, 16, JPGDEC_REG_DEST_ADDR0_V
);
261 writel(addr_v
, base
+ JPGDEC_REG_DEST_ADDR0_V
);
264 static void mtk_jpeg_dec_set_dst_bank1(void __iomem
*base
, u32 addr_y
,
265 u32 addr_u
, u32 addr_v
)
267 writel(addr_y
, base
+ JPGDEC_REG_DEST_ADDR1_Y
);
268 writel(addr_u
, base
+ JPGDEC_REG_DEST_ADDR1_U
);
269 writel(addr_v
, base
+ JPGDEC_REG_DEST_ADDR1_V
);
272 static void mtk_jpeg_dec_set_mem_stride(void __iomem
*base
, u32 stride_y
,
275 writel((stride_y
& 0xFFFF), base
+ JPGDEC_REG_STRIDE_Y
);
276 writel((stride_uv
& 0xFFFF), base
+ JPGDEC_REG_STRIDE_UV
);
279 static void mtk_jpeg_dec_set_img_stride(void __iomem
*base
, u32 stride_y
,
282 writel((stride_y
& 0xFFFF), base
+ JPGDEC_REG_IMG_STRIDE_Y
);
283 writel((stride_uv
& 0xFFFF), base
+ JPGDEC_REG_IMG_STRIDE_UV
);
286 static void mtk_jpeg_dec_set_pause_mcu_idx(void __iomem
*base
, u32 idx
)
288 writel(idx
& 0x0003FFFFFF, base
+ JPGDEC_REG_PAUSE_MCU_NUM
);
291 static void mtk_jpeg_dec_set_dec_mode(void __iomem
*base
, u32 mode
)
293 writel(mode
& 0x03, base
+ JPGDEC_REG_OPERATION_MODE
);
296 static void mtk_jpeg_dec_set_bs_write_ptr(void __iomem
*base
, u32 ptr
)
298 mtk_jpeg_verify_align(ptr
, 16, JPGDEC_REG_FILE_BRP
);
299 writel(ptr
, base
+ JPGDEC_REG_FILE_BRP
);
302 static void mtk_jpeg_dec_set_bs_info(void __iomem
*base
, u32 addr
, u32 size
)
304 mtk_jpeg_verify_align(addr
, 16, JPGDEC_REG_FILE_ADDR
);
305 mtk_jpeg_verify_align(size
, 128, JPGDEC_REG_FILE_TOTAL_SIZE
);
306 writel(addr
, base
+ JPGDEC_REG_FILE_ADDR
);
307 writel(size
, base
+ JPGDEC_REG_FILE_TOTAL_SIZE
);
310 static void mtk_jpeg_dec_set_comp_id(void __iomem
*base
, u32 id_y
, u32 id_u
,
315 val
= ((id_y
& 0x00FF) << 24) | ((id_u
& 0x00FF) << 16) |
316 ((id_v
& 0x00FF) << 8);
317 writel(val
, base
+ JPGDEC_REG_COMP_ID
);
320 static void mtk_jpeg_dec_set_total_mcu(void __iomem
*base
, u32 num
)
322 writel(num
- 1, base
+ JPGDEC_REG_TOTAL_MCU_NUM
);
325 static void mtk_jpeg_dec_set_comp0_du(void __iomem
*base
, u32 num
)
327 writel(num
- 1, base
+ JPGDEC_REG_COMP0_DATA_UNIT_NUM
);
330 static void mtk_jpeg_dec_set_du_membership(void __iomem
*base
, u32 member
,
335 member
|= (isgray
<< 31) | (gmc
<< 30);
336 writel(member
, base
+ JPGDEC_REG_DU_CTRL
);
339 static void mtk_jpeg_dec_set_q_table(void __iomem
*base
, u32 id0
, u32 id1
,
344 val
= ((id0
& 0x0f) << 8) | ((id1
& 0x0f) << 4) | ((id2
& 0x0f) << 0);
345 writel(val
, base
+ JPGDEC_REG_QT_ID
);
348 static void mtk_jpeg_dec_set_dma_group(void __iomem
*base
, u32 mcu_group
,
349 u32 group_num
, u32 last_mcu
)
353 val
= (((mcu_group
- 1) & 0x00FF) << 16) |
354 (((group_num
- 1) & 0x007F) << 8) |
355 ((last_mcu
- 1) & 0x00FF);
356 writel(val
, base
+ JPGDEC_REG_WDMA_CTRL
);
359 static void mtk_jpeg_dec_set_sampling_factor(void __iomem
*base
, u32 comp_num
,
360 u32 y_w
, u32 y_h
, u32 u_w
,
361 u32 u_h
, u32 v_w
, u32 v_h
)
364 u32 y_wh
= (MTK_JPEG_DUNUM_MASK(y_w
) << 2) | MTK_JPEG_DUNUM_MASK(y_h
);
365 u32 u_wh
= (MTK_JPEG_DUNUM_MASK(u_w
) << 2) | MTK_JPEG_DUNUM_MASK(u_h
);
366 u32 v_wh
= (MTK_JPEG_DUNUM_MASK(v_w
) << 2) | MTK_JPEG_DUNUM_MASK(v_h
);
371 val
= (y_wh
<< 8) | (u_wh
<< 4) | v_wh
;
372 writel(val
, base
+ JPGDEC_REG_DU_NUM
);
375 void mtk_jpeg_dec_set_config(void __iomem
*base
,
376 struct mtk_jpeg_dec_param
*config
,
377 struct mtk_jpeg_bs
*bs
,
378 struct mtk_jpeg_fb
*fb
)
380 mtk_jpeg_dec_set_brz_factor(base
, 0, 0, config
->uv_brz_w
, 0);
381 mtk_jpeg_dec_set_dec_mode(base
, 0);
382 mtk_jpeg_dec_set_comp0_du(base
, config
->unit_num
);
383 mtk_jpeg_dec_set_total_mcu(base
, config
->total_mcu
);
384 mtk_jpeg_dec_set_bs_info(base
, bs
->str_addr
, bs
->size
);
385 mtk_jpeg_dec_set_bs_write_ptr(base
, bs
->end_addr
);
386 mtk_jpeg_dec_set_du_membership(base
, config
->membership
, 1,
387 (config
->comp_num
== 1) ? 1 : 0);
388 mtk_jpeg_dec_set_comp_id(base
, config
->comp_id
[0], config
->comp_id
[1],
390 mtk_jpeg_dec_set_q_table(base
, config
->qtbl_num
[0],
391 config
->qtbl_num
[1], config
->qtbl_num
[2]);
392 mtk_jpeg_dec_set_sampling_factor(base
, config
->comp_num
,
393 config
->sampling_w
[0],
394 config
->sampling_h
[0],
395 config
->sampling_w
[1],
396 config
->sampling_h
[1],
397 config
->sampling_w
[2],
398 config
->sampling_h
[2]);
399 mtk_jpeg_dec_set_mem_stride(base
, config
->mem_stride
[0],
400 config
->mem_stride
[1]);
401 mtk_jpeg_dec_set_img_stride(base
, config
->img_stride
[0],
402 config
->img_stride
[1]);
403 mtk_jpeg_dec_set_dst_bank0(base
, fb
->plane_addr
[0],
404 fb
->plane_addr
[1], fb
->plane_addr
[2]);
405 mtk_jpeg_dec_set_dst_bank1(base
, 0, 0, 0);
406 mtk_jpeg_dec_set_dma_group(base
, config
->dma_mcu
, config
->dma_group
,
407 config
->dma_last_mcu
);
408 mtk_jpeg_dec_set_pause_mcu_idx(base
, config
->total_mcu
);