Phytium JPEG Encoder driver

Support for the Phytium JPEG Encoder Engine embedded in the Phytium SOCs.The engine can capture and compress video data from digital or analog sources.
Reviewed-by:maohongbo<maohongbo@phytium.com.cn>
Signed-off-by: Wang Min <wangmin@phytium.com.cn>
Signed-off-by: Chen Baozi <chenbaozi@phytium.com.cn>

(cherry picked from commit 6f9e10130c)
Signed-off-by: Alex Shi <alexsshi@tencent.com>
This commit is contained in:
xuyan 2023-06-05 15:06:40 +08:00 committed by Jianping Liu
parent d978e4cfa4
commit 94c9fd89fc
7 changed files with 1649 additions and 0 deletions

View File

@ -2096,6 +2096,7 @@ W: https://www.phytium.com.cn
F: arch/arm64/boot/dts/phytium/* F: arch/arm64/boot/dts/phytium/*
F: Documentation/devicetree/bindings/net/can/phytium-can.txt F: Documentation/devicetree/bindings/net/can/phytium-can.txt
F: drivers/net/can/phytium/* F: drivers/net/can/phytium/*
F: drivers/media/platform/phytium-jpeg/phytium_jpeg*
ARM/PLEB SUPPORT ARM/PLEB SUPPORT
M: Peter Chubb <pleb@gelato.unsw.edu.au> M: Peter Chubb <pleb@gelato.unsw.edu.au>

View File

@ -160,6 +160,16 @@ config VIDEO_TI_CAL
In TI Technical Reference Manual this module is referred as In TI Technical Reference Manual this module is referred as
Camera Interface Subsystem (CAMSS). Camera Interface Subsystem (CAMSS).
config VIDEO_PHYTIUM_JPEG
tristate "Phytium JPEG Encoder driver"
depends on VIDEO_V4L2
select VIDEOBUF2_DMA_CONTIG
help
Support for the Phytium JPEG Encoder Engine embedded
in the Phytium SOCs.
The engine can capture and compress video data from
digital or analog sources.
endif # V4L_PLATFORM_DRIVERS endif # V4L_PLATFORM_DRIVERS
menuconfig V4L_MEM2MEM_DRIVERS menuconfig V4L_MEM2MEM_DRIVERS

View File

@ -96,6 +96,8 @@ obj-$(CONFIG_VIDEO_QCOM_CAMSS) += qcom/camss/
obj-$(CONFIG_VIDEO_QCOM_VENUS) += qcom/venus/ obj-$(CONFIG_VIDEO_QCOM_VENUS) += qcom/venus/
obj-$(CONFIG_VIDEO_PHYTIUM_JPEG) += phytium-jpeg/
obj-y += meson/ obj-y += meson/
obj-y += cros-ec-cec/ obj-y += cros-ec-cec/

View File

@ -0,0 +1,3 @@
# SPDX-License-Identifier: GPL-2.0-only
phytium_jpeg-objs := phytium_jpeg_core.o
obj-$(CONFIG_VIDEO_PHYTIUM_JPEG) += phytium_jpeg.o

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,147 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* Copyright (c) 2021-2023, Phytium Technology Co., Ltd.
*/
#ifndef _PHYTIUM_JPEG_CORE_H
#define _PHYTIUM_JPEG_CORE_H
#include <linux/atomic.h>
#include <linux/bitfield.h>
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/dma-mapping.h>
#include <linux/interrupt.h>
#include <linux/jiffies.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/of.h>
#include <linux/of_irq.h>
#include <linux/of_reserved_mem.h>
#include <linux/platform_device.h>
#include <linux/sched.h>
#include <linux/spinlock.h>
#include <linux/string.h>
#include <linux/v4l2-controls.h>
#include <linux/videodev2.h>
#include <linux/wait.h>
#include <linux/workqueue.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-dev.h>
#include <media/v4l2-device.h>
#include <media/v4l2-dv-timings.h>
#include <media/v4l2-event.h>
#include <media/v4l2-ioctl.h>
#include <media/videobuf2-dma-contig.h>
#define PHYTIUM_JPEG_NAME "phytium-jpeg"
#define MAX_FRAME_RATE 60
#define MAX_HEIGHT 1080
#define MAX_WIDTH 1920
#define MIN_HEIGHT 480
#define MIN_WIDTH 640
#define MIN_PIXEL_CLOCK (640 * 480 * 60) /* 640 x 480 x 60Hz */
#define MAX_PIXEL_CLOCK (1920 * 1080 * 60) /* 1920 x 1080 x 60Hz */
#define SOURCE_RESOLUTION_DETECT_TIMEOUT msecs_to_jiffies(500)
#define RESOLUTION_CHANGE_DELAY msecs_to_jiffies(0)
#define INVALID_RESOLUTION_DELAY msecs_to_jiffies(250)
#define STOP_TIMEOUT msecs_to_jiffies(1000)
#define INVALID_RESOLUTION_RETRIES 2
#define CAPTURE_BUF_NUMBER 3 /* using how many buffers */
#define VB_BUF_NO 0 /* there are 16 buffer, use which one */
/* The below macros are defined for the JPEG header of the phytium JPEG Engine */
#define PHYTIUM_JPEG_HEADER_LEN (256 * 3)
#define PHYTIUM_JPEG_HEADER_SIZE (PHYTIUM_JPEG_HEADER_LEN / sizeof(u32))
#define PHYTIUM_JPEG_HEADER_H_INDEX 40
#define PHYTIUM_JPEG_HEADER_W_INDEX 41
/* There are two ocm buffers that are used for storaging the inputing video data */
#define OCM_BUF_NUM 2
enum phytium_jpeg_status {
VIDEO_MODE_DETECT_DONE,
VIDEO_RES_CHANGE,
VIDEO_RES_DETECT,
VIDEO_STREAMING,
VIDEO_FRAME_INPRG,
VIDEO_STOPPED,
VIDEO_CLOCKS_ON,
VIDEO_POWEROFF,
};
struct phytium_jpeg_addr {
unsigned int size;
dma_addr_t dma_addr;
void *virt_addr;
};
struct phytium_jpeg_buffer {
struct vb2_v4l2_buffer vb;
struct list_head link;
};
/**
* struct phytium_jpeg - JPEG IP abstraction
* @lock: the mutex protecting this structure
* @hw_lock: spinlock protecting the hw device resource
* @workqueue: decode work queue
* @dev: JPEG device
* @v4l2_dev: v4l2 device for mem2mem mode
* @m2m_dev: v4l2 mem2mem device data
* @alloc_ctx: videobuf2 memory allocator's context
* @dec_vdev: video device node for decoder mem2mem mode
* @dec_reg_base: JPEG registers mapping
* @clk_jdec: JPEG hw working clock
* @clk_jdec_smi: JPEG SMI bus clock
* @larb: SMI device
*/
struct phytium_jpeg_dev {
void __iomem *base_addr;
struct device *dev;
struct v4l2_device v4l2_dev;
struct v4l2_pix_format pix_fmt;
struct v4l2_bt_timings active_timings;
struct v4l2_bt_timings detected_timings;
u32 v4l2_input_status;
struct vb2_queue queue;
struct video_device vdev;
/* v4l2 and videobuf2 lock, protect the structure*/
struct mutex video_lock;
u32 jpeg_mode;
u32 comp_size_read;
wait_queue_head_t wait;
/* buffer list lock, protecting the hw device resource */
spinlock_t hw_lock;
struct delayed_work res_work;
struct list_head buffers;
unsigned long status;
unsigned int sequence;
unsigned int max_compressed_size;
struct phytium_jpeg_addr src_addrs[OCM_BUF_NUM];
struct phytium_jpeg_addr dst_addrs[16];
bool yuv420;
unsigned int frame_rate;
void __iomem *timer30_addr;
void __iomem *timer31_addr;
};
struct phytium_jpeg_config {
u32 jpeg_mode;
u32 comp_size_read;
};
#define YUV_MODE_STR_LEN 8
#define YUVID 42
enum jpeg_yuv_mode {
YUV444 = 0x0,
YUV422 = 0x1,
YUV420 = 0x2
};
#endif /* _PHYTIUM_JPEG_CORE_H */

