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