xref: /linux/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg-hw.c (revision 46fb99951fe2c71adfd7f4ea4439af5ed5ebb7f7)
1*46fb9995SMauro Carvalho Chehab // SPDX-License-Identifier: GPL-2.0
2*46fb9995SMauro Carvalho Chehab /*
3*46fb9995SMauro Carvalho Chehab  * i.MX8QXP/i.MX8QM JPEG encoder/decoder v4l2 driver
4*46fb9995SMauro Carvalho Chehab  *
5*46fb9995SMauro Carvalho Chehab  * Copyright 2018-2019 NXP
6*46fb9995SMauro Carvalho Chehab  */
7*46fb9995SMauro Carvalho Chehab 
8*46fb9995SMauro Carvalho Chehab #include <linux/delay.h>
9*46fb9995SMauro Carvalho Chehab #include <media/videobuf2-core.h>
10*46fb9995SMauro Carvalho Chehab #include "mxc-jpeg-hw.h"
11*46fb9995SMauro Carvalho Chehab 
12*46fb9995SMauro Carvalho Chehab #define print_wrapper_reg(dev, base_address, reg_offset)\
13*46fb9995SMauro Carvalho Chehab 		internal_print_wrapper_reg(dev, (base_address), #reg_offset,\
14*46fb9995SMauro Carvalho Chehab 					   (reg_offset))
15*46fb9995SMauro Carvalho Chehab #define internal_print_wrapper_reg(dev, base_address, reg_name, reg_offset) {\
16*46fb9995SMauro Carvalho Chehab 		int val;\
17*46fb9995SMauro Carvalho Chehab 		val = readl((base_address) + (reg_offset));\
18*46fb9995SMauro Carvalho Chehab 		dev_dbg(dev, "Wrapper reg %s = 0x%x\n", reg_name, val);\
19*46fb9995SMauro Carvalho Chehab }
20*46fb9995SMauro Carvalho Chehab 
21*46fb9995SMauro Carvalho Chehab void print_descriptor_info(struct device *dev, struct mxc_jpeg_desc *desc)
22*46fb9995SMauro Carvalho Chehab {
23*46fb9995SMauro Carvalho Chehab 	dev_dbg(dev, " MXC JPEG NEXT_DESCPT_PTR 0x%x\n",
24*46fb9995SMauro Carvalho Chehab 		desc->next_descpt_ptr);
25*46fb9995SMauro Carvalho Chehab 	dev_dbg(dev, " MXC JPEG BUF_BASE0 0x%x\n", desc->buf_base0);
26*46fb9995SMauro Carvalho Chehab 	dev_dbg(dev, " MXC JPEG BUF_BASE1 0x%x\n", desc->buf_base1);
27*46fb9995SMauro Carvalho Chehab 	dev_dbg(dev, " MXC JPEG LINE_PITCH %d\n", desc->line_pitch);
28*46fb9995SMauro Carvalho Chehab 	dev_dbg(dev, " MXC JPEG STM_BUFBASE 0x%x\n", desc->stm_bufbase);
29*46fb9995SMauro Carvalho Chehab 	dev_dbg(dev, " MXC JPEG STM_BUFSIZE %d\n", desc->stm_bufsize);
30*46fb9995SMauro Carvalho Chehab 	dev_dbg(dev, " MXC JPEG IMGSIZE %x (%d x %d)\n", desc->imgsize,
31*46fb9995SMauro Carvalho Chehab 		desc->imgsize >> 16, desc->imgsize & 0xFFFF);
32*46fb9995SMauro Carvalho Chehab 	dev_dbg(dev, " MXC JPEG STM_CTRL 0x%x\n", desc->stm_ctrl);
33*46fb9995SMauro Carvalho Chehab }
34*46fb9995SMauro Carvalho Chehab 
35*46fb9995SMauro Carvalho Chehab void print_cast_status(struct device *dev, void __iomem *reg,
36*46fb9995SMauro Carvalho Chehab 		       unsigned int mode)
37*46fb9995SMauro Carvalho Chehab {
38*46fb9995SMauro Carvalho Chehab 	dev_dbg(dev, "CAST IP status regs:\n");
39*46fb9995SMauro Carvalho Chehab 	print_wrapper_reg(dev, reg, CAST_STATUS0);
40*46fb9995SMauro Carvalho Chehab 	print_wrapper_reg(dev, reg, CAST_STATUS1);
41*46fb9995SMauro Carvalho Chehab 	print_wrapper_reg(dev, reg, CAST_STATUS2);
42*46fb9995SMauro Carvalho Chehab 	print_wrapper_reg(dev, reg, CAST_STATUS3);
43*46fb9995SMauro Carvalho Chehab 	print_wrapper_reg(dev, reg, CAST_STATUS4);
44*46fb9995SMauro Carvalho Chehab 	print_wrapper_reg(dev, reg, CAST_STATUS5);
45*46fb9995SMauro Carvalho Chehab 	print_wrapper_reg(dev, reg, CAST_STATUS6);
46*46fb9995SMauro Carvalho Chehab 	print_wrapper_reg(dev, reg, CAST_STATUS7);
47*46fb9995SMauro Carvalho Chehab 	print_wrapper_reg(dev, reg, CAST_STATUS8);
48*46fb9995SMauro Carvalho Chehab 	print_wrapper_reg(dev, reg, CAST_STATUS9);
49*46fb9995SMauro Carvalho Chehab 	print_wrapper_reg(dev, reg, CAST_STATUS10);
50*46fb9995SMauro Carvalho Chehab 	print_wrapper_reg(dev, reg, CAST_STATUS11);
51*46fb9995SMauro Carvalho Chehab 	print_wrapper_reg(dev, reg, CAST_STATUS12);
52*46fb9995SMauro Carvalho Chehab 	print_wrapper_reg(dev, reg, CAST_STATUS13);
53*46fb9995SMauro Carvalho Chehab 	if (mode == MXC_JPEG_DECODE)
54*46fb9995SMauro Carvalho Chehab 		return;
55*46fb9995SMauro Carvalho Chehab 	print_wrapper_reg(dev, reg, CAST_STATUS14);
56*46fb9995SMauro Carvalho Chehab 	print_wrapper_reg(dev, reg, CAST_STATUS15);
57*46fb9995SMauro Carvalho Chehab 	print_wrapper_reg(dev, reg, CAST_STATUS16);
58*46fb9995SMauro Carvalho Chehab 	print_wrapper_reg(dev, reg, CAST_STATUS17);
59*46fb9995SMauro Carvalho Chehab 	print_wrapper_reg(dev, reg, CAST_STATUS18);
60*46fb9995SMauro Carvalho Chehab 	print_wrapper_reg(dev, reg, CAST_STATUS19);
61*46fb9995SMauro Carvalho Chehab }
62*46fb9995SMauro Carvalho Chehab 
63*46fb9995SMauro Carvalho Chehab void print_wrapper_info(struct device *dev, void __iomem *reg)
64*46fb9995SMauro Carvalho Chehab {
65*46fb9995SMauro Carvalho Chehab 	dev_dbg(dev, "Wrapper regs:\n");
66*46fb9995SMauro Carvalho Chehab 	print_wrapper_reg(dev, reg, GLB_CTRL);
67*46fb9995SMauro Carvalho Chehab 	print_wrapper_reg(dev, reg, COM_STATUS);
68*46fb9995SMauro Carvalho Chehab 	print_wrapper_reg(dev, reg, BUF_BASE0);
69*46fb9995SMauro Carvalho Chehab 	print_wrapper_reg(dev, reg, BUF_BASE1);
70*46fb9995SMauro Carvalho Chehab 	print_wrapper_reg(dev, reg, LINE_PITCH);
71*46fb9995SMauro Carvalho Chehab 	print_wrapper_reg(dev, reg, STM_BUFBASE);
72*46fb9995SMauro Carvalho Chehab 	print_wrapper_reg(dev, reg, STM_BUFSIZE);
73*46fb9995SMauro Carvalho Chehab 	print_wrapper_reg(dev, reg, IMGSIZE);
74*46fb9995SMauro Carvalho Chehab 	print_wrapper_reg(dev, reg, STM_CTRL);
75*46fb9995SMauro Carvalho Chehab }
76*46fb9995SMauro Carvalho Chehab 
77*46fb9995SMauro Carvalho Chehab void mxc_jpeg_enable_irq(void __iomem *reg, int slot)
78*46fb9995SMauro Carvalho Chehab {
79*46fb9995SMauro Carvalho Chehab 	writel(0xFFFFFFFF, reg + MXC_SLOT_OFFSET(slot, SLOT_IRQ_EN));
80*46fb9995SMauro Carvalho Chehab }
81*46fb9995SMauro Carvalho Chehab 
82*46fb9995SMauro Carvalho Chehab void mxc_jpeg_sw_reset(void __iomem *reg)
83*46fb9995SMauro Carvalho Chehab {
84*46fb9995SMauro Carvalho Chehab 	/*
85*46fb9995SMauro Carvalho Chehab 	 * engine soft reset, internal state machine reset
86*46fb9995SMauro Carvalho Chehab 	 * this will not reset registers, however, it seems
87*46fb9995SMauro Carvalho Chehab 	 * the registers may remain inconsistent with the internal state
88*46fb9995SMauro Carvalho Chehab 	 * so, on purpose, at least let GLB_CTRL bits clear after this reset
89*46fb9995SMauro Carvalho Chehab 	 */
90*46fb9995SMauro Carvalho Chehab 	writel(GLB_CTRL_SFT_RST, reg + GLB_CTRL);
91*46fb9995SMauro Carvalho Chehab }
92*46fb9995SMauro Carvalho Chehab 
93*46fb9995SMauro Carvalho Chehab void mxc_jpeg_enc_mode_conf(struct device *dev, void __iomem *reg)
94*46fb9995SMauro Carvalho Chehab {
95*46fb9995SMauro Carvalho Chehab 	dev_dbg(dev, "CAST Encoder CONFIG...\n");
96*46fb9995SMauro Carvalho Chehab 	/*
97*46fb9995SMauro Carvalho Chehab 	 * "Config_Mode" enabled, "Config_Mode auto clear enabled",
98*46fb9995SMauro Carvalho Chehab 	 */
99*46fb9995SMauro Carvalho Chehab 	writel(0xa0, reg + CAST_MODE);
100*46fb9995SMauro Carvalho Chehab 
101*46fb9995SMauro Carvalho Chehab 	/* all markers and segments */
102*46fb9995SMauro Carvalho Chehab 	writel(0x3ff, reg + CAST_CFG_MODE);
103*46fb9995SMauro Carvalho Chehab 
104*46fb9995SMauro Carvalho Chehab 	/* quality factor */
105*46fb9995SMauro Carvalho Chehab 	writel(0x4b, reg + CAST_QUALITY);
106*46fb9995SMauro Carvalho Chehab }
107*46fb9995SMauro Carvalho Chehab 
108*46fb9995SMauro Carvalho Chehab void mxc_jpeg_enc_mode_go(struct device *dev, void __iomem *reg)
109*46fb9995SMauro Carvalho Chehab {
110*46fb9995SMauro Carvalho Chehab 	dev_dbg(dev, "CAST Encoder GO...\n");
111*46fb9995SMauro Carvalho Chehab 	/*
112*46fb9995SMauro Carvalho Chehab 	 * "GO" enabled, "GO bit auto clear" enabled
113*46fb9995SMauro Carvalho Chehab 	 */
114*46fb9995SMauro Carvalho Chehab 	writel(0x140, reg + CAST_MODE);
115*46fb9995SMauro Carvalho Chehab }
116*46fb9995SMauro Carvalho Chehab 
117*46fb9995SMauro Carvalho Chehab void mxc_jpeg_dec_mode_go(struct device *dev, void __iomem *reg)
118*46fb9995SMauro Carvalho Chehab {
119*46fb9995SMauro Carvalho Chehab 	dev_dbg(dev, "CAST Decoder GO...\n");
120*46fb9995SMauro Carvalho Chehab 	writel(MXC_DEC_EXIT_IDLE_MODE, reg + CAST_CTRL);
121*46fb9995SMauro Carvalho Chehab }
122*46fb9995SMauro Carvalho Chehab 
123*46fb9995SMauro Carvalho Chehab int mxc_jpeg_enable(void __iomem *reg)
124*46fb9995SMauro Carvalho Chehab {
125*46fb9995SMauro Carvalho Chehab 	u32 regval;
126*46fb9995SMauro Carvalho Chehab 
127*46fb9995SMauro Carvalho Chehab 	writel(GLB_CTRL_JPG_EN, reg + GLB_CTRL);
128*46fb9995SMauro Carvalho Chehab 	regval = readl(reg);
129*46fb9995SMauro Carvalho Chehab 	return regval;
130*46fb9995SMauro Carvalho Chehab }
131*46fb9995SMauro Carvalho Chehab 
132*46fb9995SMauro Carvalho Chehab void mxc_jpeg_enable_slot(void __iomem *reg, int slot)
133*46fb9995SMauro Carvalho Chehab {
134*46fb9995SMauro Carvalho Chehab 	u32 regval;
135*46fb9995SMauro Carvalho Chehab 
136*46fb9995SMauro Carvalho Chehab 	regval = readl(reg + GLB_CTRL);
137*46fb9995SMauro Carvalho Chehab 	writel(GLB_CTRL_SLOT_EN(slot) | regval, reg + GLB_CTRL);
138*46fb9995SMauro Carvalho Chehab }
139*46fb9995SMauro Carvalho Chehab 
140*46fb9995SMauro Carvalho Chehab void mxc_jpeg_set_l_endian(void __iomem *reg, int le)
141*46fb9995SMauro Carvalho Chehab {
142*46fb9995SMauro Carvalho Chehab 	u32 regval;
143*46fb9995SMauro Carvalho Chehab 
144*46fb9995SMauro Carvalho Chehab 	regval = readl(reg + GLB_CTRL);
145*46fb9995SMauro Carvalho Chehab 	regval &= ~GLB_CTRL_L_ENDIAN(1); /* clear */
146*46fb9995SMauro Carvalho Chehab 	writel(GLB_CTRL_L_ENDIAN(le) | regval, reg + GLB_CTRL); /* set */
147*46fb9995SMauro Carvalho Chehab }
148*46fb9995SMauro Carvalho Chehab 
149*46fb9995SMauro Carvalho Chehab void mxc_jpeg_set_bufsize(struct mxc_jpeg_desc *desc,  u32 bufsize)
150*46fb9995SMauro Carvalho Chehab {
151*46fb9995SMauro Carvalho Chehab 	desc->stm_bufsize = bufsize;
152*46fb9995SMauro Carvalho Chehab }
153*46fb9995SMauro Carvalho Chehab 
154*46fb9995SMauro Carvalho Chehab void mxc_jpeg_set_res(struct mxc_jpeg_desc *desc, u16 w, u16 h)
155*46fb9995SMauro Carvalho Chehab {
156*46fb9995SMauro Carvalho Chehab 	desc->imgsize = w << 16 | h;
157*46fb9995SMauro Carvalho Chehab }
158*46fb9995SMauro Carvalho Chehab 
159*46fb9995SMauro Carvalho Chehab void mxc_jpeg_set_line_pitch(struct mxc_jpeg_desc *desc, u32 line_pitch)
160*46fb9995SMauro Carvalho Chehab {
161*46fb9995SMauro Carvalho Chehab 	desc->line_pitch = line_pitch;
162*46fb9995SMauro Carvalho Chehab }
163*46fb9995SMauro Carvalho Chehab 
164*46fb9995SMauro Carvalho Chehab void mxc_jpeg_set_desc(u32 desc, void __iomem *reg, int slot)
165*46fb9995SMauro Carvalho Chehab {
166*46fb9995SMauro Carvalho Chehab 	writel(desc | MXC_NXT_DESCPT_EN,
167*46fb9995SMauro Carvalho Chehab 	       reg + MXC_SLOT_OFFSET(slot, SLOT_NXT_DESCPT_PTR));
168*46fb9995SMauro Carvalho Chehab }
169