View File

@ -0,0 +1,113 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (c) 2021-2023, Phytium Technology Co., Ltd.
*/
#ifndef _PHYTIUM_JPEG_REG_H
#define _PHYTIUM_JPEG_REG_H
#include <linux/bits.h>
/* define the all kinds of control registers in a JPEG soc */
/* The register is used to set the information of the video comes from main memory */
#define SRC_DDR_INFO_REG 0x00000800
/* The register is used to get the information of the video comes from external VGA */
#define SRC_VGA_INFO_REG 0x00000894
#define SRC_FORMAT BIT(0) /* 0:RGB888, 1:RGB565 */
#define SRC_DE_POLARITY BIT(1) /* 0:low level is effect, other */
#define SRC_HS_POLARITY BIT(2) /* 0:low level is effect, other */
#define SRC_VS_POLARITY BIT(3) /* 0:low level is effect, other */
#define SRC_HOR_PIXELS GENMASK(15, 4) /* the number of the horizontal pixels */
#define SRC_WIDTH_SHIFT 4 /* shift right to get width */
#define SRC_VER_PIXELS GENMASK(26, 16) /* the number of the vertical pixels */
#define SRC_HEIGHT_SHIFT 16 /* shift right to get height */
/* The below bit fields is only used by image comes from main memory */
#define SRC_COMP_DDR_IMG_EN BIT(27) /* 0: disable to JPEG compression, others */
/* marks which ocm buffer is occupied to store an image */
#define SRC_DDR_IMG2OCM_VALID GENMASK(29, 28)
/* The register controls starting work of the JPEG engine */
#define TRANSFORM_INFO_REG 0x00000804
#define TRANSINFO_ENABLE_ENGINE BIT(0) /* 1: enable the JPEG engine */
/* 1: video comes from external VGA, 0: video comes from DDR */
#define TRANSINFO_SRC_SELECT BIT(1)
/* 0: video comes from external VGA is cached to OCM, 1: DDR */
#define TRANSINFO_IMAGE_STORE BIT(2)
#define TRANSINFO_FRAME_RATE GENMASK(9, 4) /* the value notes frame rate */
#define TRANSINFO_BLOCK_SIZE BIT(12) /* 0: 8x8, 1: 16x16 */
#define TRANSINFO_ENABLE_YUV422 BIT(13) /* 1: JPEG block is populated YUV422 */
/* support burst with the values such as 1, 2, 4, 8, 16, 32, 64. using default value 0xf */
#define TRANSINFO_AXI_LEN GENMASK(22, 16)
#define TRANS_AXI_LEN_SHIFT 16
/* The interrupt and status register */
#define INT_STATUS_CTRL_REG 0x00000808
#define INT_FIFO_OVERFLOW BIT(0) /* video fifo overflow, write 1 to clear */
#define INT_OCM_BUF_OVERFLOW BIT(1) /* ocm buffer overflow, write 1 to clear */
/* JPEG engine complete compression, write 1 to clear */
#define INT_JPEG_ENCODE_COMPLETE BIT(2)
/* in VGA mode, video's format is changed */
#define INT_VIDEO_FORMAT_CHANGE BIT(3)
/* enable the interrupt of th video fifo overflow and source resolution */
#define DETECT_RESOLUTION_CHANGE_EN BIT(4)
/* enable the interrupt of the ocm buffer overflow */
#define STS_VE_OCM_BUF_OVERFLOW_EN BIT(5)
/* enable the interrupt of the JPEG complete compression */
#define STS_VE_JPEG_CODE_COMP_EN BIT(6)
/* in VGA mode, the bit notes ocm buff is busy */
#define STS_VE_OCM_BUF_BUSY BIT(7)
/* in VGA mode, the bit notes sequence number of the frame */
#define STS_VE_CUR_FRAME_NUMBER GENMASK(9, 8)
/* in VGA mode, the bit notes sequence number of the cached frame */
#define STS_VE_BUF_CACHE_NUMBER GENMASK(11, 10)
/* in VGA mode, the buffer number in buffer list */
#define STS_JPEG_COMP_BUF_NO GENMASK(15, 12)
#define INT_JPEG_COMP_BUF_LIST_NO GENMASK(31, 16) /* the interrupt number of the buffer */
#define OCM_BUF0_ADDR 0x0000080C
#define OCM_BUF1_ADDR 0x00000810
#define OCM_BUF_SHIFT 8
#define BUF_LIST_BASE_ADDR 0x00000814
#define PHYTIUM_BUF_LIST_ACTRL_AND_STS_BASE_ADDR_REG 0x00000818
#define STS_JPEG_BUF_HIGH_LEVEL_VALID BIT(0) /* Hight levle is validity */
#define JPEG_BUF_CAPACITY_SIZE GENMASK(29, 8) /* the capacity of the buffer */
#define JPEG_BUF_CAPACITY_SIZE_SHIFT 8
/* There are 16 buffers in the buffer list, the width between each other' address is 8 bytes */
#define BUF_LIST_ADDR_OFFSET 0x8
#define BUF_LIST_CTRL_AND_STS_OFFSET 0x8
/* Get the address of the specific index buffer */
#define BUF_LIST_INDEX_ADDR(index) \
(BUF_LIST_BASE_ADDR + (index) * BUF_LIST_ADDR_OFFSET)
#define JPEG_DST_ADDR_SHIFT 8
#define BUF_LIST_INDEX_CTRL_STS_ADDR(index) \
(PHYTIUM_BUF_LIST_ACTRL_AND_STS_BASE_ADDR_REG + (index) * BUF_LIST_CTRL_AND_STS_OFFSET)
#define FRAME_SAMPLE_CTRL 0x00000898
#define FRAME_SAMPLE_CTRL_EN BIT(31)
#define FRAME_SAMPLE_INTERVAL GENMASK(30, 0)
/* The below registers are all related to quantilize */
#define HUFF_MODE_REG 0x300
#define SAMPLE_MODE_REG 0x304
#define Y_QUANT_BASE_ADDR_REG 0x400
#define C_QUANT_BASE_ADDR_REG 0x500
#define QUANT_REG_NUM 64
#define Y_QUANT_INDEX_ADDR_REG(index) \
(Y_QUANT_BASE_ADDR_REG + 4 * (index))
#define C_QUANT_INDEX_ADDR_REG(index) \
(C_QUANT_BASE_ADDR_REG + 4 * (index))
#endif /* _PHYTIUM_JPEG_REG_H */