camera: rockchip: camsys driver v0.0x22.0
[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 *v0.0x21.0xb:
157         1) some log is boring, so set print level more high.
158 *v0.0x21.0xc:
159         1) support rk3288.
160 *v0.0x21.0xd:
161         1) modify mipiphy_hsfreqrange for 3368.
162 *v0.0x21.0xe
163         1) correct mipiphy_hsfreqrange of 3368.
164         2) add csi-phy timing setting for 3368.
165 *v0.0x21.0xf:
166         1) add reference count for marvin.
167 *v0.0x22.0:
168         1) delete node in irqpool list when thread disconnect.
169 */
170 #define CAMSYS_DRIVER_VERSION                   KERNEL_VERSION(0, 0x22, 0)
171
172 #define CAMSYS_PLATFORM_DRV_NAME                "RockChip-CamSys"
173 #define CAMSYS_PLATFORM_MARVIN_NAME             "Platform_MarvinDev"
174 #define CAMSYS_PLATFORM_CIF0_NAME               "Platform_Cif0Dev"
175 #define CAMSYS_PLATFORM_CIF1_NAME               "Platform_Cif1Dev"
176
177 #define CAMSYS_REGISTER_RES_NAME                "CamSys_RegMem"
178 #define CAMSYS_REGISTER_MIPIPHY_RES_NAME        "CamSys_RegMem_MipiPhy"
179 #define CAMSYS_IRQ_RES_NAME                     "CamSys_Irq"
180
181 #define CAMSYS_REGISTER_MEM_NAME                CAMSYS_REGISTER_RES_NAME
182 #define CAMSYS_I2C_MEM_NAME                     "CamSys_I2cMem"
183 #define CAMSYS_MIPIPHY_MEM_NAME                 \
184         CAMSYS_REGISTER_MIPIPHY_RES_NAME
185
186 #define CAMSYS_NAMELEN_MIN(a)                   \
187         ((strlen(a) > (CAMSYS_NAME_LEN-1))?(CAMSYS_NAME_LEN-1):strlen(a))
188 #define CAMSYS_IRQPOOL_NUM                      128
189 #define CAMSYS_DMA_BUF_MAX_NUM                  32
190
191 extern unsigned int camsys_debug;
192
193 #define camsys_trace(level, msg, ...) \
194         do { \
195                 if (camsys_debug >= level) \
196                         printk("D%d:%s(%d): " msg "\n", level,\
197                         __FUNCTION__, __LINE__, ## __VA_ARGS__); \
198         } while (0)
199
200 #define camsys_warn(msg, ...)  \
201         printk(KERN_ERR "W:%s(%d): " msg "\n", __FUNCTION__,\
202         __LINE__, ## __VA_ARGS__)
203 #define camsys_err(msg, ...)   \
204         printk(KERN_ERR "E:%s(%d): " msg "\n", __FUNCTION__,\
205         __LINE__, ## __VA_ARGS__)
206
207 typedef struct camsys_irqstas_s {
208         camsys_irqsta_t       sta;
209         struct list_head      list;
210 } camsys_irqstas_t;
211
212 typedef struct camsys_irqpool_s {
213         pid_t                 pid;
214         unsigned int          timeout;/* us */
215         unsigned int          mis;
216         unsigned int          icr;
217         spinlock_t            lock;/* lock for list */
218         camsys_irqstas_t      pool[CAMSYS_IRQPOOL_NUM];
219         struct list_head      active;
220         struct list_head      deactive;
221
222         struct list_head      list;
223
224         wait_queue_head_t     done;
225 } camsys_irqpool_t;
226
227 typedef struct camsys_irq_s {
228         unsigned int          irq_id;
229         /* lock for timeout and irq_connect in ioctl */
230         spinlock_t            lock;
231         struct list_head      irq_pool;
232 } camsys_irq_t;
233
234 typedef struct camsys_meminfo_s {
235         unsigned char name[32];
236         unsigned long phy_base;
237         unsigned long vir_base;
238         unsigned int size;
239         unsigned int vmas;
240         struct list_head list;
241 } camsys_meminfo_t;
242
243 typedef struct camsys_devmems_s {
244         camsys_meminfo_t *registermem;
245         camsys_meminfo_t *i2cmem;
246         struct list_head memslist;
247 } camsys_devmems_t;
248
249 typedef struct camsys_regulator_s {
250         struct regulator  *ldo;
251         int               min_uv;
252         int               max_uv;
253 } camsys_regulator_t;
254
255 typedef struct camsys_gpio_s {
256         unsigned int      io;
257         unsigned int      active;
258 } camsys_gpio_t;
259 typedef struct camsys_flash_s {
260         camsys_gpio_t        fl;
261         camsys_gpio_t        fl_en;
262         void *ext_fsh_dev;
263 } camsys_flash_t;
264 typedef struct camsys_extdev_s {
265         unsigned char            dev_name[CAMSYS_NAME_LEN];
266         unsigned int             dev_id;
267         camsys_regulator_t       avdd;
268         camsys_regulator_t       dovdd;
269         camsys_regulator_t       dvdd;
270         camsys_regulator_t       afvdd;
271         camsys_gpio_t            pwrdn;
272         camsys_gpio_t            rst;
273         camsys_gpio_t            afpwr;
274         camsys_gpio_t            afpwrdn;
275         camsys_gpio_t            pwren;
276         camsys_flash_t           fl;
277         camsys_extdev_phy_t      phy;
278         camsys_extdev_clk_t      clk;
279         unsigned int             dev_cfg;
280         struct platform_device *pdev;
281         struct list_head         list;
282         struct list_head         active;
283 } camsys_extdev_t;
284
285         typedef struct camsys_phyinfo_s {
286         unsigned int             phycnt;
287         void                     *clk;
288         camsys_meminfo_t         *reg;
289         int (*clkin_cb)(void *ptr, unsigned int on);
290         int (*ops)(void *ptr, camsys_mipiphy_t *phy);
291         int (*remove)(struct platform_device *pdev);
292 } camsys_phyinfo_t;
293
294 typedef struct camsys_exdevs_s {
295         struct mutex          mut;
296         struct list_head      list;
297         struct list_head      active;
298 } camsys_exdevs_t;
299
300 typedef struct camsys_dma_buf_s {
301         struct dma_buf *dma_buf;
302         struct dma_buf_attachment *attach;
303         struct sg_table *sgt;
304         dma_addr_t dma_addr;
305         int fd;
306 } camsys_dma_buf_t;
307
308 typedef struct camsys_dev_s {
309         unsigned int          dev_id;
310         camsys_irq_t          irq;
311         camsys_devmems_t      devmems;
312         struct miscdevice     miscdev;
313         void                  *clk;
314         camsys_phyinfo_t      *mipiphy;
315         camsys_phyinfo_t      cifphy;
316
317         camsys_exdevs_t       extdevs;
318         struct list_head      list;
319         struct platform_device *pdev;
320
321         void                  *soc;
322
323         camsys_meminfo_t     *csiphy_reg;
324         camsys_meminfo_t     *dsiphy_reg;
325         camsys_meminfo_t     *isp0_reg;
326
327         unsigned long         rk_grf_base;
328         unsigned long         rk_cru_base;
329         unsigned long         rk_isp_base;
330         atomic_t              refcount;
331         struct iommu_domain *domain;
332         camsys_dma_buf_t dma_buf[CAMSYS_DMA_BUF_MAX_NUM];
333         int dma_buf_cnt;
334
335         int (*clkin_cb)(void *ptr, unsigned int on);
336         int (*clkout_cb)(void *ptr, unsigned int on, unsigned int clk);
337         int (*reset_cb)(void *ptr, unsigned int on);
338
339         int (*phy_cb)
340                 (camsys_extdev_t *extdev,
341                 camsys_sysctrl_t *devctl, void *ptr);
342         int (*iomux)(camsys_extdev_t *extdev, void *ptr);
343         int (*platform_remove)(struct platform_device *pdev);
344         int (*flash_trigger_cb)(void *ptr, int mode, unsigned int on);
345         int (*iommu_cb)(void *ptr, camsys_sysctrl_t *devctl);
346 } camsys_dev_t;
347
348
349 static inline camsys_extdev_t *camsys_find_extdev(
350 unsigned int dev_id, camsys_dev_t *camsys_dev)
351 {
352         camsys_extdev_t *extdev = NULL;
353
354         if (!list_empty(&camsys_dev->extdevs.list)) {
355                 list_for_each_entry(extdev,
356                         &camsys_dev->extdevs.list, list) {
357                         if (extdev->dev_id == dev_id) {
358                                 return extdev;
359                         }
360                 }
361         }
362         return NULL;
363 }
364
365 static inline camsys_meminfo_t *camsys_find_devmem(
366 char *name, camsys_dev_t *camsys_dev)
367 {
368         camsys_meminfo_t *devmem;
369
370         if (!list_empty(&camsys_dev->devmems.memslist)) {
371                 list_for_each_entry(devmem,
372                         &camsys_dev->devmems.memslist, list) {
373                         if (strcmp(devmem->name, name) == 0) {
374                                 return devmem;
375                         }
376                 }
377         }
378         camsys_err("%s memory have not been find in %s!",
379                 name, dev_name(camsys_dev->miscdev.this_device));
380         return NULL;
381 }
382
383 static inline int camsys_sysctl_extdev(
384 camsys_extdev_t *extdev, camsys_sysctrl_t *devctl, camsys_dev_t *camsys_dev)
385 {
386         int err = 0;
387         camsys_regulator_t *regulator;
388         camsys_gpio_t *gpio;
389
390         if ((devctl->ops > CamSys_Vdd_Start_Tag) &&
391                 (devctl->ops < CamSys_Vdd_End_Tag)) {
392                 regulator = &extdev->avdd;
393                 regulator += devctl->ops-1;
394
395                 if (!IS_ERR_OR_NULL(regulator->ldo)) {
396                         if (devctl->on) {
397                                 err = regulator_set_voltage(
398                                         regulator->ldo, regulator->min_uv,
399                                         regulator->max_uv);
400                                 err |= regulator_enable(regulator->ldo);
401                                 camsys_trace(1,
402                                         "Sysctl %d success, regulator set (%d,%d) uv!",
403                                         devctl->ops, regulator->min_uv,
404                                         regulator->max_uv);
405                         } else {
406                                 while (regulator_is_enabled(regulator->ldo) > 0)
407                                         regulator_disable(regulator->ldo);
408                                 camsys_trace(1,
409                                         "Sysctl %d success, regulator off!",
410                                         devctl->ops);
411                         }
412                 } else {
413                         err = -EINVAL;
414                         goto end;
415                 }
416         } else if ((devctl->ops > CamSys_Gpio_Start_Tag) &&
417                 (devctl->ops < CamSys_Gpio_End_Tag)) {
418                 gpio = &extdev->pwrdn;
419                 gpio += devctl->ops - CamSys_Gpio_Start_Tag -1;
420
421                 if (gpio->io != 0xffffffff) {
422                         if (devctl->on) {
423                                 gpio_direction_output(gpio->io, gpio->active);
424                                 gpio_set_value(gpio->io, gpio->active);
425                                 camsys_trace(1,
426                                         "Sysctl %d success, gpio(%d) set %d",
427                                         devctl->ops, gpio->io, gpio->active);
428                         } else {
429                                 gpio_direction_output(gpio->io, !gpio->active);
430                                 gpio_set_value(gpio->io, !gpio->active);
431                                 camsys_trace(1,
432                                         "Sysctl %d success, gpio(%d) set %d",
433                                         devctl->ops, gpio->io, !gpio->active);
434                         }
435                 } else {
436                         camsys_trace(1, "Sysctl %d not do, because gpio is NULL",
437                                 devctl->ops);
438                         err = -EINVAL;
439                         goto end;
440                 }
441         } else if (devctl->ops == CamSys_ClkIn) {
442                 if (camsys_dev->clkout_cb)
443                         camsys_dev->clkout_cb
444                                 (camsys_dev, devctl->on,
445                                 extdev->clk.in_rate);
446         } else if (devctl->ops == CamSys_Phy) {
447                 if (camsys_dev->phy_cb)
448                         (camsys_dev->phy_cb)
449                                 (extdev, devctl,
450                                 (void *)camsys_dev);
451         }
452
453 end:
454         return err;
455 }
456
457 extern struct file_operations camsys_fops;
458 #endif