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