fimc-is.h (8461B)
1/* SPDX-License-Identifier: GPL-2.0-only */ 2/* 3 * Samsung EXYNOS4x12 FIMC-IS (Imaging Subsystem) driver 4 * 5 * Copyright (C) 2013 Samsung Electronics Co., Ltd. 6 * 7 * Authors: Younghwan Joo <yhwan.joo@samsung.com> 8 * Sylwester Nawrocki <s.nawrocki@samsung.com> 9 */ 10#ifndef FIMC_IS_H_ 11#define FIMC_IS_H_ 12 13#include <asm/barrier.h> 14#include <linux/clk.h> 15#include <linux/device.h> 16#include <linux/kernel.h> 17#include <linux/pinctrl/consumer.h> 18#include <linux/platform_device.h> 19#include <linux/sizes.h> 20#include <linux/spinlock.h> 21#include <linux/types.h> 22#include <media/videobuf2-v4l2.h> 23#include <media/v4l2-ctrls.h> 24 25#include "fimc-isp.h" 26#include "fimc-is-command.h" 27#include "fimc-is-sensor.h" 28#include "fimc-is-param.h" 29#include "fimc-is-regs.h" 30 31#define FIMC_IS_DRV_NAME "exynos4-fimc-is" 32 33#define FIMC_IS_FW_FILENAME "exynos4_fimc_is_fw.bin" 34#define FIMC_IS_SETFILE_6A3 "exynos4_s5k6a3_setfile.bin" 35 36#define FIMC_IS_FW_LOAD_TIMEOUT 1000 /* ms */ 37#define FIMC_IS_POWER_ON_TIMEOUT 1000 /* us */ 38 39#define FIMC_IS_SENSORS_NUM 2 40 41/* Memory definitions */ 42#define FIMC_IS_CPU_MEM_SIZE (0xa00000) 43#define FIMC_IS_CPU_BASE_MASK ((1 << 26) - 1) 44#define FIMC_IS_REGION_SIZE 0x5000 45 46#define FIMC_IS_DEBUG_REGION_OFFSET 0x0084b000 47#define FIMC_IS_SHARED_REGION_OFFSET 0x008c0000 48#define FIMC_IS_FW_INFO_LEN 31 49#define FIMC_IS_FW_VER_LEN 7 50#define FIMC_IS_FW_DESC_LEN (FIMC_IS_FW_INFO_LEN + \ 51 FIMC_IS_FW_VER_LEN) 52#define FIMC_IS_SETFILE_INFO_LEN 39 53 54#define FIMC_IS_EXTRA_MEM_SIZE (FIMC_IS_EXTRA_FW_SIZE + \ 55 FIMC_IS_EXTRA_SETFILE_SIZE + 0x1000) 56#define FIMC_IS_EXTRA_FW_SIZE 0x180000 57#define FIMC_IS_EXTRA_SETFILE_SIZE 0x4b000 58 59/* TODO: revisit */ 60#define FIMC_IS_FW_ADDR_MASK ((1 << 26) - 1) 61#define FIMC_IS_FW_SIZE_MAX (SZ_4M) 62#define FIMC_IS_FW_SIZE_MIN (SZ_32K) 63 64#define ATCLK_MCUISP_FREQUENCY 100000000UL 65#define ACLK_AXI_FREQUENCY 100000000UL 66 67enum { 68 ISS_CLK_PPMUISPX, 69 ISS_CLK_PPMUISPMX, 70 ISS_CLK_LITE0, 71 ISS_CLK_LITE1, 72 ISS_CLK_MPLL, 73 ISS_CLK_ISP, 74 ISS_CLK_DRC, 75 ISS_CLK_FD, 76 ISS_CLK_MCUISP, 77 ISS_CLK_GICISP, 78 ISS_CLK_PWM_ISP, 79 ISS_CLK_MCUCTL_ISP, 80 ISS_CLK_UART, 81 ISS_GATE_CLKS_MAX, 82 ISS_CLK_ISP_DIV0 = ISS_GATE_CLKS_MAX, 83 ISS_CLK_ISP_DIV1, 84 ISS_CLK_MCUISP_DIV0, 85 ISS_CLK_MCUISP_DIV1, 86 ISS_CLK_ACLK200, 87 ISS_CLK_ACLK200_DIV, 88 ISS_CLK_ACLK400MCUISP, 89 ISS_CLK_ACLK400MCUISP_DIV, 90 ISS_CLKS_MAX 91}; 92 93/* The driver's internal state flags */ 94enum { 95 IS_ST_IDLE, 96 IS_ST_PWR_ON, 97 IS_ST_A5_PWR_ON, 98 IS_ST_FW_LOADED, 99 IS_ST_OPEN_SENSOR, 100 IS_ST_SETFILE_LOADED, 101 IS_ST_INIT_DONE, 102 IS_ST_STREAM_ON, 103 IS_ST_STREAM_OFF, 104 IS_ST_CHANGE_MODE, 105 IS_ST_BLOCK_CMD_CLEARED, 106 IS_ST_SET_ZOOM, 107 IS_ST_PWR_SUBIP_ON, 108 IS_ST_END, 109}; 110 111enum af_state { 112 FIMC_IS_AF_IDLE = 0, 113 FIMC_IS_AF_SETCONFIG = 1, 114 FIMC_IS_AF_RUNNING = 2, 115 FIMC_IS_AF_LOCK = 3, 116 FIMC_IS_AF_ABORT = 4, 117 FIMC_IS_AF_FAILED = 5, 118}; 119 120enum af_lock_state { 121 FIMC_IS_AF_UNLOCKED = 0, 122 FIMC_IS_AF_LOCKED = 2 123}; 124 125enum ae_lock_state { 126 FIMC_IS_AE_UNLOCKED = 0, 127 FIMC_IS_AE_LOCKED = 1 128}; 129 130enum awb_lock_state { 131 FIMC_IS_AWB_UNLOCKED = 0, 132 FIMC_IS_AWB_LOCKED = 1 133}; 134 135enum { 136 IS_METERING_CONFIG_CMD, 137 IS_METERING_CONFIG_WIN_POS_X, 138 IS_METERING_CONFIG_WIN_POS_Y, 139 IS_METERING_CONFIG_WIN_WIDTH, 140 IS_METERING_CONFIG_WIN_HEIGHT, 141 IS_METERING_CONFIG_MAX 142}; 143 144struct is_setfile { 145 const struct firmware *info; 146 int state; 147 u32 sub_index; 148 u32 base; 149 size_t size; 150}; 151 152struct is_fd_result_header { 153 u32 offset; 154 u32 count; 155 u32 index; 156 u32 curr_index; 157 u32 width; 158 u32 height; 159}; 160 161struct is_af_info { 162 u16 mode; 163 u32 af_state; 164 u32 af_lock_state; 165 u32 ae_lock_state; 166 u32 awb_lock_state; 167 u16 pos_x; 168 u16 pos_y; 169 u16 prev_pos_x; 170 u16 prev_pos_y; 171 u16 use_af; 172}; 173 174struct fimc_is_firmware { 175 const struct firmware *f_w; 176 177 dma_addr_t addr; 178 void *vaddr; 179 unsigned int size; 180 181 char info[FIMC_IS_FW_INFO_LEN + 1]; 182 char version[FIMC_IS_FW_VER_LEN + 1]; 183 char setfile_info[FIMC_IS_SETFILE_INFO_LEN + 1]; 184 u8 state; 185}; 186 187struct fimc_is_memory { 188 /* DMA base address */ 189 dma_addr_t addr; 190 /* virtual base address */ 191 void *vaddr; 192 /* total length */ 193 unsigned int size; 194}; 195 196#define FIMC_IS_I2H_MAX_ARGS 12 197 198struct i2h_cmd { 199 u32 cmd; 200 u32 sensor_id; 201 u16 num_args; 202 u32 args[FIMC_IS_I2H_MAX_ARGS]; 203}; 204 205struct h2i_cmd { 206 u16 cmd_type; 207 u32 entry_id; 208}; 209 210#define FIMC_IS_DEBUG_MSG 0x3f 211#define FIMC_IS_DEBUG_LEVEL 3 212 213struct fimc_is_setfile { 214 const struct firmware *info; 215 unsigned int state; 216 unsigned int size; 217 u32 sub_index; 218 u32 base; 219}; 220 221struct chain_config { 222 struct global_param global; 223 struct sensor_param sensor; 224 struct isp_param isp; 225 struct drc_param drc; 226 struct fd_param fd; 227 228 unsigned long p_region_index[2]; 229}; 230 231/** 232 * struct fimc_is - fimc-is data structure 233 * @pdev: pointer to FIMC-IS platform device 234 * @pctrl: pointer to pinctrl structure for this device 235 * @v4l2_dev: pointer to the top level v4l2_device 236 * @fw: data structure describing the FIMC-IS firmware binary 237 * @memory: memory region assigned for the FIMC-IS (firmware) 238 * @isp: the ISP block data structure 239 * @sensor: fimc-is sensor subdevice array 240 * @setfile: descriptor of the imaging pipeline calibration data 241 * @ctrl_handler: the v4l2 controls handler 242 * @lock: mutex serializing video device and the subdev operations 243 * @slock: spinlock protecting this data structure and the hw registers 244 * @clocks: FIMC-LITE gate clock 245 * @regs: MCUCTL mmapped registers region 246 * @pmu_regs: PMU ISP mmapped registers region 247 * @irq: FIMC-IS interrupt 248 * @irq_queue: interrupt handling waitqueue 249 * @lpm: low power mode flag 250 * @state: internal driver's state flags 251 * @sensor_index: image sensor index for the firmware 252 * @i2h_cmd: FIMC-IS to the host (CPU) mailbox command data structure 253 * @h2i_cmd: the host (CPU) to FIMC-IS mailbox command data structure 254 * @fd_header: the face detection result data structure 255 * @config: shared HW pipeline configuration data 256 * @config_index: index to the @config entry currently in use 257 * @is_p_region: pointer to the shared parameter memory region 258 * @is_dma_p_region: DMA address of the shared parameter memory region 259 * @is_shared_region: pointer to the IS shared region data structure 260 * @af: auto focus data 261 * @debugfs_entry: debugfs entry for the firmware log 262 */ 263struct fimc_is { 264 struct platform_device *pdev; 265 struct pinctrl *pctrl; 266 struct v4l2_device *v4l2_dev; 267 268 struct fimc_is_firmware fw; 269 struct fimc_is_memory memory; 270 271 struct fimc_isp isp; 272 struct fimc_is_sensor sensor[FIMC_IS_SENSORS_NUM]; 273 struct fimc_is_setfile setfile; 274 275 struct v4l2_ctrl_handler ctrl_handler; 276 277 struct mutex lock; 278 spinlock_t slock; 279 280 struct clk *clocks[ISS_CLKS_MAX]; 281 void __iomem *regs; 282 void __iomem *pmu_regs; 283 int irq; 284 wait_queue_head_t irq_queue; 285 u8 lpm; 286 287 unsigned long state; 288 unsigned int sensor_index; 289 290 struct i2h_cmd i2h_cmd; 291 struct h2i_cmd h2i_cmd; 292 struct is_fd_result_header fd_header; 293 294 struct chain_config config[IS_SC_MAX]; 295 unsigned config_index; 296 297 struct is_region *is_p_region; 298 dma_addr_t is_dma_p_region; 299 struct is_share_region *is_shared_region; 300 struct is_af_info af; 301 302 struct dentry *debugfs_entry; 303}; 304 305static inline struct fimc_is *fimc_isp_to_is(struct fimc_isp *isp) 306{ 307 return container_of(isp, struct fimc_is, isp); 308} 309 310static inline struct chain_config *__get_curr_is_config(struct fimc_is *is) 311{ 312 return &is->config[is->config_index]; 313} 314 315static inline void fimc_is_mem_barrier(void) 316{ 317 mb(); 318} 319 320static inline void fimc_is_set_param_bit(struct fimc_is *is, int num) 321{ 322 struct chain_config *cfg = &is->config[is->config_index]; 323 324 set_bit(num, &cfg->p_region_index[0]); 325} 326 327static inline void fimc_is_set_param_ctrl_cmd(struct fimc_is *is, int cmd) 328{ 329 is->is_p_region->parameter.isp.control.cmd = cmd; 330} 331 332static inline void mcuctl_write(u32 v, struct fimc_is *is, unsigned int offset) 333{ 334 writel(v, is->regs + offset); 335} 336 337static inline u32 mcuctl_read(struct fimc_is *is, unsigned int offset) 338{ 339 return readl(is->regs + offset); 340} 341 342static inline void pmuisp_write(u32 v, struct fimc_is *is, unsigned int offset) 343{ 344 writel(v, is->pmu_regs + offset); 345} 346 347static inline u32 pmuisp_read(struct fimc_is *is, unsigned int offset) 348{ 349 return readl(is->pmu_regs + offset); 350} 351 352int fimc_is_wait_event(struct fimc_is *is, unsigned long bit, 353 unsigned int state, unsigned int timeout); 354int fimc_is_cpu_set_power(struct fimc_is *is, int on); 355int fimc_is_start_firmware(struct fimc_is *is); 356int fimc_is_hw_initialize(struct fimc_is *is); 357void fimc_is_log_dump(const char *level, const void *buf, size_t len); 358 359#endif /* FIMC_IS_H_ */