2 * Copyright (c) 2016 MediaTek Inc.
3 * Author: Ming Hsiu Tsai <minghsiu.tsai@mediatek.com>
4 * Rick Chang <rick.chang@mediatek.com>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
17 #include <linux/kernel.h>
18 #include <media/videobuf2-core.h>
20 #include "mtk_jpeg_hw.h"
22 #define MTK_JPEG_DUNUM_MASK(val) (((val) - 1) & 0x3)
25 MTK_JPEG_COLOR_420
= 0x00221111,
26 MTK_JPEG_COLOR_422
= 0x00211111,
27 MTK_JPEG_COLOR_444
= 0x00111111,
28 MTK_JPEG_COLOR_422V
= 0x00121111,
29 MTK_JPEG_COLOR_422X2
= 0x00412121,
30 MTK_JPEG_COLOR_422VX2
= 0x00222121,
31 MTK_JPEG_COLOR_400
= 0x00110000
34 static inline int mtk_jpeg_verify_align(u32 val
, int align
, u32 reg
)
36 if (val
& (align
- 1)) {
37 pr_err("mtk-jpeg: write reg %x without %d align\n", reg
, align
);
44 static int mtk_jpeg_decide_format(struct mtk_jpeg_dec_param
*param
)
46 param
->src_color
= (param
->sampling_w
[0] << 20) |
47 (param
->sampling_h
[0] << 16) |
48 (param
->sampling_w
[1] << 12) |
49 (param
->sampling_h
[1] << 8) |
50 (param
->sampling_w
[2] << 4) |
51 (param
->sampling_h
[2]);
54 switch (param
->src_color
) {
55 case MTK_JPEG_COLOR_444
:
57 param
->dst_fourcc
= V4L2_PIX_FMT_YUV422M
;
59 case MTK_JPEG_COLOR_422X2
:
60 case MTK_JPEG_COLOR_422
:
61 param
->dst_fourcc
= V4L2_PIX_FMT_YUV422M
;
63 case MTK_JPEG_COLOR_422V
:
64 case MTK_JPEG_COLOR_422VX2
:
66 param
->dst_fourcc
= V4L2_PIX_FMT_YUV420M
;
68 case MTK_JPEG_COLOR_420
:
69 param
->dst_fourcc
= V4L2_PIX_FMT_YUV420M
;
71 case MTK_JPEG_COLOR_400
:
72 param
->dst_fourcc
= V4L2_PIX_FMT_GREY
;
75 param
->dst_fourcc
= 0;
82 static void mtk_jpeg_calc_mcu(struct mtk_jpeg_dec_param
*param
)
84 u32 factor_w
, factor_h
;
87 factor_w
= 2 + param
->sampling_w
[0];
88 factor_h
= 2 + param
->sampling_h
[0];
89 param
->mcu_w
= (param
->pic_w
+ (1 << factor_w
) - 1) >> factor_w
;
90 param
->mcu_h
= (param
->pic_h
+ (1 << factor_h
) - 1) >> factor_h
;
91 param
->total_mcu
= param
->mcu_w
* param
->mcu_h
;
92 param
->unit_num
= ((param
->pic_w
+ 7) >> 3) * ((param
->pic_h
+ 7) >> 3);
94 for (i
= 0; i
< MTK_JPEG_COMP_MAX
; i
++) {
95 param
->blk_comp
[i
] = 0;
96 if (i
>= param
->comp_num
)
98 param
->blk_comp
[i
] = param
->sampling_w
[i
] *
100 param
->blk_num
+= param
->blk_comp
[i
];
103 param
->membership
= 0;
104 for (i
= 0, blk
= 0, comp
= 0; i
< MTK_JPEG_BLOCK_MAX
; i
++) {
105 if (i
< param
->blk_num
&& comp
< param
->comp_num
) {
108 tmp
= (0x04 + (comp
& 0x3));
109 param
->membership
|= tmp
<< (i
* 3);
110 if (++blk
== param
->blk_comp
[comp
]) {
115 param
->membership
|= 7 << (i
* 3);
120 static void mtk_jpeg_calc_dma_group(struct mtk_jpeg_dec_param
*param
)
124 if (param
->src_color
== MTK_JPEG_COLOR_444
&&
125 param
->dst_fourcc
== V4L2_PIX_FMT_YUV422M
)
127 else if (param
->src_color
== MTK_JPEG_COLOR_422V
&&
128 param
->dst_fourcc
== V4L2_PIX_FMT_YUV420M
)
130 else if (param
->src_color
== MTK_JPEG_COLOR_422X2
&&
131 param
->dst_fourcc
== V4L2_PIX_FMT_YUV422M
)
133 else if (param
->src_color
== MTK_JPEG_COLOR_400
||
134 (param
->src_color
& 0x0FFFF) == 0)
137 param
->dma_mcu
= 1 << factor_mcu
;
138 param
->dma_group
= param
->mcu_w
/ param
->dma_mcu
;
139 param
->dma_last_mcu
= param
->mcu_w
% param
->dma_mcu
;
140 if (param
->dma_last_mcu
)
143 param
->dma_last_mcu
= param
->dma_mcu
;
146 static int mtk_jpeg_calc_dst_size(struct mtk_jpeg_dec_param
*param
)
153 brz_w
[1] = param
->uv_brz_w
;
156 for (i
= 0; i
< param
->comp_num
; i
++) {
160 padding_w
= param
->mcu_w
* MTK_JPEG_DCTSIZE
*
161 param
->sampling_w
[i
];
162 /* output format is 420/422 */
163 param
->comp_w
[i
] = padding_w
>> brz_w
[i
];
164 param
->comp_w
[i
] = mtk_jpeg_align(param
->comp_w
[i
],
166 param
->img_stride
[i
] = i
? mtk_jpeg_align(param
->comp_w
[i
], 16)
167 : mtk_jpeg_align(param
->comp_w
[i
], 32);
168 ds_row_h
[i
] = (MTK_JPEG_DCTSIZE
* param
->sampling_h
[i
]);
170 param
->dec_w
= param
->img_stride
[0];
171 param
->dec_h
= ds_row_h
[0] * param
->mcu_h
;
173 for (i
= 0; i
< MTK_JPEG_COMP_MAX
; i
++) {
174 /* They must be equal in frame mode. */
175 param
->mem_stride
[i
] = param
->img_stride
[i
];
176 param
->comp_size
[i
] = param
->mem_stride
[i
] * ds_row_h
[i
] *
180 param
->y_size
= param
->comp_size
[0];
181 param
->uv_size
= param
->comp_size
[1];
182 param
->dec_size
= param
->y_size
+ (param
->uv_size
<< 1);
187 int mtk_jpeg_dec_fill_param(struct mtk_jpeg_dec_param
*param
)
189 if (mtk_jpeg_decide_format(param
))
192 mtk_jpeg_calc_mcu(param
);
193 mtk_jpeg_calc_dma_group(param
);
194 if (mtk_jpeg_calc_dst_size(param
))
200 u32
mtk_jpeg_dec_get_int_status(void __iomem
*base
)
204 ret
= readl(base
+ JPGDEC_REG_INTERRUPT_STATUS
) & BIT_INQST_MASK_ALLIRQ
;
206 writel(ret
, base
+ JPGDEC_REG_INTERRUPT_STATUS
);
211 u32
mtk_jpeg_dec_enum_result(u32 irq_result
)
213 if (irq_result
& BIT_INQST_MASK_EOF
)
214 return MTK_JPEG_DEC_RESULT_EOF_DONE
;
215 if (irq_result
& BIT_INQST_MASK_PAUSE
)
216 return MTK_JPEG_DEC_RESULT_PAUSE
;
217 if (irq_result
& BIT_INQST_MASK_UNDERFLOW
)
218 return MTK_JPEG_DEC_RESULT_UNDERFLOW
;
219 if (irq_result
& BIT_INQST_MASK_OVERFLOW
)
220 return MTK_JPEG_DEC_RESULT_OVERFLOW
;
221 if (irq_result
& BIT_INQST_MASK_ERROR_BS
)
222 return MTK_JPEG_DEC_RESULT_ERROR_BS
;
224 return MTK_JPEG_DEC_RESULT_ERROR_UNKNOWN
;
227 void mtk_jpeg_dec_start(void __iomem
*base
)
229 writel(0, base
+ JPGDEC_REG_TRIG
);
232 static void mtk_jpeg_dec_soft_reset(void __iomem
*base
)
234 writel(0x0000FFFF, base
+ JPGDEC_REG_INTERRUPT_STATUS
);
235 writel(0x00, base
+ JPGDEC_REG_RESET
);
236 writel(0x01, base
+ JPGDEC_REG_RESET
);
239 static void mtk_jpeg_dec_hard_reset(void __iomem
*base
)
241 writel(0x00, base
+ JPGDEC_REG_RESET
);
242 writel(0x10, base
+ JPGDEC_REG_RESET
);
245 void mtk_jpeg_dec_reset(void __iomem
*base
)
247 mtk_jpeg_dec_soft_reset(base
);
248 mtk_jpeg_dec_hard_reset(base
);
251 static void mtk_jpeg_dec_set_brz_factor(void __iomem
*base
, u8 yscale_w
,
252 u8 yscale_h
, u8 uvscale_w
, u8 uvscale_h
)
256 val
= (uvscale_h
<< 12) | (uvscale_w
<< 8) |
257 (yscale_h
<< 4) | yscale_w
;
258 writel(val
, base
+ JPGDEC_REG_BRZ_FACTOR
);
261 static void mtk_jpeg_dec_set_dst_bank0(void __iomem
*base
, u32 addr_y
,
262 u32 addr_u
, u32 addr_v
)
264 mtk_jpeg_verify_align(addr_y
, 16, JPGDEC_REG_DEST_ADDR0_Y
);
265 writel(addr_y
, base
+ JPGDEC_REG_DEST_ADDR0_Y
);
266 mtk_jpeg_verify_align(addr_u
, 16, JPGDEC_REG_DEST_ADDR0_U
);
267 writel(addr_u
, base
+ JPGDEC_REG_DEST_ADDR0_U
);
268 mtk_jpeg_verify_align(addr_v
, 16, JPGDEC_REG_DEST_ADDR0_V
);
269 writel(addr_v
, base
+ JPGDEC_REG_DEST_ADDR0_V
);
272 static void mtk_jpeg_dec_set_dst_bank1(void __iomem
*base
, u32 addr_y
,
273 u32 addr_u
, u32 addr_v
)
275 writel(addr_y
, base
+ JPGDEC_REG_DEST_ADDR1_Y
);
276 writel(addr_u
, base
+ JPGDEC_REG_DEST_ADDR1_U
);
277 writel(addr_v
, base
+ JPGDEC_REG_DEST_ADDR1_V
);
280 static void mtk_jpeg_dec_set_mem_stride(void __iomem
*base
, u32 stride_y
,
283 writel((stride_y
& 0xFFFF), base
+ JPGDEC_REG_STRIDE_Y
);
284 writel((stride_uv
& 0xFFFF), base
+ JPGDEC_REG_STRIDE_UV
);
287 static void mtk_jpeg_dec_set_img_stride(void __iomem
*base
, u32 stride_y
,
290 writel((stride_y
& 0xFFFF), base
+ JPGDEC_REG_IMG_STRIDE_Y
);
291 writel((stride_uv
& 0xFFFF), base
+ JPGDEC_REG_IMG_STRIDE_UV
);
294 static void mtk_jpeg_dec_set_pause_mcu_idx(void __iomem
*base
, u32 idx
)
296 writel(idx
& 0x0003FFFFFF, base
+ JPGDEC_REG_PAUSE_MCU_NUM
);
299 static void mtk_jpeg_dec_set_dec_mode(void __iomem
*base
, u32 mode
)
301 writel(mode
& 0x03, base
+ JPGDEC_REG_OPERATION_MODE
);
304 static void mtk_jpeg_dec_set_bs_write_ptr(void __iomem
*base
, u32 ptr
)
306 mtk_jpeg_verify_align(ptr
, 16, JPGDEC_REG_FILE_BRP
);
307 writel(ptr
, base
+ JPGDEC_REG_FILE_BRP
);
310 static void mtk_jpeg_dec_set_bs_info(void __iomem
*base
, u32 addr
, u32 size
)
312 mtk_jpeg_verify_align(addr
, 16, JPGDEC_REG_FILE_ADDR
);
313 mtk_jpeg_verify_align(size
, 128, JPGDEC_REG_FILE_TOTAL_SIZE
);
314 writel(addr
, base
+ JPGDEC_REG_FILE_ADDR
);
315 writel(size
, base
+ JPGDEC_REG_FILE_TOTAL_SIZE
);
318 static void mtk_jpeg_dec_set_comp_id(void __iomem
*base
, u32 id_y
, u32 id_u
,
323 val
= ((id_y
& 0x00FF) << 24) | ((id_u
& 0x00FF) << 16) |
324 ((id_v
& 0x00FF) << 8);
325 writel(val
, base
+ JPGDEC_REG_COMP_ID
);
328 static void mtk_jpeg_dec_set_total_mcu(void __iomem
*base
, u32 num
)
330 writel(num
- 1, base
+ JPGDEC_REG_TOTAL_MCU_NUM
);
333 static void mtk_jpeg_dec_set_comp0_du(void __iomem
*base
, u32 num
)
335 writel(num
- 1, base
+ JPGDEC_REG_COMP0_DATA_UNIT_NUM
);
338 static void mtk_jpeg_dec_set_du_membership(void __iomem
*base
, u32 member
,
343 member
|= (isgray
<< 31) | (gmc
<< 30);
344 writel(member
, base
+ JPGDEC_REG_DU_CTRL
);
347 static void mtk_jpeg_dec_set_q_table(void __iomem
*base
, u32 id0
, u32 id1
,
352 val
= ((id0
& 0x0f) << 8) | ((id1
& 0x0f) << 4) | ((id2
& 0x0f) << 0);
353 writel(val
, base
+ JPGDEC_REG_QT_ID
);
356 static void mtk_jpeg_dec_set_dma_group(void __iomem
*base
, u32 mcu_group
,
357 u32 group_num
, u32 last_mcu
)
361 val
= (((mcu_group
- 1) & 0x00FF) << 16) |
362 (((group_num
- 1) & 0x007F) << 8) |
363 ((last_mcu
- 1) & 0x00FF);
364 writel(val
, base
+ JPGDEC_REG_WDMA_CTRL
);
367 static void mtk_jpeg_dec_set_sampling_factor(void __iomem
*base
, u32 comp_num
,
368 u32 y_w
, u32 y_h
, u32 u_w
,
369 u32 u_h
, u32 v_w
, u32 v_h
)
372 u32 y_wh
= (MTK_JPEG_DUNUM_MASK(y_w
) << 2) | MTK_JPEG_DUNUM_MASK(y_h
);
373 u32 u_wh
= (MTK_JPEG_DUNUM_MASK(u_w
) << 2) | MTK_JPEG_DUNUM_MASK(u_h
);
374 u32 v_wh
= (MTK_JPEG_DUNUM_MASK(v_w
) << 2) | MTK_JPEG_DUNUM_MASK(v_h
);
379 val
= (y_wh
<< 8) | (u_wh
<< 4) | v_wh
;
380 writel(val
, base
+ JPGDEC_REG_DU_NUM
);
383 void mtk_jpeg_dec_set_config(void __iomem
*base
,
384 struct mtk_jpeg_dec_param
*config
,
385 struct mtk_jpeg_bs
*bs
,
386 struct mtk_jpeg_fb
*fb
)
388 mtk_jpeg_dec_set_brz_factor(base
, 0, 0, config
->uv_brz_w
, 0);
389 mtk_jpeg_dec_set_dec_mode(base
, 0);
390 mtk_jpeg_dec_set_comp0_du(base
, config
->unit_num
);
391 mtk_jpeg_dec_set_total_mcu(base
, config
->total_mcu
);
392 mtk_jpeg_dec_set_bs_info(base
, bs
->str_addr
, bs
->size
);
393 mtk_jpeg_dec_set_bs_write_ptr(base
, bs
->end_addr
);
394 mtk_jpeg_dec_set_du_membership(base
, config
->membership
, 1,
395 (config
->comp_num
== 1) ? 1 : 0);
396 mtk_jpeg_dec_set_comp_id(base
, config
->comp_id
[0], config
->comp_id
[1],
398 mtk_jpeg_dec_set_q_table(base
, config
->qtbl_num
[0],
399 config
->qtbl_num
[1], config
->qtbl_num
[2]);
400 mtk_jpeg_dec_set_sampling_factor(base
, config
->comp_num
,
401 config
->sampling_w
[0],
402 config
->sampling_h
[0],
403 config
->sampling_w
[1],
404 config
->sampling_h
[1],
405 config
->sampling_w
[2],
406 config
->sampling_h
[2]);
407 mtk_jpeg_dec_set_mem_stride(base
, config
->mem_stride
[0],
408 config
->mem_stride
[1]);
409 mtk_jpeg_dec_set_img_stride(base
, config
->img_stride
[0],
410 config
->img_stride
[1]);
411 mtk_jpeg_dec_set_dst_bank0(base
, fb
->plane_addr
[0],
412 fb
->plane_addr
[1], fb
->plane_addr
[2]);
413 mtk_jpeg_dec_set_dst_bank1(base
, 0, 0, 0);
414 mtk_jpeg_dec_set_dma_group(base
, config
->dma_mcu
, config
->dma_group
,
415 config
->dma_last_mcu
);
416 mtk_jpeg_dec_set_pause_mcu_idx(base
, config
->total_mcu
);