Hans Verkuil | 85756a0 | 2015-05-12 08:52:21 -0300 | [diff] [blame] | 1 | /* |
| 2 | * cobalt driver internal defines and structures |
| 3 | * |
| 4 | * Derived from cx18-driver.h |
| 5 | * |
| 6 | * Copyright 2012-2015 Cisco Systems, Inc. and/or its affiliates. |
| 7 | * All rights reserved. |
| 8 | * |
| 9 | * This program is free software; you may redistribute it and/or modify |
| 10 | * it under the terms of the GNU General Public License as published by |
| 11 | * the Free Software Foundation; version 2 of the License. |
| 12 | * |
| 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
| 14 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
| 15 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
| 16 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS |
| 17 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN |
| 18 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN |
| 19 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
| 20 | * SOFTWARE. |
| 21 | */ |
| 22 | |
| 23 | #ifndef COBALT_DRIVER_H |
| 24 | #define COBALT_DRIVER_H |
| 25 | |
| 26 | #include <linux/module.h> |
| 27 | #include <linux/pci.h> |
| 28 | #include <linux/spinlock.h> |
| 29 | #include <linux/i2c.h> |
| 30 | #include <linux/list.h> |
| 31 | #include <linux/workqueue.h> |
| 32 | #include <linux/mutex.h> |
| 33 | |
| 34 | #include <media/v4l2-common.h> |
| 35 | #include <media/v4l2-ioctl.h> |
| 36 | #include <media/v4l2-device.h> |
| 37 | #include <media/v4l2-fh.h> |
| 38 | #include <media/videobuf2-dma-sg.h> |
| 39 | |
| 40 | #include "m00233_video_measure_memmap_package.h" |
| 41 | #include "m00235_fdma_packer_memmap_package.h" |
| 42 | #include "m00389_cvi_memmap_package.h" |
| 43 | #include "m00460_evcnt_memmap_package.h" |
| 44 | #include "m00473_freewheel_memmap_package.h" |
| 45 | #include "m00479_clk_loss_detector_memmap_package.h" |
| 46 | #include "m00514_syncgen_flow_evcnt_memmap_package.h" |
| 47 | |
| 48 | /* System device ID */ |
| 49 | #define PCI_DEVICE_ID_COBALT 0x2732 |
| 50 | |
| 51 | /* Number of cobalt device nodes. */ |
| 52 | #define COBALT_NUM_INPUTS 4 |
| 53 | #define COBALT_NUM_NODES 6 |
| 54 | |
| 55 | /* Number of cobalt device streams. */ |
| 56 | #define COBALT_NUM_STREAMS 12 |
| 57 | |
| 58 | #define COBALT_HSMA_IN_NODE 4 |
| 59 | #define COBALT_HSMA_OUT_NODE 5 |
| 60 | |
| 61 | /* Cobalt audio streams */ |
| 62 | #define COBALT_AUDIO_IN_STREAM 6 |
| 63 | #define COBALT_AUDIO_OUT_STREAM 11 |
| 64 | |
| 65 | /* DMA stuff */ |
| 66 | #define DMA_CHANNELS_MAX 16 |
| 67 | |
| 68 | /* i2c stuff */ |
| 69 | #define I2C_CLIENTS_MAX 16 |
| 70 | #define COBALT_NUM_ADAPTERS 5 |
| 71 | |
| 72 | #define COBALT_CLK 50000000 |
| 73 | |
| 74 | /* System status register */ |
| 75 | #define COBALT_SYSSTAT_DIP0_MSK (1 << 0) |
| 76 | #define COBALT_SYSSTAT_DIP1_MSK (1 << 1) |
| 77 | #define COBALT_SYSSTAT_HSMA_PRSNTN_MSK (1 << 2) |
| 78 | #define COBALT_SYSSTAT_FLASH_RDYBSYN_MSK (1 << 3) |
| 79 | #define COBALT_SYSSTAT_VI0_5V_MSK (1 << 4) |
| 80 | #define COBALT_SYSSTAT_VI0_INT1_MSK (1 << 5) |
| 81 | #define COBALT_SYSSTAT_VI0_INT2_MSK (1 << 6) |
| 82 | #define COBALT_SYSSTAT_VI0_LOST_DATA_MSK (1 << 7) |
| 83 | #define COBALT_SYSSTAT_VI1_5V_MSK (1 << 8) |
| 84 | #define COBALT_SYSSTAT_VI1_INT1_MSK (1 << 9) |
| 85 | #define COBALT_SYSSTAT_VI1_INT2_MSK (1 << 10) |
| 86 | #define COBALT_SYSSTAT_VI1_LOST_DATA_MSK (1 << 11) |
| 87 | #define COBALT_SYSSTAT_VI2_5V_MSK (1 << 12) |
| 88 | #define COBALT_SYSSTAT_VI2_INT1_MSK (1 << 13) |
| 89 | #define COBALT_SYSSTAT_VI2_INT2_MSK (1 << 14) |
| 90 | #define COBALT_SYSSTAT_VI2_LOST_DATA_MSK (1 << 15) |
| 91 | #define COBALT_SYSSTAT_VI3_5V_MSK (1 << 16) |
| 92 | #define COBALT_SYSSTAT_VI3_INT1_MSK (1 << 17) |
| 93 | #define COBALT_SYSSTAT_VI3_INT2_MSK (1 << 18) |
| 94 | #define COBALT_SYSSTAT_VI3_LOST_DATA_MSK (1 << 19) |
| 95 | #define COBALT_SYSSTAT_VIHSMA_5V_MSK (1 << 20) |
| 96 | #define COBALT_SYSSTAT_VIHSMA_INT1_MSK (1 << 21) |
| 97 | #define COBALT_SYSSTAT_VIHSMA_INT2_MSK (1 << 22) |
| 98 | #define COBALT_SYSSTAT_VIHSMA_LOST_DATA_MSK (1 << 23) |
Hans Verkuil | 86bad00 | 2015-05-21 06:19:28 -0300 | [diff] [blame^] | 99 | #define COBALT_SYSSTAT_VOHSMA_INT1_MSK (1 << 24) |
| 100 | #define COBALT_SYSSTAT_VOHSMA_PLL_LOCKED_MSK (1 << 25) |
| 101 | #define COBALT_SYSSTAT_VOHSMA_LOST_DATA_MSK (1 << 26) |
Hans Verkuil | 85756a0 | 2015-05-12 08:52:21 -0300 | [diff] [blame] | 102 | #define COBALT_SYSSTAT_AUD_PLL_LOCKED_MSK (1 << 28) |
| 103 | #define COBALT_SYSSTAT_AUD_IN_LOST_DATA_MSK (1 << 29) |
| 104 | #define COBALT_SYSSTAT_AUD_OUT_LOST_DATA_MSK (1 << 30) |
| 105 | #define COBALT_SYSSTAT_PCIE_SMBCLK_MSK (1 << 31) |
| 106 | |
| 107 | /* Cobalt memory map */ |
| 108 | #define COBALT_I2C_0_BASE 0x0 |
| 109 | #define COBALT_I2C_1_BASE 0x080 |
| 110 | #define COBALT_I2C_2_BASE 0x100 |
| 111 | #define COBALT_I2C_3_BASE 0x180 |
| 112 | #define COBALT_I2C_HSMA_BASE 0x200 |
| 113 | |
| 114 | #define COBALT_SYS_CTRL_BASE 0x400 |
| 115 | #define COBALT_SYS_CTRL_HSMA_TX_ENABLE_BIT 1 |
| 116 | #define COBALT_SYS_CTRL_VIDEO_RX_RESETN_BIT(n) (4 + 4 * (n)) |
| 117 | #define COBALT_SYS_CTRL_NRESET_TO_HDMI_BIT(n) (5 + 4 * (n)) |
| 118 | #define COBALT_SYS_CTRL_HPD_TO_CONNECTOR_BIT(n) (6 + 4 * (n)) |
| 119 | #define COBALT_SYS_CTRL_AUDIO_IPP_RESETN_BIT(n) (7 + 4 * (n)) |
| 120 | #define COBALT_SYS_CTRL_PWRDN0_TO_HSMA_TX_BIT 24 |
| 121 | #define COBALT_SYS_CTRL_VIDEO_TX_RESETN_BIT 25 |
| 122 | #define COBALT_SYS_CTRL_AUDIO_OPP_RESETN_BIT 27 |
| 123 | |
| 124 | #define COBALT_SYS_STAT_BASE 0x500 |
| 125 | #define COBALT_SYS_STAT_MASK (COBALT_SYS_STAT_BASE + 0x08) |
| 126 | #define COBALT_SYS_STAT_EDGE (COBALT_SYS_STAT_BASE + 0x0c) |
| 127 | |
| 128 | #define COBALT_HDL_INFO_BASE 0x4800 |
| 129 | #define COBALT_HDL_INFO_SIZE 0x200 |
| 130 | |
| 131 | #define COBALT_VID_BASE 0x10000 |
| 132 | #define COBALT_VID_SIZE 0x1000 |
| 133 | |
| 134 | #define COBALT_CVI(cobalt, c) \ |
| 135 | (cobalt->bar1 + COBALT_VID_BASE + (c) * COBALT_VID_SIZE) |
| 136 | #define COBALT_CVI_VMR(cobalt, c) \ |
| 137 | (cobalt->bar1 + COBALT_VID_BASE + (c) * COBALT_VID_SIZE + 0x100) |
| 138 | #define COBALT_CVI_EVCNT(cobalt, c) \ |
| 139 | (cobalt->bar1 + COBALT_VID_BASE + (c) * COBALT_VID_SIZE + 0x200) |
| 140 | #define COBALT_CVI_FREEWHEEL(cobalt, c) \ |
| 141 | (cobalt->bar1 + COBALT_VID_BASE + (c) * COBALT_VID_SIZE + 0x300) |
| 142 | #define COBALT_CVI_CLK_LOSS(cobalt, c) \ |
| 143 | (cobalt->bar1 + COBALT_VID_BASE + (c) * COBALT_VID_SIZE + 0x400) |
| 144 | #define COBALT_CVI_PACKER(cobalt, c) \ |
| 145 | (cobalt->bar1 + COBALT_VID_BASE + (c) * COBALT_VID_SIZE + 0x500) |
| 146 | |
| 147 | #define COBALT_TX_BASE(cobalt) (cobalt->bar1 + COBALT_VID_BASE + 0x5000) |
| 148 | |
| 149 | #define DMA_INTERRUPT_STATUS_REG 0x08 |
| 150 | |
| 151 | #define COBALT_HDL_SEARCH_STR "** HDL version info **" |
| 152 | |
| 153 | /* Cobalt CPU bus interface */ |
| 154 | #define COBALT_BUS_BAR1_BASE 0x600 |
| 155 | #define COBALT_BUS_SRAM_BASE 0x0 |
| 156 | #define COBALT_BUS_CPLD_BASE 0x00600000 |
| 157 | #define COBALT_BUS_FLASH_BASE 0x08000000 |
| 158 | |
| 159 | /* FDMA to PCIe packing */ |
| 160 | #define COBALT_BYTES_PER_PIXEL_YUYV 2 |
| 161 | #define COBALT_BYTES_PER_PIXEL_RGB24 3 |
| 162 | #define COBALT_BYTES_PER_PIXEL_RGB32 4 |
| 163 | |
| 164 | /* debugging */ |
| 165 | extern int cobalt_debug; |
| 166 | extern int cobalt_ignore_err; |
| 167 | |
| 168 | #define cobalt_err(fmt, arg...) v4l2_err(&cobalt->v4l2_dev, fmt, ## arg) |
| 169 | #define cobalt_warn(fmt, arg...) v4l2_warn(&cobalt->v4l2_dev, fmt, ## arg) |
| 170 | #define cobalt_info(fmt, arg...) v4l2_info(&cobalt->v4l2_dev, fmt, ## arg) |
| 171 | #define cobalt_dbg(level, fmt, arg...) \ |
| 172 | v4l2_dbg(level, cobalt_debug, &cobalt->v4l2_dev, fmt, ## arg) |
| 173 | |
| 174 | struct cobalt; |
| 175 | struct cobalt_i2c_regs; |
| 176 | |
| 177 | /* Per I2C bus private algo callback data */ |
| 178 | struct cobalt_i2c_data { |
| 179 | struct cobalt *cobalt; |
| 180 | volatile struct cobalt_i2c_regs __iomem *regs; |
| 181 | }; |
| 182 | |
| 183 | struct pci_consistent_buffer { |
| 184 | void *virt; |
| 185 | dma_addr_t bus; |
| 186 | size_t bytes; |
| 187 | }; |
| 188 | |
| 189 | struct sg_dma_desc_info { |
| 190 | void *virt; |
| 191 | dma_addr_t bus; |
| 192 | unsigned size; |
| 193 | void *last_desc_virt; |
| 194 | struct device *dev; |
| 195 | }; |
| 196 | |
| 197 | #define COBALT_MAX_WIDTH 1920 |
| 198 | #define COBALT_MAX_HEIGHT 1200 |
| 199 | #define COBALT_MAX_BPP 3 |
| 200 | #define COBALT_MAX_FRAMESZ \ |
| 201 | (COBALT_MAX_WIDTH * COBALT_MAX_HEIGHT * COBALT_MAX_BPP) |
| 202 | |
| 203 | #define NR_BUFS VIDEO_MAX_FRAME |
| 204 | |
| 205 | #define COBALT_STREAM_FL_DMA_IRQ 0 |
| 206 | #define COBALT_STREAM_FL_ADV_IRQ 1 |
| 207 | |
| 208 | struct cobalt_buffer { |
| 209 | struct vb2_buffer vb; |
| 210 | struct list_head list; |
| 211 | }; |
| 212 | |
| 213 | static inline struct cobalt_buffer *to_cobalt_buffer(struct vb2_buffer *vb2) |
| 214 | { |
| 215 | return container_of(vb2, struct cobalt_buffer, vb); |
| 216 | } |
| 217 | |
| 218 | struct cobalt_stream { |
| 219 | struct video_device vdev; |
| 220 | struct vb2_queue q; |
| 221 | struct list_head bufs; |
| 222 | struct i2c_adapter *i2c_adap; |
| 223 | struct v4l2_subdev *sd; |
| 224 | struct mutex lock; |
| 225 | spinlock_t irqlock; |
| 226 | struct v4l2_dv_timings timings; |
| 227 | u32 input; |
| 228 | u32 pad_source; |
| 229 | u32 width, height, bpp; |
| 230 | u32 stride; |
| 231 | u32 pixfmt; |
| 232 | u32 sequence; |
| 233 | u32 colorspace; |
| 234 | u32 ycbcr_enc; |
| 235 | u32 quantization; |
| 236 | |
| 237 | u8 dma_channel; |
| 238 | int video_channel; |
Hans Verkuil | 86bad00 | 2015-05-21 06:19:28 -0300 | [diff] [blame^] | 239 | unsigned dma_fifo_mask; |
| 240 | unsigned adv_irq_mask; |
Hans Verkuil | 85756a0 | 2015-05-12 08:52:21 -0300 | [diff] [blame] | 241 | struct sg_dma_desc_info dma_desc_info[NR_BUFS]; |
| 242 | unsigned long flags; |
| 243 | bool unstable_frame; |
| 244 | bool enable_cvi; |
| 245 | bool enable_freewheel; |
| 246 | unsigned skip_first_frames; |
| 247 | bool is_output; |
| 248 | bool is_audio; |
| 249 | bool is_dummy; |
| 250 | |
| 251 | struct cobalt *cobalt; |
| 252 | struct snd_cobalt_card *alsa; |
| 253 | }; |
| 254 | |
| 255 | struct snd_cobalt_card; |
| 256 | |
| 257 | /* Struct to hold info about cobalt cards */ |
| 258 | struct cobalt { |
| 259 | int instance; |
| 260 | struct pci_dev *pci_dev; |
| 261 | struct v4l2_device v4l2_dev; |
| 262 | void *alloc_ctx; |
| 263 | |
| 264 | void __iomem *bar0, *bar1; |
| 265 | |
| 266 | u8 card_rev; |
| 267 | u16 device_id; |
| 268 | |
| 269 | /* device nodes */ |
| 270 | struct cobalt_stream streams[DMA_CHANNELS_MAX]; |
| 271 | struct i2c_adapter i2c_adap[COBALT_NUM_ADAPTERS]; |
| 272 | struct cobalt_i2c_data i2c_data[COBALT_NUM_ADAPTERS]; |
| 273 | bool have_hsma_rx; |
| 274 | bool have_hsma_tx; |
| 275 | |
| 276 | /* irq */ |
| 277 | struct workqueue_struct *irq_work_queues; |
| 278 | struct work_struct irq_work_queue; /* work entry */ |
| 279 | /* irq counters */ |
| 280 | u32 irq_adv1; |
| 281 | u32 irq_adv2; |
| 282 | u32 irq_advout; |
| 283 | u32 irq_dma_tot; |
| 284 | u32 irq_dma[COBALT_NUM_STREAMS]; |
| 285 | u32 irq_none; |
| 286 | u32 irq_full_fifo; |
| 287 | |
| 288 | bool msi_enabled; |
| 289 | |
| 290 | /* omnitek dma */ |
| 291 | int dma_channels; |
| 292 | int first_fifo_channel; |
| 293 | bool pci_32_bit; |
| 294 | |
| 295 | char hdl_info[COBALT_HDL_INFO_SIZE]; |
| 296 | |
| 297 | /* NOR flash */ |
| 298 | struct mtd_info *mtd; |
| 299 | }; |
| 300 | |
| 301 | static inline struct cobalt *to_cobalt(struct v4l2_device *v4l2_dev) |
| 302 | { |
| 303 | return container_of(v4l2_dev, struct cobalt, v4l2_dev); |
| 304 | } |
| 305 | |
| 306 | static inline void cobalt_write_bar0(struct cobalt *cobalt, u32 reg, u32 val) |
| 307 | { |
| 308 | iowrite32(val, cobalt->bar0 + reg); |
| 309 | } |
| 310 | |
| 311 | static inline u32 cobalt_read_bar0(struct cobalt *cobalt, u32 reg) |
| 312 | { |
| 313 | return ioread32(cobalt->bar0 + reg); |
| 314 | } |
| 315 | |
| 316 | static inline void cobalt_write_bar1(struct cobalt *cobalt, u32 reg, u32 val) |
| 317 | { |
| 318 | iowrite32(val, cobalt->bar1 + reg); |
| 319 | } |
| 320 | |
| 321 | static inline u32 cobalt_read_bar1(struct cobalt *cobalt, u32 reg) |
| 322 | { |
| 323 | return ioread32(cobalt->bar1 + reg); |
| 324 | } |
| 325 | |
| 326 | static inline u32 cobalt_g_sysctrl(struct cobalt *cobalt) |
| 327 | { |
| 328 | return cobalt_read_bar1(cobalt, COBALT_SYS_CTRL_BASE); |
| 329 | } |
| 330 | |
| 331 | static inline void cobalt_s_bit_sysctrl(struct cobalt *cobalt, |
| 332 | int bit, int val) |
| 333 | { |
| 334 | u32 ctrl = cobalt_read_bar1(cobalt, COBALT_SYS_CTRL_BASE); |
| 335 | |
| 336 | cobalt_write_bar1(cobalt, COBALT_SYS_CTRL_BASE, |
| 337 | (ctrl & ~(1UL << bit)) | (val << bit)); |
| 338 | } |
| 339 | |
| 340 | static inline u32 cobalt_g_sysstat(struct cobalt *cobalt) |
| 341 | { |
| 342 | return cobalt_read_bar1(cobalt, COBALT_SYS_STAT_BASE); |
| 343 | } |
| 344 | |
| 345 | #define ADRS_REG (cobalt->bar1 + COBALT_BUS_BAR1_BASE + 0) |
| 346 | #define LOWER_DATA (cobalt->bar1 + COBALT_BUS_BAR1_BASE + 4) |
| 347 | #define UPPER_DATA (cobalt->bar1 + COBALT_BUS_BAR1_BASE + 6) |
| 348 | |
| 349 | static inline u32 cobalt_bus_read32(struct cobalt *cobalt, u32 bus_adrs) |
| 350 | { |
| 351 | iowrite32(bus_adrs, ADRS_REG); |
| 352 | return ioread32(LOWER_DATA); |
| 353 | } |
| 354 | |
| 355 | static inline void cobalt_bus_write16(struct cobalt *cobalt, |
| 356 | u32 bus_adrs, u16 data) |
| 357 | { |
| 358 | iowrite32(bus_adrs, ADRS_REG); |
| 359 | if (bus_adrs & 2) |
| 360 | iowrite16(data, UPPER_DATA); |
| 361 | else |
| 362 | iowrite16(data, LOWER_DATA); |
| 363 | } |
| 364 | |
| 365 | static inline void cobalt_bus_write32(struct cobalt *cobalt, |
| 366 | u32 bus_adrs, u16 data) |
| 367 | { |
| 368 | iowrite32(bus_adrs, ADRS_REG); |
| 369 | if (bus_adrs & 2) |
| 370 | iowrite32(data, UPPER_DATA); |
| 371 | else |
| 372 | iowrite32(data, LOWER_DATA); |
| 373 | } |
| 374 | |
| 375 | /*==============Prototypes==================*/ |
| 376 | |
| 377 | void cobalt_pcie_status_show(struct cobalt *cobalt); |
| 378 | |
| 379 | #endif |