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