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