1 /* 2 * TI OMAP4 ISS V4L2 Driver 3 * 4 * Copyright (C) 2012 Texas Instruments. 5 * 6 * Author: Sergio Aguirre <sergio.a.aguirre@gmail.com> 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; either version 2 of the License, or 11 * (at your option) any later version. 12 */ 13 14 #ifndef _OMAP4_ISS_H_ 15 #define _OMAP4_ISS_H_ 16 17 #include <media/v4l2-device.h> 18 #include <media/v4l2-mc.h> 19 20 #include <linux/device.h> 21 #include <linux/io.h> 22 #include <linux/platform_device.h> 23 #include <linux/wait.h> 24 25 #include <linux/platform_data/media/omap4iss.h> 26 27 #include "iss_regs.h" 28 #include "iss_csiphy.h" 29 #include "iss_csi2.h" 30 #include "iss_ipipeif.h" 31 #include "iss_ipipe.h" 32 #include "iss_resizer.h" 33 34 struct regmap; 35 36 #define to_iss_device(ptr_module) \ 37 container_of(ptr_module, struct iss_device, ptr_module) 38 #define to_device(ptr_module) \ 39 (to_iss_device(ptr_module)->dev) 40 41 enum iss_mem_resources { 42 OMAP4_ISS_MEM_TOP, 43 OMAP4_ISS_MEM_CSI2_A_REGS1, 44 OMAP4_ISS_MEM_CAMERARX_CORE1, 45 OMAP4_ISS_MEM_CSI2_B_REGS1, 46 OMAP4_ISS_MEM_CAMERARX_CORE2, 47 OMAP4_ISS_MEM_BTE, 48 OMAP4_ISS_MEM_ISP_SYS1, 49 OMAP4_ISS_MEM_ISP_RESIZER, 50 OMAP4_ISS_MEM_ISP_IPIPE, 51 OMAP4_ISS_MEM_ISP_ISIF, 52 OMAP4_ISS_MEM_ISP_IPIPEIF, 53 OMAP4_ISS_MEM_LAST, 54 }; 55 56 enum iss_subclk_resource { 57 OMAP4_ISS_SUBCLK_SIMCOP = (1 << 0), 58 OMAP4_ISS_SUBCLK_ISP = (1 << 1), 59 OMAP4_ISS_SUBCLK_CSI2_A = (1 << 2), 60 OMAP4_ISS_SUBCLK_CSI2_B = (1 << 3), 61 OMAP4_ISS_SUBCLK_CCP2 = (1 << 4), 62 }; 63 64 enum iss_isp_subclk_resource { 65 OMAP4_ISS_ISP_SUBCLK_BL = (1 << 0), 66 OMAP4_ISS_ISP_SUBCLK_ISIF = (1 << 1), 67 OMAP4_ISS_ISP_SUBCLK_H3A = (1 << 2), 68 OMAP4_ISS_ISP_SUBCLK_RSZ = (1 << 3), 69 OMAP4_ISS_ISP_SUBCLK_IPIPE = (1 << 4), 70 OMAP4_ISS_ISP_SUBCLK_IPIPEIF = (1 << 5), 71 }; 72 73 /* 74 * struct iss_reg - Structure for ISS register values. 75 * @reg: 32-bit Register address. 76 * @val: 32-bit Register value. 77 */ 78 struct iss_reg { 79 enum iss_mem_resources mmio_range; 80 u32 reg; 81 u32 val; 82 }; 83 84 /* 85 * struct iss_device - ISS device structure. 86 * @syscon: Regmap for the syscon register space 87 * @crashed: Crashed entities 88 */ 89 struct iss_device { 90 struct v4l2_device v4l2_dev; 91 struct media_device media_dev; 92 struct device *dev; 93 u32 revision; 94 95 /* platform HW resources */ 96 struct iss_platform_data *pdata; 97 unsigned int irq_num; 98 99 struct resource *res[OMAP4_ISS_MEM_LAST]; 100 void __iomem *regs[OMAP4_ISS_MEM_LAST]; 101 struct regmap *syscon; 102 103 u64 raw_dmamask; 104 105 struct mutex iss_mutex; /* For handling ref_count field */ 106 struct media_entity_enum crashed; 107 int has_context; 108 int ref_count; 109 110 struct clk *iss_fck; 111 struct clk *iss_ctrlclk; 112 113 /* ISS modules */ 114 struct iss_csi2_device csi2a; 115 struct iss_csi2_device csi2b; 116 struct iss_csiphy csiphy1; 117 struct iss_csiphy csiphy2; 118 struct iss_ipipeif_device ipipeif; 119 struct iss_ipipe_device ipipe; 120 struct iss_resizer_device resizer; 121 122 unsigned int subclk_resources; 123 unsigned int isp_subclk_resources; 124 }; 125 126 #define v4l2_dev_to_iss_device(dev) \ 127 container_of(dev, struct iss_device, v4l2_dev) 128 129 int omap4iss_get_external_info(struct iss_pipeline *pipe, 130 struct media_link *link); 131 132 int omap4iss_module_sync_idle(struct media_entity *me, wait_queue_head_t *wait, 133 atomic_t *stopping); 134 135 int omap4iss_module_sync_is_stopping(wait_queue_head_t *wait, 136 atomic_t *stopping); 137 138 int omap4iss_pipeline_set_stream(struct iss_pipeline *pipe, 139 enum iss_pipeline_stream_state state); 140 void omap4iss_pipeline_cancel_stream(struct iss_pipeline *pipe); 141 142 void omap4iss_configure_bridge(struct iss_device *iss, 143 enum ipipeif_input_entity input); 144 145 struct iss_device *omap4iss_get(struct iss_device *iss); 146 void omap4iss_put(struct iss_device *iss); 147 int omap4iss_subclk_enable(struct iss_device *iss, 148 enum iss_subclk_resource res); 149 int omap4iss_subclk_disable(struct iss_device *iss, 150 enum iss_subclk_resource res); 151 void omap4iss_isp_subclk_enable(struct iss_device *iss, 152 enum iss_isp_subclk_resource res); 153 void omap4iss_isp_subclk_disable(struct iss_device *iss, 154 enum iss_isp_subclk_resource res); 155 156 int omap4iss_register_entities(struct platform_device *pdev, 157 struct v4l2_device *v4l2_dev); 158 void omap4iss_unregister_entities(struct platform_device *pdev); 159 160 /* 161 * iss_reg_read - Read the value of an OMAP4 ISS register 162 * @iss: the ISS device 163 * @res: memory resource in which the register is located 164 * @offset: register offset in the memory resource 165 * 166 * Return the register value. 167 */ 168 static inline 169 u32 iss_reg_read(struct iss_device *iss, enum iss_mem_resources res, 170 u32 offset) 171 { 172 return readl(iss->regs[res] + offset); 173 } 174 175 /* 176 * iss_reg_write - Write a value to an OMAP4 ISS register 177 * @iss: the ISS device 178 * @res: memory resource in which the register is located 179 * @offset: register offset in the memory resource 180 * @value: value to be written 181 */ 182 static inline 183 void iss_reg_write(struct iss_device *iss, enum iss_mem_resources res, 184 u32 offset, u32 value) 185 { 186 writel(value, iss->regs[res] + offset); 187 } 188 189 /* 190 * iss_reg_clr - Clear bits in an OMAP4 ISS register 191 * @iss: the ISS device 192 * @res: memory resource in which the register is located 193 * @offset: register offset in the memory resource 194 * @clr: bit mask to be cleared 195 */ 196 static inline 197 void iss_reg_clr(struct iss_device *iss, enum iss_mem_resources res, 198 u32 offset, u32 clr) 199 { 200 u32 v = iss_reg_read(iss, res, offset); 201 202 iss_reg_write(iss, res, offset, v & ~clr); 203 } 204 205 /* 206 * iss_reg_set - Set bits in an OMAP4 ISS register 207 * @iss: the ISS device 208 * @res: memory resource in which the register is located 209 * @offset: register offset in the memory resource 210 * @set: bit mask to be set 211 */ 212 static inline 213 void iss_reg_set(struct iss_device *iss, enum iss_mem_resources res, 214 u32 offset, u32 set) 215 { 216 u32 v = iss_reg_read(iss, res, offset); 217 218 iss_reg_write(iss, res, offset, v | set); 219 } 220 221 /* 222 * iss_reg_update - Clear and set bits in an OMAP4 ISS register 223 * @iss: the ISS device 224 * @res: memory resource in which the register is located 225 * @offset: register offset in the memory resource 226 * @clr: bit mask to be cleared 227 * @set: bit mask to be set 228 * 229 * Clear the clr mask first and then set the set mask. 230 */ 231 static inline 232 void iss_reg_update(struct iss_device *iss, enum iss_mem_resources res, 233 u32 offset, u32 clr, u32 set) 234 { 235 u32 v = iss_reg_read(iss, res, offset); 236 237 iss_reg_write(iss, res, offset, (v & ~clr) | set); 238 } 239 240 #define iss_poll_condition_timeout(cond, timeout, min_ival, max_ival) \ 241 ({ \ 242 unsigned long __timeout = jiffies + usecs_to_jiffies(timeout); \ 243 unsigned int __min_ival = (min_ival); \ 244 unsigned int __max_ival = (max_ival); \ 245 bool __cond; \ 246 while (!(__cond = (cond))) { \ 247 if (time_after(jiffies, __timeout)) \ 248 break; \ 249 usleep_range(__min_ival, __max_ival); \ 250 } \ 251 !__cond; \ 252 }) 253 254 #endif /* _OMAP4_ISS_H_ */ 255