1/* SPDX-License-Identifier: GPL-2.0-only */ 2/* 3 * TI Camera Access Layer (CAL) 4 * 5 * Copyright (c) 2015-2020 Texas Instruments Inc. 6 * 7 * Authors: 8 * Benoit Parrot <bparrot@ti.com> 9 * Laurent Pinchart <laurent.pinchart@ideasonboard.com> 10 */ 11#ifndef __TI_CAL_H__ 12#define __TI_CAL_H__ 13 14#include <linux/bitfield.h> 15#include <linux/io.h> 16#include <linux/list.h> 17#include <linux/mutex.h> 18#include <linux/spinlock.h> 19#include <linux/videodev2.h> 20 21#include <media/media-device.h> 22#include <media/v4l2-async.h> 23#include <media/v4l2-ctrls.h> 24#include <media/v4l2-dev.h> 25#include <media/v4l2-device.h> 26#include <media/v4l2-fwnode.h> 27#include <media/videobuf2-v4l2.h> 28 29#define CAL_MODULE_NAME "cal" 30#define CAL_NUM_CONTEXT 2 31#define CAL_NUM_CSI2_PORTS 2 32 33#define MAX_WIDTH_BYTES (8192 * 8) 34#define MAX_HEIGHT_LINES 16383 35 36struct device; 37struct device_node; 38struct resource; 39struct regmap; 40struct regmap_fied; 41struct v4l2_subdev; 42 43/* CTRL_CORE_CAMERRX_CONTROL register field id */ 44enum cal_camerarx_field { 45 F_CTRLCLKEN, 46 F_CAMMODE, 47 F_LANEENABLE, 48 F_CSI_MODE, 49 F_MAX_FIELDS, 50}; 51 52struct cal_fmt { 53 u32 fourcc; 54 u32 code; 55 /* Bits per pixel */ 56 u8 bpp; 57}; 58 59/* buffer for one video frame */ 60struct cal_buffer { 61 /* common v4l buffer stuff -- must be first */ 62 struct vb2_v4l2_buffer vb; 63 struct list_head list; 64}; 65 66struct cal_dmaqueue { 67 struct list_head active; 68}; 69 70struct cal_camerarx_data { 71 struct { 72 unsigned int lsb; 73 unsigned int msb; 74 } fields[F_MAX_FIELDS]; 75 unsigned int num_lanes; 76}; 77 78struct cal_data { 79 const struct cal_camerarx_data *camerarx; 80 unsigned int num_csi2_phy; 81 unsigned int flags; 82}; 83 84/* 85 * The Camera Adaptation Layer (CAL) module is paired with one or more complex 86 * I/O PHYs (CAMERARX). It contains multiple instances of CSI-2, processing and 87 * DMA contexts. 88 * 89 * The cal_dev structure represents the whole subsystem, including the CAL and 90 * the CAMERARX instances. Instances of struct cal_dev are named cal through the 91 * driver. 92 * 93 * The cal_camerarx structure represents one CAMERARX instance. Instances of 94 * cal_camerarx are named phy through the driver. 95 * 96 * The cal_ctx structure represents the combination of one CSI-2 context, one 97 * processing context and one DMA context. Instance of struct cal_ctx are named 98 * ctx through the driver. 99 */ 100 101struct cal_camerarx { 102 void __iomem *base; 103 struct resource *res; 104 struct device *dev; 105 struct regmap_field *fields[F_MAX_FIELDS]; 106 107 struct cal_dev *cal; 108 unsigned int instance; 109 110 struct v4l2_fwnode_endpoint endpoint; 111 struct device_node *sensor_node; 112 struct v4l2_subdev *sensor; 113}; 114 115struct cal_dev { 116 struct clk *fclk; 117 int irq; 118 void __iomem *base; 119 struct resource *res; 120 struct device *dev; 121 122 const struct cal_data *data; 123 u32 revision; 124 125 /* Control Module handle */ 126 struct regmap *syscon_camerrx; 127 u32 syscon_camerrx_offset; 128 129 /* Camera Core Module handle */ 130 struct cal_camerarx *phy[CAL_NUM_CSI2_PORTS]; 131 132 struct cal_ctx *ctx[CAL_NUM_CONTEXT]; 133 134 struct media_device mdev; 135 struct v4l2_device v4l2_dev; 136 struct v4l2_async_notifier notifier; 137}; 138 139/* 140 * There is one cal_ctx structure for each camera core context. 141 */ 142struct cal_ctx { 143 struct v4l2_ctrl_handler ctrl_handler; 144 struct video_device vdev; 145 struct media_pad pad; 146 147 struct cal_dev *cal; 148 struct cal_camerarx *phy; 149 150 /* v4l2_ioctl mutex */ 151 struct mutex mutex; 152 /* v4l2 buffers lock */ 153 spinlock_t slock; 154 155 struct cal_dmaqueue vidq; 156 157 /* video capture */ 158 const struct cal_fmt *fmt; 159 /* Used to store current pixel format */ 160 struct v4l2_format v_fmt; 161 /* Used to store current mbus frame format */ 162 struct v4l2_mbus_framefmt m_fmt; 163 164 /* Current subdev enumerated format */ 165 const struct cal_fmt **active_fmt; 166 unsigned int num_active_fmt; 167 168 unsigned int sequence; 169 struct vb2_queue vb_vidq; 170 unsigned int index; 171 unsigned int cport; 172 173 /* Pointer pointing to current v4l2_buffer */ 174 struct cal_buffer *cur_frm; 175 /* Pointer pointing to next v4l2_buffer */ 176 struct cal_buffer *next_frm; 177 178 bool dma_act; 179}; 180 181extern unsigned int cal_debug; 182extern int cal_video_nr; 183 184#define cal_dbg(level, cal, fmt, arg...) \ 185 do { \ 186 if (cal_debug >= (level)) \ 187 dev_printk(KERN_DEBUG, (cal)->dev, fmt, ##arg); \ 188 } while (0) 189#define cal_info(cal, fmt, arg...) \ 190 dev_info((cal)->dev, fmt, ##arg) 191#define cal_err(cal, fmt, arg...) \ 192 dev_err((cal)->dev, fmt, ##arg) 193 194#define ctx_dbg(level, ctx, fmt, arg...) \ 195 cal_dbg(level, (ctx)->cal, "ctx%u: " fmt, (ctx)->index, ##arg) 196#define ctx_info(ctx, fmt, arg...) \ 197 cal_info((ctx)->cal, "ctx%u: " fmt, (ctx)->index, ##arg) 198#define ctx_err(ctx, fmt, arg...) \ 199 cal_err((ctx)->cal, "ctx%u: " fmt, (ctx)->index, ##arg) 200 201#define phy_dbg(level, phy, fmt, arg...) \ 202 cal_dbg(level, (phy)->cal, "phy%u: " fmt, (phy)->instance, ##arg) 203#define phy_info(phy, fmt, arg...) \ 204 cal_info((phy)->cal, "phy%u: " fmt, (phy)->instance, ##arg) 205#define phy_err(phy, fmt, arg...) \ 206 cal_err((phy)->cal, "phy%u: " fmt, (phy)->instance, ##arg) 207 208static inline u32 cal_read(struct cal_dev *cal, u32 offset) 209{ 210 return ioread32(cal->base + offset); 211} 212 213static inline void cal_write(struct cal_dev *cal, u32 offset, u32 val) 214{ 215 iowrite32(val, cal->base + offset); 216} 217 218static __always_inline u32 cal_read_field(struct cal_dev *cal, u32 offset, u32 mask) 219{ 220 return FIELD_GET(mask, cal_read(cal, offset)); 221} 222 223static inline void cal_write_field(struct cal_dev *cal, u32 offset, u32 value, 224 u32 mask) 225{ 226 u32 val = cal_read(cal, offset); 227 228 val &= ~mask; 229 val |= (value << __ffs(mask)) & mask; 230 cal_write(cal, offset, val); 231} 232 233static inline void cal_set_field(u32 *valp, u32 field, u32 mask) 234{ 235 u32 val = *valp; 236 237 val &= ~mask; 238 val |= (field << __ffs(mask)) & mask; 239 *valp = val; 240} 241 242void cal_quickdump_regs(struct cal_dev *cal); 243 244void cal_camerarx_disable(struct cal_camerarx *phy); 245int cal_camerarx_start(struct cal_camerarx *phy, const struct cal_fmt *fmt); 246void cal_camerarx_stop(struct cal_camerarx *phy); 247void cal_camerarx_enable_irqs(struct cal_camerarx *phy); 248void cal_camerarx_disable_irqs(struct cal_camerarx *phy); 249void cal_camerarx_ppi_enable(struct cal_camerarx *phy); 250void cal_camerarx_ppi_disable(struct cal_camerarx *phy); 251void cal_camerarx_i913_errata(struct cal_camerarx *phy); 252struct cal_camerarx *cal_camerarx_create(struct cal_dev *cal, 253 unsigned int instance); 254void cal_camerarx_destroy(struct cal_camerarx *phy); 255 256void cal_ctx_csi2_config(struct cal_ctx *ctx); 257void cal_ctx_pix_proc_config(struct cal_ctx *ctx); 258void cal_ctx_wr_dma_config(struct cal_ctx *ctx, unsigned int width, 259 unsigned int height); 260void cal_ctx_wr_dma_addr(struct cal_ctx *ctx, unsigned int dmaaddr); 261 262int cal_ctx_v4l2_register(struct cal_ctx *ctx); 263void cal_ctx_v4l2_unregister(struct cal_ctx *ctx); 264int cal_ctx_v4l2_init(struct cal_ctx *ctx); 265void cal_ctx_v4l2_cleanup(struct cal_ctx *ctx); 266 267#endif /* __TI_CAL_H__ */ 268