camera: rockchip: camsys v0.0x21.0xa
[firefly-linux-kernel-4.4.55.git] / drivers / media / video / rk_camsys / camsys_internal.h
1 #ifndef __RKCAMSYS_INTERNAL_H__
2 #define __RKCAMSYS_INTERNAL_H__
3
4 #include <linux/module.h>
5 #include <linux/moduleparam.h>
6 #include <linux/init.h>
7 #include <linux/delay.h>
8 #include <linux/device.h>
9 #include <linux/kernel.h>
10 #include <linux/slab.h>
11 #include <linux/i2c.h>
12 #include <linux/io.h>
13 #include <linux/fs.h>
14 #include <linux/interrupt.h>
15 #include <linux/errno.h>
16 #include <linux/err.h>
17 #include <linux/types.h>
18 #include <linux/proc_fs.h>
19 #include <linux/fcntl.h>
20 #include <linux/clk.h>
21 #include <linux/seq_file.h>
22 #include <linux/cdev.h>
23 #include <linux/miscdevice.h>
24 #include <linux/version.h>
25 #include <linux/device.h>
26 #include <linux/platform_device.h>
27 #include <linux/list.h>
28 #include <linux/mutex.h>
29 #include <linux/regulator/machine.h>
30 #include <linux/log2.h>
31 #include <linux/gpio.h>
32 #include <linux/rockchip/cpu.h>
33 #include <linux/rockchip/iomap.h>
34 #include <linux/rockchip/grf.h>
35 #include <asm/uaccess.h>
36 #include <linux/of.h>
37 #include <linux/of_device.h>
38 #include <linux/pinctrl/consumer.h>
39 #include <linux/of_address.h>
40 #include <linux/of_irq.h>
41 #include <linux/of_gpio.h>
42 #include <linux/rockchip/cpu.h>
43 #include <media/camsys_head.h>
44 #include <linux/rockchip-iovmm.h>
45
46 /*
47 *               C A M S Y S   D R I V E R   V E R S I O N
48 *
49 *v0.0.1:
50 *        1) test version;
51 *v0.0.2:
52 *        1) add mipi csi phy;
53 *v0.0.3:
54 *        1) add support cif phy for marvin;
55 *v0.0.4:
56 *        1) add clock information in struct camsys_devio_name_s;
57 *v0.0.5:
58 *        1) set isp clock at 32MHz;
59 *v0.0.6:
60 *        1) iomux d0 d1 for cif phy raw10 in rk319x after i2c operated;
61 *        2) check mis value in camsys_irq_connect;
62                 3) add soft rest callback;
63 *v0.7.0:
64                 1) check extdev is activate or not before delete from
65                 camsys_dev active list;
66 *v0.8.0:
67                 1) fix deregister a unregister extdev oops
68                 in camsys_extdev_deregister;
69 *v0.9.0: 1) set isp freq to 210M
70 *v0.a.0: 
71                 1) fix camsys_i2c_write and camsys_i2c_write
72                 can't support reg_size=0;
73 *v0.b.0:
74                 1) control ddr freq by marvin self other than by clk unit.
75 *v0.c.0:
76 *        1) add flash_trigger_out control
77 *v0.d.0:
78 *        1) add Isp_SoftRst for rk3288;
79 *v0.e.0:
80 *        1) isp_clk 208.8M for 1lane, isp_clk 416.6M for 2lane;
81 *v0.f.0:
82                 1) mi_mis register may read erro, this may cause
83                 mistaken mi frame_end irqs.
84 *v0.0x10.0:
85                 1) add flash_prelight control.
86 *v0.0x11.0:
87                 1) raise qos of isp up to the same as lcdc.
88 *v0.0x12.0:
89                 1) support iommu.
90 *v0.0x13.0:
91                 1) camsys_extdev_register return failed when this
92                 dev_id has been registered;
93                 2) add support JPG irq connect;
94 *v0.0x14.0:
95                 1) camsys_extdev_register return -EBUSY when this
96                 dev_id has been registered;
97 *v0.0x15.0:
98                 1) check extdev name when dev_id has been registered;
99 *v0.0x16.0:
100                 1) enable or disable IOMMU just depending
101                 on CONFIG_ROCKCHIP_IOMMU.
102 *v0.0x17.0:
103                 1) isp iommu status depend on vpu iommu status.
104 *v0.0x18.0:
105                 1) add flashlight RT8547 driver
106                 2) support torch mode
107 *v0.0x19.0:
108                 1) set CONFIG_CAMSYS_DRV disable as default,
109                 enable in defconfig file if needed.
110 *v0.0x1a.0:
111                 1) vpu_node changed from "vpu_service" to "rockchip,vpu_sub"
112 *v0.0x1b.0:
113                 1) use of_find_node_by_name to get vpu node
114                 instead of of_find_compatible_node
115 *v0.0x1c.0:
116                 1) support rk3368.
117 *v0.0x1d.0:
118                 1) enable aclk_rga for rk3368, otherwise,
119                 isp reset will cause system halted.
120 *v0.0x1e.0:
121                 1) dts remove aclk_rga, change aclk_isp
122                 from <clk_gates17 0> to <&clk_gates16 0>.
123                 2) add rl3369 pd_isp enable/disable.
124 *v0.0x1f.0:
125                 1) GPIO(gpio7 GPIO_B5) is EBUSY
126                 when register after factory reset,
127                 but after power on ,it's normal.
128 *v0.0x20.0:
129                 1) rk3368 camera: hold vio0 noc clock during the camera work,
130                 fixed isp iommu stall failed.
131 *v0.0x21.0:
132                 1) add isp-dvp-d4d11 iomux support.
133 *v0.0x21.1:
134                 1) support rk3368-sheep kernel ver4.4.
135 *v0.0x21.2:
136                 1) support rk3399.
137 *v0.0x21.3:
138                 1) some modifications.
139 *v0.0x21.4:
140                 1) modify for rk3399.
141 *v0.0x21.5:
142                 1) modify for mipiphy hsfreqrange.
143 *v0.0x21.6:
144                 1) support drm iommu.
145 *v0.0x21.7:
146 *       1) remove memset function wrong called code.
147 *v0.0x21.8:
148 *       1) flash module exist risk, fix up it.
149 *v0.0x21.9:
150         1) fix drm iommu crash.
151         if process cameraserver was died during streaming, iommu resource
152         was not released correctly. when cameraserver was recovered and
153         streaming again, iommu resource may be conflicted.
154 *v0.0x21.0xa:
155         1) clock clk_vio0_noc would cause mipi lcdc no display on 3368h, remove it.
156 */
157 #define CAMSYS_DRIVER_VERSION                   KERNEL_VERSION(0, 0x21, 0xa)
158
159 #define CAMSYS_PLATFORM_DRV_NAME                "RockChip-CamSys"
160 #define CAMSYS_PLATFORM_MARVIN_NAME             "Platform_MarvinDev"
161 #define CAMSYS_PLATFORM_CIF0_NAME               "Platform_Cif0Dev"
162 #define CAMSYS_PLATFORM_CIF1_NAME               "Platform_Cif1Dev"
163
164 #define CAMSYS_REGISTER_RES_NAME                "CamSys_RegMem"
165 #define CAMSYS_REGISTER_MIPIPHY_RES_NAME        "CamSys_RegMem_MipiPhy"
166 #define CAMSYS_IRQ_RES_NAME                     "CamSys_Irq"
167
168 #define CAMSYS_REGISTER_MEM_NAME                CAMSYS_REGISTER_RES_NAME
169 #define CAMSYS_I2C_MEM_NAME                     "CamSys_I2cMem"
170 #define CAMSYS_MIPIPHY_MEM_NAME                 \
171         CAMSYS_REGISTER_MIPIPHY_RES_NAME
172
173 #define CAMSYS_NAMELEN_MIN(a)                   \
174         ((strlen(a) > (CAMSYS_NAME_LEN-1))?(CAMSYS_NAME_LEN-1):strlen(a))
175 #define CAMSYS_IRQPOOL_NUM                      128
176 #define CAMSYS_DMA_BUF_MAX_NUM                  32
177
178 extern unsigned int camsys_debug;
179
180 #define camsys_trace(level, msg, ...) \
181         do { \
182                 if (camsys_debug >= level) \
183                         printk("D%d:%s(%d): " msg "\n", level,\
184                         __FUNCTION__, __LINE__, ## __VA_ARGS__); \
185         } while (0)
186
187 #define camsys_warn(msg, ...)  \
188         printk(KERN_ERR "W:%s(%d): " msg "\n", __FUNCTION__,\
189         __LINE__, ## __VA_ARGS__)
190 #define camsys_err(msg, ...)   \
191         printk(KERN_ERR "E:%s(%d): " msg "\n", __FUNCTION__,\
192         __LINE__, ## __VA_ARGS__)
193
194 typedef struct camsys_irqstas_s {
195         camsys_irqsta_t       sta;
196         struct list_head      list;
197 } camsys_irqstas_t;
198
199 typedef struct camsys_irqpool_s {
200         pid_t                 pid;
201         unsigned int          timeout;/* us */
202         unsigned int          mis;
203         unsigned int          icr;
204         spinlock_t            lock;/* lock for list */
205         camsys_irqstas_t      pool[CAMSYS_IRQPOOL_NUM];
206         struct list_head      active;
207         struct list_head      deactive;
208
209         struct list_head      list;
210
211         wait_queue_head_t     done;
212 } camsys_irqpool_t;
213
214 typedef struct camsys_irq_s {
215         unsigned int          irq_id;
216         /* lock for timeout and irq_connect in ioctl */
217         spinlock_t            lock;
218         struct list_head      irq_pool;
219 } camsys_irq_t;
220
221 typedef struct camsys_meminfo_s {
222         unsigned char name[32];
223         unsigned long phy_base;
224         unsigned long vir_base;
225         unsigned int size;
226         unsigned int vmas;
227         struct list_head list;
228 } camsys_meminfo_t;
229
230 typedef struct camsys_devmems_s {
231         camsys_meminfo_t *registermem;
232         camsys_meminfo_t *i2cmem;
233         struct list_head memslist;
234 } camsys_devmems_t;
235
236 typedef struct camsys_regulator_s {
237         struct regulator  *ldo;
238         int               min_uv;
239         int               max_uv;
240 } camsys_regulator_t;
241
242 typedef struct camsys_gpio_s {
243         unsigned int      io;
244         unsigned int      active;
245 } camsys_gpio_t;
246 typedef struct camsys_flash_s {
247         camsys_gpio_t        fl;
248         camsys_gpio_t        fl_en;
249         void *ext_fsh_dev;
250 } camsys_flash_t;
251 typedef struct camsys_extdev_s {
252         unsigned char            dev_name[CAMSYS_NAME_LEN];
253         unsigned int             dev_id;
254         camsys_regulator_t       avdd;
255         camsys_regulator_t       dovdd;
256         camsys_regulator_t       dvdd;
257         camsys_regulator_t       afvdd;
258         camsys_gpio_t            pwrdn;
259         camsys_gpio_t            rst;
260         camsys_gpio_t            afpwr;
261         camsys_gpio_t            afpwrdn;
262         camsys_gpio_t            pwren;
263         camsys_flash_t           fl;
264         camsys_extdev_phy_t      phy;
265         camsys_extdev_clk_t      clk;
266         unsigned int             dev_cfg;
267         struct platform_device *pdev;
268         struct list_head         list;
269         struct list_head         active;
270 } camsys_extdev_t;
271
272         typedef struct camsys_phyinfo_s {
273         unsigned int             phycnt;
274         void                     *clk;
275         camsys_meminfo_t         *reg;
276         int (*clkin_cb)(void *ptr, unsigned int on);
277         int (*ops)(void *ptr, camsys_mipiphy_t *phy);
278         int (*remove)(struct platform_device *pdev);
279 } camsys_phyinfo_t;
280
281 typedef struct camsys_exdevs_s {
282         struct mutex          mut;
283         struct list_head      list;
284         struct list_head      active;
285 } camsys_exdevs_t;
286
287 typedef struct camsys_dma_buf_s {
288         struct dma_buf *dma_buf;
289         struct dma_buf_attachment *attach;
290         struct sg_table *sgt;
291         dma_addr_t dma_addr;
292         int fd;
293 } camsys_dma_buf_t;
294
295 typedef struct camsys_dev_s {
296         unsigned int          dev_id;
297         camsys_irq_t          irq;
298         camsys_devmems_t      devmems;
299         struct miscdevice     miscdev;
300         void                  *clk;
301         camsys_phyinfo_t      *mipiphy;
302         camsys_phyinfo_t      cifphy;
303
304         camsys_exdevs_t       extdevs;
305         struct list_head      list;
306         struct platform_device *pdev;
307
308         void                  *soc;
309
310         camsys_meminfo_t     *csiphy_reg;
311         camsys_meminfo_t     *dsiphy_reg;
312         camsys_meminfo_t     *isp0_reg;
313
314         unsigned long         rk_grf_base;
315         unsigned long         rk_cru_base;
316         unsigned long         rk_isp_base;
317
318         struct iommu_domain *domain;
319         camsys_dma_buf_t dma_buf[CAMSYS_DMA_BUF_MAX_NUM];
320         int dma_buf_cnt;
321
322         int (*clkin_cb)(void *ptr, unsigned int on);
323         int (*clkout_cb)(void *ptr, unsigned int on, unsigned int clk);
324         int (*reset_cb)(void *ptr, unsigned int on);
325
326         int (*phy_cb)
327                 (camsys_extdev_t *extdev,
328                 camsys_sysctrl_t *devctl, void *ptr);
329         int (*iomux)(camsys_extdev_t *extdev, void *ptr);
330         int (*platform_remove)(struct platform_device *pdev);
331         int (*flash_trigger_cb)(void *ptr, int mode, unsigned int on);
332         int (*iommu_cb)(void *ptr, camsys_sysctrl_t *devctl);
333 } camsys_dev_t;
334
335
336 static inline camsys_extdev_t *camsys_find_extdev(
337 unsigned int dev_id, camsys_dev_t *camsys_dev)
338 {
339         camsys_extdev_t *extdev = NULL;
340
341         if (!list_empty(&camsys_dev->extdevs.list)) {
342                 list_for_each_entry(extdev,
343                         &camsys_dev->extdevs.list, list) {
344                         if (extdev->dev_id == dev_id) {
345                                 return extdev;
346                         }
347                 }
348         }
349         return NULL;
350 }
351
352 static inline camsys_meminfo_t *camsys_find_devmem(
353 char *name, camsys_dev_t *camsys_dev)
354 {
355         camsys_meminfo_t *devmem;
356
357         if (!list_empty(&camsys_dev->devmems.memslist)) {
358                 list_for_each_entry(devmem,
359                         &camsys_dev->devmems.memslist, list) {
360                         if (strcmp(devmem->name, name) == 0) {
361                                 return devmem;
362                         }
363                 }
364         }
365         camsys_err("%s memory have not been find in %s!",
366                 name, dev_name(camsys_dev->miscdev.this_device));
367         return NULL;
368 }
369
370 static inline int camsys_sysctl_extdev(
371 camsys_extdev_t *extdev, camsys_sysctrl_t *devctl, camsys_dev_t *camsys_dev)
372 {
373         int err = 0;
374         camsys_regulator_t *regulator;
375         camsys_gpio_t *gpio;
376
377         if ((devctl->ops > CamSys_Vdd_Start_Tag) &&
378                 (devctl->ops < CamSys_Vdd_End_Tag)) {
379                 regulator = &extdev->avdd;
380                 regulator += devctl->ops-1;
381
382                 if (!IS_ERR_OR_NULL(regulator->ldo)) {
383                         if (devctl->on) {
384                                 err = regulator_set_voltage(
385                                         regulator->ldo, regulator->min_uv,
386                                         regulator->max_uv);
387                                 err |= regulator_enable(regulator->ldo);
388                                 camsys_trace(1,
389                                         "Sysctl %d success, regulator set (%d,%d) uv!",
390                                         devctl->ops, regulator->min_uv,
391                                         regulator->max_uv);
392                         } else {
393                                 while (regulator_is_enabled(regulator->ldo) > 0)
394                                         regulator_disable(regulator->ldo);
395                                 camsys_trace(1,
396                                         "Sysctl %d success, regulator off!",
397                                         devctl->ops);
398                         }
399                 } else {
400                         err = -EINVAL;
401                         goto end;
402                 }
403         } else if ((devctl->ops > CamSys_Gpio_Start_Tag) &&
404                 (devctl->ops < CamSys_Gpio_End_Tag)) {
405                 gpio = &extdev->pwrdn;
406                 gpio += devctl->ops - CamSys_Gpio_Start_Tag -1;
407
408                 if (gpio->io != 0xffffffff) {
409                         if (devctl->on) {
410                                 gpio_direction_output(gpio->io, gpio->active);
411                                 gpio_set_value(gpio->io, gpio->active);
412                                 camsys_trace(1,
413                                         "Sysctl %d success, gpio(%d) set %d",
414                                         devctl->ops, gpio->io, gpio->active);
415                         } else {
416                                 gpio_direction_output(gpio->io, !gpio->active);
417                                 gpio_set_value(gpio->io, !gpio->active);
418                                 camsys_trace(1,
419                                         "Sysctl %d success, gpio(%d) set %d",
420                                         devctl->ops, gpio->io, !gpio->active);
421                         }
422                 } else {
423                         camsys_err("Sysctl %d failed, because gpio is NULL!",
424                                 devctl->ops);
425                         err = -EINVAL;
426                         goto end;
427                 }
428         } else if (devctl->ops == CamSys_ClkIn) {
429                 if (camsys_dev->clkout_cb)
430                         camsys_dev->clkout_cb
431                                 (camsys_dev, devctl->on,
432                                 extdev->clk.in_rate);
433         } else if (devctl->ops == CamSys_Phy) {
434                 if (camsys_dev->phy_cb)
435                         (camsys_dev->phy_cb)
436                                 (extdev, devctl,
437                                 (void *)camsys_dev);
438         }
439
440 end:
441         return err;
442 }
443
444 extern struct file_operations camsys_fops;
445 #endif