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