Merge remote-tracking branch 'origin/capture/jpeg' into capture/next
* origin/capture/jpeg: (9 commits) MLK-22835: mxc-jpeg: jpeg decoder stuck due to race condition mxc-jpeg: Fix warning at build, for EXPORT_SYMBOL on static variable media: mxc-jpeg: jpeg: Replace stracpy with strscpy mxc-jpeg: Build mxc-jpeg as module, by default mxc-jpeg: Add support for multi power domain ...
This commit is contained in:
commit
9c7f085807
|
@ -0,0 +1,107 @@
|
|||
Freescale i.MX8QXP/QM JPEG encoder/decoder
|
||||
=========================
|
||||
|
||||
jpegdec node
|
||||
--------------
|
||||
|
||||
This is the device node for the JPEG decoder in i.MXQXP/QM SoC, an
|
||||
ISO/IEC 10918-1 JPEG standard compliant decoder, for Baseline
|
||||
and Extended Sequential DCT modes.
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible : "fsl,imx8-jpgdec";
|
||||
- reg : base address and length of the register set for the device;
|
||||
- interrupts : list of interrupts for jpeg decoder
|
||||
- clocks : list of clock specifiers, see
|
||||
Documentation/devicetree/bindings/clock/clock-bindings.txt for details;
|
||||
- assigned-clock-rates : the value should be 200MHz;
|
||||
- power-domains : a list of phandle to the power domain, see
|
||||
Documentation/devicetree/bindings/power/power_domain.txt for details;
|
||||
|
||||
|
||||
Optional properties:
|
||||
- clock-names : must contain clock names to match entries in the
|
||||
clock property;
|
||||
- power-domain-name : must contain matching names for entries in the
|
||||
the power-domains property.
|
||||
|
||||
|
||||
example:
|
||||
|
||||
jpegdec: jpegdec@58400000 {
|
||||
compatible = "fsl,imx8-jpgdec";
|
||||
reg = <0x58400000 0x00050000 >;
|
||||
interrupts = <GIC_SPI 309 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 310 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 311 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 312 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&img_jpeg_dec_clk 0>,
|
||||
<&img_jpeg_dec_clk 1>;
|
||||
clock-names = "per", "ipg";
|
||||
assigned-clocks = <&img_jpeg_dec_clk 0>,
|
||||
<&img_jpeg_dec_clk 1>;
|
||||
assigned-clock-rates = <200000000>;
|
||||
power-domains = <&pd IMX_SC_R_ISI_CH0>,
|
||||
<&pd IMX_SC_R_MJPEG_DEC_MP>,
|
||||
<&pd IMX_SC_R_MJPEG_DEC_S0>,
|
||||
<&pd IMX_SC_R_MJPEG_DEC_S1>,
|
||||
<&pd IMX_SC_R_MJPEG_DEC_S2>,
|
||||
<&pd IMX_SC_R_MJPEG_DEC_S3>;
|
||||
power-domain-names = "pd_isi_ch0", "pd_dec_mp",
|
||||
"pd_dec_s0", "pd_dec_s1",
|
||||
"pd_dec_s2", "pd_dec_s3";
|
||||
status = "disabled";
|
||||
|
||||
|
||||
jpegenc node
|
||||
--------------
|
||||
|
||||
This is the device node for the JPEG encoder in i.MXQXP/QM SoC,
|
||||
similar with the JPEG decoder above.
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible : "fsl,imx8-jpgenc";
|
||||
- reg : base address and length of the register set for the device;
|
||||
- interrupts : list of interrupts for jpeg encoder
|
||||
- clocks : list of clock specifiers, see
|
||||
Documentation/devicetree/bindings/clock/clock-bindings.txt for details;
|
||||
- assigned-clock-rates : the value should be 200MHz;
|
||||
- power-domains : a list of phandle to the power domain, see
|
||||
Documentation/devicetree/bindings/power/power_domain.txt for details;
|
||||
|
||||
|
||||
Optional properties:
|
||||
- clock-names : must contain clock names to match entries in the
|
||||
clock property;
|
||||
- power-domain-name : must contain matching names for entries in the
|
||||
the power-domains property.
|
||||
|
||||
|
||||
example:
|
||||
|
||||
jpegenc: jpegenc@58450000 {
|
||||
compatible = "fsl,imx8-jpgenc";
|
||||
reg = <0x58450000 0x00050000 >;
|
||||
interrupts = <GIC_SPI 305 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 306 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 307 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 308 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&img_jpeg_enc_clk 0>,
|
||||
<&img_jpeg_enc_clk 1>;
|
||||
clock-names = "per", "ipg";
|
||||
assigned-clocks = <&img_jpeg_enc_clk 0>,
|
||||
<&img_jpeg_enc_clk 1>;
|
||||
assigned-clock-rates = <200000000>;
|
||||
power-domains = <&pd IMX_SC_R_ISI_CH0>,
|
||||
<&pd IMX_SC_R_MJPEG_ENC_MP>,
|
||||
<&pd IMX_SC_R_MJPEG_ENC_S0>,
|
||||
<&pd IMX_SC_R_MJPEG_ENC_S1>,
|
||||
<&pd IMX_SC_R_MJPEG_ENC_S2>,
|
||||
<&pd IMX_SC_R_MJPEG_ENC_S3>;
|
||||
power-domain-names = "pd_isi_ch0", "pd_enc_mp",
|
||||
"pd_enc_s0", "pd_enc_s1",
|
||||
"pd_enc_s2", "pd_enc_s3";
|
||||
status = "disabled";
|
||||
};
|
|
@ -148,7 +148,6 @@ config VIDEO_MX8_CAPTURE
|
|||
This is the video4linux2 capture driver based on i.MX8 module.
|
||||
|
||||
source "drivers/media/platform/imx8/Kconfig"
|
||||
|
||||
source "drivers/media/platform/exynos4-is/Kconfig"
|
||||
source "drivers/media/platform/am437x/Kconfig"
|
||||
source "drivers/media/platform/xilinx/Kconfig"
|
||||
|
|
|
@ -5,6 +5,13 @@ config IMX8_MIPI_CSI2_YAV
|
|||
tristate "IMX8 MIPI CSI2 Controller Yet Another Version"
|
||||
default y
|
||||
|
||||
config IMX8_JPEG
|
||||
tristate "IMX8 JPEG Encoder/Decoder"
|
||||
depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
|
||||
select V4L2_MEM2MEM_DEV
|
||||
select VIDEOBUF2_DMA_CONTIG
|
||||
default m
|
||||
|
||||
endmenu
|
||||
endif #VIDEO_MX8_CAPTURE
|
||||
|
||||
|
|
|
@ -1 +1,3 @@
|
|||
obj-$(CONFIG_IMX8_MIPI_CSI2_YAV) += mxc-mipi-csi2_yav.o
|
||||
mxc-jpeg-encdec-objs := mxc-jpeg-hw.o mxc-jpeg.o
|
||||
obj-$(CONFIG_IMX8_JPEG) += mxc-jpeg-encdec.o
|
||||
|
|
|
@ -0,0 +1,248 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* i.MX8QXP/i.MX8QM JPEG encoder/decoder v4l2 driver
|
||||
*
|
||||
* Copyright 2018-2019 NXP
|
||||
*/
|
||||
|
||||
#include <linux/delay.h>
|
||||
#include <media/videobuf2-core.h>
|
||||
#include "mxc-jpeg-hw.h"
|
||||
|
||||
#define print_wrapper_reg(dev, base_address, reg_offset)\
|
||||
internal_print_wrapper_reg(dev, (base_address), #reg_offset,\
|
||||
(reg_offset))
|
||||
#define internal_print_wrapper_reg(dev, base_address, reg_name, reg_offset) {\
|
||||
int val;\
|
||||
val = readl((base_address) + (reg_offset));\
|
||||
dev_dbg(dev, "Wrapper reg %s = 0x%x\n", reg_name, val);\
|
||||
}
|
||||
|
||||
void print_descriptor_info(struct device *dev, struct mxc_jpeg_desc *desc)
|
||||
{
|
||||
dev_dbg(dev, " MXC JPEG NEXT_DESCPT_PTR 0x%x\n",
|
||||
desc->next_descpt_ptr);
|
||||
dev_dbg(dev, " MXC JPEG BUF_BASE0 0x%x\n", desc->buf_base0);
|
||||
dev_dbg(dev, " MXC JPEG BUF_BASE1 0x%x\n", desc->buf_base1);
|
||||
dev_dbg(dev, " MXC JPEG LINE_PITCH %d\n", desc->line_pitch);
|
||||
dev_dbg(dev, " MXC JPEG STM_BUFBASE 0x%x\n", desc->stm_bufbase);
|
||||
dev_dbg(dev, " MXC JPEG STM_BUFSIZE %d\n", desc->stm_bufsize);
|
||||
dev_dbg(dev, " MXC JPEG IMGSIZE %x (%d x %d)\n", desc->imgsize,
|
||||
desc->imgsize >> 16, desc->imgsize & 0xFFFF);
|
||||
dev_dbg(dev, " MXC JPEG STM_CTRL 0x%x\n", desc->stm_ctrl);
|
||||
}
|
||||
|
||||
void print_cast_status(struct device *dev, void __iomem *reg,
|
||||
unsigned int mode)
|
||||
{
|
||||
dev_dbg(dev, "CAST IP status regs:\n");
|
||||
print_wrapper_reg(dev, reg, CAST_STATUS0);
|
||||
print_wrapper_reg(dev, reg, CAST_STATUS1);
|
||||
print_wrapper_reg(dev, reg, CAST_STATUS2);
|
||||
print_wrapper_reg(dev, reg, CAST_STATUS3);
|
||||
print_wrapper_reg(dev, reg, CAST_STATUS4);
|
||||
print_wrapper_reg(dev, reg, CAST_STATUS5);
|
||||
print_wrapper_reg(dev, reg, CAST_STATUS6);
|
||||
print_wrapper_reg(dev, reg, CAST_STATUS7);
|
||||
print_wrapper_reg(dev, reg, CAST_STATUS8);
|
||||
print_wrapper_reg(dev, reg, CAST_STATUS9);
|
||||
print_wrapper_reg(dev, reg, CAST_STATUS10);
|
||||
print_wrapper_reg(dev, reg, CAST_STATUS11);
|
||||
print_wrapper_reg(dev, reg, CAST_STATUS12);
|
||||
print_wrapper_reg(dev, reg, CAST_STATUS13);
|
||||
if (mode == MXC_JPEG_DECODE)
|
||||
return;
|
||||
print_wrapper_reg(dev, reg, CAST_STATUS14);
|
||||
print_wrapper_reg(dev, reg, CAST_STATUS15);
|
||||
print_wrapper_reg(dev, reg, CAST_STATUS16);
|
||||
print_wrapper_reg(dev, reg, CAST_STATUS17);
|
||||
print_wrapper_reg(dev, reg, CAST_STATUS18);
|
||||
print_wrapper_reg(dev, reg, CAST_STATUS19);
|
||||
}
|
||||
|
||||
void print_wrapper_info(struct device *dev, void __iomem *reg)
|
||||
{
|
||||
dev_dbg(dev, "Wrapper regs:\n");
|
||||
print_wrapper_reg(dev, reg, GLB_CTRL);
|
||||
print_wrapper_reg(dev, reg, COM_STATUS);
|
||||
print_wrapper_reg(dev, reg, BUF_BASE0);
|
||||
print_wrapper_reg(dev, reg, BUF_BASE1);
|
||||
print_wrapper_reg(dev, reg, LINE_PITCH);
|
||||
print_wrapper_reg(dev, reg, STM_BUFBASE);
|
||||
print_wrapper_reg(dev, reg, STM_BUFSIZE);
|
||||
print_wrapper_reg(dev, reg, IMGSIZE);
|
||||
print_wrapper_reg(dev, reg, 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_sw_reset(void __iomem *reg)
|
||||
{
|
||||
/*
|
||||
* engine soft reset, internal state machine reset
|
||||
* this will not reset registers, however, it seems
|
||||
* the registers may remain inconsistent with the internal state
|
||||
* so, on purpose, at least let GLB_CTRL bits clear after this reset
|
||||
*/
|
||||
writel(GLB_CTRL_SFT_RST, reg + GLB_CTRL);
|
||||
}
|
||||
|
||||
u32 mxc_jpeg_get_offset(void __iomem *reg, int slot)
|
||||
{
|
||||
return readl(reg + MXC_SLOT_OFFSET(slot, SLOT_BUF_PTR));
|
||||
}
|
||||
|
||||
void mxc_jpeg_enc_mode_conf(struct device *dev, void __iomem *reg)
|
||||
{
|
||||
dev_dbg(dev, "CAST Encoder CONFIG...\n");
|
||||
/*
|
||||
* "Config_Mode" enabled, "Config_Mode auto clear enabled",
|
||||
*/
|
||||
writel(0xa0, reg + CAST_MODE);
|
||||
|
||||
/* all markers and segments */
|
||||
writel(0x3ff, reg + CAST_CFG_MODE);
|
||||
|
||||
/* quality factor */
|
||||
writel(0x4b, reg + CAST_QUALITY);
|
||||
}
|
||||
|
||||
void mxc_jpeg_enc_mode_go(struct device *dev, void __iomem *reg)
|
||||
{
|
||||
dev_dbg(dev, "CAST Encoder GO...\n");
|
||||
/*
|
||||
* "GO" enabled, "GO bit auto clear" enabled
|
||||
*/
|
||||
writel(0x140, reg + CAST_MODE);
|
||||
}
|
||||
|
||||
void wait_frmdone(struct device *dev, void __iomem *reg)
|
||||
{
|
||||
u32 regval = 0;
|
||||
|
||||
do {
|
||||
regval = readl(reg + MXC_SLOT_OFFSET(0, SLOT_STATUS));
|
||||
} while (!(regval & SLOTa_STATUS_FRMDONE));
|
||||
|
||||
writel(regval, reg + MXC_SLOT_OFFSET(0, SLOT_STATUS)); /* w1c */
|
||||
|
||||
dev_dbg(dev, "Received FRMDONE\n");
|
||||
if (regval & SLOTa_STATUS_ENC_CONFIG_ERR)
|
||||
dev_info(dev, "SLOTa_STATUS_ENC_CONFIG_ERR\n");
|
||||
}
|
||||
|
||||
int mxc_jpeg_enable(void __iomem *reg)
|
||||
{
|
||||
u32 regval;
|
||||
|
||||
writel(GLB_CTRL_JPG_EN, reg + GLB_CTRL);
|
||||
regval = readl(reg);
|
||||
return regval;
|
||||
}
|
||||
|
||||
void mxc_jpeg_dec_mode_go(struct device *dev, void __iomem *reg)
|
||||
{
|
||||
dev_dbg(dev, "CAST Decoder GO...\n");
|
||||
writel(MXC_DEC_EXIT_IDLE_MODE, reg + CAST_CTRL);
|
||||
}
|
||||
|
||||
int mxc_jpeg_get_slot(void __iomem *reg)
|
||||
{
|
||||
int slot_val;
|
||||
int i = 0;
|
||||
int tmp = GLB_CTRL_SLOT_EN(0);
|
||||
|
||||
/* currently enabled slots */
|
||||
slot_val = readl(reg + GLB_CTRL) & 0xF0;
|
||||
|
||||
for (; tmp != tmp << 4; tmp = tmp << 1) {
|
||||
if ((slot_val & tmp) == 0)
|
||||
/* first free slot */
|
||||
return i;
|
||||
++i;
|
||||
}
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
void mxc_jpeg_enable_slot(void __iomem *reg, int slot)
|
||||
{
|
||||
u32 regval;
|
||||
|
||||
regval = readl(reg + GLB_CTRL);
|
||||
writel(GLB_CTRL_SLOT_EN(slot) | regval, reg + GLB_CTRL);
|
||||
}
|
||||
|
||||
void mxc_jpeg_set_l_endian(void __iomem *reg, int le)
|
||||
{
|
||||
u32 regval;
|
||||
|
||||
regval = readl(reg + GLB_CTRL);
|
||||
regval &= ~GLB_CTRL_L_ENDIAN(1); /* clear */
|
||||
writel(GLB_CTRL_L_ENDIAN(le) | regval, reg + GLB_CTRL); /* set */
|
||||
}
|
||||
|
||||
void mxc_jpeg_set_config_mode(void __iomem *reg, int config_mode)
|
||||
{
|
||||
u32 regval;
|
||||
|
||||
regval = readl(reg + STM_CTRL);
|
||||
regval &= ~STM_CTRL_CONFIG_MOD(1);
|
||||
writel(STM_CTRL_CONFIG_MOD(config_mode) | regval, reg + STM_CTRL);
|
||||
}
|
||||
|
||||
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_bufsize(struct mxc_jpeg_desc *desc, u32 bufsize)
|
||||
{
|
||||
desc->stm_bufsize = bufsize;
|
||||
}
|
||||
|
||||
void mxc_jpeg_set_res(struct mxc_jpeg_desc *desc, u16 w, u16 h)
|
||||
{
|
||||
desc->imgsize = w << 16 | h;
|
||||
}
|
||||
|
||||
|
||||
void mxc_jpeg_set_line_pitch(struct mxc_jpeg_desc *desc, u32 line_pitch)
|
||||
{
|
||||
desc->line_pitch = line_pitch;
|
||||
}
|
||||
|
||||
void mxc_jpeg_set_desc(u32 desc, void __iomem *reg, int slot)
|
||||
{
|
||||
writel(desc | MXC_NXT_DESCPT_EN,
|
||||
reg + MXC_SLOT_OFFSET(slot, SLOT_NXT_DESCPT_PTR));
|
||||
}
|
||||
|
||||
void mxc_jpeg_set_regs_from_desc(struct mxc_jpeg_desc *desc, void __iomem *reg)
|
||||
{
|
||||
writel(desc->buf_base0, reg + BUF_BASE0);
|
||||
writel(desc->buf_base1, reg + BUF_BASE1);
|
||||
writel(desc->line_pitch, reg + LINE_PITCH);
|
||||
writel(desc->stm_bufbase, reg + STM_BUFBASE);
|
||||
writel(desc->stm_bufsize, reg + STM_BUFSIZE);
|
||||
writel(desc->imgsize, reg + IMGSIZE);
|
||||
writel(desc->stm_ctrl, reg + STM_CTRL);
|
||||
}
|
|
@ -0,0 +1,144 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* i.MX8QXP/i.MX8QM JPEG encoder/decoder v4l2 driver
|
||||
*
|
||||
* Copyright 2018-2019 NXP
|
||||
*/
|
||||
|
||||
#ifndef _MXC_JPEG_HW_H
|
||||
#define _MXC_JPEG_HW_H
|
||||
|
||||
#define MXC_JPEG_DECODE 0
|
||||
#define MXC_JPEG_ENCODE 1
|
||||
|
||||
/* JPEG Decoder/Encoder Wrapper Register Map */
|
||||
#define GLB_CTRL 0x0
|
||||
#define COM_STATUS 0x4
|
||||
#define BUF_BASE0 0x14
|
||||
#define BUF_BASE1 0x18
|
||||
#define LINE_PITCH 0x1C
|
||||
#define STM_BUFBASE 0x20
|
||||
#define STM_BUFSIZE 0x24
|
||||
#define IMGSIZE 0x28
|
||||
#define STM_CTRL 0x2C
|
||||
|
||||
/* CAST JPEG-Decoder/Encoder Status Register Map (read-only)*/
|
||||
#define CAST_STATUS0 0x100
|
||||
#define CAST_STATUS1 0x104
|
||||
#define CAST_STATUS2 0x108
|
||||
#define CAST_STATUS3 0x10c
|
||||
#define CAST_STATUS4 0x110
|
||||
#define CAST_STATUS5 0x114
|
||||
#define CAST_STATUS6 0x118
|
||||
#define CAST_STATUS7 0x11c
|
||||
#define CAST_STATUS8 0x120
|
||||
#define CAST_STATUS9 0x124
|
||||
#define CAST_STATUS10 0x128
|
||||
#define CAST_STATUS11 0x12c
|
||||
#define CAST_STATUS12 0x130
|
||||
#define CAST_STATUS13 0x134
|
||||
/* the following are for encoder only */
|
||||
#define CAST_STATUS14 0x138
|
||||
#define CAST_STATUS15 0x13c
|
||||
#define CAST_STATUS16 0x140
|
||||
#define CAST_STATUS17 0x144
|
||||
#define CAST_STATUS18 0x148
|
||||
#define CAST_STATUS19 0x14c
|
||||
|
||||
/* CAST JPEG-Decoder Control Register Map (write-only) */
|
||||
#define CAST_CTRL CAST_STATUS13
|
||||
|
||||
/* CAST JPEG-Encoder Control Register Map (write-only) */
|
||||
#define CAST_MODE CAST_STATUS0
|
||||
#define CAST_CFG_MODE CAST_STATUS1
|
||||
#define CAST_QUALITY CAST_STATUS2
|
||||
#define CAST_RSVD CAST_STATUS3
|
||||
#define CAST_REC_REGS_SEL CAST_STATUS4
|
||||
#define CAST_LUMTH CAST_STATUS5
|
||||
#define CAST_CHRTH CAST_STATUS6
|
||||
#define CAST_NOMFRSIZE_LO CAST_STATUS7
|
||||
#define CAST_NOMFRSIZE_HI CAST_STATUS8
|
||||
#define CAST_OFBSIZE_LO CAST_STATUS9
|
||||
#define CAST_OFBSIZE_HI CAST_STATUS10
|
||||
|
||||
#define MXC_MAX_SLOTS 1 /* TODO use all 4 slots*/
|
||||
/* JPEG-Decoder Wrapper Slot Registers 0..3 */
|
||||
#define SLOT_BASE 0x10000
|
||||
#define SLOT_STATUS 0x0
|
||||
#define SLOT_IRQ_EN 0x4
|
||||
#define SLOT_BUF_PTR 0x8
|
||||
#define SLOT_CUR_DESCPT_PTR 0xC
|
||||
#define SLOT_NXT_DESCPT_PTR 0x10
|
||||
#define MXC_SLOT_OFFSET(slot, offset) ((SLOT_BASE * (slot + 1)) + offset)
|
||||
|
||||
/* GLB_CTRL fields */
|
||||
#define GLB_CTRL_JPG_EN 0x1
|
||||
#define GLB_CTRL_SFT_RST (0x1 << 1)
|
||||
#define GLB_CTRL_DEC_GO (0x1 << 2)
|
||||
#define GLB_CTRL_L_ENDIAN(le) ((le) << 3)
|
||||
#define GLB_CTRL_SLOT_EN(slot) (0x1 << (slot + 4))
|
||||
|
||||
/* COM_STAUS fields */
|
||||
#define COM_STATUS_DEC_ONGOING(r) (((r) & (1 << 31)) >> 31)
|
||||
#define COM_STATUS_CUR_SLOT(r) (((r) & (0x3 << 29)) >> 29)
|
||||
|
||||
/* STM_CTRL fields */
|
||||
#define STM_CTRL_PIXEL_PRECISION (0x1 << 2)
|
||||
#define STM_CTRL_IMAGE_FORMAT(img_fmt) ((img_fmt) << 3)
|
||||
#define STM_CTRL_IMAGE_FORMAT_MASK (0xF << 3)
|
||||
#define STM_CTRL_BITBUF_PTR_CLR(clr) ((clr) << 7)
|
||||
#define STM_CTRL_AUTO_START(go) ((go) << 8)
|
||||
#define STM_CTRL_CONFIG_MOD(mod) ((mod) << 9)
|
||||
|
||||
/* SLOTa_STATUS fields TBD */
|
||||
#define SLOTa_STATUS_FRMDONE (0x1 << 3)
|
||||
#define SLOTa_STATUS_ENC_CONFIG_ERR (0x1 << 8)
|
||||
|
||||
/* SLOTa_IRQ_EN fields TBD */
|
||||
|
||||
#define MXC_NXT_DESCPT_EN 0x1
|
||||
#define MXC_DEC_EXIT_IDLE_MODE 0x4
|
||||
|
||||
/* JPEG-Decoder Wrapper - STM_CTRL Register Fields */
|
||||
#define MXC_PIXEL_PRECISION(precision) ((precision)/8 << 2)
|
||||
enum mxc_jpeg_image_format {
|
||||
MXC_JPEG_INVALID = -1,
|
||||
MXC_JPEG_YUV420 = 0x0, /* 2 Plannar, Y=1st plane UV=2nd plane */
|
||||
MXC_JPEG_YUV422 = 0x1, /* 1 Plannar, YUYV sequence */
|
||||
MXC_JPEG_RGB = 0x2, /* RGBRGB packed format */
|
||||
MXC_JPEG_YUV444 = 0x3, /* 1 Plannar, YUVYUV sequence */
|
||||
MXC_JPEG_GRAY = 0x4, /* Y8 or Y12 or Single Component */
|
||||
MXC_JPEG_RESERVED = 0x5,
|
||||
MXC_JPEG_ARGB = 0x6,
|
||||
};
|
||||
|
||||
|
||||
#include "mxc-jpeg.h"
|
||||
void print_descriptor_info(struct device *dev, struct mxc_jpeg_desc *desc);
|
||||
void print_cast_status(struct device *dev, void __iomem *reg,
|
||||
unsigned int mode);
|
||||
void print_wrapper_info(struct device *dev, void __iomem *reg);
|
||||
void mxc_jpeg_sw_reset(void __iomem *reg);
|
||||
int mxc_jpeg_enable(void __iomem *reg);
|
||||
void wait_frmdone(struct device *dev, void __iomem *reg);
|
||||
void mxc_jpeg_enc_mode_conf(struct device *dev, void __iomem *reg);
|
||||
void mxc_jpeg_enc_mode_go(struct device *dev, void __iomem *reg);
|
||||
void mxc_jpeg_dec_mode_go(struct device *dev, void __iomem *reg);
|
||||
int mxc_jpeg_get_slot(void __iomem *reg);
|
||||
u32 mxc_jpeg_get_offset(void __iomem *reg, int slot);
|
||||
void mxc_jpeg_enable_slot(void __iomem *reg, int slot);
|
||||
void mxc_jpeg_set_l_endian(void __iomem *reg, int le);
|
||||
void mxc_jpeg_enable_irq(void __iomem *reg, int slot);
|
||||
int mxc_jpeg_set_input(void __iomem *reg, u32 in_buf, u32 bufsize);
|
||||
int mxc_jpeg_set_output(void __iomem *reg, u16 out_pitch, u32 out_buf,
|
||||
u16 w, u16 h);
|
||||
void mxc_jpeg_set_config_mode(void __iomem *reg, int config_mode);
|
||||
int mxc_jpeg_set_params(struct mxc_jpeg_desc *desc, u32 bufsize, u16
|
||||
out_pitch, u32 format);
|
||||
void mxc_jpeg_set_bufsize(struct mxc_jpeg_desc *desc, u32 bufsize);
|
||||
void mxc_jpeg_set_res(struct mxc_jpeg_desc *desc, u16 w, u16 h);
|
||||
void mxc_jpeg_set_line_pitch(struct mxc_jpeg_desc *desc, u32 line_pitch);
|
||||
void mxc_jpeg_set_desc(u32 desc, void __iomem *reg, int slot);
|
||||
void mxc_jpeg_set_regs_from_desc(struct mxc_jpeg_desc *desc,
|
||||
void __iomem *reg);
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,170 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* i.MX8QXP/i.MX8QM JPEG encoder/decoder v4l2 driver
|
||||
*
|
||||
* Copyright 2018-2019 NXP
|
||||
*/
|
||||
|
||||
#include <media/v4l2-ctrls.h>
|
||||
#include <media/v4l2-device.h>
|
||||
#include <media/v4l2-fh.h>
|
||||
|
||||
#ifndef _MXC_JPEG_CORE_H
|
||||
#define _MXC_JPEG_CORE_H
|
||||
|
||||
#define MXC_JPEG_M2M_NAME "mxc-jpeg"
|
||||
#define MXC_JPEG_NAME "mxc-jpeg"
|
||||
#define MXC_IN_FORMAT 0
|
||||
#define MXC_OUT_FORMAT 1
|
||||
#define MXC_JPEG_FMT_TYPE_ENC 0
|
||||
#define MXC_JPEG_FMT_TYPE_RAW 1
|
||||
#define MXC_JPEG_DEFAULT_WIDTH 1280
|
||||
#define MXC_JPEG_DEFAULT_HEIGHT 720
|
||||
#define MXC_JPEG_DEFAULT_PFMT V4L2_PIX_FMT_RGB24
|
||||
#define MXC_JPEG_MIN_WIDTH 64
|
||||
#define MXC_JPEG_MIN_HEIGHT 64
|
||||
#define MXC_JPEG_MAX_WIDTH 0x2000
|
||||
#define MXC_JPEG_MAX_HEIGHT 0x2000
|
||||
#define MXC_JPEG_MAX_CFG_STREAM 0x1000
|
||||
#define MXC_JPEG_H_ALIGN 3
|
||||
#define MXC_JPEG_W_ALIGN 3
|
||||
#define MXC_JPEG_DEFAULT_SIZEIMAGE (6 * MXC_JPEG_DEFAULT_WIDTH * \
|
||||
MXC_JPEG_DEFAULT_HEIGHT)
|
||||
#define MXC_JPEG_MAX_SIZEIMAGE 0xFFFFFC00
|
||||
#define MXC_JPEG_ENC_CONF 1
|
||||
#define MXC_JPEG_ENC_DONE 0
|
||||
#define SOF0 0xC0
|
||||
#define SOF1 0xC1
|
||||
#define SOF2 0xC2
|
||||
#define SOS 0xDA
|
||||
#define DHT 0xC4
|
||||
#define APP14 0xEE
|
||||
#define MXC_JPEG_ENC_CONF_DONE 1
|
||||
#define MXC_JPEG_MAX_PLANES 2
|
||||
#define MXC_JPEG_NUM_PD 6
|
||||
|
||||
|
||||
/**
|
||||
* struct jpeg_fmt - driver's internal color format data
|
||||
* @name: format description
|
||||
* @fourcc: fourcc code, 0 if not applicable
|
||||
* @depth: number of bits per pixel
|
||||
* @colplanes: number of color planes (1 for packed formats)
|
||||
* @h_align: horizontal alignment order (align to 2^h_align)
|
||||
* @v_align: vertical alignment order (align to 2^v_align)
|
||||
* @flags: flags describing format applicability
|
||||
*/
|
||||
struct mxc_jpeg_fmt {
|
||||
char *name;
|
||||
u32 fourcc;
|
||||
int depth;
|
||||
int colplanes;
|
||||
int memplanes;
|
||||
int h_align;
|
||||
int v_align;
|
||||
int subsampling;
|
||||
u32 flags;
|
||||
};
|
||||
struct mxc_jpeg_desc {
|
||||
u32 next_descpt_ptr;
|
||||
u32 buf_base0;
|
||||
u32 buf_base1;
|
||||
u32 line_pitch;
|
||||
u32 stm_bufbase;
|
||||
u32 stm_bufsize;
|
||||
u32 imgsize;
|
||||
u32 stm_ctrl;
|
||||
} __packed;
|
||||
|
||||
struct mxc_jpeg_q_data {
|
||||
struct mxc_jpeg_fmt *fmt;
|
||||
u32 sizeimage[MXC_JPEG_MAX_PLANES];
|
||||
u32 bytesperline[MXC_JPEG_MAX_PLANES];
|
||||
int w;
|
||||
int w_adjusted;
|
||||
int h;
|
||||
int h_adjusted;
|
||||
};
|
||||
struct mxc_jpeg_ctx {
|
||||
struct mxc_jpeg_dev *mxc_jpeg;
|
||||
struct mxc_jpeg_q_data out_q;
|
||||
struct mxc_jpeg_q_data cap_q;
|
||||
struct v4l2_rect crop_rect;
|
||||
unsigned long state;
|
||||
struct v4l2_fh fh;
|
||||
unsigned int mode;
|
||||
unsigned int enc_state;
|
||||
unsigned int aborting;
|
||||
unsigned int stopping;
|
||||
unsigned int dht_needed;
|
||||
unsigned int slot;
|
||||
enum v4l2_colorspace colorspace;
|
||||
enum v4l2_ycbcr_encoding ycbcr_enc;
|
||||
enum v4l2_quantization quantization;
|
||||
enum v4l2_xfer_func xfer_func;
|
||||
};
|
||||
|
||||
struct mxc_jpeg_slot_data {
|
||||
bool used;
|
||||
struct mxc_jpeg_desc *desc; // enc/dec descriptor
|
||||
struct mxc_jpeg_desc *cfg_desc; // configuration descriptor
|
||||
void *cfg_stream_vaddr; // configuration bitstream virtual address
|
||||
unsigned int cfg_stream_size;
|
||||
int flags;
|
||||
dma_addr_t desc_handle;
|
||||
dma_addr_t cfg_desc_handle; // configuration descriptor dma address
|
||||
dma_addr_t cfg_stream_handle; // configuration bitstream dma address
|
||||
};
|
||||
|
||||
struct mxc_jpeg_dev {
|
||||
spinlock_t hw_lock;
|
||||
unsigned int mode;
|
||||
struct mutex lock;
|
||||
bool enc;
|
||||
bool dec;
|
||||
struct clk *clk_ipg;
|
||||
struct clk *clk_per;
|
||||
struct platform_device *pdev;
|
||||
struct device *dev;
|
||||
void __iomem *base_reg;
|
||||
void __iomem *enc_reg;
|
||||
struct v4l2_device v4l2_dev;
|
||||
struct v4l2_m2m_dev *m2m_dev;
|
||||
struct video_device *dec_vdev;
|
||||
unsigned int irq;
|
||||
int id;
|
||||
struct mxc_jpeg_slot_data slot_data[MXC_MAX_SLOTS];
|
||||
struct device *pd_dev[MXC_JPEG_NUM_PD];
|
||||
struct device_link *pd_link[MXC_JPEG_NUM_PD];
|
||||
};
|
||||
|
||||
#define MXC_JPEG_MAX_COMPONENTS 4
|
||||
/* JPEG Start Of Frame marker fields*/
|
||||
struct mxc_jpeg_sof_comp {
|
||||
u8 id; /*component id*/
|
||||
u8 v :4; /* vertical sampling*/
|
||||
u8 h :4; /* horizontal sampling*/
|
||||
u8 quantization_table_no;
|
||||
} __packed;
|
||||
|
||||
struct mxc_jpeg_sof {
|
||||
u16 length;
|
||||
u8 precision;
|
||||
u16 height, width;
|
||||
u8 components_no;
|
||||
struct mxc_jpeg_sof_comp comp[MXC_JPEG_MAX_COMPONENTS];
|
||||
} __packed;
|
||||
|
||||
/* JPEG Start Of Scan marker fields*/
|
||||
struct mxc_jpeg_sos_comp {
|
||||
u8 id; /*component id*/
|
||||
u8 huffman_table_no;
|
||||
} __packed;
|
||||
struct mxc_jpeg_sos {
|
||||
u16 length;
|
||||
u8 components_no;
|
||||
struct mxc_jpeg_sos_comp comp[MXC_JPEG_MAX_COMPONENTS];
|
||||
u8 ignorable_bytes[3];
|
||||
} __packed;
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue