blob: 6bb1b1d20f53a86b3d24cd93ce884bef4c6f1c56 [file] [log] [blame]
/*
* Copyright 2017 NXP
*/
/*
* The code contained herein is licensed under the GNU General Public
* License. You may obtain a copy of the GNU General Public License
* Version 2 or later at the following locations:
*
* http://www.opensource.org/licenses/gpl-license.html
* http://www.gnu.org/copyleft/gpl.html
*/
#include <linux/delay.h>
#include <media/videobuf2-core.h>
#include "mxc-jpeg-hw.h"
enum mxc_jpeg_image_format {
MXC_JPEG_YUV420 = 0x0,
MXC_JPEG_YUV422 = 0x1,
MXC_JPEG_RGB = 0x2,
MXC_JPEG_YUV444 = 0x3,
MXC_JPEG_Y = 0x4,
MXC_JPEG_ARGB = 0x6,
};
void print_descriptor_info(struct mxc_jpeg_desc *desc)
{
printk(KERN_DEBUG " MXC JPEG NEXT PTR %x\n", desc->next_descpt_ptr);
printk(KERN_DEBUG " MXC JPEG BUF BASE0 %x\n", desc->buf_base0);
printk(KERN_DEBUG " MXC JPEG PITCH %d\n", desc->line_pitch);
printk(KERN_DEBUG " MXC JPEG BUF BASE %x\n", desc->stm_bufbase);
printk(KERN_DEBUG " MXC JPEG BUF SIZE %d\n", desc->stm_bufsize);
printk(KERN_DEBUG " MXC JPEG IMGSIZE %dx%d\n", desc->w, desc->h);
printk(KERN_DEBUG " MXC JPEG STM CTRL %x\n", desc->stm_ctrl);
}
void mxc_jpeg_enable_irq(void __iomem *reg, int slot)
{
writel(0xFFFFFFFF, reg + MXC_SLOT_OFFSET(slot, SLOT_IRQ_EN));
}
void mxc_jpeg_reset(void __iomem *reg)
{
writel(MXC_ENABLE_DEC, reg);
}
u32 mxc_jpeg_get_offset(void __iomem *reg, int slot)
{
return readl(reg + MXC_SLOT_OFFSET(slot, SLOT_BUF_PTR));
}
void mxc_jpeg_enc_config(void __iomem *reg, struct mxc_jpeg_desc *cfg_desc,
u32 cfg_handle, u32 tbl_handle, u32 jpg_handle)
{
u32 regval, slot;
writel(0x1e0, reg + CAST_STATUS0);
writel(0x3ff, reg + CAST_STATUS1);
writel(0x4b, reg + CAST_STATUS2);
slot = mxc_jpeg_get_slot(reg);
mxc_jpeg_enable_irq(reg, slot);
writel((1 << (slot + 4)), reg);
cfg_desc->next_descpt_ptr = 0;
cfg_desc->buf_base0 = tbl_handle;
cfg_desc->buf_base1 = 0;
cfg_desc->line_pitch = 0x300;
cfg_desc->stm_bufbase = jpg_handle;
cfg_desc->stm_bufsize = 0x100000;
cfg_desc->w = 0x0100;
cfg_desc->h = 0x0100;
cfg_desc->stm_ctrl = MXC_CONFIG_MOD;
//print_descriptor_info(cfg_desc);
writel(cfg_handle, reg + MXC_SLOT_OFFSET(slot, SLOT_NXT_DESCPT_PTR));
writel(cfg_handle | 1, reg +
MXC_SLOT_OFFSET(slot, SLOT_NXT_DESCPT_PTR));
writel((1 << (slot + 4)) | MXC_ENDIAN_MD | MXC_ENABLE_DEC |
MXC_DEC_GO, reg);
regval = readl(reg + STM_BUFBASE);
regval = readl(reg + MXC_SLOT_OFFSET(slot, SLOT_BUF_PTR));
}
int mxc_jpeg_enable(void __iomem *reg)
{
u32 regval;
regval = readl(reg);
writel(MXC_ENABLE_DEC, reg);
regval = readl(reg);
return regval;
}
void mxc_jpeg_go(void __iomem *reg)
{
u32 val;
val = readl(reg);
writel(MXC_ENDIAN_MD | MXC_DEC_GO | val, reg);
writel(0x4, reg + 0x134);
//print_cast_decoder_info(reg);
}
void print_cast_decoder_info(void __iomem *reg)
{
int regval;
regval = readl(reg + MXC_SLOT_OFFSET(0, SLOT_CUR_DESCPT_PTR));
printk(KERN_DEBUG " MXC_JPEG: CUR DESCPT PTR: %x\n", regval);
regval = readl(reg + 0x100);
printk(KERN_DEBUG " MXC_JPEG: CAST_INFO 1: %x\n", regval);
regval = readl(reg + 0x104);
printk(KERN_DEBUG " MXC_JPEG: CAST_INFO 2: %x\n", regval);
regval = readl(reg + 0x108);
printk(KERN_DEBUG " MXC_JPEG: CAST_INFO 3: %x\n", regval);
regval = readl(reg + 0x10c);
printk(KERN_DEBUG " MXC_JPEG: CAST_INFO 4: %x\n", regval);
regval = readl(reg + 0x110);
printk(KERN_DEBUG " MXC_JPEG: CAST_INFO 5: %x\n", regval);
regval = readl(reg + 0x114);
printk(KERN_DEBUG " MXC_JPEG: CAST_INFO 6: %x\n", regval);
regval = readl(reg + 0x118);
printk(KERN_DEBUG " MXC_JPEG: CAST_INFO 7: %x\n", regval);
regval = readl(reg + 0x11c);
printk(KERN_DEBUG " MXC_JPEG: CAST_INFO 8: %x\n", regval);
regval = readl(reg + 0x120);
printk(KERN_DEBUG " MXC_JPEG: CAST_INFO 9: %x\n", regval);
regval = readl(reg + 0x124);
printk(KERN_DEBUG " MXC_JPEG: CAST_INFO 10: %x\n", regval);
regval = readl(reg + 0x128);
printk(KERN_DEBUG " MXC_JPEG: CAST_INFO 11: %x\n", regval);
regval = readl(reg + 0x12c);
printk(KERN_DEBUG " MXC_JPEG: CAST_INFO 12: %x\n", regval);
regval = readl(reg + 0x130);
printk(KERN_DEBUG " MXC_JPEG: CAST_INFO 13: %x\n", regval);
regval = readl(reg + 0x134);
printk(KERN_DEBUG " MXC_JPEG: CAST_INFO 14: %x\n", regval);
}
int mxc_jpeg_get_slot(void __iomem *reg)
{
int slot_val;
int i = 0;
int tmp = MXC_SLOT_EN;
slot_val = readl(reg) & 0xF0;
for (; tmp != tmp << 4; tmp = tmp << 1) {
if ((slot_val & tmp) == 0)
return i;
++i;
}
return -EINVAL;
}
void mxc_jpeg_enable_slot(void __iomem *reg, int slot)
{
u32 regval;
regval = readl(reg);
writel((1 << (slot + 4)) | regval, reg);
}
void mxc_jpeg_set_addrs(struct mxc_jpeg_desc *desc, u32 buf_base0, u32 bufbase)
{
desc->buf_base0 = buf_base0;
desc->stm_bufbase = bufbase;
}
int mxc_jpeg_set_params(struct mxc_jpeg_desc *desc, u32 bufsize,
u16 out_pitch, u32 format)
{
desc->line_pitch = out_pitch;
desc->stm_bufsize = bufsize;
switch (format) {
case V4L2_PIX_FMT_YUV32:
desc->stm_ctrl |= MXC_JPEG_YUV444 << 3;
break;
case V4L2_PIX_FMT_YUYV:
desc->stm_ctrl |= MXC_JPEG_YUV422 << 3;
break;
case V4L2_PIX_FMT_RGB32:
desc->stm_ctrl |= MXC_JPEG_RGB << 3;
break;
default:
return -1;
}
return 0;
}
void mxc_jpeg_set_res(struct mxc_jpeg_desc *desc, u16 w, u16 h)
{
desc->w = w;
desc->h = h;
}
void mxc_jpeg_set_desc(u32 desc, void __iomem *reg, int slot)
{
writel(desc | 1, reg + MXC_SLOT_OFFSET(slot, SLOT_NXT_DESCPT_PTR));
}