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 paddr; 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 /* physical base address */ 189 dma_addr_t paddr; 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 top the level v4l2_device 236 * @lock: mutex serializing video device and the subdev operations 237 * @slock: spinlock protecting this data structure and the hw registers 238 * @clocks: FIMC-LITE gate clock 239 * @regs: MCUCTL mmapped registers region 240 * @pmu_regs: PMU ISP mmapped registers region 241 * @irq_queue: interrupt handling waitqueue 242 * @lpm: low power mode flag 243 * @state: internal driver's state flags 244 */ 245struct fimc_is { 246 struct platform_device *pdev; 247 struct pinctrl *pctrl; 248 struct v4l2_device *v4l2_dev; 249 250 struct fimc_is_firmware fw; 251 struct fimc_is_memory memory; 252 struct firmware *f_w; 253 254 struct fimc_isp isp; 255 struct fimc_is_sensor sensor[FIMC_IS_SENSORS_NUM]; 256 struct fimc_is_setfile setfile; 257 258 struct v4l2_ctrl_handler ctrl_handler; 259 260 struct mutex lock; 261 spinlock_t slock; 262 263 struct clk *clocks[ISS_CLKS_MAX]; 264 void __iomem *regs; 265 void __iomem *pmu_regs; 266 int irq; 267 wait_queue_head_t irq_queue; 268 u8 lpm; 269 270 unsigned long state; 271 unsigned int sensor_index; 272 273 struct i2h_cmd i2h_cmd; 274 struct h2i_cmd h2i_cmd; 275 struct is_fd_result_header fd_header; 276 277 struct chain_config config[IS_SC_MAX]; 278 unsigned config_index; 279 280 struct is_region *is_p_region; 281 dma_addr_t is_dma_p_region; 282 struct is_share_region *is_shared_region; 283 struct is_af_info af; 284 285 struct dentry *debugfs_entry; 286}; 287 288static inline struct fimc_is *fimc_isp_to_is(struct fimc_isp *isp) 289{ 290 return container_of(isp, struct fimc_is, isp); 291} 292 293static inline struct chain_config *__get_curr_is_config(struct fimc_is *is) 294{ 295 return &is->config[is->config_index]; 296} 297 298static inline void fimc_is_mem_barrier(void) 299{ 300 mb(); 301} 302 303static inline void fimc_is_set_param_bit(struct fimc_is *is, int num) 304{ 305 struct chain_config *cfg = &is->config[is->config_index]; 306 307 set_bit(num, &cfg->p_region_index[0]); 308} 309 310static inline void fimc_is_set_param_ctrl_cmd(struct fimc_is *is, int cmd) 311{ 312 is->is_p_region->parameter.isp.control.cmd = cmd; 313} 314 315static inline void mcuctl_write(u32 v, struct fimc_is *is, unsigned int offset) 316{ 317 writel(v, is->regs + offset); 318} 319 320static inline u32 mcuctl_read(struct fimc_is *is, unsigned int offset) 321{ 322 return readl(is->regs + offset); 323} 324 325static inline void pmuisp_write(u32 v, struct fimc_is *is, unsigned int offset) 326{ 327 writel(v, is->pmu_regs + offset); 328} 329 330static inline u32 pmuisp_read(struct fimc_is *is, unsigned int offset) 331{ 332 return readl(is->pmu_regs + offset); 333} 334 335int fimc_is_wait_event(struct fimc_is *is, unsigned long bit, 336 unsigned int state, unsigned int timeout); 337int fimc_is_cpu_set_power(struct fimc_is *is, int on); 338int fimc_is_start_firmware(struct fimc_is *is); 339int fimc_is_hw_initialize(struct fimc_is *is); 340void fimc_is_log_dump(const char *level, const void *buf, size_t len); 341 342#endif /* FIMC_IS_H_ */ 343