Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[media] v4l: omap4iss: Add support for OMAP4 camera interface - Core

This adds a very simplistic driver to utilize the CSI2A interface inside
the ISS subsystem in OMAP4, and dump the data to memory.
Check Documentation/video4linux/omap4_camera.txt for details.
This commit adds the driver core, registers definitions and
documentation.

Signed-off-by: Sergio Aguirre <sergio.a.aguirre@gmail.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>

authored by

Sergio Aguirre and committed by
Mauro Carvalho Chehab
59f0ad80 64695905

+2638
+60
Documentation/video4linux/omap4_camera.txt
··· 1 + OMAP4 ISS Driver 2 + ================ 3 + 4 + Introduction 5 + ------------ 6 + 7 + The OMAP44XX family of chips contains the Imaging SubSystem (a.k.a. ISS), 8 + Which contains several components that can be categorized in 3 big groups: 9 + 10 + - Interfaces (2 Interfaces: CSI2-A & CSI2-B/CCP2) 11 + - ISP (Image Signal Processor) 12 + - SIMCOP (Still Image Coprocessor) 13 + 14 + For more information, please look in [1] for latest version of: 15 + "OMAP4430 Multimedia Device Silicon Revision 2.x" 16 + 17 + As of Revision AB, the ISS is described in detail in section 8. 18 + 19 + This driver is supporting _only_ the CSI2-A/B interfaces for now. 20 + 21 + It makes use of the Media Controller framework [2], and inherited most of the 22 + code from OMAP3 ISP driver (found under drivers/media/platform/omap3isp/*), 23 + except that it doesn't need an IOMMU now for ISS buffers memory mapping. 24 + 25 + Supports usage of MMAP buffers only (for now). 26 + 27 + Tested platforms 28 + ---------------- 29 + 30 + - OMAP4430SDP, w/ ES2.1 GP & SEVM4430-CAM-V1-0 (Contains IMX060 & OV5640, in 31 + which only the last one is supported, outputting YUV422 frames). 32 + 33 + - TI Blaze MDP, w/ OMAP4430 ES2.2 EMU (Contains 1 IMX060 & 2 OV5650 sensors, in 34 + which only the OV5650 are supported, outputting RAW10 frames). 35 + 36 + - PandaBoard, Rev. A2, w/ OMAP4430 ES2.1 GP & OV adapter board, tested with 37 + following sensors: 38 + * OV5640 39 + * OV5650 40 + 41 + - Tested on mainline kernel: 42 + 43 + http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=summary 44 + 45 + Tag: v3.3 (commit c16fa4f2ad19908a47c63d8fa436a1178438c7e7) 46 + 47 + File list 48 + --------- 49 + drivers/staging/media/omap4iss/ 50 + include/media/omap4iss.h 51 + 52 + References 53 + ---------- 54 + 55 + [1] http://focus.ti.com/general/docs/wtbu/wtbudocumentcenter.tsp?navigationId=12037&templateId=6123#62 56 + [2] http://lwn.net/Articles/420485/ 57 + [3] http://www.spinics.net/lists/linux-media/msg44370.html 58 + -- 59 + Author: Sergio Aguirre <sergio.a.aguirre@gmail.com> 60 + Copyright (C) 2012, Texas Instruments
+1477
drivers/staging/media/omap4iss/iss.c
··· 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 + #include <linux/clk.h> 15 + #include <linux/delay.h> 16 + #include <linux/device.h> 17 + #include <linux/dma-mapping.h> 18 + #include <linux/i2c.h> 19 + #include <linux/interrupt.h> 20 + #include <linux/module.h> 21 + #include <linux/platform_device.h> 22 + #include <linux/slab.h> 23 + #include <linux/sched.h> 24 + #include <linux/vmalloc.h> 25 + 26 + #include <media/v4l2-common.h> 27 + #include <media/v4l2-device.h> 28 + #include <media/v4l2-ctrls.h> 29 + 30 + #include "iss.h" 31 + #include "iss_regs.h" 32 + 33 + #define ISS_PRINT_REGISTER(iss, name)\ 34 + dev_dbg(iss->dev, "###ISS " #name "=0x%08x\n", \ 35 + readl(iss->regs[OMAP4_ISS_MEM_TOP] + ISS_##name)) 36 + 37 + static void iss_print_status(struct iss_device *iss) 38 + { 39 + dev_dbg(iss->dev, "-------------ISS HL Register dump-------------\n"); 40 + 41 + ISS_PRINT_REGISTER(iss, HL_REVISION); 42 + ISS_PRINT_REGISTER(iss, HL_SYSCONFIG); 43 + ISS_PRINT_REGISTER(iss, HL_IRQSTATUS_5); 44 + ISS_PRINT_REGISTER(iss, HL_IRQENABLE_5_SET); 45 + ISS_PRINT_REGISTER(iss, HL_IRQENABLE_5_CLR); 46 + ISS_PRINT_REGISTER(iss, CTRL); 47 + ISS_PRINT_REGISTER(iss, CLKCTRL); 48 + ISS_PRINT_REGISTER(iss, CLKSTAT); 49 + 50 + dev_dbg(iss->dev, "-----------------------------------------------\n"); 51 + } 52 + 53 + /* 54 + * omap4iss_flush - Post pending L3 bus writes by doing a register readback 55 + * @iss: OMAP4 ISS device 56 + * 57 + * In order to force posting of pending writes, we need to write and 58 + * readback the same register, in this case the revision register. 59 + * 60 + * See this link for reference: 61 + * http://www.mail-archive.com/linux-omap@vger.kernel.org/msg08149.html 62 + */ 63 + void omap4iss_flush(struct iss_device *iss) 64 + { 65 + writel(0, iss->regs[OMAP4_ISS_MEM_TOP] + ISS_HL_REVISION); 66 + readl(iss->regs[OMAP4_ISS_MEM_TOP] + ISS_HL_REVISION); 67 + } 68 + 69 + /* 70 + * iss_enable_interrupts - Enable ISS interrupts. 71 + * @iss: OMAP4 ISS device 72 + */ 73 + static void iss_enable_interrupts(struct iss_device *iss) 74 + { 75 + static const u32 hl_irq = ISS_HL_IRQ_CSIA | ISS_HL_IRQ_CSIB | ISS_HL_IRQ_ISP(0); 76 + 77 + /* Enable HL interrupts */ 78 + writel(hl_irq, iss->regs[OMAP4_ISS_MEM_TOP] + ISS_HL_IRQSTATUS_5); 79 + writel(hl_irq, iss->regs[OMAP4_ISS_MEM_TOP] + ISS_HL_IRQENABLE_5_SET); 80 + 81 + } 82 + 83 + /* 84 + * iss_disable_interrupts - Disable ISS interrupts. 85 + * @iss: OMAP4 ISS device 86 + */ 87 + static void iss_disable_interrupts(struct iss_device *iss) 88 + { 89 + writel(-1, iss->regs[OMAP4_ISS_MEM_TOP] + ISS_HL_IRQENABLE_5_CLR); 90 + } 91 + 92 + /* 93 + * iss_isp_enable_interrupts - Enable ISS ISP interrupts. 94 + * @iss: OMAP4 ISS device 95 + */ 96 + void omap4iss_isp_enable_interrupts(struct iss_device *iss) 97 + { 98 + static const u32 isp_irq = ISP5_IRQ_OCP_ERR | 99 + ISP5_IRQ_RSZ_FIFO_IN_BLK | 100 + ISP5_IRQ_RSZ_FIFO_OVF | 101 + ISP5_IRQ_RSZ_INT_DMA | 102 + ISP5_IRQ_ISIF0; 103 + 104 + /* Enable ISP interrupts */ 105 + writel(isp_irq, iss->regs[OMAP4_ISS_MEM_ISP_SYS1] + ISP5_IRQSTATUS(0)); 106 + writel(isp_irq, iss->regs[OMAP4_ISS_MEM_ISP_SYS1] + ISP5_IRQENABLE_SET(0)); 107 + } 108 + 109 + /* 110 + * iss_isp_disable_interrupts - Disable ISS interrupts. 111 + * @iss: OMAP4 ISS device 112 + */ 113 + void omap4iss_isp_disable_interrupts(struct iss_device *iss) 114 + { 115 + writel(-1, iss->regs[OMAP4_ISS_MEM_ISP_SYS1] + ISP5_IRQENABLE_CLR(0)); 116 + } 117 + 118 + int omap4iss_get_external_info(struct iss_pipeline *pipe, 119 + struct media_link *link) 120 + { 121 + struct iss_device *iss = 122 + container_of(pipe, struct iss_video, pipe)->iss; 123 + struct v4l2_subdev_format fmt; 124 + struct v4l2_ext_controls ctrls; 125 + struct v4l2_ext_control ctrl; 126 + int ret; 127 + 128 + if (!pipe->external) 129 + return 0; 130 + 131 + if (pipe->external_rate) 132 + return 0; 133 + 134 + memset(&fmt, 0, sizeof(fmt)); 135 + 136 + fmt.pad = link->source->index; 137 + fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE; 138 + ret = v4l2_subdev_call(media_entity_to_v4l2_subdev(link->sink->entity), 139 + pad, get_fmt, NULL, &fmt); 140 + if (ret < 0) 141 + return -EPIPE; 142 + 143 + pipe->external_bpp = omap4iss_video_format_info(fmt.format.code)->bpp; 144 + 145 + memset(&ctrls, 0, sizeof(ctrls)); 146 + memset(&ctrl, 0, sizeof(ctrl)); 147 + 148 + ctrl.id = V4L2_CID_PIXEL_RATE; 149 + 150 + ctrls.ctrl_class = V4L2_CTRL_ID2CLASS(ctrl.id); 151 + ctrls.count = 1; 152 + ctrls.controls = &ctrl; 153 + 154 + ret = v4l2_g_ext_ctrls(pipe->external->ctrl_handler, &ctrls); 155 + if (ret < 0) { 156 + dev_warn(iss->dev, "no pixel rate control in subdev %s\n", 157 + pipe->external->name); 158 + return ret; 159 + } 160 + 161 + pipe->external_rate = ctrl.value64; 162 + 163 + return 0; 164 + } 165 + 166 + /* 167 + * Configure the bridge. Valid inputs are 168 + * 169 + * IPIPEIF_INPUT_CSI2A: CSI2a receiver 170 + * IPIPEIF_INPUT_CSI2B: CSI2b receiver 171 + * 172 + * The bridge and lane shifter are configured according to the selected input 173 + * and the ISP platform data. 174 + */ 175 + void omap4iss_configure_bridge(struct iss_device *iss, 176 + enum ipipeif_input_entity input) 177 + { 178 + u32 issctrl_val; 179 + u32 isp5ctrl_val; 180 + 181 + issctrl_val = readl(iss->regs[OMAP4_ISS_MEM_TOP] + ISS_CTRL); 182 + issctrl_val &= ~ISS_CTRL_INPUT_SEL_MASK; 183 + issctrl_val &= ~ISS_CTRL_CLK_DIV_MASK; 184 + 185 + isp5ctrl_val = readl(iss->regs[OMAP4_ISS_MEM_ISP_SYS1] + ISP5_CTRL); 186 + 187 + switch (input) { 188 + case IPIPEIF_INPUT_CSI2A: 189 + issctrl_val |= ISS_CTRL_INPUT_SEL_CSI2A; 190 + isp5ctrl_val |= ISP5_CTRL_VD_PULSE_EXT; 191 + break; 192 + 193 + case IPIPEIF_INPUT_CSI2B: 194 + issctrl_val |= ISS_CTRL_INPUT_SEL_CSI2B; 195 + isp5ctrl_val |= ISP5_CTRL_VD_PULSE_EXT; 196 + break; 197 + 198 + default: 199 + return; 200 + } 201 + 202 + issctrl_val |= ISS_CTRL_SYNC_DETECT_VS_RAISING; 203 + 204 + isp5ctrl_val |= ISP5_CTRL_PSYNC_CLK_SEL | ISP5_CTRL_SYNC_ENABLE; 205 + 206 + writel(issctrl_val, iss->regs[OMAP4_ISS_MEM_TOP] + ISS_CTRL); 207 + writel(isp5ctrl_val, iss->regs[OMAP4_ISS_MEM_ISP_SYS1] + ISP5_CTRL); 208 + } 209 + 210 + static inline void iss_isr_dbg(struct iss_device *iss, u32 irqstatus) 211 + { 212 + static const char *name[] = { 213 + "ISP_IRQ0", 214 + "ISP_IRQ1", 215 + "ISP_IRQ2", 216 + "ISP_IRQ3", 217 + "CSIA_IRQ", 218 + "CSIB_IRQ", 219 + "CCP2_IRQ0", 220 + "CCP2_IRQ1", 221 + "CCP2_IRQ2", 222 + "CCP2_IRQ3", 223 + "CBUFF_IRQ", 224 + "BTE_IRQ", 225 + "SIMCOP_IRQ0", 226 + "SIMCOP_IRQ1", 227 + "SIMCOP_IRQ2", 228 + "SIMCOP_IRQ3", 229 + "CCP2_IRQ8", 230 + "HS_VS_IRQ", 231 + "res18", 232 + "res19", 233 + "res20", 234 + "res21", 235 + "res22", 236 + "res23", 237 + "res24", 238 + "res25", 239 + "res26", 240 + "res27", 241 + "res28", 242 + "res29", 243 + "res30", 244 + "res31", 245 + }; 246 + int i; 247 + 248 + dev_dbg(iss->dev, "ISS IRQ: "); 249 + 250 + for (i = 0; i < ARRAY_SIZE(name); i++) { 251 + if ((1 << i) & irqstatus) 252 + pr_cont("%s ", name[i]); 253 + } 254 + pr_cont("\n"); 255 + } 256 + 257 + /* 258 + * iss_isr - Interrupt Service Routine for ISS module. 259 + * @irq: Not used currently. 260 + * @_iss: Pointer to the OMAP4 ISS device 261 + * 262 + * Handles the corresponding callback if plugged in. 263 + * 264 + * Returns IRQ_HANDLED when IRQ was correctly handled, or IRQ_NONE when the 265 + * IRQ wasn't handled. 266 + */ 267 + static irqreturn_t iss_isr(int irq, void *_iss) 268 + { 269 + static const u32 ipipeif_events = ISP5_IRQ_IPIPEIF | 270 + ISP5_IRQ_ISIF0; 271 + static const u32 resizer_events = ISP5_IRQ_RSZ_FIFO_IN_BLK | 272 + ISP5_IRQ_RSZ_FIFO_OVF | 273 + ISP5_IRQ_RSZ_INT_DMA; 274 + struct iss_device *iss = _iss; 275 + u32 irqstatus; 276 + 277 + irqstatus = readl(iss->regs[OMAP4_ISS_MEM_TOP] + ISS_HL_IRQSTATUS_5); 278 + writel(irqstatus, iss->regs[OMAP4_ISS_MEM_TOP] + ISS_HL_IRQSTATUS_5); 279 + 280 + if (irqstatus & ISS_HL_IRQ_CSIA) 281 + omap4iss_csi2_isr(&iss->csi2a); 282 + 283 + if (irqstatus & ISS_HL_IRQ_CSIB) 284 + omap4iss_csi2_isr(&iss->csi2b); 285 + 286 + if (irqstatus & ISS_HL_IRQ_ISP(0)) { 287 + u32 isp_irqstatus = readl(iss->regs[OMAP4_ISS_MEM_ISP_SYS1] + 288 + ISP5_IRQSTATUS(0)); 289 + writel(isp_irqstatus, iss->regs[OMAP4_ISS_MEM_ISP_SYS1] + 290 + ISP5_IRQSTATUS(0)); 291 + 292 + if (isp_irqstatus & ISP5_IRQ_OCP_ERR) 293 + dev_dbg(iss->dev, "ISP5 OCP Error!\n"); 294 + 295 + if (isp_irqstatus & ipipeif_events) { 296 + omap4iss_ipipeif_isr(&iss->ipipeif, 297 + isp_irqstatus & ipipeif_events); 298 + } 299 + 300 + if (isp_irqstatus & resizer_events) 301 + omap4iss_resizer_isr(&iss->resizer, 302 + isp_irqstatus & resizer_events); 303 + } 304 + 305 + omap4iss_flush(iss); 306 + 307 + #if defined(DEBUG) && defined(ISS_ISR_DEBUG) 308 + iss_isr_dbg(iss, irqstatus); 309 + #endif 310 + 311 + return IRQ_HANDLED; 312 + } 313 + 314 + /* ----------------------------------------------------------------------------- 315 + * Pipeline power management 316 + * 317 + * Entities must be powered up when part of a pipeline that contains at least 318 + * one open video device node. 319 + * 320 + * To achieve this use the entity use_count field to track the number of users. 321 + * For entities corresponding to video device nodes the use_count field stores 322 + * the users count of the node. For entities corresponding to subdevs the 323 + * use_count field stores the total number of users of all video device nodes 324 + * in the pipeline. 325 + * 326 + * The omap4iss_pipeline_pm_use() function must be called in the open() and 327 + * close() handlers of video device nodes. It increments or decrements the use 328 + * count of all subdev entities in the pipeline. 329 + * 330 + * To react to link management on powered pipelines, the link setup notification 331 + * callback updates the use count of all entities in the source and sink sides 332 + * of the link. 333 + */ 334 + 335 + /* 336 + * iss_pipeline_pm_use_count - Count the number of users of a pipeline 337 + * @entity: The entity 338 + * 339 + * Return the total number of users of all video device nodes in the pipeline. 340 + */ 341 + static int iss_pipeline_pm_use_count(struct media_entity *entity) 342 + { 343 + struct media_entity_graph graph; 344 + int use = 0; 345 + 346 + media_entity_graph_walk_start(&graph, entity); 347 + 348 + while ((entity = media_entity_graph_walk_next(&graph))) { 349 + if (media_entity_type(entity) == MEDIA_ENT_T_DEVNODE) 350 + use += entity->use_count; 351 + } 352 + 353 + return use; 354 + } 355 + 356 + /* 357 + * iss_pipeline_pm_power_one - Apply power change to an entity 358 + * @entity: The entity 359 + * @change: Use count change 360 + * 361 + * Change the entity use count by @change. If the entity is a subdev update its 362 + * power state by calling the core::s_power operation when the use count goes 363 + * from 0 to != 0 or from != 0 to 0. 364 + * 365 + * Return 0 on success or a negative error code on failure. 366 + */ 367 + static int iss_pipeline_pm_power_one(struct media_entity *entity, int change) 368 + { 369 + struct v4l2_subdev *subdev; 370 + 371 + subdev = media_entity_type(entity) == MEDIA_ENT_T_V4L2_SUBDEV 372 + ? media_entity_to_v4l2_subdev(entity) : NULL; 373 + 374 + if (entity->use_count == 0 && change > 0 && subdev != NULL) { 375 + int ret; 376 + 377 + ret = v4l2_subdev_call(subdev, core, s_power, 1); 378 + if (ret < 0 && ret != -ENOIOCTLCMD) 379 + return ret; 380 + } 381 + 382 + entity->use_count += change; 383 + WARN_ON(entity->use_count < 0); 384 + 385 + if (entity->use_count == 0 && change < 0 && subdev != NULL) 386 + v4l2_subdev_call(subdev, core, s_power, 0); 387 + 388 + return 0; 389 + } 390 + 391 + /* 392 + * iss_pipeline_pm_power - Apply power change to all entities in a pipeline 393 + * @entity: The entity 394 + * @change: Use count change 395 + * 396 + * Walk the pipeline to update the use count and the power state of all non-node 397 + * entities. 398 + * 399 + * Return 0 on success or a negative error code on failure. 400 + */ 401 + static int iss_pipeline_pm_power(struct media_entity *entity, int change) 402 + { 403 + struct media_entity_graph graph; 404 + struct media_entity *first = entity; 405 + int ret = 0; 406 + 407 + if (!change) 408 + return 0; 409 + 410 + media_entity_graph_walk_start(&graph, entity); 411 + 412 + while (!ret && (entity = media_entity_graph_walk_next(&graph))) 413 + if (media_entity_type(entity) != MEDIA_ENT_T_DEVNODE) 414 + ret = iss_pipeline_pm_power_one(entity, change); 415 + 416 + if (!ret) 417 + return 0; 418 + 419 + media_entity_graph_walk_start(&graph, first); 420 + 421 + while ((first = media_entity_graph_walk_next(&graph)) 422 + && first != entity) 423 + if (media_entity_type(first) != MEDIA_ENT_T_DEVNODE) 424 + iss_pipeline_pm_power_one(first, -change); 425 + 426 + return ret; 427 + } 428 + 429 + /* 430 + * omap4iss_pipeline_pm_use - Update the use count of an entity 431 + * @entity: The entity 432 + * @use: Use (1) or stop using (0) the entity 433 + * 434 + * Update the use count of all entities in the pipeline and power entities on or 435 + * off accordingly. 436 + * 437 + * Return 0 on success or a negative error code on failure. Powering entities 438 + * off is assumed to never fail. No failure can occur when the use parameter is 439 + * set to 0. 440 + */ 441 + int omap4iss_pipeline_pm_use(struct media_entity *entity, int use) 442 + { 443 + int change = use ? 1 : -1; 444 + int ret; 445 + 446 + mutex_lock(&entity->parent->graph_mutex); 447 + 448 + /* Apply use count to node. */ 449 + entity->use_count += change; 450 + WARN_ON(entity->use_count < 0); 451 + 452 + /* Apply power change to connected non-nodes. */ 453 + ret = iss_pipeline_pm_power(entity, change); 454 + if (ret < 0) 455 + entity->use_count -= change; 456 + 457 + mutex_unlock(&entity->parent->graph_mutex); 458 + 459 + return ret; 460 + } 461 + 462 + /* 463 + * iss_pipeline_link_notify - Link management notification callback 464 + * @link: The link 465 + * @flags: New link flags that will be applied 466 + * 467 + * React to link management on powered pipelines by updating the use count of 468 + * all entities in the source and sink sides of the link. Entities are powered 469 + * on or off accordingly. 470 + * 471 + * Return 0 on success or a negative error code on failure. Powering entities 472 + * off is assumed to never fail. This function will not fail for disconnection 473 + * events. 474 + */ 475 + static int iss_pipeline_link_notify(struct media_link *link, u32 flags, 476 + unsigned int notification) 477 + { 478 + struct media_entity *source = link->source->entity; 479 + struct media_entity *sink = link->sink->entity; 480 + int source_use = iss_pipeline_pm_use_count(source); 481 + int sink_use = iss_pipeline_pm_use_count(sink); 482 + int ret; 483 + 484 + if (notification == MEDIA_DEV_NOTIFY_POST_LINK_CH && 485 + !(link->flags & MEDIA_LNK_FL_ENABLED)) { 486 + /* Powering off entities is assumed to never fail. */ 487 + iss_pipeline_pm_power(source, -sink_use); 488 + iss_pipeline_pm_power(sink, -source_use); 489 + return 0; 490 + } 491 + 492 + if (notification == MEDIA_DEV_NOTIFY_POST_LINK_CH && 493 + (flags & MEDIA_LNK_FL_ENABLED)) { 494 + ret = iss_pipeline_pm_power(source, sink_use); 495 + if (ret < 0) 496 + return ret; 497 + 498 + ret = iss_pipeline_pm_power(sink, source_use); 499 + if (ret < 0) 500 + iss_pipeline_pm_power(source, -sink_use); 501 + 502 + return ret; 503 + } 504 + 505 + return 0; 506 + } 507 + 508 + /* ----------------------------------------------------------------------------- 509 + * Pipeline stream management 510 + */ 511 + 512 + /* 513 + * iss_pipeline_enable - Enable streaming on a pipeline 514 + * @pipe: ISS pipeline 515 + * @mode: Stream mode (single shot or continuous) 516 + * 517 + * Walk the entities chain starting at the pipeline output video node and start 518 + * all modules in the chain in the given mode. 519 + * 520 + * Return 0 if successful, or the return value of the failed video::s_stream 521 + * operation otherwise. 522 + */ 523 + static int iss_pipeline_enable(struct iss_pipeline *pipe, 524 + enum iss_pipeline_stream_state mode) 525 + { 526 + struct media_entity *entity; 527 + struct media_pad *pad; 528 + struct v4l2_subdev *subdev; 529 + unsigned long flags; 530 + int ret; 531 + 532 + spin_lock_irqsave(&pipe->lock, flags); 533 + pipe->state &= ~(ISS_PIPELINE_IDLE_INPUT | ISS_PIPELINE_IDLE_OUTPUT); 534 + spin_unlock_irqrestore(&pipe->lock, flags); 535 + 536 + pipe->do_propagation = false; 537 + 538 + entity = &pipe->output->video.entity; 539 + while (1) { 540 + pad = &entity->pads[0]; 541 + if (!(pad->flags & MEDIA_PAD_FL_SINK)) 542 + break; 543 + 544 + pad = media_entity_remote_pad(pad); 545 + if (pad == NULL || 546 + media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV) 547 + break; 548 + 549 + entity = pad->entity; 550 + subdev = media_entity_to_v4l2_subdev(entity); 551 + 552 + ret = v4l2_subdev_call(subdev, video, s_stream, mode); 553 + if (ret < 0 && ret != -ENOIOCTLCMD) 554 + return ret; 555 + } 556 + iss_print_status(pipe->output->iss); 557 + return 0; 558 + } 559 + 560 + /* 561 + * iss_pipeline_disable - Disable streaming on a pipeline 562 + * @pipe: ISS pipeline 563 + * 564 + * Walk the entities chain starting at the pipeline output video node and stop 565 + * all modules in the chain. Wait synchronously for the modules to be stopped if 566 + * necessary. 567 + */ 568 + static int iss_pipeline_disable(struct iss_pipeline *pipe) 569 + { 570 + struct media_entity *entity; 571 + struct media_pad *pad; 572 + struct v4l2_subdev *subdev; 573 + int failure = 0; 574 + 575 + entity = &pipe->output->video.entity; 576 + while (1) { 577 + pad = &entity->pads[0]; 578 + if (!(pad->flags & MEDIA_PAD_FL_SINK)) 579 + break; 580 + 581 + pad = media_entity_remote_pad(pad); 582 + if (pad == NULL || 583 + media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV) 584 + break; 585 + 586 + entity = pad->entity; 587 + subdev = media_entity_to_v4l2_subdev(entity); 588 + 589 + v4l2_subdev_call(subdev, video, s_stream, 0); 590 + } 591 + 592 + return failure; 593 + } 594 + 595 + /* 596 + * omap4iss_pipeline_set_stream - Enable/disable streaming on a pipeline 597 + * @pipe: ISS pipeline 598 + * @state: Stream state (stopped, single shot or continuous) 599 + * 600 + * Set the pipeline to the given stream state. Pipelines can be started in 601 + * single-shot or continuous mode. 602 + * 603 + * Return 0 if successful, or the return value of the failed video::s_stream 604 + * operation otherwise. The pipeline state is not updated when the operation 605 + * fails, except when stopping the pipeline. 606 + */ 607 + int omap4iss_pipeline_set_stream(struct iss_pipeline *pipe, 608 + enum iss_pipeline_stream_state state) 609 + { 610 + int ret; 611 + 612 + if (state == ISS_PIPELINE_STREAM_STOPPED) 613 + ret = iss_pipeline_disable(pipe); 614 + else 615 + ret = iss_pipeline_enable(pipe, state); 616 + 617 + if (ret == 0 || state == ISS_PIPELINE_STREAM_STOPPED) 618 + pipe->stream_state = state; 619 + 620 + return ret; 621 + } 622 + 623 + /* 624 + * iss_pipeline_is_last - Verify if entity has an enabled link to the output 625 + * video node 626 + * @me: ISS module's media entity 627 + * 628 + * Returns 1 if the entity has an enabled link to the output video node or 0 629 + * otherwise. It's true only while pipeline can have no more than one output 630 + * node. 631 + */ 632 + static int iss_pipeline_is_last(struct media_entity *me) 633 + { 634 + struct iss_pipeline *pipe; 635 + struct media_pad *pad; 636 + 637 + if (!me->pipe) 638 + return 0; 639 + pipe = to_iss_pipeline(me); 640 + if (pipe->stream_state == ISS_PIPELINE_STREAM_STOPPED) 641 + return 0; 642 + pad = media_entity_remote_pad(&pipe->output->pad); 643 + return pad->entity == me; 644 + } 645 + 646 + static int iss_reset(struct iss_device *iss) 647 + { 648 + unsigned long timeout = 0; 649 + 650 + writel(readl(iss->regs[OMAP4_ISS_MEM_TOP] + ISS_HL_SYSCONFIG) | 651 + ISS_HL_SYSCONFIG_SOFTRESET, 652 + iss->regs[OMAP4_ISS_MEM_TOP] + ISS_HL_SYSCONFIG); 653 + 654 + while (readl(iss->regs[OMAP4_ISS_MEM_TOP] + ISS_HL_SYSCONFIG) & 655 + ISS_HL_SYSCONFIG_SOFTRESET) { 656 + if (timeout++ > 10000) { 657 + dev_alert(iss->dev, "cannot reset ISS\n"); 658 + return -ETIMEDOUT; 659 + } 660 + udelay(1); 661 + } 662 + 663 + return 0; 664 + } 665 + 666 + static int iss_isp_reset(struct iss_device *iss) 667 + { 668 + unsigned long timeout = 0; 669 + 670 + /* Fist, ensure that the ISP is IDLE (no transactions happening) */ 671 + writel((readl(iss->regs[OMAP4_ISS_MEM_ISP_SYS1] + ISP5_SYSCONFIG) & 672 + ~ISP5_SYSCONFIG_STANDBYMODE_MASK) | 673 + ISP5_SYSCONFIG_STANDBYMODE_SMART, 674 + iss->regs[OMAP4_ISS_MEM_ISP_SYS1] + ISP5_SYSCONFIG); 675 + 676 + writel(readl(iss->regs[OMAP4_ISS_MEM_ISP_SYS1] + ISP5_CTRL) | 677 + ISP5_CTRL_MSTANDBY, 678 + iss->regs[OMAP4_ISS_MEM_ISP_SYS1] + ISP5_CTRL); 679 + 680 + for (;;) { 681 + if (readl(iss->regs[OMAP4_ISS_MEM_ISP_SYS1] + ISP5_CTRL) & 682 + ISP5_CTRL_MSTANDBY_WAIT) 683 + break; 684 + if (timeout++ > 1000) { 685 + dev_alert(iss->dev, "cannot set ISP5 to standby\n"); 686 + return -ETIMEDOUT; 687 + } 688 + msleep(1); 689 + } 690 + 691 + /* Now finally, do the reset */ 692 + writel(readl(iss->regs[OMAP4_ISS_MEM_ISP_SYS1] + ISP5_SYSCONFIG) | 693 + ISP5_SYSCONFIG_SOFTRESET, 694 + iss->regs[OMAP4_ISS_MEM_ISP_SYS1] + ISP5_SYSCONFIG); 695 + 696 + timeout = 0; 697 + while (readl(iss->regs[OMAP4_ISS_MEM_ISP_SYS1] + ISP5_SYSCONFIG) & 698 + ISP5_SYSCONFIG_SOFTRESET) { 699 + if (timeout++ > 1000) { 700 + dev_alert(iss->dev, "cannot reset ISP5\n"); 701 + return -ETIMEDOUT; 702 + } 703 + msleep(1); 704 + } 705 + 706 + return 0; 707 + } 708 + 709 + /* 710 + * iss_module_sync_idle - Helper to sync module with its idle state 711 + * @me: ISS submodule's media entity 712 + * @wait: ISS submodule's wait queue for streamoff/interrupt synchronization 713 + * @stopping: flag which tells module wants to stop 714 + * 715 + * This function checks if ISS submodule needs to wait for next interrupt. If 716 + * yes, makes the caller to sleep while waiting for such event. 717 + */ 718 + int omap4iss_module_sync_idle(struct media_entity *me, wait_queue_head_t *wait, 719 + atomic_t *stopping) 720 + { 721 + struct iss_pipeline *pipe = to_iss_pipeline(me); 722 + struct iss_video *video = pipe->output; 723 + unsigned long flags; 724 + 725 + if (pipe->stream_state == ISS_PIPELINE_STREAM_STOPPED || 726 + (pipe->stream_state == ISS_PIPELINE_STREAM_SINGLESHOT && 727 + !iss_pipeline_ready(pipe))) 728 + return 0; 729 + 730 + /* 731 + * atomic_set() doesn't include memory barrier on ARM platform for SMP 732 + * scenario. We'll call it here to avoid race conditions. 733 + */ 734 + atomic_set(stopping, 1); 735 + smp_wmb(); 736 + 737 + /* 738 + * If module is the last one, it's writing to memory. In this case, 739 + * it's necessary to check if the module is already paused due to 740 + * DMA queue underrun or if it has to wait for next interrupt to be 741 + * idle. 742 + * If it isn't the last one, the function won't sleep but *stopping 743 + * will still be set to warn next submodule caller's interrupt the 744 + * module wants to be idle. 745 + */ 746 + if (!iss_pipeline_is_last(me)) 747 + return 0; 748 + 749 + spin_lock_irqsave(&video->qlock, flags); 750 + if (video->dmaqueue_flags & ISS_VIDEO_DMAQUEUE_UNDERRUN) { 751 + spin_unlock_irqrestore(&video->qlock, flags); 752 + atomic_set(stopping, 0); 753 + smp_wmb(); 754 + return 0; 755 + } 756 + spin_unlock_irqrestore(&video->qlock, flags); 757 + if (!wait_event_timeout(*wait, !atomic_read(stopping), 758 + msecs_to_jiffies(1000))) { 759 + atomic_set(stopping, 0); 760 + smp_wmb(); 761 + return -ETIMEDOUT; 762 + } 763 + 764 + return 0; 765 + } 766 + 767 + /* 768 + * omap4iss_module_sync_is_stopped - Helper to verify if module was stopping 769 + * @wait: ISS submodule's wait queue for streamoff/interrupt synchronization 770 + * @stopping: flag which tells module wants to stop 771 + * 772 + * This function checks if ISS submodule was stopping. In case of yes, it 773 + * notices the caller by setting stopping to 0 and waking up the wait queue. 774 + * Returns 1 if it was stopping or 0 otherwise. 775 + */ 776 + int omap4iss_module_sync_is_stopping(wait_queue_head_t *wait, 777 + atomic_t *stopping) 778 + { 779 + if (atomic_cmpxchg(stopping, 1, 0)) { 780 + wake_up(wait); 781 + return 1; 782 + } 783 + 784 + return 0; 785 + } 786 + 787 + /* -------------------------------------------------------------------------- 788 + * Clock management 789 + */ 790 + 791 + #define ISS_CLKCTRL_MASK (ISS_CLKCTRL_CSI2_A |\ 792 + ISS_CLKCTRL_CSI2_B |\ 793 + ISS_CLKCTRL_ISP) 794 + 795 + static int __iss_subclk_update(struct iss_device *iss) 796 + { 797 + u32 clk = 0; 798 + int ret = 0, timeout = 1000; 799 + 800 + if (iss->subclk_resources & OMAP4_ISS_SUBCLK_CSI2_A) 801 + clk |= ISS_CLKCTRL_CSI2_A; 802 + 803 + if (iss->subclk_resources & OMAP4_ISS_SUBCLK_CSI2_B) 804 + clk |= ISS_CLKCTRL_CSI2_B; 805 + 806 + if (iss->subclk_resources & OMAP4_ISS_SUBCLK_ISP) 807 + clk |= ISS_CLKCTRL_ISP; 808 + 809 + writel((readl(iss->regs[OMAP4_ISS_MEM_TOP] + ISS_CLKCTRL) & 810 + ~ISS_CLKCTRL_MASK) | clk, 811 + iss->regs[OMAP4_ISS_MEM_TOP] + ISS_CLKCTRL); 812 + 813 + /* Wait for HW assertion */ 814 + while (--timeout > 0) { 815 + udelay(1); 816 + if ((readl(iss->regs[OMAP4_ISS_MEM_TOP] + ISS_CLKSTAT) & 817 + ISS_CLKCTRL_MASK) == clk) 818 + break; 819 + } 820 + 821 + if (!timeout) 822 + ret = -EBUSY; 823 + 824 + return ret; 825 + } 826 + 827 + int omap4iss_subclk_enable(struct iss_device *iss, 828 + enum iss_subclk_resource res) 829 + { 830 + iss->subclk_resources |= res; 831 + 832 + return __iss_subclk_update(iss); 833 + } 834 + 835 + int omap4iss_subclk_disable(struct iss_device *iss, 836 + enum iss_subclk_resource res) 837 + { 838 + iss->subclk_resources &= ~res; 839 + 840 + return __iss_subclk_update(iss); 841 + } 842 + 843 + #define ISS_ISP5_CLKCTRL_MASK (ISP5_CTRL_BL_CLK_ENABLE |\ 844 + ISP5_CTRL_ISIF_CLK_ENABLE |\ 845 + ISP5_CTRL_H3A_CLK_ENABLE |\ 846 + ISP5_CTRL_RSZ_CLK_ENABLE |\ 847 + ISP5_CTRL_IPIPE_CLK_ENABLE |\ 848 + ISP5_CTRL_IPIPEIF_CLK_ENABLE) 849 + 850 + static int __iss_isp_subclk_update(struct iss_device *iss) 851 + { 852 + u32 clk = 0; 853 + 854 + if (iss->isp_subclk_resources & OMAP4_ISS_ISP_SUBCLK_ISIF) 855 + clk |= ISP5_CTRL_ISIF_CLK_ENABLE; 856 + 857 + if (iss->isp_subclk_resources & OMAP4_ISS_ISP_SUBCLK_H3A) 858 + clk |= ISP5_CTRL_H3A_CLK_ENABLE; 859 + 860 + if (iss->isp_subclk_resources & OMAP4_ISS_ISP_SUBCLK_RSZ) 861 + clk |= ISP5_CTRL_RSZ_CLK_ENABLE; 862 + 863 + if (iss->isp_subclk_resources & OMAP4_ISS_ISP_SUBCLK_IPIPE) 864 + clk |= ISP5_CTRL_IPIPE_CLK_ENABLE; 865 + 866 + if (iss->isp_subclk_resources & OMAP4_ISS_ISP_SUBCLK_IPIPEIF) 867 + clk |= ISP5_CTRL_IPIPEIF_CLK_ENABLE; 868 + 869 + if (clk) 870 + clk |= ISP5_CTRL_BL_CLK_ENABLE; 871 + 872 + writel((readl(iss->regs[OMAP4_ISS_MEM_ISP_SYS1] + ISP5_CTRL) & 873 + ~ISS_ISP5_CLKCTRL_MASK) | clk, 874 + iss->regs[OMAP4_ISS_MEM_ISP_SYS1] + ISP5_CTRL); 875 + 876 + return 0; 877 + } 878 + 879 + int omap4iss_isp_subclk_enable(struct iss_device *iss, 880 + enum iss_isp_subclk_resource res) 881 + { 882 + iss->isp_subclk_resources |= res; 883 + 884 + return __iss_isp_subclk_update(iss); 885 + } 886 + 887 + int omap4iss_isp_subclk_disable(struct iss_device *iss, 888 + enum iss_isp_subclk_resource res) 889 + { 890 + iss->isp_subclk_resources &= ~res; 891 + 892 + return __iss_isp_subclk_update(iss); 893 + } 894 + 895 + /* 896 + * iss_enable_clocks - Enable ISS clocks 897 + * @iss: OMAP4 ISS device 898 + * 899 + * Return 0 if successful, or clk_enable return value if any of tthem fails. 900 + */ 901 + static int iss_enable_clocks(struct iss_device *iss) 902 + { 903 + int r; 904 + 905 + r = clk_enable(iss->iss_fck); 906 + if (r) { 907 + dev_err(iss->dev, "clk_enable iss_fck failed\n"); 908 + return r; 909 + } 910 + 911 + r = clk_enable(iss->iss_ctrlclk); 912 + if (r) { 913 + dev_err(iss->dev, "clk_enable iss_ctrlclk failed\n"); 914 + goto out_clk_enable_ctrlclk; 915 + } 916 + return 0; 917 + 918 + out_clk_enable_ctrlclk: 919 + clk_disable(iss->iss_fck); 920 + return r; 921 + } 922 + 923 + /* 924 + * iss_disable_clocks - Disable ISS clocks 925 + * @iss: OMAP4 ISS device 926 + */ 927 + static void iss_disable_clocks(struct iss_device *iss) 928 + { 929 + clk_disable(iss->iss_ctrlclk); 930 + clk_disable(iss->iss_fck); 931 + } 932 + 933 + static void iss_put_clocks(struct iss_device *iss) 934 + { 935 + if (iss->iss_fck) { 936 + clk_put(iss->iss_fck); 937 + iss->iss_fck = NULL; 938 + } 939 + 940 + if (iss->iss_ctrlclk) { 941 + clk_put(iss->iss_ctrlclk); 942 + iss->iss_ctrlclk = NULL; 943 + } 944 + } 945 + 946 + static int iss_get_clocks(struct iss_device *iss) 947 + { 948 + iss->iss_fck = clk_get(iss->dev, "iss_fck"); 949 + if (IS_ERR(iss->iss_fck)) { 950 + dev_err(iss->dev, "Unable to get iss_fck clock info\n"); 951 + iss_put_clocks(iss); 952 + return PTR_ERR(iss->iss_fck); 953 + } 954 + 955 + iss->iss_ctrlclk = clk_get(iss->dev, "iss_ctrlclk"); 956 + if (IS_ERR(iss->iss_ctrlclk)) { 957 + dev_err(iss->dev, "Unable to get iss_ctrlclk clock info\n"); 958 + iss_put_clocks(iss); 959 + return PTR_ERR(iss->iss_fck); 960 + } 961 + 962 + return 0; 963 + } 964 + 965 + /* 966 + * omap4iss_get - Acquire the ISS resource. 967 + * 968 + * Initializes the clocks for the first acquire. 969 + * 970 + * Increment the reference count on the ISS. If the first reference is taken, 971 + * enable clocks and power-up all submodules. 972 + * 973 + * Return a pointer to the ISS device structure, or NULL if an error occurred. 974 + */ 975 + struct iss_device *omap4iss_get(struct iss_device *iss) 976 + { 977 + struct iss_device *__iss = iss; 978 + 979 + if (iss == NULL) 980 + return NULL; 981 + 982 + mutex_lock(&iss->iss_mutex); 983 + if (iss->ref_count > 0) 984 + goto out; 985 + 986 + if (iss_enable_clocks(iss) < 0) { 987 + __iss = NULL; 988 + goto out; 989 + } 990 + 991 + iss_enable_interrupts(iss); 992 + 993 + out: 994 + if (__iss != NULL) 995 + iss->ref_count++; 996 + mutex_unlock(&iss->iss_mutex); 997 + 998 + return __iss; 999 + } 1000 + 1001 + /* 1002 + * omap4iss_put - Release the ISS 1003 + * 1004 + * Decrement the reference count on the ISS. If the last reference is released, 1005 + * power-down all submodules, disable clocks and free temporary buffers. 1006 + */ 1007 + void omap4iss_put(struct iss_device *iss) 1008 + { 1009 + if (iss == NULL) 1010 + return; 1011 + 1012 + mutex_lock(&iss->iss_mutex); 1013 + BUG_ON(iss->ref_count == 0); 1014 + if (--iss->ref_count == 0) { 1015 + iss_disable_interrupts(iss); 1016 + iss_disable_clocks(iss); 1017 + } 1018 + mutex_unlock(&iss->iss_mutex); 1019 + } 1020 + 1021 + static int iss_map_mem_resource(struct platform_device *pdev, 1022 + struct iss_device *iss, 1023 + enum iss_mem_resources res) 1024 + { 1025 + struct resource *mem; 1026 + 1027 + /* request the mem region for the camera registers */ 1028 + 1029 + mem = platform_get_resource(pdev, IORESOURCE_MEM, res); 1030 + if (!mem) { 1031 + dev_err(iss->dev, "no mem resource?\n"); 1032 + return -ENODEV; 1033 + } 1034 + 1035 + if (!request_mem_region(mem->start, resource_size(mem), pdev->name)) { 1036 + dev_err(iss->dev, 1037 + "cannot reserve camera register I/O region\n"); 1038 + return -ENODEV; 1039 + } 1040 + iss->res[res] = mem; 1041 + 1042 + /* map the region */ 1043 + iss->regs[res] = ioremap_nocache(mem->start, resource_size(mem)); 1044 + if (!iss->regs[res]) { 1045 + dev_err(iss->dev, "cannot map camera register I/O region\n"); 1046 + return -ENODEV; 1047 + } 1048 + 1049 + return 0; 1050 + } 1051 + 1052 + static void iss_unregister_entities(struct iss_device *iss) 1053 + { 1054 + omap4iss_resizer_unregister_entities(&iss->resizer); 1055 + omap4iss_ipipe_unregister_entities(&iss->ipipe); 1056 + omap4iss_ipipeif_unregister_entities(&iss->ipipeif); 1057 + omap4iss_csi2_unregister_entities(&iss->csi2a); 1058 + omap4iss_csi2_unregister_entities(&iss->csi2b); 1059 + 1060 + v4l2_device_unregister(&iss->v4l2_dev); 1061 + media_device_unregister(&iss->media_dev); 1062 + } 1063 + 1064 + /* 1065 + * iss_register_subdev_group - Register a group of subdevices 1066 + * @iss: OMAP4 ISS device 1067 + * @board_info: I2C subdevs board information array 1068 + * 1069 + * Register all I2C subdevices in the board_info array. The array must be 1070 + * terminated by a NULL entry, and the first entry must be the sensor. 1071 + * 1072 + * Return a pointer to the sensor media entity if it has been successfully 1073 + * registered, or NULL otherwise. 1074 + */ 1075 + static struct v4l2_subdev * 1076 + iss_register_subdev_group(struct iss_device *iss, 1077 + struct iss_subdev_i2c_board_info *board_info) 1078 + { 1079 + struct v4l2_subdev *sensor = NULL; 1080 + unsigned int first; 1081 + 1082 + if (board_info->board_info == NULL) 1083 + return NULL; 1084 + 1085 + for (first = 1; board_info->board_info; ++board_info, first = 0) { 1086 + struct v4l2_subdev *subdev; 1087 + struct i2c_adapter *adapter; 1088 + 1089 + adapter = i2c_get_adapter(board_info->i2c_adapter_id); 1090 + if (adapter == NULL) { 1091 + dev_err(iss->dev, "%s: Unable to get I2C adapter %d for " 1092 + "device %s\n", __func__, 1093 + board_info->i2c_adapter_id, 1094 + board_info->board_info->type); 1095 + continue; 1096 + } 1097 + 1098 + subdev = v4l2_i2c_new_subdev_board(&iss->v4l2_dev, adapter, 1099 + board_info->board_info, NULL); 1100 + if (subdev == NULL) { 1101 + dev_err(iss->dev, "%s: Unable to register subdev %s\n", 1102 + __func__, board_info->board_info->type); 1103 + continue; 1104 + } 1105 + 1106 + if (first) 1107 + sensor = subdev; 1108 + } 1109 + 1110 + return sensor; 1111 + } 1112 + 1113 + static int iss_register_entities(struct iss_device *iss) 1114 + { 1115 + struct iss_platform_data *pdata = iss->pdata; 1116 + struct iss_v4l2_subdevs_group *subdevs; 1117 + int ret; 1118 + 1119 + iss->media_dev.dev = iss->dev; 1120 + strlcpy(iss->media_dev.model, "TI OMAP4 ISS", 1121 + sizeof(iss->media_dev.model)); 1122 + iss->media_dev.hw_revision = iss->revision; 1123 + iss->media_dev.link_notify = iss_pipeline_link_notify; 1124 + ret = media_device_register(&iss->media_dev); 1125 + if (ret < 0) { 1126 + printk(KERN_ERR "%s: Media device registration failed (%d)\n", 1127 + __func__, ret); 1128 + return ret; 1129 + } 1130 + 1131 + iss->v4l2_dev.mdev = &iss->media_dev; 1132 + ret = v4l2_device_register(iss->dev, &iss->v4l2_dev); 1133 + if (ret < 0) { 1134 + printk(KERN_ERR "%s: V4L2 device registration failed (%d)\n", 1135 + __func__, ret); 1136 + goto done; 1137 + } 1138 + 1139 + /* Register internal entities */ 1140 + ret = omap4iss_csi2_register_entities(&iss->csi2a, &iss->v4l2_dev); 1141 + if (ret < 0) 1142 + goto done; 1143 + 1144 + ret = omap4iss_csi2_register_entities(&iss->csi2b, &iss->v4l2_dev); 1145 + if (ret < 0) 1146 + goto done; 1147 + 1148 + ret = omap4iss_ipipeif_register_entities(&iss->ipipeif, &iss->v4l2_dev); 1149 + if (ret < 0) 1150 + goto done; 1151 + 1152 + ret = omap4iss_ipipe_register_entities(&iss->ipipe, &iss->v4l2_dev); 1153 + if (ret < 0) 1154 + goto done; 1155 + 1156 + ret = omap4iss_resizer_register_entities(&iss->resizer, &iss->v4l2_dev); 1157 + if (ret < 0) 1158 + goto done; 1159 + 1160 + /* Register external entities */ 1161 + for (subdevs = pdata->subdevs; subdevs && subdevs->subdevs; ++subdevs) { 1162 + struct v4l2_subdev *sensor; 1163 + struct media_entity *input; 1164 + unsigned int flags; 1165 + unsigned int pad; 1166 + 1167 + sensor = iss_register_subdev_group(iss, subdevs->subdevs); 1168 + if (sensor == NULL) 1169 + continue; 1170 + 1171 + sensor->host_priv = subdevs; 1172 + 1173 + /* Connect the sensor to the correct interface module. 1174 + * CSI2a receiver through CSIPHY1, or 1175 + * CSI2b receiver through CSIPHY2 1176 + */ 1177 + switch (subdevs->interface) { 1178 + case ISS_INTERFACE_CSI2A_PHY1: 1179 + input = &iss->csi2a.subdev.entity; 1180 + pad = CSI2_PAD_SINK; 1181 + flags = MEDIA_LNK_FL_IMMUTABLE 1182 + | MEDIA_LNK_FL_ENABLED; 1183 + break; 1184 + 1185 + case ISS_INTERFACE_CSI2B_PHY2: 1186 + input = &iss->csi2b.subdev.entity; 1187 + pad = CSI2_PAD_SINK; 1188 + flags = MEDIA_LNK_FL_IMMUTABLE 1189 + | MEDIA_LNK_FL_ENABLED; 1190 + break; 1191 + 1192 + default: 1193 + printk(KERN_ERR "%s: invalid interface type %u\n", 1194 + __func__, subdevs->interface); 1195 + ret = -EINVAL; 1196 + goto done; 1197 + } 1198 + 1199 + ret = media_entity_create_link(&sensor->entity, 0, input, pad, 1200 + flags); 1201 + if (ret < 0) 1202 + goto done; 1203 + } 1204 + 1205 + ret = v4l2_device_register_subdev_nodes(&iss->v4l2_dev); 1206 + 1207 + done: 1208 + if (ret < 0) 1209 + iss_unregister_entities(iss); 1210 + 1211 + return ret; 1212 + } 1213 + 1214 + static void iss_cleanup_modules(struct iss_device *iss) 1215 + { 1216 + omap4iss_csi2_cleanup(iss); 1217 + omap4iss_ipipeif_cleanup(iss); 1218 + omap4iss_ipipe_cleanup(iss); 1219 + omap4iss_resizer_cleanup(iss); 1220 + } 1221 + 1222 + static int iss_initialize_modules(struct iss_device *iss) 1223 + { 1224 + int ret; 1225 + 1226 + ret = omap4iss_csiphy_init(iss); 1227 + if (ret < 0) { 1228 + dev_err(iss->dev, "CSI PHY initialization failed\n"); 1229 + goto error_csiphy; 1230 + } 1231 + 1232 + ret = omap4iss_csi2_init(iss); 1233 + if (ret < 0) { 1234 + dev_err(iss->dev, "CSI2 initialization failed\n"); 1235 + goto error_csi2; 1236 + } 1237 + 1238 + ret = omap4iss_ipipeif_init(iss); 1239 + if (ret < 0) { 1240 + dev_err(iss->dev, "ISP IPIPEIF initialization failed\n"); 1241 + goto error_ipipeif; 1242 + } 1243 + 1244 + ret = omap4iss_ipipe_init(iss); 1245 + if (ret < 0) { 1246 + dev_err(iss->dev, "ISP IPIPE initialization failed\n"); 1247 + goto error_ipipe; 1248 + } 1249 + 1250 + ret = omap4iss_resizer_init(iss); 1251 + if (ret < 0) { 1252 + dev_err(iss->dev, "ISP RESIZER initialization failed\n"); 1253 + goto error_resizer; 1254 + } 1255 + 1256 + /* Connect the submodules. */ 1257 + ret = media_entity_create_link( 1258 + &iss->csi2a.subdev.entity, CSI2_PAD_SOURCE, 1259 + &iss->ipipeif.subdev.entity, IPIPEIF_PAD_SINK, 0); 1260 + if (ret < 0) 1261 + goto error_link; 1262 + 1263 + ret = media_entity_create_link( 1264 + &iss->csi2b.subdev.entity, CSI2_PAD_SOURCE, 1265 + &iss->ipipeif.subdev.entity, IPIPEIF_PAD_SINK, 0); 1266 + if (ret < 0) 1267 + goto error_link; 1268 + 1269 + ret = media_entity_create_link( 1270 + &iss->ipipeif.subdev.entity, IPIPEIF_PAD_SOURCE_VP, 1271 + &iss->resizer.subdev.entity, RESIZER_PAD_SINK, 0); 1272 + if (ret < 0) 1273 + goto error_link; 1274 + 1275 + ret = media_entity_create_link( 1276 + &iss->ipipeif.subdev.entity, IPIPEIF_PAD_SOURCE_VP, 1277 + &iss->ipipe.subdev.entity, IPIPE_PAD_SINK, 0); 1278 + if (ret < 0) 1279 + goto error_link; 1280 + 1281 + ret = media_entity_create_link( 1282 + &iss->ipipe.subdev.entity, IPIPE_PAD_SOURCE_VP, 1283 + &iss->resizer.subdev.entity, RESIZER_PAD_SINK, 0); 1284 + if (ret < 0) 1285 + goto error_link; 1286 + 1287 + return 0; 1288 + 1289 + error_link: 1290 + omap4iss_resizer_cleanup(iss); 1291 + error_resizer: 1292 + omap4iss_ipipe_cleanup(iss); 1293 + error_ipipe: 1294 + omap4iss_ipipeif_cleanup(iss); 1295 + error_ipipeif: 1296 + omap4iss_csi2_cleanup(iss); 1297 + error_csi2: 1298 + error_csiphy: 1299 + return ret; 1300 + } 1301 + 1302 + static int iss_probe(struct platform_device *pdev) 1303 + { 1304 + struct iss_platform_data *pdata = pdev->dev.platform_data; 1305 + struct iss_device *iss; 1306 + int i, ret; 1307 + 1308 + if (pdata == NULL) 1309 + return -EINVAL; 1310 + 1311 + iss = kzalloc(sizeof(*iss), GFP_KERNEL); 1312 + if (!iss) { 1313 + dev_err(&pdev->dev, "Could not allocate memory\n"); 1314 + return -ENOMEM; 1315 + } 1316 + 1317 + mutex_init(&iss->iss_mutex); 1318 + 1319 + iss->dev = &pdev->dev; 1320 + iss->pdata = pdata; 1321 + iss->ref_count = 0; 1322 + 1323 + iss->raw_dmamask = DMA_BIT_MASK(32); 1324 + iss->dev->dma_mask = &iss->raw_dmamask; 1325 + iss->dev->coherent_dma_mask = DMA_BIT_MASK(32); 1326 + 1327 + platform_set_drvdata(pdev, iss); 1328 + 1329 + /* Clocks */ 1330 + ret = iss_map_mem_resource(pdev, iss, OMAP4_ISS_MEM_TOP); 1331 + if (ret < 0) 1332 + goto error; 1333 + 1334 + ret = iss_get_clocks(iss); 1335 + if (ret < 0) 1336 + goto error; 1337 + 1338 + if (omap4iss_get(iss) == NULL) 1339 + goto error; 1340 + 1341 + ret = iss_reset(iss); 1342 + if (ret < 0) 1343 + goto error_iss; 1344 + 1345 + iss->revision = readl(iss->regs[OMAP4_ISS_MEM_TOP] + ISS_HL_REVISION); 1346 + dev_info(iss->dev, "Revision %08x found\n", iss->revision); 1347 + 1348 + for (i = 1; i < OMAP4_ISS_MEM_LAST; i++) { 1349 + ret = iss_map_mem_resource(pdev, iss, i); 1350 + if (ret) 1351 + goto error_iss; 1352 + } 1353 + 1354 + /* Configure BTE BW_LIMITER field to max recommended value (1 GB) */ 1355 + writel((readl(iss->regs[OMAP4_ISS_MEM_BTE] + BTE_CTRL) & ~BTE_CTRL_BW_LIMITER_MASK) | 1356 + (18 << BTE_CTRL_BW_LIMITER_SHIFT), 1357 + iss->regs[OMAP4_ISS_MEM_BTE] + BTE_CTRL); 1358 + 1359 + /* Perform ISP reset */ 1360 + ret = omap4iss_subclk_enable(iss, OMAP4_ISS_SUBCLK_ISP); 1361 + if (ret < 0) 1362 + goto error_iss; 1363 + 1364 + ret = iss_isp_reset(iss); 1365 + if (ret < 0) 1366 + goto error_iss; 1367 + 1368 + dev_info(iss->dev, "ISP Revision %08x found\n", 1369 + readl(iss->regs[OMAP4_ISS_MEM_ISP_SYS1] + ISP5_REVISION)); 1370 + 1371 + /* Interrupt */ 1372 + iss->irq_num = platform_get_irq(pdev, 0); 1373 + if (iss->irq_num <= 0) { 1374 + dev_err(iss->dev, "No IRQ resource\n"); 1375 + ret = -ENODEV; 1376 + goto error_iss; 1377 + } 1378 + 1379 + if (request_irq(iss->irq_num, iss_isr, IRQF_SHARED, "OMAP4 ISS", iss)) { 1380 + dev_err(iss->dev, "Unable to request IRQ\n"); 1381 + ret = -EINVAL; 1382 + goto error_iss; 1383 + } 1384 + 1385 + /* Entities */ 1386 + ret = iss_initialize_modules(iss); 1387 + if (ret < 0) 1388 + goto error_irq; 1389 + 1390 + ret = iss_register_entities(iss); 1391 + if (ret < 0) 1392 + goto error_modules; 1393 + 1394 + omap4iss_put(iss); 1395 + 1396 + return 0; 1397 + 1398 + error_modules: 1399 + iss_cleanup_modules(iss); 1400 + error_irq: 1401 + free_irq(iss->irq_num, iss); 1402 + error_iss: 1403 + omap4iss_put(iss); 1404 + error: 1405 + iss_put_clocks(iss); 1406 + 1407 + for (i = 0; i < OMAP4_ISS_MEM_LAST; i++) { 1408 + if (iss->regs[i]) { 1409 + iounmap(iss->regs[i]); 1410 + iss->regs[i] = NULL; 1411 + } 1412 + 1413 + if (iss->res[i]) { 1414 + release_mem_region(iss->res[i]->start, 1415 + resource_size(iss->res[i])); 1416 + iss->res[i] = NULL; 1417 + } 1418 + } 1419 + platform_set_drvdata(pdev, NULL); 1420 + 1421 + mutex_destroy(&iss->iss_mutex); 1422 + kfree(iss); 1423 + 1424 + return ret; 1425 + } 1426 + 1427 + static int iss_remove(struct platform_device *pdev) 1428 + { 1429 + struct iss_device *iss = platform_get_drvdata(pdev); 1430 + int i; 1431 + 1432 + iss_unregister_entities(iss); 1433 + iss_cleanup_modules(iss); 1434 + 1435 + free_irq(iss->irq_num, iss); 1436 + iss_put_clocks(iss); 1437 + 1438 + for (i = 0; i < OMAP4_ISS_MEM_LAST; i++) { 1439 + if (iss->regs[i]) { 1440 + iounmap(iss->regs[i]); 1441 + iss->regs[i] = NULL; 1442 + } 1443 + 1444 + if (iss->res[i]) { 1445 + release_mem_region(iss->res[i]->start, 1446 + resource_size(iss->res[i])); 1447 + iss->res[i] = NULL; 1448 + } 1449 + } 1450 + 1451 + kfree(iss); 1452 + 1453 + return 0; 1454 + } 1455 + 1456 + static struct platform_device_id omap4iss_id_table[] = { 1457 + { "omap4iss", 0 }, 1458 + { }, 1459 + }; 1460 + MODULE_DEVICE_TABLE(platform, omap4iss_id_table); 1461 + 1462 + static struct platform_driver iss_driver = { 1463 + .probe = iss_probe, 1464 + .remove = iss_remove, 1465 + .id_table = omap4iss_id_table, 1466 + .driver = { 1467 + .owner = THIS_MODULE, 1468 + .name = "omap4iss", 1469 + }, 1470 + }; 1471 + 1472 + module_platform_driver(iss_driver); 1473 + 1474 + MODULE_DESCRIPTION("TI OMAP4 ISS driver"); 1475 + MODULE_AUTHOR("Sergio Aguirre <sergio.a.aguirre@gmail.com>"); 1476 + MODULE_LICENSE("GPL"); 1477 + MODULE_VERSION(ISS_VIDEO_DRIVER_VERSION);
+153
drivers/staging/media/omap4iss/iss.h
··· 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 <linux/device.h> 19 + #include <linux/io.h> 20 + #include <linux/platform_device.h> 21 + #include <linux/wait.h> 22 + 23 + #include <media/omap4iss.h> 24 + 25 + #include "iss_regs.h" 26 + #include "iss_csiphy.h" 27 + #include "iss_csi2.h" 28 + #include "iss_ipipeif.h" 29 + #include "iss_ipipe.h" 30 + #include "iss_resizer.h" 31 + 32 + #define to_iss_device(ptr_module) \ 33 + container_of(ptr_module, struct iss_device, ptr_module) 34 + #define to_device(ptr_module) \ 35 + (to_iss_device(ptr_module)->dev) 36 + 37 + enum iss_mem_resources { 38 + OMAP4_ISS_MEM_TOP, 39 + OMAP4_ISS_MEM_CSI2_A_REGS1, 40 + OMAP4_ISS_MEM_CAMERARX_CORE1, 41 + OMAP4_ISS_MEM_CSI2_B_REGS1, 42 + OMAP4_ISS_MEM_CAMERARX_CORE2, 43 + OMAP4_ISS_MEM_BTE, 44 + OMAP4_ISS_MEM_ISP_SYS1, 45 + OMAP4_ISS_MEM_ISP_RESIZER, 46 + OMAP4_ISS_MEM_ISP_IPIPE, 47 + OMAP4_ISS_MEM_ISP_ISIF, 48 + OMAP4_ISS_MEM_ISP_IPIPEIF, 49 + OMAP4_ISS_MEM_LAST, 50 + }; 51 + 52 + enum iss_subclk_resource { 53 + OMAP4_ISS_SUBCLK_SIMCOP = (1 << 0), 54 + OMAP4_ISS_SUBCLK_ISP = (1 << 1), 55 + OMAP4_ISS_SUBCLK_CSI2_A = (1 << 2), 56 + OMAP4_ISS_SUBCLK_CSI2_B = (1 << 3), 57 + OMAP4_ISS_SUBCLK_CCP2 = (1 << 4), 58 + }; 59 + 60 + enum iss_isp_subclk_resource { 61 + OMAP4_ISS_ISP_SUBCLK_BL = (1 << 0), 62 + OMAP4_ISS_ISP_SUBCLK_ISIF = (1 << 1), 63 + OMAP4_ISS_ISP_SUBCLK_H3A = (1 << 2), 64 + OMAP4_ISS_ISP_SUBCLK_RSZ = (1 << 3), 65 + OMAP4_ISS_ISP_SUBCLK_IPIPE = (1 << 4), 66 + OMAP4_ISS_ISP_SUBCLK_IPIPEIF = (1 << 5), 67 + }; 68 + 69 + /* 70 + * struct iss_reg - Structure for ISS register values. 71 + * @reg: 32-bit Register address. 72 + * @val: 32-bit Register value. 73 + */ 74 + struct iss_reg { 75 + enum iss_mem_resources mmio_range; 76 + u32 reg; 77 + u32 val; 78 + }; 79 + 80 + struct iss_device { 81 + struct v4l2_device v4l2_dev; 82 + struct media_device media_dev; 83 + struct device *dev; 84 + u32 revision; 85 + 86 + /* platform HW resources */ 87 + struct iss_platform_data *pdata; 88 + unsigned int irq_num; 89 + 90 + struct resource *res[OMAP4_ISS_MEM_LAST]; 91 + void __iomem *regs[OMAP4_ISS_MEM_LAST]; 92 + 93 + u64 raw_dmamask; 94 + 95 + struct mutex iss_mutex; /* For handling ref_count field */ 96 + int has_context; 97 + int ref_count; 98 + 99 + struct clk *iss_fck; 100 + struct clk *iss_ctrlclk; 101 + 102 + /* ISS modules */ 103 + struct iss_csi2_device csi2a; 104 + struct iss_csi2_device csi2b; 105 + struct iss_csiphy csiphy1; 106 + struct iss_csiphy csiphy2; 107 + struct iss_ipipeif_device ipipeif; 108 + struct iss_ipipe_device ipipe; 109 + struct iss_resizer_device resizer; 110 + 111 + unsigned int subclk_resources; 112 + unsigned int isp_subclk_resources; 113 + }; 114 + 115 + #define v4l2_dev_to_iss_device(dev) \ 116 + container_of(dev, struct iss_device, v4l2_dev) 117 + 118 + int omap4iss_get_external_info(struct iss_pipeline *pipe, 119 + struct media_link *link); 120 + 121 + int omap4iss_module_sync_idle(struct media_entity *me, wait_queue_head_t *wait, 122 + atomic_t *stopping); 123 + 124 + int omap4iss_module_sync_is_stopping(wait_queue_head_t *wait, 125 + atomic_t *stopping); 126 + 127 + int omap4iss_pipeline_set_stream(struct iss_pipeline *pipe, 128 + enum iss_pipeline_stream_state state); 129 + 130 + void omap4iss_configure_bridge(struct iss_device *iss, 131 + enum ipipeif_input_entity input); 132 + 133 + struct iss_device *omap4iss_get(struct iss_device *iss); 134 + void omap4iss_put(struct iss_device *iss); 135 + int omap4iss_subclk_enable(struct iss_device *iss, 136 + enum iss_subclk_resource res); 137 + int omap4iss_subclk_disable(struct iss_device *iss, 138 + enum iss_subclk_resource res); 139 + int omap4iss_isp_subclk_enable(struct iss_device *iss, 140 + enum iss_isp_subclk_resource res); 141 + int omap4iss_isp_subclk_disable(struct iss_device *iss, 142 + enum iss_isp_subclk_resource res); 143 + 144 + void omap4iss_isp_enable_interrupts(struct iss_device *iss); 145 + void omap4iss_isp_disable_interrupts(struct iss_device *iss); 146 + 147 + int omap4iss_pipeline_pm_use(struct media_entity *entity, int use); 148 + 149 + int omap4iss_register_entities(struct platform_device *pdev, 150 + struct v4l2_device *v4l2_dev); 151 + void omap4iss_unregister_entities(struct platform_device *pdev); 152 + 153 + #endif /* _OMAP4_ISS_H_ */
+883
drivers/staging/media/omap4iss/iss_regs.h
··· 1 + /* 2 + * TI OMAP4 ISS V4L2 Driver - Register defines 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_REGS_H_ 15 + #define _OMAP4_ISS_REGS_H_ 16 + 17 + /* ISS */ 18 + #define ISS_HL_REVISION 0x0 19 + 20 + #define ISS_HL_SYSCONFIG 0x10 21 + #define ISS_HL_SYSCONFIG_IDLEMODE_SHIFT 2 22 + #define ISS_HL_SYSCONFIG_IDLEMODE_FORCEIDLE 0x0 23 + #define ISS_HL_SYSCONFIG_IDLEMODE_NOIDLE 0x1 24 + #define ISS_HL_SYSCONFIG_IDLEMODE_SMARTIDLE 0x2 25 + #define ISS_HL_SYSCONFIG_SOFTRESET (1 << 0) 26 + 27 + #define ISS_HL_IRQSTATUS_5 (0x24 + (0x10 * 5)) 28 + #define ISS_HL_IRQENABLE_5_SET (0x28 + (0x10 * 5)) 29 + #define ISS_HL_IRQENABLE_5_CLR (0x2C + (0x10 * 5)) 30 + 31 + #define ISS_HL_IRQ_BTE (1 << 11) 32 + #define ISS_HL_IRQ_CBUFF (1 << 10) 33 + #define ISS_HL_IRQ_CSIB (1 << 5) 34 + #define ISS_HL_IRQ_CSIA (1 << 4) 35 + #define ISS_HL_IRQ_ISP(i) (1 << (i)) 36 + 37 + #define ISS_CTRL 0x80 38 + #define ISS_CTRL_CLK_DIV_MASK (3 << 4) 39 + #define ISS_CTRL_INPUT_SEL_MASK (3 << 2) 40 + #define ISS_CTRL_INPUT_SEL_CSI2A (0 << 2) 41 + #define ISS_CTRL_INPUT_SEL_CSI2B (1 << 2) 42 + #define ISS_CTRL_SYNC_DETECT_VS_RAISING (3 << 0) 43 + 44 + #define ISS_CLKCTRL 0x84 45 + #define ISS_CLKCTRL_VPORT2_CLK (1 << 30) 46 + #define ISS_CLKCTRL_VPORT1_CLK (1 << 29) 47 + #define ISS_CLKCTRL_VPORT0_CLK (1 << 28) 48 + #define ISS_CLKCTRL_CCP2 (1 << 4) 49 + #define ISS_CLKCTRL_CSI2_B (1 << 3) 50 + #define ISS_CLKCTRL_CSI2_A (1 << 2) 51 + #define ISS_CLKCTRL_ISP (1 << 1) 52 + #define ISS_CLKCTRL_SIMCOP (1 << 0) 53 + 54 + #define ISS_CLKSTAT 0x88 55 + #define ISS_CLKSTAT_VPORT2_CLK (1 << 30) 56 + #define ISS_CLKSTAT_VPORT1_CLK (1 << 29) 57 + #define ISS_CLKSTAT_VPORT0_CLK (1 << 28) 58 + #define ISS_CLKSTAT_CCP2 (1 << 4) 59 + #define ISS_CLKSTAT_CSI2_B (1 << 3) 60 + #define ISS_CLKSTAT_CSI2_A (1 << 2) 61 + #define ISS_CLKSTAT_ISP (1 << 1) 62 + #define ISS_CLKSTAT_SIMCOP (1 << 0) 63 + 64 + #define ISS_PM_STATUS 0x8C 65 + #define ISS_PM_STATUS_CBUFF_PM_MASK (3 << 12) 66 + #define ISS_PM_STATUS_BTE_PM_MASK (3 << 10) 67 + #define ISS_PM_STATUS_SIMCOP_PM_MASK (3 << 8) 68 + #define ISS_PM_STATUS_ISP_PM_MASK (3 << 6) 69 + #define ISS_PM_STATUS_CCP2_PM_MASK (3 << 4) 70 + #define ISS_PM_STATUS_CSI2_B_PM_MASK (3 << 2) 71 + #define ISS_PM_STATUS_CSI2_A_PM_MASK (3 << 0) 72 + 73 + #define REGISTER0 0x0 74 + #define REGISTER0_HSCLOCKCONFIG (1 << 24) 75 + #define REGISTER0_THS_TERM_MASK (0xFF << 8) 76 + #define REGISTER0_THS_TERM_SHIFT 8 77 + #define REGISTER0_THS_SETTLE_MASK (0xFF << 0) 78 + #define REGISTER0_THS_SETTLE_SHIFT 0 79 + 80 + #define REGISTER1 0x4 81 + #define REGISTER1_RESET_DONE_CTRLCLK (1 << 29) 82 + #define REGISTER1_CLOCK_MISS_DETECTOR_STATUS (1 << 25) 83 + #define REGISTER1_TCLK_TERM_MASK (0x3F << 18) 84 + #define REGISTER1_TCLK_TERM_SHIFT 18 85 + #define REGISTER1_DPHY_HS_SYNC_PATTERN_SHIFT 10 86 + #define REGISTER1_CTRLCLK_DIV_FACTOR_MASK (0x3 << 8) 87 + #define REGISTER1_CTRLCLK_DIV_FACTOR_SHIFT 8 88 + #define REGISTER1_TCLK_SETTLE_MASK (0xFF << 0) 89 + #define REGISTER1_TCLK_SETTLE_SHIFT 0 90 + 91 + #define REGISTER2 0x8 92 + 93 + #define CSI2_SYSCONFIG 0x10 94 + #define CSI2_SYSCONFIG_MSTANDBY_MODE_MASK (3 << 12) 95 + #define CSI2_SYSCONFIG_MSTANDBY_MODE_FORCE (0 << 12) 96 + #define CSI2_SYSCONFIG_MSTANDBY_MODE_NO (1 << 12) 97 + #define CSI2_SYSCONFIG_MSTANDBY_MODE_SMART (2 << 12) 98 + #define CSI2_SYSCONFIG_SOFT_RESET (1 << 1) 99 + #define CSI2_SYSCONFIG_AUTO_IDLE (1 << 0) 100 + 101 + #define CSI2_SYSSTATUS 0x14 102 + #define CSI2_SYSSTATUS_RESET_DONE (1 << 0) 103 + 104 + #define CSI2_IRQSTATUS 0x18 105 + #define CSI2_IRQENABLE 0x1C 106 + 107 + /* Shared bits across CSI2_IRQENABLE and IRQSTATUS */ 108 + 109 + #define CSI2_IRQ_OCP_ERR (1 << 14) 110 + #define CSI2_IRQ_SHORT_PACKET (1 << 13) 111 + #define CSI2_IRQ_ECC_CORRECTION (1 << 12) 112 + #define CSI2_IRQ_ECC_NO_CORRECTION (1 << 11) 113 + #define CSI2_IRQ_COMPLEXIO_ERR (1 << 9) 114 + #define CSI2_IRQ_FIFO_OVF (1 << 8) 115 + #define CSI2_IRQ_CONTEXT0 (1 << 0) 116 + 117 + #define CSI2_CTRL 0x40 118 + #define CSI2_CTRL_MFLAG_LEVH_MASK (7 << 20) 119 + #define CSI2_CTRL_MFLAG_LEVH_SHIFT 20 120 + #define CSI2_CTRL_MFLAG_LEVL_MASK (7 << 17) 121 + #define CSI2_CTRL_MFLAG_LEVL_SHIFT 17 122 + #define CSI2_CTRL_BURST_SIZE_EXPAND (1 << 16) 123 + #define CSI2_CTRL_VP_CLK_EN (1 << 15) 124 + #define CSI2_CTRL_NON_POSTED_WRITE (1 << 13) 125 + #define CSI2_CTRL_VP_ONLY_EN (1 << 11) 126 + #define CSI2_CTRL_VP_OUT_CTRL_MASK (3 << 8) 127 + #define CSI2_CTRL_VP_OUT_CTRL_SHIFT 8 128 + #define CSI2_CTRL_DBG_EN (1 << 7) 129 + #define CSI2_CTRL_BURST_SIZE_MASK (3 << 5) 130 + #define CSI2_CTRL_ENDIANNESS (1 << 4) 131 + #define CSI2_CTRL_FRAME (1 << 3) 132 + #define CSI2_CTRL_ECC_EN (1 << 2) 133 + #define CSI2_CTRL_IF_EN (1 << 0) 134 + 135 + #define CSI2_DBG_H 0x44 136 + 137 + #define CSI2_COMPLEXIO_CFG 0x50 138 + #define CSI2_COMPLEXIO_CFG_RESET_CTRL (1 << 30) 139 + #define CSI2_COMPLEXIO_CFG_RESET_DONE (1 << 29) 140 + #define CSI2_COMPLEXIO_CFG_PWD_CMD_MASK (3 << 27) 141 + #define CSI2_COMPLEXIO_CFG_PWD_CMD_OFF (0 << 27) 142 + #define CSI2_COMPLEXIO_CFG_PWD_CMD_ON (1 << 27) 143 + #define CSI2_COMPLEXIO_CFG_PWD_CMD_ULP (2 << 27) 144 + #define CSI2_COMPLEXIO_CFG_PWD_STATUS_MASK (3 << 25) 145 + #define CSI2_COMPLEXIO_CFG_PWD_STATUS_OFF (0 << 25) 146 + #define CSI2_COMPLEXIO_CFG_PWD_STATUS_ON (1 << 25) 147 + #define CSI2_COMPLEXIO_CFG_PWD_STATUS_ULP (2 << 25) 148 + #define CSI2_COMPLEXIO_CFG_PWR_AUTO (1 << 24) 149 + #define CSI2_COMPLEXIO_CFG_DATA_POL(i) (1 << (((i) * 4) + 3)) 150 + #define CSI2_COMPLEXIO_CFG_DATA_POSITION_MASK(i) (7 << ((i) * 4)) 151 + #define CSI2_COMPLEXIO_CFG_DATA_POSITION_SHIFT(i) ((i) * 4) 152 + #define CSI2_COMPLEXIO_CFG_CLOCK_POL (1 << 3) 153 + #define CSI2_COMPLEXIO_CFG_CLOCK_POSITION_MASK (7 << 0) 154 + #define CSI2_COMPLEXIO_CFG_CLOCK_POSITION_SHIFT 0 155 + 156 + #define CSI2_COMPLEXIO_IRQSTATUS 0x54 157 + 158 + #define CSI2_SHORT_PACKET 0x5C 159 + 160 + #define CSI2_COMPLEXIO_IRQENABLE 0x60 161 + 162 + /* Shared bits across CSI2_COMPLEXIO_IRQENABLE and IRQSTATUS */ 163 + #define CSI2_COMPLEXIO_IRQ_STATEALLULPMEXIT (1 << 26) 164 + #define CSI2_COMPLEXIO_IRQ_STATEALLULPMENTER (1 << 25) 165 + #define CSI2_COMPLEXIO_IRQ_STATEULPM5 (1 << 24) 166 + #define CSI2_COMPLEXIO_IRQ_STATEULPM4 (1 << 23) 167 + #define CSI2_COMPLEXIO_IRQ_STATEULPM3 (1 << 22) 168 + #define CSI2_COMPLEXIO_IRQ_STATEULPM2 (1 << 21) 169 + #define CSI2_COMPLEXIO_IRQ_STATEULPM1 (1 << 20) 170 + #define CSI2_COMPLEXIO_IRQ_ERRCONTROL5 (1 << 19) 171 + #define CSI2_COMPLEXIO_IRQ_ERRCONTROL4 (1 << 18) 172 + #define CSI2_COMPLEXIO_IRQ_ERRCONTROL3 (1 << 17) 173 + #define CSI2_COMPLEXIO_IRQ_ERRCONTROL2 (1 << 16) 174 + #define CSI2_COMPLEXIO_IRQ_ERRCONTROL1 (1 << 15) 175 + #define CSI2_COMPLEXIO_IRQ_ERRESC5 (1 << 14) 176 + #define CSI2_COMPLEXIO_IRQ_ERRESC4 (1 << 13) 177 + #define CSI2_COMPLEXIO_IRQ_ERRESC3 (1 << 12) 178 + #define CSI2_COMPLEXIO_IRQ_ERRESC2 (1 << 11) 179 + #define CSI2_COMPLEXIO_IRQ_ERRESC1 (1 << 10) 180 + #define CSI2_COMPLEXIO_IRQ_ERRSOTSYNCHS5 (1 << 9) 181 + #define CSI2_COMPLEXIO_IRQ_ERRSOTSYNCHS4 (1 << 8) 182 + #define CSI2_COMPLEXIO_IRQ_ERRSOTSYNCHS3 (1 << 7) 183 + #define CSI2_COMPLEXIO_IRQ_ERRSOTSYNCHS2 (1 << 6) 184 + #define CSI2_COMPLEXIO_IRQ_ERRSOTSYNCHS1 (1 << 5) 185 + #define CSI2_COMPLEXIO_IRQ_ERRSOTHS5 (1 << 4) 186 + #define CSI2_COMPLEXIO_IRQ_ERRSOTHS4 (1 << 3) 187 + #define CSI2_COMPLEXIO_IRQ_ERRSOTHS3 (1 << 2) 188 + #define CSI2_COMPLEXIO_IRQ_ERRSOTHS2 (1 << 1) 189 + #define CSI2_COMPLEXIO_IRQ_ERRSOTHS1 (1 << 0) 190 + 191 + #define CSI2_DBG_P 0x68 192 + 193 + #define CSI2_TIMING 0x6C 194 + #define CSI2_TIMING_FORCE_RX_MODE_IO1 (1 << 15) 195 + #define CSI2_TIMING_STOP_STATE_X16_IO1 (1 << 14) 196 + #define CSI2_TIMING_STOP_STATE_X4_IO1 (1 << 13) 197 + #define CSI2_TIMING_STOP_STATE_COUNTER_IO1_MASK (0x1FFF << 0) 198 + #define CSI2_TIMING_STOP_STATE_COUNTER_IO1_SHIFT 0 199 + 200 + #define CSI2_CTX_CTRL1(i) (0x70 + (0x20 * i)) 201 + #define CSI2_CTX_CTRL1_GENERIC (1 << 30) 202 + #define CSI2_CTX_CTRL1_TRANSCODE (0xF << 24) 203 + #define CSI2_CTX_CTRL1_FEC_NUMBER_MASK (0xFF << 16) 204 + #define CSI2_CTX_CTRL1_COUNT_MASK (0xFF << 8) 205 + #define CSI2_CTX_CTRL1_COUNT_SHIFT 8 206 + #define CSI2_CTX_CTRL1_EOF_EN (1 << 7) 207 + #define CSI2_CTX_CTRL1_EOL_EN (1 << 6) 208 + #define CSI2_CTX_CTRL1_CS_EN (1 << 5) 209 + #define CSI2_CTX_CTRL1_COUNT_UNLOCK (1 << 4) 210 + #define CSI2_CTX_CTRL1_PING_PONG (1 << 3) 211 + #define CSI2_CTX_CTRL1_CTX_EN (1 << 0) 212 + 213 + #define CSI2_CTX_CTRL2(i) (0x74 + (0x20 * i)) 214 + #define CSI2_CTX_CTRL2_USER_DEF_MAP_SHIFT 13 215 + #define CSI2_CTX_CTRL2_USER_DEF_MAP_MASK \ 216 + (0x3 << CSI2_CTX_CTRL2_USER_DEF_MAP_SHIFT) 217 + #define CSI2_CTX_CTRL2_VIRTUAL_ID_MASK (3 << 11) 218 + #define CSI2_CTX_CTRL2_VIRTUAL_ID_SHIFT 11 219 + #define CSI2_CTX_CTRL2_DPCM_PRED (1 << 10) 220 + #define CSI2_CTX_CTRL2_FORMAT_MASK (0x3FF << 0) 221 + #define CSI2_CTX_CTRL2_FORMAT_SHIFT 0 222 + 223 + #define CSI2_CTX_DAT_OFST(i) (0x78 + (0x20 * i)) 224 + #define CSI2_CTX_DAT_OFST_MASK (0xFFF << 5) 225 + 226 + #define CSI2_CTX_PING_ADDR(i) (0x7C + (0x20 * i)) 227 + #define CSI2_CTX_PING_ADDR_MASK 0xFFFFFFE0 228 + 229 + #define CSI2_CTX_PONG_ADDR(i) (0x80 + (0x20 * i)) 230 + #define CSI2_CTX_PONG_ADDR_MASK CSI2_CTX_PING_ADDR_MASK 231 + 232 + #define CSI2_CTX_IRQENABLE(i) (0x84 + (0x20 * i)) 233 + #define CSI2_CTX_IRQSTATUS(i) (0x88 + (0x20 * i)) 234 + 235 + #define CSI2_CTX_CTRL3(i) (0x8C + (0x20 * i)) 236 + #define CSI2_CTX_CTRL3_ALPHA_SHIFT 5 237 + #define CSI2_CTX_CTRL3_ALPHA_MASK \ 238 + (0x3fff << CSI2_CTX_CTRL3_ALPHA_SHIFT) 239 + 240 + /* Shared bits across CSI2_CTX_IRQENABLE and IRQSTATUS */ 241 + #define CSI2_CTX_IRQ_ECC_CORRECTION (1 << 8) 242 + #define CSI2_CTX_IRQ_LINE_NUMBER (1 << 7) 243 + #define CSI2_CTX_IRQ_FRAME_NUMBER (1 << 6) 244 + #define CSI2_CTX_IRQ_CS (1 << 5) 245 + #define CSI2_CTX_IRQ_LE (1 << 3) 246 + #define CSI2_CTX_IRQ_LS (1 << 2) 247 + #define CSI2_CTX_IRQ_FE (1 << 1) 248 + #define CSI2_CTX_IRQ_FS (1 << 0) 249 + 250 + /* ISS BTE */ 251 + #define BTE_CTRL (0x0030) 252 + #define BTE_CTRL_BW_LIMITER_MASK (0x3FF << 22) 253 + #define BTE_CTRL_BW_LIMITER_SHIFT 22 254 + 255 + /* ISS ISP_SYS1 */ 256 + #define ISP5_REVISION (0x0000) 257 + #define ISP5_SYSCONFIG (0x0010) 258 + #define ISP5_SYSCONFIG_STANDBYMODE_MASK (3 << 4) 259 + #define ISP5_SYSCONFIG_STANDBYMODE_FORCE (0 << 4) 260 + #define ISP5_SYSCONFIG_STANDBYMODE_NO (1 << 4) 261 + #define ISP5_SYSCONFIG_STANDBYMODE_SMART (2 << 4) 262 + #define ISP5_SYSCONFIG_SOFTRESET (1 << 1) 263 + 264 + #define ISP5_IRQSTATUS(i) (0x0028 + (0x10 * (i))) 265 + #define ISP5_IRQENABLE_SET(i) (0x002C + (0x10 * (i))) 266 + #define ISP5_IRQENABLE_CLR(i) (0x0030 + (0x10 * (i))) 267 + 268 + /* Bits shared for ISP5_IRQ* registers */ 269 + #define ISP5_IRQ_OCP_ERR (1 << 31) 270 + #define ISP5_IRQ_RSZ_INT_EOF0 (1 << 22) 271 + #define ISP5_IRQ_RSZ_FIFO_IN_BLK (1 << 19) 272 + #define ISP5_IRQ_RSZ_FIFO_OVF (1 << 18) 273 + #define ISP5_IRQ_RSZ_INT_CYC_RSZA (1 << 16) 274 + #define ISP5_IRQ_RSZ_INT_DMA (1 << 15) 275 + #define ISP5_IRQ_IPIPEIF (1 << 9) 276 + #define ISP5_IRQ_ISIF3 (1 << 3) 277 + #define ISP5_IRQ_ISIF2 (1 << 2) 278 + #define ISP5_IRQ_ISIF1 (1 << 1) 279 + #define ISP5_IRQ_ISIF0 (1 << 0) 280 + 281 + #define ISP5_CTRL (0x006C) 282 + #define ISP5_CTRL_MSTANDBY (1 << 24) 283 + #define ISP5_CTRL_VD_PULSE_EXT (1 << 23) 284 + #define ISP5_CTRL_MSTANDBY_WAIT (1 << 20) 285 + #define ISP5_CTRL_BL_CLK_ENABLE (1 << 15) 286 + #define ISP5_CTRL_ISIF_CLK_ENABLE (1 << 14) 287 + #define ISP5_CTRL_H3A_CLK_ENABLE (1 << 13) 288 + #define ISP5_CTRL_RSZ_CLK_ENABLE (1 << 12) 289 + #define ISP5_CTRL_IPIPE_CLK_ENABLE (1 << 11) 290 + #define ISP5_CTRL_IPIPEIF_CLK_ENABLE (1 << 10) 291 + #define ISP5_CTRL_SYNC_ENABLE (1 << 9) 292 + #define ISP5_CTRL_PSYNC_CLK_SEL (1 << 8) 293 + 294 + /* ISS ISP ISIF register offsets */ 295 + #define ISIF_SYNCEN (0x0000) 296 + #define ISIF_SYNCEN_DWEN (1 << 1) 297 + #define ISIF_SYNCEN_SYEN (1 << 0) 298 + 299 + #define ISIF_MODESET (0x0004) 300 + #define ISIF_MODESET_INPMOD_MASK (3 << 12) 301 + #define ISIF_MODESET_INPMOD_RAW (0 << 12) 302 + #define ISIF_MODESET_INPMOD_YCBCR16 (1 << 12) 303 + #define ISIF_MODESET_INPMOD_YCBCR8 (2 << 12) 304 + #define ISIF_MODESET_CCDW_MASK (7 << 8) 305 + #define ISIF_MODESET_CCDW_2BIT (2 << 8) 306 + #define ISIF_MODESET_CCDMD (1 << 7) 307 + #define ISIF_MODESET_SWEN (1 << 5) 308 + #define ISIF_MODESET_HDPOL (1 << 3) 309 + #define ISIF_MODESET_VDPOL (1 << 2) 310 + 311 + #define ISIF_SPH (0x0018) 312 + #define ISIF_SPH_MASK (0x7FFF) 313 + 314 + #define ISIF_LNH (0x001C) 315 + #define ISIF_LNH_MASK (0x7FFF) 316 + 317 + #define ISIF_LNV (0x0028) 318 + #define ISIF_LNV_MASK (0x7FFF) 319 + 320 + #define ISIF_HSIZE (0x0034) 321 + #define ISIF_HSIZE_ADCR (1 << 12) 322 + #define ISIF_HSIZE_HSIZE_MASK (0xFFF) 323 + 324 + #define ISIF_CADU (0x003C) 325 + #define ISIF_CADU_MASK (0x7FF) 326 + 327 + #define ISIF_CADL (0x0040) 328 + #define ISIF_CADL_MASK (0xFFFF) 329 + 330 + #define ISIF_CCOLP (0x004C) 331 + #define ISIF_CCOLP_CP0_F0_R (0 << 6) 332 + #define ISIF_CCOLP_CP0_F0_GR (1 << 6) 333 + #define ISIF_CCOLP_CP0_F0_B (3 << 6) 334 + #define ISIF_CCOLP_CP0_F0_GB (2 << 6) 335 + #define ISIF_CCOLP_CP1_F0_R (0 << 4) 336 + #define ISIF_CCOLP_CP1_F0_GR (1 << 4) 337 + #define ISIF_CCOLP_CP1_F0_B (3 << 4) 338 + #define ISIF_CCOLP_CP1_F0_GB (2 << 4) 339 + #define ISIF_CCOLP_CP2_F0_R (0 << 2) 340 + #define ISIF_CCOLP_CP2_F0_GR (1 << 2) 341 + #define ISIF_CCOLP_CP2_F0_B (3 << 2) 342 + #define ISIF_CCOLP_CP2_F0_GB (2 << 2) 343 + #define ISIF_CCOLP_CP3_F0_R (0 << 0) 344 + #define ISIF_CCOLP_CP3_F0_GR (1 << 0) 345 + #define ISIF_CCOLP_CP3_F0_B (3 << 0) 346 + #define ISIF_CCOLP_CP3_F0_GB (2 << 0) 347 + 348 + #define ISIF_VDINT0 (0x0070) 349 + #define ISIF_VDINT0_MASK (0x7FFF) 350 + 351 + #define ISIF_CGAMMAWD (0x0080) 352 + #define ISIF_CGAMMAWD_GWDI_MASK (0xF << 1) 353 + #define ISIF_CGAMMAWD_GWDI_BIT11 (0x4 << 1) 354 + 355 + #define ISIF_CCDCFG (0x0088) 356 + #define ISIF_CCDCFG_Y8POS (1 << 11) 357 + 358 + /* ISS ISP IPIPEIF register offsets */ 359 + #define IPIPEIF_ENABLE (0x0000) 360 + 361 + #define IPIPEIF_CFG1 (0x0004) 362 + #define IPIPEIF_CFG1_INPSRC1_MASK (3 << 14) 363 + #define IPIPEIF_CFG1_INPSRC1_VPORT_RAW (0 << 14) 364 + #define IPIPEIF_CFG1_INPSRC1_SDRAM_RAW (1 << 14) 365 + #define IPIPEIF_CFG1_INPSRC1_ISIF_DARKFM (2 << 14) 366 + #define IPIPEIF_CFG1_INPSRC1_SDRAM_YUV (3 << 14) 367 + #define IPIPEIF_CFG1_INPSRC2_MASK (3 << 2) 368 + #define IPIPEIF_CFG1_INPSRC2_ISIF (0 << 2) 369 + #define IPIPEIF_CFG1_INPSRC2_SDRAM_RAW (1 << 2) 370 + #define IPIPEIF_CFG1_INPSRC2_ISIF_DARKFM (2 << 2) 371 + #define IPIPEIF_CFG1_INPSRC2_SDRAM_YUV (3 << 2) 372 + 373 + #define IPIPEIF_CFG2 (0x0030) 374 + #define IPIPEIF_CFG2_YUV8P (1 << 7) 375 + #define IPIPEIF_CFG2_YUV8 (1 << 6) 376 + #define IPIPEIF_CFG2_YUV16 (1 << 3) 377 + #define IPIPEIF_CFG2_VDPOL (1 << 2) 378 + #define IPIPEIF_CFG2_HDPOL (1 << 1) 379 + #define IPIPEIF_CFG2_INTSW (1 << 0) 380 + 381 + #define IPIPEIF_CLKDIV (0x0040) 382 + 383 + /* ISS ISP IPIPE register offsets */ 384 + #define IPIPE_SRC_EN (0x0000) 385 + #define IPIPE_SRC_EN_EN (1 << 0) 386 + 387 + #define IPIPE_SRC_MODE (0x0004) 388 + #define IPIPE_SRC_MODE_WRT (1 << 1) 389 + #define IPIPE_SRC_MODE_OST (1 << 0) 390 + 391 + #define IPIPE_SRC_FMT (0x0008) 392 + #define IPIPE_SRC_FMT_RAW2YUV (0 << 0) 393 + #define IPIPE_SRC_FMT_RAW2RAW (1 << 0) 394 + #define IPIPE_SRC_FMT_RAW2STATS (2 << 0) 395 + #define IPIPE_SRC_FMT_YUV2YUV (3 << 0) 396 + 397 + #define IPIPE_SRC_COL (0x000C) 398 + #define IPIPE_SRC_COL_OO_R (0 << 6) 399 + #define IPIPE_SRC_COL_OO_GR (1 << 6) 400 + #define IPIPE_SRC_COL_OO_B (3 << 6) 401 + #define IPIPE_SRC_COL_OO_GB (2 << 6) 402 + #define IPIPE_SRC_COL_OE_R (0 << 4) 403 + #define IPIPE_SRC_COL_OE_GR (1 << 4) 404 + #define IPIPE_SRC_COL_OE_B (3 << 4) 405 + #define IPIPE_SRC_COL_OE_GB (2 << 4) 406 + #define IPIPE_SRC_COL_EO_R (0 << 2) 407 + #define IPIPE_SRC_COL_EO_GR (1 << 2) 408 + #define IPIPE_SRC_COL_EO_B (3 << 2) 409 + #define IPIPE_SRC_COL_EO_GB (2 << 2) 410 + #define IPIPE_SRC_COL_EE_R (0 << 0) 411 + #define IPIPE_SRC_COL_EE_GR (1 << 0) 412 + #define IPIPE_SRC_COL_EE_B (3 << 0) 413 + #define IPIPE_SRC_COL_EE_GB (2 << 0) 414 + 415 + #define IPIPE_SRC_VPS (0x0010) 416 + #define IPIPE_SRC_VPS_MASK (0xFFFF) 417 + 418 + #define IPIPE_SRC_VSZ (0x0014) 419 + #define IPIPE_SRC_VSZ_MASK (0x1FFF) 420 + 421 + #define IPIPE_SRC_HPS (0x0018) 422 + #define IPIPE_SRC_HPS_MASK (0xFFFF) 423 + 424 + #define IPIPE_SRC_HSZ (0x001C) 425 + #define IPIPE_SRC_HSZ_MASK (0x1FFE) 426 + 427 + #define IPIPE_SEL_SBU (0x0020) 428 + 429 + #define IPIPE_SRC_STA (0x0024) 430 + 431 + #define IPIPE_GCK_MMR (0x0028) 432 + #define IPIPE_GCK_MMR_REG (1 << 0) 433 + 434 + #define IPIPE_GCK_PIX (0x002C) 435 + #define IPIPE_GCK_PIX_G3 (1 << 3) 436 + #define IPIPE_GCK_PIX_G2 (1 << 2) 437 + #define IPIPE_GCK_PIX_G1 (1 << 1) 438 + #define IPIPE_GCK_PIX_G0 (1 << 0) 439 + 440 + #define IPIPE_DPC_LUT_EN (0x0034) 441 + #define IPIPE_DPC_LUT_SEL (0x0038) 442 + #define IPIPE_DPC_LUT_ADR (0x003C) 443 + #define IPIPE_DPC_LUT_SIZ (0x0040) 444 + 445 + #define IPIPE_DPC_OTF_EN (0x0044) 446 + #define IPIPE_DPC_OTF_TYP (0x0048) 447 + #define IPIPE_DPC_OTF_2_D_THR_R (0x004C) 448 + #define IPIPE_DPC_OTF_2_D_THR_GR (0x0050) 449 + #define IPIPE_DPC_OTF_2_D_THR_GB (0x0054) 450 + #define IPIPE_DPC_OTF_2_D_THR_B (0x0058) 451 + #define IPIPE_DPC_OTF_2_C_THR_R (0x005C) 452 + #define IPIPE_DPC_OTF_2_C_THR_GR (0x0060) 453 + #define IPIPE_DPC_OTF_2_C_THR_GB (0x0064) 454 + #define IPIPE_DPC_OTF_2_C_THR_B (0x0068) 455 + #define IPIPE_DPC_OTF_3_SHF (0x006C) 456 + #define IPIPE_DPC_OTF_3_D_THR (0x0070) 457 + #define IPIPE_DPC_OTF_3_D_SPL (0x0074) 458 + #define IPIPE_DPC_OTF_3_D_MIN (0x0078) 459 + #define IPIPE_DPC_OTF_3_D_MAX (0x007C) 460 + #define IPIPE_DPC_OTF_3_C_THR (0x0080) 461 + #define IPIPE_DPC_OTF_3_C_SLP (0x0084) 462 + #define IPIPE_DPC_OTF_3_C_MIN (0x0088) 463 + #define IPIPE_DPC_OTF_3_C_MAX (0x008C) 464 + 465 + #define IPIPE_LSC_VOFT (0x0090) 466 + #define IPIPE_LSC_VA2 (0x0094) 467 + #define IPIPE_LSC_VA1 (0x0098) 468 + #define IPIPE_LSC_VS (0x009C) 469 + #define IPIPE_LSC_HOFT (0x00A0) 470 + #define IPIPE_LSC_HA2 (0x00A4) 471 + #define IPIPE_LSC_HA1 (0x00A8) 472 + #define IPIPE_LSC_HS (0x00AC) 473 + #define IPIPE_LSC_GAN_R (0x00B0) 474 + #define IPIPE_LSC_GAN_GR (0x00B4) 475 + #define IPIPE_LSC_GAN_GB (0x00B8) 476 + #define IPIPE_LSC_GAN_B (0x00BC) 477 + #define IPIPE_LSC_OFT_R (0x00C0) 478 + #define IPIPE_LSC_OFT_GR (0x00C4) 479 + #define IPIPE_LSC_OFT_GB (0x00C8) 480 + #define IPIPE_LSC_OFT_B (0x00CC) 481 + #define IPIPE_LSC_SHF (0x00D0) 482 + #define IPIPE_LSC_MAX (0x00D4) 483 + 484 + #define IPIPE_D2F_1ST_EN (0x00D8) 485 + #define IPIPE_D2F_1ST_TYP (0x00DC) 486 + #define IPIPE_D2F_1ST_THR_00 (0x00E0) 487 + #define IPIPE_D2F_1ST_THR_01 (0x00E4) 488 + #define IPIPE_D2F_1ST_THR_02 (0x00E8) 489 + #define IPIPE_D2F_1ST_THR_03 (0x00EC) 490 + #define IPIPE_D2F_1ST_THR_04 (0x00F0) 491 + #define IPIPE_D2F_1ST_THR_05 (0x00F4) 492 + #define IPIPE_D2F_1ST_THR_06 (0x00F8) 493 + #define IPIPE_D2F_1ST_THR_07 (0x00FC) 494 + #define IPIPE_D2F_1ST_STR_00 (0x0100) 495 + #define IPIPE_D2F_1ST_STR_01 (0x0104) 496 + #define IPIPE_D2F_1ST_STR_02 (0x0108) 497 + #define IPIPE_D2F_1ST_STR_03 (0x010C) 498 + #define IPIPE_D2F_1ST_STR_04 (0x0110) 499 + #define IPIPE_D2F_1ST_STR_05 (0x0114) 500 + #define IPIPE_D2F_1ST_STR_06 (0x0118) 501 + #define IPIPE_D2F_1ST_STR_07 (0x011C) 502 + #define IPIPE_D2F_1ST_SPR_00 (0x0120) 503 + #define IPIPE_D2F_1ST_SPR_01 (0x0124) 504 + #define IPIPE_D2F_1ST_SPR_02 (0x0128) 505 + #define IPIPE_D2F_1ST_SPR_03 (0x012C) 506 + #define IPIPE_D2F_1ST_SPR_04 (0x0130) 507 + #define IPIPE_D2F_1ST_SPR_05 (0x0134) 508 + #define IPIPE_D2F_1ST_SPR_06 (0x0138) 509 + #define IPIPE_D2F_1ST_SPR_07 (0x013C) 510 + #define IPIPE_D2F_1ST_EDG_MIN (0x0140) 511 + #define IPIPE_D2F_1ST_EDG_MAX (0x0144) 512 + #define IPIPE_D2F_2ND_EN (0x0148) 513 + #define IPIPE_D2F_2ND_TYP (0x014C) 514 + #define IPIPE_D2F_2ND_THR00 (0x0150) 515 + #define IPIPE_D2F_2ND_THR01 (0x0154) 516 + #define IPIPE_D2F_2ND_THR02 (0x0158) 517 + #define IPIPE_D2F_2ND_THR03 (0x015C) 518 + #define IPIPE_D2F_2ND_THR04 (0x0160) 519 + #define IPIPE_D2F_2ND_THR05 (0x0164) 520 + #define IPIPE_D2F_2ND_THR06 (0x0168) 521 + #define IPIPE_D2F_2ND_THR07 (0x016C) 522 + #define IPIPE_D2F_2ND_STR_00 (0x0170) 523 + #define IPIPE_D2F_2ND_STR_01 (0x0174) 524 + #define IPIPE_D2F_2ND_STR_02 (0x0178) 525 + #define IPIPE_D2F_2ND_STR_03 (0x017C) 526 + #define IPIPE_D2F_2ND_STR_04 (0x0180) 527 + #define IPIPE_D2F_2ND_STR_05 (0x0184) 528 + #define IPIPE_D2F_2ND_STR_06 (0x0188) 529 + #define IPIPE_D2F_2ND_STR_07 (0x018C) 530 + #define IPIPE_D2F_2ND_SPR_00 (0x0190) 531 + #define IPIPE_D2F_2ND_SPR_01 (0x0194) 532 + #define IPIPE_D2F_2ND_SPR_02 (0x0198) 533 + #define IPIPE_D2F_2ND_SPR_03 (0x019C) 534 + #define IPIPE_D2F_2ND_SPR_04 (0x01A0) 535 + #define IPIPE_D2F_2ND_SPR_05 (0x01A4) 536 + #define IPIPE_D2F_2ND_SPR_06 (0x01A8) 537 + #define IPIPE_D2F_2ND_SPR_07 (0x01AC) 538 + #define IPIPE_D2F_2ND_EDG_MIN (0x01B0) 539 + #define IPIPE_D2F_2ND_EDG_MAX (0x01B4) 540 + 541 + #define IPIPE_GIC_EN (0x01B8) 542 + #define IPIPE_GIC_TYP (0x01BC) 543 + #define IPIPE_GIC_GAN (0x01C0) 544 + #define IPIPE_GIC_NFGAIN (0x01C4) 545 + #define IPIPE_GIC_THR (0x01C8) 546 + #define IPIPE_GIC_SLP (0x01CC) 547 + 548 + #define IPIPE_WB2_OFT_R (0x01D0) 549 + #define IPIPE_WB2_OFT_GR (0x01D4) 550 + #define IPIPE_WB2_OFT_GB (0x01D8) 551 + #define IPIPE_WB2_OFT_B (0x01DC) 552 + 553 + #define IPIPE_WB2_WGN_R (0x01E0) 554 + #define IPIPE_WB2_WGN_GR (0x01E4) 555 + #define IPIPE_WB2_WGN_GB (0x01E8) 556 + #define IPIPE_WB2_WGN_B (0x01EC) 557 + 558 + #define IPIPE_CFA_MODE (0x01F0) 559 + #define IPIPE_CFA_2DIR_HPF_THR (0x01F4) 560 + #define IPIPE_CFA_2DIR_HPF_SLP (0x01F8) 561 + #define IPIPE_CFA_2DIR_MIX_THR (0x01FC) 562 + #define IPIPE_CFA_2DIR_MIX_SLP (0x0200) 563 + #define IPIPE_CFA_2DIR_DIR_TRH (0x0204) 564 + #define IPIPE_CFA_2DIR_DIR_SLP (0x0208) 565 + #define IPIPE_CFA_2DIR_NDWT (0x020C) 566 + #define IPIPE_CFA_MONO_HUE_FRA (0x0210) 567 + #define IPIPE_CFA_MONO_EDG_THR (0x0214) 568 + #define IPIPE_CFA_MONO_THR_MIN (0x0218) 569 + 570 + #define IPIPE_CFA_MONO_THR_SLP (0x021C) 571 + #define IPIPE_CFA_MONO_SLP_MIN (0x0220) 572 + #define IPIPE_CFA_MONO_SLP_SLP (0x0224) 573 + #define IPIPE_CFA_MONO_LPWT (0x0228) 574 + 575 + #define IPIPE_RGB1_MUL_RR (0x022C) 576 + #define IPIPE_RGB1_MUL_GR (0x0230) 577 + #define IPIPE_RGB1_MUL_BR (0x0234) 578 + #define IPIPE_RGB1_MUL_RG (0x0238) 579 + #define IPIPE_RGB1_MUL_GG (0x023C) 580 + #define IPIPE_RGB1_MUL_BG (0x0240) 581 + #define IPIPE_RGB1_MUL_RB (0x0244) 582 + #define IPIPE_RGB1_MUL_GB (0x0248) 583 + #define IPIPE_RGB1_MUL_BB (0x024C) 584 + #define IPIPE_RGB1_OFT_OR (0x0250) 585 + #define IPIPE_RGB1_OFT_OG (0x0254) 586 + #define IPIPE_RGB1_OFT_OB (0x0258) 587 + #define IPIPE_GMM_CFG (0x025C) 588 + #define IPIPE_RGB2_MUL_RR (0x0260) 589 + #define IPIPE_RGB2_MUL_GR (0x0264) 590 + #define IPIPE_RGB2_MUL_BR (0x0268) 591 + #define IPIPE_RGB2_MUL_RG (0x026C) 592 + #define IPIPE_RGB2_MUL_GG (0x0270) 593 + #define IPIPE_RGB2_MUL_BG (0x0274) 594 + #define IPIPE_RGB2_MUL_RB (0x0278) 595 + #define IPIPE_RGB2_MUL_GB (0x027C) 596 + #define IPIPE_RGB2_MUL_BB (0x0280) 597 + #define IPIPE_RGB2_OFT_OR (0x0284) 598 + #define IPIPE_RGB2_OFT_OG (0x0288) 599 + #define IPIPE_RGB2_OFT_OB (0x028C) 600 + 601 + #define IPIPE_YUV_ADJ (0x0294) 602 + #define IPIPE_YUV_MUL_RY (0x0298) 603 + #define IPIPE_YUV_MUL_GY (0x029C) 604 + #define IPIPE_YUV_MUL_BY (0x02A0) 605 + #define IPIPE_YUV_MUL_RCB (0x02A4) 606 + #define IPIPE_YUV_MUL_GCB (0x02A8) 607 + #define IPIPE_YUV_MUL_BCB (0x02AC) 608 + #define IPIPE_YUV_MUL_RCR (0x02B0) 609 + #define IPIPE_YUV_MUL_GCR (0x02B4) 610 + #define IPIPE_YUV_MUL_BCR (0x02B8) 611 + #define IPIPE_YUV_OFT_Y (0x02BC) 612 + #define IPIPE_YUV_OFT_CB (0x02C0) 613 + #define IPIPE_YUV_OFT_CR (0x02C4) 614 + 615 + #define IPIPE_YUV_PHS (0x02C8) 616 + #define IPIPE_YUV_PHS_LPF (1 << 1) 617 + #define IPIPE_YUV_PHS_POS (1 << 0) 618 + 619 + #define IPIPE_YEE_EN (0x02D4) 620 + #define IPIPE_YEE_TYP (0x02D8) 621 + #define IPIPE_YEE_SHF (0x02DC) 622 + #define IPIPE_YEE_MUL_00 (0x02E0) 623 + #define IPIPE_YEE_MUL_01 (0x02E4) 624 + #define IPIPE_YEE_MUL_02 (0x02E8) 625 + #define IPIPE_YEE_MUL_10 (0x02EC) 626 + #define IPIPE_YEE_MUL_11 (0x02F0) 627 + #define IPIPE_YEE_MUL_12 (0x02F4) 628 + #define IPIPE_YEE_MUL_20 (0x02F8) 629 + #define IPIPE_YEE_MUL_21 (0x02FC) 630 + #define IPIPE_YEE_MUL_22 (0x0300) 631 + #define IPIPE_YEE_THR (0x0304) 632 + #define IPIPE_YEE_E_GAN (0x0308) 633 + #define IPIPE_YEE_E_THR_1 (0x030C) 634 + #define IPIPE_YEE_E_THR_2 (0x0310) 635 + #define IPIPE_YEE_G_GAN (0x0314) 636 + #define IPIPE_YEE_G_OFT (0x0318) 637 + 638 + #define IPIPE_CAR_EN (0x031C) 639 + #define IPIPE_CAR_TYP (0x0320) 640 + #define IPIPE_CAR_SW (0x0324) 641 + #define IPIPE_CAR_HPF_TYP (0x0328) 642 + #define IPIPE_CAR_HPF_SHF (0x032C) 643 + #define IPIPE_CAR_HPF_THR (0x0330) 644 + #define IPIPE_CAR_GN1_GAN (0x0334) 645 + #define IPIPE_CAR_GN1_SHF (0x0338) 646 + #define IPIPE_CAR_GN1_MIN (0x033C) 647 + #define IPIPE_CAR_GN2_GAN (0x0340) 648 + #define IPIPE_CAR_GN2_SHF (0x0344) 649 + #define IPIPE_CAR_GN2_MIN (0x0348) 650 + #define IPIPE_CGS_EN (0x034C) 651 + #define IPIPE_CGS_GN1_L_THR (0x0350) 652 + #define IPIPE_CGS_GN1_L_GAIN (0x0354) 653 + #define IPIPE_CGS_GN1_L_SHF (0x0358) 654 + #define IPIPE_CGS_GN1_L_MIN (0x035C) 655 + #define IPIPE_CGS_GN1_H_THR (0x0360) 656 + #define IPIPE_CGS_GN1_H_GAIN (0x0364) 657 + #define IPIPE_CGS_GN1_H_SHF (0x0368) 658 + #define IPIPE_CGS_GN1_H_MIN (0x036C) 659 + #define IPIPE_CGS_GN2_L_THR (0x0370) 660 + #define IPIPE_CGS_GN2_L_GAIN (0x0374) 661 + #define IPIPE_CGS_GN2_L_SHF (0x0378) 662 + #define IPIPE_CGS_GN2_L_MIN (0x037C) 663 + 664 + #define IPIPE_BOX_EN (0x0380) 665 + #define IPIPE_BOX_MODE (0x0384) 666 + #define IPIPE_BOX_TYP (0x0388) 667 + #define IPIPE_BOX_SHF (0x038C) 668 + #define IPIPE_BOX_SDR_SAD_H (0x0390) 669 + #define IPIPE_BOX_SDR_SAD_L (0x0394) 670 + 671 + #define IPIPE_HST_EN (0x039C) 672 + #define IPIPE_HST_MODE (0x03A0) 673 + #define IPIPE_HST_SEL (0x03A4) 674 + #define IPIPE_HST_PARA (0x03A8) 675 + #define IPIPE_HST_0_VPS (0x03AC) 676 + #define IPIPE_HST_0_VSZ (0x03B0) 677 + #define IPIPE_HST_0_HPS (0x03B4) 678 + #define IPIPE_HST_0_HSZ (0x03B8) 679 + #define IPIPE_HST_1_VPS (0x03BC) 680 + #define IPIPE_HST_1_VSZ (0x03C0) 681 + #define IPIPE_HST_1_HPS (0x03C4) 682 + #define IPIPE_HST_1_HSZ (0x03C8) 683 + #define IPIPE_HST_2_VPS (0x03CC) 684 + #define IPIPE_HST_2_VSZ (0x03D0) 685 + #define IPIPE_HST_2_HPS (0x03D4) 686 + #define IPIPE_HST_2_HSZ (0x03D8) 687 + #define IPIPE_HST_3_VPS (0x03DC) 688 + #define IPIPE_HST_3_VSZ (0x03E0) 689 + #define IPIPE_HST_3_HPS (0x03E4) 690 + #define IPIPE_HST_3_HSZ (0x03E8) 691 + #define IPIPE_HST_TBL (0x03EC) 692 + #define IPIPE_HST_MUL_R (0x03F0) 693 + #define IPIPE_HST_MUL_GR (0x03F4) 694 + #define IPIPE_HST_MUL_GB (0x03F8) 695 + #define IPIPE_HST_MUL_B (0x03FC) 696 + 697 + #define IPIPE_BSC_EN (0x0400) 698 + #define IPIPE_BSC_MODE (0x0404) 699 + #define IPIPE_BSC_TYP (0x0408) 700 + #define IPIPE_BSC_ROW_VCT (0x040C) 701 + #define IPIPE_BSC_ROW_SHF (0x0410) 702 + #define IPIPE_BSC_ROW_VPO (0x0414) 703 + #define IPIPE_BSC_ROW_VNU (0x0418) 704 + #define IPIPE_BSC_ROW_VSKIP (0x041C) 705 + #define IPIPE_BSC_ROW_HPO (0x0420) 706 + #define IPIPE_BSC_ROW_HNU (0x0424) 707 + #define IPIPE_BSC_ROW_HSKIP (0x0428) 708 + #define IPIPE_BSC_COL_VCT (0x042C) 709 + #define IPIPE_BSC_COL_SHF (0x0430) 710 + #define IPIPE_BSC_COL_VPO (0x0434) 711 + #define IPIPE_BSC_COL_VNU (0x0438) 712 + #define IPIPE_BSC_COL_VSKIP (0x043C) 713 + #define IPIPE_BSC_COL_HPO (0x0440) 714 + #define IPIPE_BSC_COL_HNU (0x0444) 715 + #define IPIPE_BSC_COL_HSKIP (0x0448) 716 + 717 + #define IPIPE_BSC_EN (0x0400) 718 + 719 + /* ISS ISP Resizer register offsets */ 720 + #define RSZ_REVISION (0x0000) 721 + #define RSZ_SYSCONFIG (0x0004) 722 + #define RSZ_SYSCONFIG_RSZB_CLK_EN (1 << 9) 723 + #define RSZ_SYSCONFIG_RSZA_CLK_EN (1 << 8) 724 + 725 + #define RSZ_IN_FIFO_CTRL (0x000C) 726 + #define RSZ_IN_FIFO_CTRL_THRLD_LOW_MASK (0x1FF << 16) 727 + #define RSZ_IN_FIFO_CTRL_THRLD_LOW_SHIFT 16 728 + #define RSZ_IN_FIFO_CTRL_THRLD_HIGH_MASK (0x1FF << 0) 729 + #define RSZ_IN_FIFO_CTRL_THRLD_HIGH_SHIFT 0 730 + 731 + #define RSZ_FRACDIV (0x0008) 732 + #define RSZ_FRACDIV_MASK (0xFFFF) 733 + 734 + #define RSZ_SRC_EN (0x0020) 735 + #define RSZ_SRC_EN_SRC_EN (1 << 0) 736 + 737 + #define RSZ_SRC_MODE (0x0024) 738 + #define RSZ_SRC_MODE_OST (1 << 0) 739 + #define RSZ_SRC_MODE_WRT (1 << 1) 740 + 741 + #define RSZ_SRC_FMT0 (0x0028) 742 + #define RSZ_SRC_FMT0_BYPASS (1 << 1) 743 + #define RSZ_SRC_FMT0_SEL (1 << 0) 744 + 745 + #define RSZ_SRC_FMT1 (0x002C) 746 + #define RSZ_SRC_FMT1_IN420 (1 << 1) 747 + 748 + #define RSZ_SRC_VPS (0x0030) 749 + #define RSZ_SRC_VSZ (0x0034) 750 + #define RSZ_SRC_HPS (0x0038) 751 + #define RSZ_SRC_HSZ (0x003C) 752 + #define RSZ_DMA_RZA (0x0040) 753 + #define RSZ_DMA_RZB (0x0044) 754 + #define RSZ_DMA_STA (0x0048) 755 + #define RSZ_GCK_MMR (0x004C) 756 + #define RSZ_GCK_MMR_MMR (1 << 0) 757 + 758 + #define RSZ_GCK_SDR (0x0054) 759 + #define RSZ_GCK_SDR_CORE (1 << 0) 760 + 761 + #define RSZ_IRQ_RZA (0x0058) 762 + #define RSZ_IRQ_RZA_MASK (0x1FFF) 763 + 764 + #define RSZ_IRQ_RZB (0x005C) 765 + #define RSZ_IRQ_RZB_MASK (0x1FFF) 766 + 767 + #define RSZ_YUV_Y_MIN (0x0060) 768 + #define RSZ_YUV_Y_MAX (0x0064) 769 + #define RSZ_YUV_C_MIN (0x0068) 770 + #define RSZ_YUV_C_MAX (0x006C) 771 + 772 + #define RSZ_SEQ (0x0074) 773 + #define RSZ_SEQ_HRVB (1 << 2) 774 + #define RSZ_SEQ_HRVA (1 << 0) 775 + 776 + #define RZA_EN (0x0078) 777 + #define RZA_MODE (0x007C) 778 + #define RZA_MODE_ONE_SHOT (1 << 0) 779 + 780 + #define RZA_420 (0x0080) 781 + #define RZA_I_VPS (0x0084) 782 + #define RZA_I_HPS (0x0088) 783 + #define RZA_O_VSZ (0x008C) 784 + #define RZA_O_HSZ (0x0090) 785 + #define RZA_V_PHS_Y (0x0094) 786 + #define RZA_V_PHS_C (0x0098) 787 + #define RZA_V_DIF (0x009C) 788 + #define RZA_V_TYP (0x00A0) 789 + #define RZA_V_LPF (0x00A4) 790 + #define RZA_H_PHS (0x00A8) 791 + #define RZA_H_DIF (0x00B0) 792 + #define RZA_H_TYP (0x00B4) 793 + #define RZA_H_LPF (0x00B8) 794 + #define RZA_DWN_EN (0x00BC) 795 + #define RZA_SDR_Y_BAD_H (0x00D0) 796 + #define RZA_SDR_Y_BAD_L (0x00D4) 797 + #define RZA_SDR_Y_SAD_H (0x00D8) 798 + #define RZA_SDR_Y_SAD_L (0x00DC) 799 + #define RZA_SDR_Y_OFT (0x00E0) 800 + #define RZA_SDR_Y_PTR_S (0x00E4) 801 + #define RZA_SDR_Y_PTR_E (0x00E8) 802 + #define RZA_SDR_C_BAD_H (0x00EC) 803 + #define RZA_SDR_C_BAD_L (0x00F0) 804 + #define RZA_SDR_C_SAD_H (0x00F4) 805 + #define RZA_SDR_C_SAD_L (0x00F8) 806 + #define RZA_SDR_C_OFT (0x00FC) 807 + #define RZA_SDR_C_PTR_S (0x0100) 808 + #define RZA_SDR_C_PTR_E (0x0104) 809 + 810 + #define RZB_EN (0x0108) 811 + #define RZB_MODE (0x010C) 812 + #define RZB_420 (0x0110) 813 + #define RZB_I_VPS (0x0114) 814 + #define RZB_I_HPS (0x0118) 815 + #define RZB_O_VSZ (0x011C) 816 + #define RZB_O_HSZ (0x0120) 817 + 818 + #define RZB_V_DIF (0x012C) 819 + #define RZB_V_TYP (0x0130) 820 + #define RZB_V_LPF (0x0134) 821 + 822 + #define RZB_H_DIF (0x0140) 823 + #define RZB_H_TYP (0x0144) 824 + #define RZB_H_LPF (0x0148) 825 + 826 + #define RZB_SDR_Y_BAD_H (0x0160) 827 + #define RZB_SDR_Y_BAD_L (0x0164) 828 + #define RZB_SDR_Y_SAD_H (0x0168) 829 + #define RZB_SDR_Y_SAD_L (0x016C) 830 + #define RZB_SDR_Y_OFT (0x0170) 831 + #define RZB_SDR_Y_PTR_S (0x0174) 832 + #define RZB_SDR_Y_PTR_E (0x0178) 833 + #define RZB_SDR_C_BAD_H (0x017C) 834 + #define RZB_SDR_C_BAD_L (0x0180) 835 + #define RZB_SDR_C_SAD_H (0x0184) 836 + #define RZB_SDR_C_SAD_L (0x0188) 837 + 838 + #define RZB_SDR_C_PTR_S (0x0190) 839 + #define RZB_SDR_C_PTR_E (0x0194) 840 + 841 + /* Shared Bitmasks between RZA & RZB */ 842 + #define RSZ_EN_EN (1 << 0) 843 + 844 + #define RSZ_420_CEN (1 << 1) 845 + #define RSZ_420_YEN (1 << 0) 846 + 847 + #define RSZ_I_VPS_MASK (0x1FFF) 848 + 849 + #define RSZ_I_HPS_MASK (0x1FFF) 850 + 851 + #define RSZ_O_VSZ_MASK (0x1FFF) 852 + 853 + #define RSZ_O_HSZ_MASK (0x1FFE) 854 + 855 + #define RSZ_V_PHS_Y_MASK (0x3FFF) 856 + 857 + #define RSZ_V_PHS_C_MASK (0x3FFF) 858 + 859 + #define RSZ_V_DIF_MASK (0x3FFF) 860 + 861 + #define RSZ_V_TYP_C (1 << 1) 862 + #define RSZ_V_TYP_Y (1 << 0) 863 + 864 + #define RSZ_V_LPF_C_MASK (0x3F << 6) 865 + #define RSZ_V_LPF_C_SHIFT 6 866 + #define RSZ_V_LPF_Y_MASK (0x3F << 0) 867 + #define RSZ_V_LPF_Y_SHIFT 0 868 + 869 + #define RSZ_H_PHS_MASK (0x3FFF) 870 + 871 + #define RSZ_H_DIF_MASK (0x3FFF) 872 + 873 + #define RSZ_H_TYP_C (1 << 1) 874 + #define RSZ_H_TYP_Y (1 << 0) 875 + 876 + #define RSZ_H_LPF_C_MASK (0x3F << 6) 877 + #define RSZ_H_LPF_C_SHIFT 6 878 + #define RSZ_H_LPF_Y_MASK (0x3F << 0) 879 + #define RSZ_H_LPF_Y_SHIFT 0 880 + 881 + #define RSZ_DWN_EN_DWN_EN (1 << 0) 882 + 883 + #endif /* _OMAP4_ISS_REGS_H_ */
+65
include/media/omap4iss.h
··· 1 + #ifndef ARCH_ARM_PLAT_OMAP4_ISS_H 2 + #define ARCH_ARM_PLAT_OMAP4_ISS_H 3 + 4 + #include <linux/i2c.h> 5 + 6 + struct iss_device; 7 + 8 + enum iss_interface_type { 9 + ISS_INTERFACE_CSI2A_PHY1, 10 + ISS_INTERFACE_CSI2B_PHY2, 11 + }; 12 + 13 + /** 14 + * struct iss_csiphy_lane: CSI2 lane position and polarity 15 + * @pos: position of the lane 16 + * @pol: polarity of the lane 17 + */ 18 + struct iss_csiphy_lane { 19 + u8 pos; 20 + u8 pol; 21 + }; 22 + 23 + #define ISS_CSIPHY1_NUM_DATA_LANES 4 24 + #define ISS_CSIPHY2_NUM_DATA_LANES 1 25 + 26 + /** 27 + * struct iss_csiphy_lanes_cfg - CSI2 lane configuration 28 + * @data: Configuration of one or two data lanes 29 + * @clk: Clock lane configuration 30 + */ 31 + struct iss_csiphy_lanes_cfg { 32 + struct iss_csiphy_lane data[ISS_CSIPHY1_NUM_DATA_LANES]; 33 + struct iss_csiphy_lane clk; 34 + }; 35 + 36 + /** 37 + * struct iss_csi2_platform_data - CSI2 interface platform data 38 + * @crc: Enable the cyclic redundancy check 39 + * @vpclk_div: Video port output clock control 40 + */ 41 + struct iss_csi2_platform_data { 42 + unsigned crc:1; 43 + unsigned vpclk_div:2; 44 + struct iss_csiphy_lanes_cfg lanecfg; 45 + }; 46 + 47 + struct iss_subdev_i2c_board_info { 48 + struct i2c_board_info *board_info; 49 + int i2c_adapter_id; 50 + }; 51 + 52 + struct iss_v4l2_subdevs_group { 53 + struct iss_subdev_i2c_board_info *subdevs; 54 + enum iss_interface_type interface; 55 + union { 56 + struct iss_csi2_platform_data csi2; 57 + } bus; /* gcc < 4.6.0 chokes on anonymous union initializers */ 58 + }; 59 + 60 + struct iss_platform_data { 61 + struct iss_v4l2_subdevs_group *subdevs; 62 + void (*set_constraints)(struct iss_device *iss, bool enable); 63 + }; 64 + 65 + #endif