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/mfd/syscon.h> 21#include <linux/module.h> 22#include <linux/platform_device.h> 23#include <linux/slab.h> 24#include <linux/sched.h> 25#include <linux/vmalloc.h> 26 27#include <media/v4l2-common.h> 28#include <media/v4l2-device.h> 29#include <media/v4l2-ctrls.h> 30 31#include "iss.h" 32#include "iss_regs.h" 33 34#define ISS_PRINT_REGISTER(iss, name)\ 35 dev_dbg(iss->dev, "###ISS " #name "=0x%08x\n", \ 36 iss_reg_read(iss, OMAP4_ISS_MEM_TOP, ISS_##name)) 37 38static void iss_print_status(struct iss_device *iss) 39{ 40 dev_dbg(iss->dev, "-------------ISS HL Register dump-------------\n"); 41 42 ISS_PRINT_REGISTER(iss, HL_REVISION); 43 ISS_PRINT_REGISTER(iss, HL_SYSCONFIG); 44 ISS_PRINT_REGISTER(iss, HL_IRQSTATUS(5)); 45 ISS_PRINT_REGISTER(iss, HL_IRQENABLE_SET(5)); 46 ISS_PRINT_REGISTER(iss, HL_IRQENABLE_CLR(5)); 47 ISS_PRINT_REGISTER(iss, CTRL); 48 ISS_PRINT_REGISTER(iss, CLKCTRL); 49 ISS_PRINT_REGISTER(iss, CLKSTAT); 50 51 dev_dbg(iss->dev, "-----------------------------------------------\n"); 52} 53 54/* 55 * omap4iss_flush - Post pending L3 bus writes by doing a register readback 56 * @iss: OMAP4 ISS device 57 * 58 * In order to force posting of pending writes, we need to write and 59 * readback the same register, in this case the revision register. 60 * 61 * See this link for reference: 62 * http://www.mail-archive.com/linux-omap@vger.kernel.org/msg08149.html 63 */ 64void omap4iss_flush(struct iss_device *iss) 65{ 66 iss_reg_write(iss, OMAP4_ISS_MEM_TOP, ISS_HL_REVISION, 0); 67 iss_reg_read(iss, OMAP4_ISS_MEM_TOP, ISS_HL_REVISION); 68} 69 70/* 71 * iss_isp_enable_interrupts - Enable ISS ISP interrupts. 72 * @iss: OMAP4 ISS device 73 */ 74static void omap4iss_isp_enable_interrupts(struct iss_device *iss) 75{ 76 static const u32 isp_irq = ISP5_IRQ_OCP_ERR | 77 ISP5_IRQ_RSZ_FIFO_IN_BLK_ERR | 78 ISP5_IRQ_RSZ_FIFO_OVF | 79 ISP5_IRQ_RSZ_INT_DMA | 80 ISP5_IRQ_ISIF_INT(0); 81 82 /* Enable ISP interrupts */ 83 iss_reg_write(iss, OMAP4_ISS_MEM_ISP_SYS1, ISP5_IRQSTATUS(0), isp_irq); 84 iss_reg_write(iss, OMAP4_ISS_MEM_ISP_SYS1, ISP5_IRQENABLE_SET(0), 85 isp_irq); 86} 87 88/* 89 * iss_isp_disable_interrupts - Disable ISS interrupts. 90 * @iss: OMAP4 ISS device 91 */ 92static void omap4iss_isp_disable_interrupts(struct iss_device *iss) 93{ 94 iss_reg_write(iss, OMAP4_ISS_MEM_ISP_SYS1, ISP5_IRQENABLE_CLR(0), ~0); 95} 96 97/* 98 * iss_enable_interrupts - Enable ISS interrupts. 99 * @iss: OMAP4 ISS device 100 */ 101static void iss_enable_interrupts(struct iss_device *iss) 102{ 103 static const u32 hl_irq = ISS_HL_IRQ_CSIA | ISS_HL_IRQ_CSIB 104 | ISS_HL_IRQ_ISP(0); 105 106 /* Enable HL interrupts */ 107 iss_reg_write(iss, OMAP4_ISS_MEM_TOP, ISS_HL_IRQSTATUS(5), hl_irq); 108 iss_reg_write(iss, OMAP4_ISS_MEM_TOP, ISS_HL_IRQENABLE_SET(5), hl_irq); 109 110 if (iss->regs[OMAP4_ISS_MEM_ISP_SYS1]) 111 omap4iss_isp_enable_interrupts(iss); 112} 113 114/* 115 * iss_disable_interrupts - Disable ISS interrupts. 116 * @iss: OMAP4 ISS device 117 */ 118static void iss_disable_interrupts(struct iss_device *iss) 119{ 120 if (iss->regs[OMAP4_ISS_MEM_ISP_SYS1]) 121 omap4iss_isp_disable_interrupts(iss); 122 123 iss_reg_write(iss, OMAP4_ISS_MEM_TOP, ISS_HL_IRQENABLE_CLR(5), ~0); 124} 125 126int omap4iss_get_external_info(struct iss_pipeline *pipe, 127 struct media_link *link) 128{ 129 struct iss_device *iss = 130 container_of(pipe, struct iss_video, pipe)->iss; 131 struct v4l2_subdev_format fmt; 132 struct v4l2_ctrl *ctrl; 133 int ret; 134 135 if (!pipe->external) 136 return 0; 137 138 if (pipe->external_rate) 139 return 0; 140 141 memset(&fmt, 0, sizeof(fmt)); 142 143 fmt.pad = link->source->index; 144 fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE; 145 ret = v4l2_subdev_call(media_entity_to_v4l2_subdev(link->sink->entity), 146 pad, get_fmt, NULL, &fmt); 147 if (ret < 0) 148 return -EPIPE; 149 150 pipe->external_bpp = omap4iss_video_format_info(fmt.format.code)->bpp; 151 152 ctrl = v4l2_ctrl_find(pipe->external->ctrl_handler, 153 V4L2_CID_PIXEL_RATE); 154 if (ctrl == NULL) { 155 dev_warn(iss->dev, "no pixel rate control in subdev %s\n", 156 pipe->external->name); 157 return -EPIPE; 158 } 159 160 pipe->external_rate = v4l2_ctrl_g_ctrl_int64(ctrl); 161 162 return 0; 163} 164 165/* 166 * Configure the bridge. Valid inputs are 167 * 168 * IPIPEIF_INPUT_CSI2A: CSI2a receiver 169 * IPIPEIF_INPUT_CSI2B: CSI2b receiver 170 * 171 * The bridge and lane shifter are configured according to the selected input 172 * and the ISP platform data. 173 */ 174void omap4iss_configure_bridge(struct iss_device *iss, 175 enum ipipeif_input_entity input) 176{ 177 u32 issctrl_val; 178 u32 isp5ctrl_val; 179 180 issctrl_val = iss_reg_read(iss, OMAP4_ISS_MEM_TOP, ISS_CTRL); 181 issctrl_val &= ~ISS_CTRL_INPUT_SEL_MASK; 182 issctrl_val &= ~ISS_CTRL_CLK_DIV_MASK; 183 184 isp5ctrl_val = iss_reg_read(iss, OMAP4_ISS_MEM_ISP_SYS1, ISP5_CTRL); 185 186 switch (input) { 187 case IPIPEIF_INPUT_CSI2A: 188 issctrl_val |= ISS_CTRL_INPUT_SEL_CSI2A; 189 break; 190 191 case IPIPEIF_INPUT_CSI2B: 192 issctrl_val |= ISS_CTRL_INPUT_SEL_CSI2B; 193 break; 194 195 default: 196 return; 197 } 198 199 issctrl_val |= ISS_CTRL_SYNC_DETECT_VS_RAISING; 200 201 isp5ctrl_val |= ISP5_CTRL_VD_PULSE_EXT | ISP5_CTRL_PSYNC_CLK_SEL | 202 ISP5_CTRL_SYNC_ENABLE; 203 204 iss_reg_write(iss, OMAP4_ISS_MEM_TOP, ISS_CTRL, issctrl_val); 205 iss_reg_write(iss, OMAP4_ISS_MEM_ISP_SYS1, ISP5_CTRL, isp5ctrl_val); 206} 207 208#ifdef ISS_ISR_DEBUG 209static void iss_isr_dbg(struct iss_device *iss, u32 irqstatus) 210{ 211 static const char * const name[] = { 212 "ISP_0", 213 "ISP_1", 214 "ISP_2", 215 "ISP_3", 216 "CSIA", 217 "CSIB", 218 "CCP2_0", 219 "CCP2_1", 220 "CCP2_2", 221 "CCP2_3", 222 "CBUFF", 223 "BTE", 224 "SIMCOP_0", 225 "SIMCOP_1", 226 "SIMCOP_2", 227 "SIMCOP_3", 228 "CCP2_8", 229 "HS_VS", 230 "18", 231 "19", 232 "20", 233 "21", 234 "22", 235 "23", 236 "24", 237 "25", 238 "26", 239 "27", 240 "28", 241 "29", 242 "30", 243 "31", 244 }; 245 unsigned int i; 246 247 dev_dbg(iss->dev, "ISS IRQ: "); 248 249 for (i = 0; i < ARRAY_SIZE(name); i++) { 250 if ((1 << i) & irqstatus) 251 pr_cont("%s ", name[i]); 252 } 253 pr_cont("\n"); 254} 255 256static void iss_isp_isr_dbg(struct iss_device *iss, u32 irqstatus) 257{ 258 static const char * const name[] = { 259 "ISIF_0", 260 "ISIF_1", 261 "ISIF_2", 262 "ISIF_3", 263 "IPIPEREQ", 264 "IPIPELAST_PIX", 265 "IPIPEDMA", 266 "IPIPEBSC", 267 "IPIPEHST", 268 "IPIPEIF", 269 "AEW", 270 "AF", 271 "H3A", 272 "RSZ_REG", 273 "RSZ_LAST_PIX", 274 "RSZ_DMA", 275 "RSZ_CYC_RZA", 276 "RSZ_CYC_RZB", 277 "RSZ_FIFO_OVF", 278 "RSZ_FIFO_IN_BLK_ERR", 279 "20", 280 "21", 281 "RSZ_EOF0", 282 "RSZ_EOF1", 283 "H3A_EOF", 284 "IPIPE_EOF", 285 "26", 286 "IPIPE_DPC_INI", 287 "IPIPE_DPC_RNEW0", 288 "IPIPE_DPC_RNEW1", 289 "30", 290 "OCP_ERR", 291 }; 292 unsigned int i; 293 294 dev_dbg(iss->dev, "ISP IRQ: "); 295 296 for (i = 0; i < ARRAY_SIZE(name); i++) { 297 if ((1 << i) & irqstatus) 298 pr_cont("%s ", name[i]); 299 } 300 pr_cont("\n"); 301} 302#endif 303 304/* 305 * iss_isr - Interrupt Service Routine for ISS module. 306 * @irq: Not used currently. 307 * @_iss: Pointer to the OMAP4 ISS device 308 * 309 * Handles the corresponding callback if plugged in. 310 * 311 * Returns IRQ_HANDLED when IRQ was correctly handled, or IRQ_NONE when the 312 * IRQ wasn't handled. 313 */ 314static irqreturn_t iss_isr(int irq, void *_iss) 315{ 316 static const u32 ipipeif_events = ISP5_IRQ_IPIPEIF_IRQ | 317 ISP5_IRQ_ISIF_INT(0); 318 static const u32 resizer_events = ISP5_IRQ_RSZ_FIFO_IN_BLK_ERR | 319 ISP5_IRQ_RSZ_FIFO_OVF | 320 ISP5_IRQ_RSZ_INT_DMA; 321 struct iss_device *iss = _iss; 322 u32 irqstatus; 323 324 irqstatus = iss_reg_read(iss, OMAP4_ISS_MEM_TOP, ISS_HL_IRQSTATUS(5)); 325 iss_reg_write(iss, OMAP4_ISS_MEM_TOP, ISS_HL_IRQSTATUS(5), irqstatus); 326 327 if (irqstatus & ISS_HL_IRQ_CSIA) 328 omap4iss_csi2_isr(&iss->csi2a); 329 330 if (irqstatus & ISS_HL_IRQ_CSIB) 331 omap4iss_csi2_isr(&iss->csi2b); 332 333 if (irqstatus & ISS_HL_IRQ_ISP(0)) { 334 u32 isp_irqstatus = iss_reg_read(iss, OMAP4_ISS_MEM_ISP_SYS1, 335 ISP5_IRQSTATUS(0)); 336 iss_reg_write(iss, OMAP4_ISS_MEM_ISP_SYS1, ISP5_IRQSTATUS(0), 337 isp_irqstatus); 338 339 if (isp_irqstatus & ISP5_IRQ_OCP_ERR) 340 dev_dbg(iss->dev, "ISP5 OCP Error!\n"); 341 342 if (isp_irqstatus & ipipeif_events) { 343 omap4iss_ipipeif_isr(&iss->ipipeif, 344 isp_irqstatus & ipipeif_events); 345 } 346 347 if (isp_irqstatus & resizer_events) 348 omap4iss_resizer_isr(&iss->resizer, 349 isp_irqstatus & resizer_events); 350 351#ifdef ISS_ISR_DEBUG 352 iss_isp_isr_dbg(iss, isp_irqstatus); 353#endif 354 } 355 356 omap4iss_flush(iss); 357 358#ifdef ISS_ISR_DEBUG 359 iss_isr_dbg(iss, irqstatus); 360#endif 361 362 return IRQ_HANDLED; 363} 364 365/* ----------------------------------------------------------------------------- 366 * Pipeline power management 367 * 368 * Entities must be powered up when part of a pipeline that contains at least 369 * one open video device node. 370 * 371 * To achieve this use the entity use_count field to track the number of users. 372 * For entities corresponding to video device nodes the use_count field stores 373 * the users count of the node. For entities corresponding to subdevs the 374 * use_count field stores the total number of users of all video device nodes 375 * in the pipeline. 376 * 377 * The omap4iss_pipeline_pm_use() function must be called in the open() and 378 * close() handlers of video device nodes. It increments or decrements the use 379 * count of all subdev entities in the pipeline. 380 * 381 * To react to link management on powered pipelines, the link setup notification 382 * callback updates the use count of all entities in the source and sink sides 383 * of the link. 384 */ 385 386/* 387 * iss_pipeline_pm_use_count - Count the number of users of a pipeline 388 * @entity: The entity 389 * 390 * Return the total number of users of all video device nodes in the pipeline. 391 */ 392static int iss_pipeline_pm_use_count(struct media_entity *entity) 393{ 394 struct media_entity_graph graph; 395 int use = 0; 396 397 media_entity_graph_walk_start(&graph, entity); 398 399 while ((entity = media_entity_graph_walk_next(&graph))) { 400 if (media_entity_type(entity) == MEDIA_ENT_T_DEVNODE) 401 use += entity->use_count; 402 } 403 404 return use; 405} 406 407/* 408 * iss_pipeline_pm_power_one - Apply power change to an entity 409 * @entity: The entity 410 * @change: Use count change 411 * 412 * Change the entity use count by @change. If the entity is a subdev update its 413 * power state by calling the core::s_power operation when the use count goes 414 * from 0 to != 0 or from != 0 to 0. 415 * 416 * Return 0 on success or a negative error code on failure. 417 */ 418static int iss_pipeline_pm_power_one(struct media_entity *entity, int change) 419{ 420 struct v4l2_subdev *subdev; 421 422 subdev = media_entity_type(entity) == MEDIA_ENT_T_V4L2_SUBDEV 423 ? media_entity_to_v4l2_subdev(entity) : NULL; 424 425 if (entity->use_count == 0 && change > 0 && subdev != NULL) { 426 int ret; 427 428 ret = v4l2_subdev_call(subdev, core, s_power, 1); 429 if (ret < 0 && ret != -ENOIOCTLCMD) 430 return ret; 431 } 432 433 entity->use_count += change; 434 WARN_ON(entity->use_count < 0); 435 436 if (entity->use_count == 0 && change < 0 && subdev != NULL) 437 v4l2_subdev_call(subdev, core, s_power, 0); 438 439 return 0; 440} 441 442/* 443 * iss_pipeline_pm_power - Apply power change to all entities in a pipeline 444 * @entity: The entity 445 * @change: Use count change 446 * 447 * Walk the pipeline to update the use count and the power state of all non-node 448 * entities. 449 * 450 * Return 0 on success or a negative error code on failure. 451 */ 452static int iss_pipeline_pm_power(struct media_entity *entity, int change) 453{ 454 struct media_entity_graph graph; 455 struct media_entity *first = entity; 456 int ret = 0; 457 458 if (!change) 459 return 0; 460 461 media_entity_graph_walk_start(&graph, entity); 462 463 while (!ret && (entity = media_entity_graph_walk_next(&graph))) 464 if (media_entity_type(entity) != MEDIA_ENT_T_DEVNODE) 465 ret = iss_pipeline_pm_power_one(entity, change); 466 467 if (!ret) 468 return 0; 469 470 media_entity_graph_walk_start(&graph, first); 471 472 while ((first = media_entity_graph_walk_next(&graph)) 473 && first != entity) 474 if (media_entity_type(first) != MEDIA_ENT_T_DEVNODE) 475 iss_pipeline_pm_power_one(first, -change); 476 477 return ret; 478} 479 480/* 481 * omap4iss_pipeline_pm_use - Update the use count of an entity 482 * @entity: The entity 483 * @use: Use (1) or stop using (0) the entity 484 * 485 * Update the use count of all entities in the pipeline and power entities on or 486 * off accordingly. 487 * 488 * Return 0 on success or a negative error code on failure. Powering entities 489 * off is assumed to never fail. No failure can occur when the use parameter is 490 * set to 0. 491 */ 492int omap4iss_pipeline_pm_use(struct media_entity *entity, int use) 493{ 494 int change = use ? 1 : -1; 495 int ret; 496 497 mutex_lock(&entity->parent->graph_mutex); 498 499 /* Apply use count to node. */ 500 entity->use_count += change; 501 WARN_ON(entity->use_count < 0); 502 503 /* Apply power change to connected non-nodes. */ 504 ret = iss_pipeline_pm_power(entity, change); 505 if (ret < 0) 506 entity->use_count -= change; 507 508 mutex_unlock(&entity->parent->graph_mutex); 509 510 return ret; 511} 512 513/* 514 * iss_pipeline_link_notify - Link management notification callback 515 * @link: The link 516 * @flags: New link flags that will be applied 517 * 518 * React to link management on powered pipelines by updating the use count of 519 * all entities in the source and sink sides of the link. Entities are powered 520 * on or off accordingly. 521 * 522 * Return 0 on success or a negative error code on failure. Powering entities 523 * off is assumed to never fail. This function will not fail for disconnection 524 * events. 525 */ 526static int iss_pipeline_link_notify(struct media_link *link, u32 flags, 527 unsigned int notification) 528{ 529 struct media_entity *source = link->source->entity; 530 struct media_entity *sink = link->sink->entity; 531 int source_use = iss_pipeline_pm_use_count(source); 532 int sink_use = iss_pipeline_pm_use_count(sink); 533 int ret; 534 535 if (notification == MEDIA_DEV_NOTIFY_POST_LINK_CH && 536 !(link->flags & MEDIA_LNK_FL_ENABLED)) { 537 /* Powering off entities is assumed to never fail. */ 538 iss_pipeline_pm_power(source, -sink_use); 539 iss_pipeline_pm_power(sink, -source_use); 540 return 0; 541 } 542 543 if (notification == MEDIA_DEV_NOTIFY_POST_LINK_CH && 544 (flags & MEDIA_LNK_FL_ENABLED)) { 545 ret = iss_pipeline_pm_power(source, sink_use); 546 if (ret < 0) 547 return ret; 548 549 ret = iss_pipeline_pm_power(sink, source_use); 550 if (ret < 0) 551 iss_pipeline_pm_power(source, -sink_use); 552 553 return ret; 554 } 555 556 return 0; 557} 558 559/* ----------------------------------------------------------------------------- 560 * Pipeline stream management 561 */ 562 563/* 564 * iss_pipeline_disable - Disable streaming on a pipeline 565 * @pipe: ISS pipeline 566 * @until: entity at which to stop pipeline walk 567 * 568 * Walk the entities chain starting at the pipeline output video node and stop 569 * all modules in the chain. Wait synchronously for the modules to be stopped if 570 * necessary. 571 * 572 * If the until argument isn't NULL, stop the pipeline walk when reaching the 573 * until entity. This is used to disable a partially started pipeline due to a 574 * subdev start error. 575 */ 576static int iss_pipeline_disable(struct iss_pipeline *pipe, 577 struct media_entity *until) 578{ 579 struct iss_device *iss = pipe->output->iss; 580 struct media_entity *entity; 581 struct media_pad *pad; 582 struct v4l2_subdev *subdev; 583 int failure = 0; 584 int ret; 585 586 entity = &pipe->output->video.entity; 587 while (1) { 588 pad = &entity->pads[0]; 589 if (!(pad->flags & MEDIA_PAD_FL_SINK)) 590 break; 591 592 pad = media_entity_remote_pad(pad); 593 if (pad == NULL || 594 media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV) 595 break; 596 597 entity = pad->entity; 598 if (entity == until) 599 break; 600 601 subdev = media_entity_to_v4l2_subdev(entity); 602 ret = v4l2_subdev_call(subdev, video, s_stream, 0); 603 if (ret < 0) { 604 dev_dbg(iss->dev, "%s: module stop timeout.\n", 605 subdev->name); 606 /* If the entity failed to stopped, assume it has 607 * crashed. Mark it as such, the ISS will be reset when 608 * applications will release it. 609 */ 610 iss->crashed |= 1U << subdev->entity.id; 611 failure = -ETIMEDOUT; 612 } 613 } 614 615 return failure; 616} 617 618/* 619 * iss_pipeline_enable - Enable streaming on a pipeline 620 * @pipe: ISS pipeline 621 * @mode: Stream mode (single shot or continuous) 622 * 623 * Walk the entities chain starting at the pipeline output video node and start 624 * all modules in the chain in the given mode. 625 * 626 * Return 0 if successful, or the return value of the failed video::s_stream 627 * operation otherwise. 628 */ 629static int iss_pipeline_enable(struct iss_pipeline *pipe, 630 enum iss_pipeline_stream_state mode) 631{ 632 struct iss_device *iss = pipe->output->iss; 633 struct media_entity *entity; 634 struct media_pad *pad; 635 struct v4l2_subdev *subdev; 636 unsigned long flags; 637 int ret; 638 639 /* If one of the entities in the pipeline has crashed it will not work 640 * properly. Refuse to start streaming in that case. This check must be 641 * performed before the loop below to avoid starting entities if the 642 * pipeline won't start anyway (those entities would then likely fail to 643 * stop, making the problem worse). 644 */ 645 if (pipe->entities & iss->crashed) 646 return -EIO; 647 648 spin_lock_irqsave(&pipe->lock, flags); 649 pipe->state &= ~(ISS_PIPELINE_IDLE_INPUT | ISS_PIPELINE_IDLE_OUTPUT); 650 spin_unlock_irqrestore(&pipe->lock, flags); 651 652 pipe->do_propagation = false; 653 654 entity = &pipe->output->video.entity; 655 while (1) { 656 pad = &entity->pads[0]; 657 if (!(pad->flags & MEDIA_PAD_FL_SINK)) 658 break; 659 660 pad = media_entity_remote_pad(pad); 661 if (pad == NULL || 662 media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV) 663 break; 664 665 entity = pad->entity; 666 subdev = media_entity_to_v4l2_subdev(entity); 667 668 ret = v4l2_subdev_call(subdev, video, s_stream, mode); 669 if (ret < 0 && ret != -ENOIOCTLCMD) { 670 iss_pipeline_disable(pipe, entity); 671 return ret; 672 } 673 674 if (subdev == &iss->csi2a.subdev || 675 subdev == &iss->csi2b.subdev) 676 pipe->do_propagation = true; 677 } 678 679 iss_print_status(pipe->output->iss); 680 return 0; 681} 682 683/* 684 * omap4iss_pipeline_set_stream - Enable/disable streaming on a pipeline 685 * @pipe: ISS pipeline 686 * @state: Stream state (stopped, single shot or continuous) 687 * 688 * Set the pipeline to the given stream state. Pipelines can be started in 689 * single-shot or continuous mode. 690 * 691 * Return 0 if successful, or the return value of the failed video::s_stream 692 * operation otherwise. The pipeline state is not updated when the operation 693 * fails, except when stopping the pipeline. 694 */ 695int omap4iss_pipeline_set_stream(struct iss_pipeline *pipe, 696 enum iss_pipeline_stream_state state) 697{ 698 int ret; 699 700 if (state == ISS_PIPELINE_STREAM_STOPPED) 701 ret = iss_pipeline_disable(pipe, NULL); 702 else 703 ret = iss_pipeline_enable(pipe, state); 704 705 if (ret == 0 || state == ISS_PIPELINE_STREAM_STOPPED) 706 pipe->stream_state = state; 707 708 return ret; 709} 710 711/* 712 * omap4iss_pipeline_cancel_stream - Cancel stream on a pipeline 713 * @pipe: ISS pipeline 714 * 715 * Cancelling a stream mark all buffers on all video nodes in the pipeline as 716 * erroneous and makes sure no new buffer can be queued. This function is called 717 * when a fatal error that prevents any further operation on the pipeline 718 * occurs. 719 */ 720void omap4iss_pipeline_cancel_stream(struct iss_pipeline *pipe) 721{ 722 if (pipe->input) 723 omap4iss_video_cancel_stream(pipe->input); 724 if (pipe->output) 725 omap4iss_video_cancel_stream(pipe->output); 726} 727 728/* 729 * iss_pipeline_is_last - Verify if entity has an enabled link to the output 730 * video node 731 * @me: ISS module's media entity 732 * 733 * Returns 1 if the entity has an enabled link to the output video node or 0 734 * otherwise. It's true only while pipeline can have no more than one output 735 * node. 736 */ 737static int iss_pipeline_is_last(struct media_entity *me) 738{ 739 struct iss_pipeline *pipe; 740 struct media_pad *pad; 741 742 if (!me->pipe) 743 return 0; 744 pipe = to_iss_pipeline(me); 745 if (pipe->stream_state == ISS_PIPELINE_STREAM_STOPPED) 746 return 0; 747 pad = media_entity_remote_pad(&pipe->output->pad); 748 return pad->entity == me; 749} 750 751static int iss_reset(struct iss_device *iss) 752{ 753 unsigned int timeout; 754 755 iss_reg_set(iss, OMAP4_ISS_MEM_TOP, ISS_HL_SYSCONFIG, 756 ISS_HL_SYSCONFIG_SOFTRESET); 757 758 timeout = iss_poll_condition_timeout( 759 !(iss_reg_read(iss, OMAP4_ISS_MEM_TOP, ISS_HL_SYSCONFIG) & 760 ISS_HL_SYSCONFIG_SOFTRESET), 1000, 10, 100); 761 if (timeout) { 762 dev_err(iss->dev, "ISS reset timeout\n"); 763 return -ETIMEDOUT; 764 } 765 766 iss->crashed = 0; 767 return 0; 768} 769 770static int iss_isp_reset(struct iss_device *iss) 771{ 772 unsigned int timeout; 773 774 /* Fist, ensure that the ISP is IDLE (no transactions happening) */ 775 iss_reg_update(iss, OMAP4_ISS_MEM_ISP_SYS1, ISP5_SYSCONFIG, 776 ISP5_SYSCONFIG_STANDBYMODE_MASK, 777 ISP5_SYSCONFIG_STANDBYMODE_SMART); 778 779 iss_reg_set(iss, OMAP4_ISS_MEM_ISP_SYS1, ISP5_CTRL, ISP5_CTRL_MSTANDBY); 780 781 timeout = iss_poll_condition_timeout( 782 iss_reg_read(iss, OMAP4_ISS_MEM_ISP_SYS1, ISP5_CTRL) & 783 ISP5_CTRL_MSTANDBY_WAIT, 1000000, 1000, 1500); 784 if (timeout) { 785 dev_err(iss->dev, "ISP5 standby timeout\n"); 786 return -ETIMEDOUT; 787 } 788 789 /* Now finally, do the reset */ 790 iss_reg_set(iss, OMAP4_ISS_MEM_ISP_SYS1, ISP5_SYSCONFIG, 791 ISP5_SYSCONFIG_SOFTRESET); 792 793 timeout = iss_poll_condition_timeout( 794 !(iss_reg_read(iss, OMAP4_ISS_MEM_ISP_SYS1, ISP5_SYSCONFIG) & 795 ISP5_SYSCONFIG_SOFTRESET), 1000000, 1000, 1500); 796 if (timeout) { 797 dev_err(iss->dev, "ISP5 reset timeout\n"); 798 return -ETIMEDOUT; 799 } 800 801 return 0; 802} 803 804/* 805 * iss_module_sync_idle - Helper to sync module with its idle state 806 * @me: ISS submodule's media entity 807 * @wait: ISS submodule's wait queue for streamoff/interrupt synchronization 808 * @stopping: flag which tells module wants to stop 809 * 810 * This function checks if ISS submodule needs to wait for next interrupt. If 811 * yes, makes the caller to sleep while waiting for such event. 812 */ 813int omap4iss_module_sync_idle(struct media_entity *me, wait_queue_head_t *wait, 814 atomic_t *stopping) 815{ 816 struct iss_pipeline *pipe = to_iss_pipeline(me); 817 struct iss_video *video = pipe->output; 818 unsigned long flags; 819 820 if (pipe->stream_state == ISS_PIPELINE_STREAM_STOPPED || 821 (pipe->stream_state == ISS_PIPELINE_STREAM_SINGLESHOT && 822 !iss_pipeline_ready(pipe))) 823 return 0; 824 825 /* 826 * atomic_set() doesn't include memory barrier on ARM platform for SMP 827 * scenario. We'll call it here to avoid race conditions. 828 */ 829 atomic_set(stopping, 1); 830 smp_wmb(); 831 832 /* 833 * If module is the last one, it's writing to memory. In this case, 834 * it's necessary to check if the module is already paused due to 835 * DMA queue underrun or if it has to wait for next interrupt to be 836 * idle. 837 * If it isn't the last one, the function won't sleep but *stopping 838 * will still be set to warn next submodule caller's interrupt the 839 * module wants to be idle. 840 */ 841 if (!iss_pipeline_is_last(me)) 842 return 0; 843 844 spin_lock_irqsave(&video->qlock, flags); 845 if (video->dmaqueue_flags & ISS_VIDEO_DMAQUEUE_UNDERRUN) { 846 spin_unlock_irqrestore(&video->qlock, flags); 847 atomic_set(stopping, 0); 848 smp_wmb(); 849 return 0; 850 } 851 spin_unlock_irqrestore(&video->qlock, flags); 852 if (!wait_event_timeout(*wait, !atomic_read(stopping), 853 msecs_to_jiffies(1000))) { 854 atomic_set(stopping, 0); 855 smp_wmb(); 856 return -ETIMEDOUT; 857 } 858 859 return 0; 860} 861 862/* 863 * omap4iss_module_sync_is_stopped - Helper to verify if module was stopping 864 * @wait: ISS submodule's wait queue for streamoff/interrupt synchronization 865 * @stopping: flag which tells module wants to stop 866 * 867 * This function checks if ISS submodule was stopping. In case of yes, it 868 * notices the caller by setting stopping to 0 and waking up the wait queue. 869 * Returns 1 if it was stopping or 0 otherwise. 870 */ 871int omap4iss_module_sync_is_stopping(wait_queue_head_t *wait, 872 atomic_t *stopping) 873{ 874 if (atomic_cmpxchg(stopping, 1, 0)) { 875 wake_up(wait); 876 return 1; 877 } 878 879 return 0; 880} 881 882/* -------------------------------------------------------------------------- 883 * Clock management 884 */ 885 886#define ISS_CLKCTRL_MASK (ISS_CLKCTRL_CSI2_A |\ 887 ISS_CLKCTRL_CSI2_B |\ 888 ISS_CLKCTRL_ISP) 889 890static int __iss_subclk_update(struct iss_device *iss) 891{ 892 u32 clk = 0; 893 int ret = 0, timeout = 1000; 894 895 if (iss->subclk_resources & OMAP4_ISS_SUBCLK_CSI2_A) 896 clk |= ISS_CLKCTRL_CSI2_A; 897 898 if (iss->subclk_resources & OMAP4_ISS_SUBCLK_CSI2_B) 899 clk |= ISS_CLKCTRL_CSI2_B; 900 901 if (iss->subclk_resources & OMAP4_ISS_SUBCLK_ISP) 902 clk |= ISS_CLKCTRL_ISP; 903 904 iss_reg_update(iss, OMAP4_ISS_MEM_TOP, ISS_CLKCTRL, 905 ISS_CLKCTRL_MASK, clk); 906 907 /* Wait for HW assertion */ 908 while (--timeout > 0) { 909 udelay(1); 910 if ((iss_reg_read(iss, OMAP4_ISS_MEM_TOP, ISS_CLKSTAT) & 911 ISS_CLKCTRL_MASK) == clk) 912 break; 913 } 914 915 if (!timeout) 916 ret = -EBUSY; 917 918 return ret; 919} 920 921int omap4iss_subclk_enable(struct iss_device *iss, 922 enum iss_subclk_resource res) 923{ 924 iss->subclk_resources |= res; 925 926 return __iss_subclk_update(iss); 927} 928 929int omap4iss_subclk_disable(struct iss_device *iss, 930 enum iss_subclk_resource res) 931{ 932 iss->subclk_resources &= ~res; 933 934 return __iss_subclk_update(iss); 935} 936 937#define ISS_ISP5_CLKCTRL_MASK (ISP5_CTRL_BL_CLK_ENABLE |\ 938 ISP5_CTRL_ISIF_CLK_ENABLE |\ 939 ISP5_CTRL_H3A_CLK_ENABLE |\ 940 ISP5_CTRL_RSZ_CLK_ENABLE |\ 941 ISP5_CTRL_IPIPE_CLK_ENABLE |\ 942 ISP5_CTRL_IPIPEIF_CLK_ENABLE) 943 944static void __iss_isp_subclk_update(struct iss_device *iss) 945{ 946 u32 clk = 0; 947 948 if (iss->isp_subclk_resources & OMAP4_ISS_ISP_SUBCLK_ISIF) 949 clk |= ISP5_CTRL_ISIF_CLK_ENABLE; 950 951 if (iss->isp_subclk_resources & OMAP4_ISS_ISP_SUBCLK_H3A) 952 clk |= ISP5_CTRL_H3A_CLK_ENABLE; 953 954 if (iss->isp_subclk_resources & OMAP4_ISS_ISP_SUBCLK_RSZ) 955 clk |= ISP5_CTRL_RSZ_CLK_ENABLE; 956 957 if (iss->isp_subclk_resources & OMAP4_ISS_ISP_SUBCLK_IPIPE) 958 clk |= ISP5_CTRL_IPIPE_CLK_ENABLE; 959 960 if (iss->isp_subclk_resources & OMAP4_ISS_ISP_SUBCLK_IPIPEIF) 961 clk |= ISP5_CTRL_IPIPEIF_CLK_ENABLE; 962 963 if (clk) 964 clk |= ISP5_CTRL_BL_CLK_ENABLE; 965 966 iss_reg_update(iss, OMAP4_ISS_MEM_ISP_SYS1, ISP5_CTRL, 967 ISS_ISP5_CLKCTRL_MASK, clk); 968} 969 970void omap4iss_isp_subclk_enable(struct iss_device *iss, 971 enum iss_isp_subclk_resource res) 972{ 973 iss->isp_subclk_resources |= res; 974 975 __iss_isp_subclk_update(iss); 976} 977 978void omap4iss_isp_subclk_disable(struct iss_device *iss, 979 enum iss_isp_subclk_resource res) 980{ 981 iss->isp_subclk_resources &= ~res; 982 983 __iss_isp_subclk_update(iss); 984} 985 986/* 987 * iss_enable_clocks - Enable ISS clocks 988 * @iss: OMAP4 ISS device 989 * 990 * Return 0 if successful, or clk_enable return value if any of tthem fails. 991 */ 992static int iss_enable_clocks(struct iss_device *iss) 993{ 994 int ret; 995 996 ret = clk_enable(iss->iss_fck); 997 if (ret) { 998 dev_err(iss->dev, "clk_enable iss_fck failed\n"); 999 return ret; 1000 } 1001 1002 ret = clk_enable(iss->iss_ctrlclk); 1003 if (ret) { 1004 dev_err(iss->dev, "clk_enable iss_ctrlclk failed\n"); 1005 clk_disable(iss->iss_fck); 1006 return ret; 1007 } 1008 1009 return 0; 1010} 1011 1012/* 1013 * iss_disable_clocks - Disable ISS clocks 1014 * @iss: OMAP4 ISS device 1015 */ 1016static void iss_disable_clocks(struct iss_device *iss) 1017{ 1018 clk_disable(iss->iss_ctrlclk); 1019 clk_disable(iss->iss_fck); 1020} 1021 1022static int iss_get_clocks(struct iss_device *iss) 1023{ 1024 iss->iss_fck = devm_clk_get(iss->dev, "iss_fck"); 1025 if (IS_ERR(iss->iss_fck)) { 1026 dev_err(iss->dev, "Unable to get iss_fck clock info\n"); 1027 return PTR_ERR(iss->iss_fck); 1028 } 1029 1030 iss->iss_ctrlclk = devm_clk_get(iss->dev, "iss_ctrlclk"); 1031 if (IS_ERR(iss->iss_ctrlclk)) { 1032 dev_err(iss->dev, "Unable to get iss_ctrlclk clock info\n"); 1033 return PTR_ERR(iss->iss_ctrlclk); 1034 } 1035 1036 return 0; 1037} 1038 1039/* 1040 * omap4iss_get - Acquire the ISS resource. 1041 * 1042 * Initializes the clocks for the first acquire. 1043 * 1044 * Increment the reference count on the ISS. If the first reference is taken, 1045 * enable clocks and power-up all submodules. 1046 * 1047 * Return a pointer to the ISS device structure, or NULL if an error occurred. 1048 */ 1049struct iss_device *omap4iss_get(struct iss_device *iss) 1050{ 1051 struct iss_device *__iss = iss; 1052 1053 if (iss == NULL) 1054 return NULL; 1055 1056 mutex_lock(&iss->iss_mutex); 1057 if (iss->ref_count > 0) 1058 goto out; 1059 1060 if (iss_enable_clocks(iss) < 0) { 1061 __iss = NULL; 1062 goto out; 1063 } 1064 1065 iss_enable_interrupts(iss); 1066 1067out: 1068 if (__iss != NULL) 1069 iss->ref_count++; 1070 mutex_unlock(&iss->iss_mutex); 1071 1072 return __iss; 1073} 1074 1075/* 1076 * omap4iss_put - Release the ISS 1077 * 1078 * Decrement the reference count on the ISS. If the last reference is released, 1079 * power-down all submodules, disable clocks and free temporary buffers. 1080 */ 1081void omap4iss_put(struct iss_device *iss) 1082{ 1083 if (iss == NULL) 1084 return; 1085 1086 mutex_lock(&iss->iss_mutex); 1087 BUG_ON(iss->ref_count == 0); 1088 if (--iss->ref_count == 0) { 1089 iss_disable_interrupts(iss); 1090 /* Reset the ISS if an entity has failed to stop. This is the 1091 * only way to recover from such conditions, although it would 1092 * be worth investigating whether resetting the ISP only can't 1093 * fix the problem in some cases. 1094 */ 1095 if (iss->crashed) 1096 iss_reset(iss); 1097 iss_disable_clocks(iss); 1098 } 1099 mutex_unlock(&iss->iss_mutex); 1100} 1101 1102static int iss_map_mem_resource(struct platform_device *pdev, 1103 struct iss_device *iss, 1104 enum iss_mem_resources res) 1105{ 1106 struct resource *mem; 1107 1108 mem = platform_get_resource(pdev, IORESOURCE_MEM, res); 1109 1110 iss->regs[res] = devm_ioremap_resource(iss->dev, mem); 1111 1112 return PTR_ERR_OR_ZERO(iss->regs[res]); 1113} 1114 1115static void iss_unregister_entities(struct iss_device *iss) 1116{ 1117 omap4iss_resizer_unregister_entities(&iss->resizer); 1118 omap4iss_ipipe_unregister_entities(&iss->ipipe); 1119 omap4iss_ipipeif_unregister_entities(&iss->ipipeif); 1120 omap4iss_csi2_unregister_entities(&iss->csi2a); 1121 omap4iss_csi2_unregister_entities(&iss->csi2b); 1122 1123 v4l2_device_unregister(&iss->v4l2_dev); 1124 media_device_unregister(&iss->media_dev); 1125} 1126 1127/* 1128 * iss_register_subdev_group - Register a group of subdevices 1129 * @iss: OMAP4 ISS device 1130 * @board_info: I2C subdevs board information array 1131 * 1132 * Register all I2C subdevices in the board_info array. The array must be 1133 * terminated by a NULL entry, and the first entry must be the sensor. 1134 * 1135 * Return a pointer to the sensor media entity if it has been successfully 1136 * registered, or NULL otherwise. 1137 */ 1138static struct v4l2_subdev * 1139iss_register_subdev_group(struct iss_device *iss, 1140 struct iss_subdev_i2c_board_info *board_info) 1141{ 1142 struct v4l2_subdev *sensor = NULL; 1143 unsigned int first; 1144 1145 if (board_info->board_info == NULL) 1146 return NULL; 1147 1148 for (first = 1; board_info->board_info; ++board_info, first = 0) { 1149 struct v4l2_subdev *subdev; 1150 struct i2c_adapter *adapter; 1151 1152 adapter = i2c_get_adapter(board_info->i2c_adapter_id); 1153 if (adapter == NULL) { 1154 dev_err(iss->dev, 1155 "%s: Unable to get I2C adapter %d for device %s\n", 1156 __func__, board_info->i2c_adapter_id, 1157 board_info->board_info->type); 1158 continue; 1159 } 1160 1161 subdev = v4l2_i2c_new_subdev_board(&iss->v4l2_dev, adapter, 1162 board_info->board_info, NULL); 1163 if (subdev == NULL) { 1164 dev_err(iss->dev, "Unable to register subdev %s\n", 1165 board_info->board_info->type); 1166 continue; 1167 } 1168 1169 if (first) 1170 sensor = subdev; 1171 } 1172 1173 return sensor; 1174} 1175 1176static int iss_register_entities(struct iss_device *iss) 1177{ 1178 struct iss_platform_data *pdata = iss->pdata; 1179 struct iss_v4l2_subdevs_group *subdevs; 1180 int ret; 1181 1182 iss->media_dev.dev = iss->dev; 1183 strlcpy(iss->media_dev.model, "TI OMAP4 ISS", 1184 sizeof(iss->media_dev.model)); 1185 iss->media_dev.hw_revision = iss->revision; 1186 iss->media_dev.link_notify = iss_pipeline_link_notify; 1187 ret = media_device_register(&iss->media_dev); 1188 if (ret < 0) { 1189 dev_err(iss->dev, "Media device registration failed (%d)\n", 1190 ret); 1191 return ret; 1192 } 1193 1194 iss->v4l2_dev.mdev = &iss->media_dev; 1195 ret = v4l2_device_register(iss->dev, &iss->v4l2_dev); 1196 if (ret < 0) { 1197 dev_err(iss->dev, "V4L2 device registration failed (%d)\n", 1198 ret); 1199 goto done; 1200 } 1201 1202 /* Register internal entities */ 1203 ret = omap4iss_csi2_register_entities(&iss->csi2a, &iss->v4l2_dev); 1204 if (ret < 0) 1205 goto done; 1206 1207 ret = omap4iss_csi2_register_entities(&iss->csi2b, &iss->v4l2_dev); 1208 if (ret < 0) 1209 goto done; 1210 1211 ret = omap4iss_ipipeif_register_entities(&iss->ipipeif, &iss->v4l2_dev); 1212 if (ret < 0) 1213 goto done; 1214 1215 ret = omap4iss_ipipe_register_entities(&iss->ipipe, &iss->v4l2_dev); 1216 if (ret < 0) 1217 goto done; 1218 1219 ret = omap4iss_resizer_register_entities(&iss->resizer, &iss->v4l2_dev); 1220 if (ret < 0) 1221 goto done; 1222 1223 /* Register external entities */ 1224 for (subdevs = pdata->subdevs; subdevs && subdevs->subdevs; ++subdevs) { 1225 struct v4l2_subdev *sensor; 1226 struct media_entity *input; 1227 unsigned int flags; 1228 unsigned int pad; 1229 1230 sensor = iss_register_subdev_group(iss, subdevs->subdevs); 1231 if (sensor == NULL) 1232 continue; 1233 1234 sensor->host_priv = subdevs; 1235 1236 /* Connect the sensor to the correct interface module. 1237 * CSI2a receiver through CSIPHY1, or 1238 * CSI2b receiver through CSIPHY2 1239 */ 1240 switch (subdevs->interface) { 1241 case ISS_INTERFACE_CSI2A_PHY1: 1242 input = &iss->csi2a.subdev.entity; 1243 pad = CSI2_PAD_SINK; 1244 flags = MEDIA_LNK_FL_IMMUTABLE 1245 | MEDIA_LNK_FL_ENABLED; 1246 break; 1247 1248 case ISS_INTERFACE_CSI2B_PHY2: 1249 input = &iss->csi2b.subdev.entity; 1250 pad = CSI2_PAD_SINK; 1251 flags = MEDIA_LNK_FL_IMMUTABLE 1252 | MEDIA_LNK_FL_ENABLED; 1253 break; 1254 1255 default: 1256 dev_err(iss->dev, "invalid interface type %u\n", 1257 subdevs->interface); 1258 ret = -EINVAL; 1259 goto done; 1260 } 1261 1262 ret = media_entity_create_link(&sensor->entity, 0, input, pad, 1263 flags); 1264 if (ret < 0) 1265 goto done; 1266 } 1267 1268 ret = v4l2_device_register_subdev_nodes(&iss->v4l2_dev); 1269 1270done: 1271 if (ret < 0) 1272 iss_unregister_entities(iss); 1273 1274 return ret; 1275} 1276 1277static void iss_cleanup_modules(struct iss_device *iss) 1278{ 1279 omap4iss_csi2_cleanup(iss); 1280 omap4iss_ipipeif_cleanup(iss); 1281 omap4iss_ipipe_cleanup(iss); 1282 omap4iss_resizer_cleanup(iss); 1283} 1284 1285static int iss_initialize_modules(struct iss_device *iss) 1286{ 1287 int ret; 1288 1289 ret = omap4iss_csiphy_init(iss); 1290 if (ret < 0) { 1291 dev_err(iss->dev, "CSI PHY initialization failed\n"); 1292 goto error_csiphy; 1293 } 1294 1295 ret = omap4iss_csi2_init(iss); 1296 if (ret < 0) { 1297 dev_err(iss->dev, "CSI2 initialization failed\n"); 1298 goto error_csi2; 1299 } 1300 1301 ret = omap4iss_ipipeif_init(iss); 1302 if (ret < 0) { 1303 dev_err(iss->dev, "ISP IPIPEIF initialization failed\n"); 1304 goto error_ipipeif; 1305 } 1306 1307 ret = omap4iss_ipipe_init(iss); 1308 if (ret < 0) { 1309 dev_err(iss->dev, "ISP IPIPE initialization failed\n"); 1310 goto error_ipipe; 1311 } 1312 1313 ret = omap4iss_resizer_init(iss); 1314 if (ret < 0) { 1315 dev_err(iss->dev, "ISP RESIZER initialization failed\n"); 1316 goto error_resizer; 1317 } 1318 1319 /* Connect the submodules. */ 1320 ret = media_entity_create_link( 1321 &iss->csi2a.subdev.entity, CSI2_PAD_SOURCE, 1322 &iss->ipipeif.subdev.entity, IPIPEIF_PAD_SINK, 0); 1323 if (ret < 0) 1324 goto error_link; 1325 1326 ret = media_entity_create_link( 1327 &iss->csi2b.subdev.entity, CSI2_PAD_SOURCE, 1328 &iss->ipipeif.subdev.entity, IPIPEIF_PAD_SINK, 0); 1329 if (ret < 0) 1330 goto error_link; 1331 1332 ret = media_entity_create_link( 1333 &iss->ipipeif.subdev.entity, IPIPEIF_PAD_SOURCE_VP, 1334 &iss->resizer.subdev.entity, RESIZER_PAD_SINK, 0); 1335 if (ret < 0) 1336 goto error_link; 1337 1338 ret = media_entity_create_link( 1339 &iss->ipipeif.subdev.entity, IPIPEIF_PAD_SOURCE_VP, 1340 &iss->ipipe.subdev.entity, IPIPE_PAD_SINK, 0); 1341 if (ret < 0) 1342 goto error_link; 1343 1344 ret = media_entity_create_link( 1345 &iss->ipipe.subdev.entity, IPIPE_PAD_SOURCE_VP, 1346 &iss->resizer.subdev.entity, RESIZER_PAD_SINK, 0); 1347 if (ret < 0) 1348 goto error_link; 1349 1350 return 0; 1351 1352error_link: 1353 omap4iss_resizer_cleanup(iss); 1354error_resizer: 1355 omap4iss_ipipe_cleanup(iss); 1356error_ipipe: 1357 omap4iss_ipipeif_cleanup(iss); 1358error_ipipeif: 1359 omap4iss_csi2_cleanup(iss); 1360error_csi2: 1361error_csiphy: 1362 return ret; 1363} 1364 1365static int iss_probe(struct platform_device *pdev) 1366{ 1367 struct iss_platform_data *pdata = pdev->dev.platform_data; 1368 struct iss_device *iss; 1369 unsigned int i; 1370 int ret; 1371 1372 if (pdata == NULL) 1373 return -EINVAL; 1374 1375 iss = devm_kzalloc(&pdev->dev, sizeof(*iss), GFP_KERNEL); 1376 if (!iss) 1377 return -ENOMEM; 1378 1379 mutex_init(&iss->iss_mutex); 1380 1381 iss->dev = &pdev->dev; 1382 iss->pdata = pdata; 1383 1384 iss->raw_dmamask = DMA_BIT_MASK(32); 1385 iss->dev->dma_mask = &iss->raw_dmamask; 1386 iss->dev->coherent_dma_mask = DMA_BIT_MASK(32); 1387 1388 platform_set_drvdata(pdev, iss); 1389 1390 /* 1391 * TODO: When implementing DT support switch to syscon regmap lookup by 1392 * phandle. 1393 */ 1394 iss->syscon = syscon_regmap_lookup_by_compatible("syscon"); 1395 if (IS_ERR(iss->syscon)) { 1396 ret = PTR_ERR(iss->syscon); 1397 goto error; 1398 } 1399 1400 /* Clocks */ 1401 ret = iss_map_mem_resource(pdev, iss, OMAP4_ISS_MEM_TOP); 1402 if (ret < 0) 1403 goto error; 1404 1405 ret = iss_get_clocks(iss); 1406 if (ret < 0) 1407 goto error; 1408 1409 if (omap4iss_get(iss) == NULL) 1410 goto error; 1411 1412 ret = iss_reset(iss); 1413 if (ret < 0) 1414 goto error_iss; 1415 1416 iss->revision = iss_reg_read(iss, OMAP4_ISS_MEM_TOP, ISS_HL_REVISION); 1417 dev_info(iss->dev, "Revision %08x found\n", iss->revision); 1418 1419 for (i = 1; i < OMAP4_ISS_MEM_LAST; i++) { 1420 ret = iss_map_mem_resource(pdev, iss, i); 1421 if (ret) 1422 goto error_iss; 1423 } 1424 1425 /* Configure BTE BW_LIMITER field to max recommended value (1 GB) */ 1426 iss_reg_update(iss, OMAP4_ISS_MEM_BTE, BTE_CTRL, 1427 BTE_CTRL_BW_LIMITER_MASK, 1428 18 << BTE_CTRL_BW_LIMITER_SHIFT); 1429 1430 /* Perform ISP reset */ 1431 ret = omap4iss_subclk_enable(iss, OMAP4_ISS_SUBCLK_ISP); 1432 if (ret < 0) 1433 goto error_iss; 1434 1435 ret = iss_isp_reset(iss); 1436 if (ret < 0) 1437 goto error_iss; 1438 1439 dev_info(iss->dev, "ISP Revision %08x found\n", 1440 iss_reg_read(iss, OMAP4_ISS_MEM_ISP_SYS1, ISP5_REVISION)); 1441 1442 /* Interrupt */ 1443 iss->irq_num = platform_get_irq(pdev, 0); 1444 if (iss->irq_num <= 0) { 1445 dev_err(iss->dev, "No IRQ resource\n"); 1446 ret = -ENODEV; 1447 goto error_iss; 1448 } 1449 1450 if (devm_request_irq(iss->dev, iss->irq_num, iss_isr, IRQF_SHARED, 1451 "OMAP4 ISS", iss)) { 1452 dev_err(iss->dev, "Unable to request IRQ\n"); 1453 ret = -EINVAL; 1454 goto error_iss; 1455 } 1456 1457 /* Entities */ 1458 ret = iss_initialize_modules(iss); 1459 if (ret < 0) 1460 goto error_iss; 1461 1462 ret = iss_register_entities(iss); 1463 if (ret < 0) 1464 goto error_modules; 1465 1466 omap4iss_put(iss); 1467 1468 return 0; 1469 1470error_modules: 1471 iss_cleanup_modules(iss); 1472error_iss: 1473 omap4iss_put(iss); 1474error: 1475 platform_set_drvdata(pdev, NULL); 1476 1477 mutex_destroy(&iss->iss_mutex); 1478 1479 return ret; 1480} 1481 1482static int iss_remove(struct platform_device *pdev) 1483{ 1484 struct iss_device *iss = platform_get_drvdata(pdev); 1485 1486 iss_unregister_entities(iss); 1487 iss_cleanup_modules(iss); 1488 1489 return 0; 1490} 1491 1492static struct platform_device_id omap4iss_id_table[] = { 1493 { "omap4iss", 0 }, 1494 { }, 1495}; 1496MODULE_DEVICE_TABLE(platform, omap4iss_id_table); 1497 1498static struct platform_driver iss_driver = { 1499 .probe = iss_probe, 1500 .remove = iss_remove, 1501 .id_table = omap4iss_id_table, 1502 .driver = { 1503 .name = "omap4iss", 1504 }, 1505}; 1506 1507module_platform_driver(iss_driver); 1508 1509MODULE_DESCRIPTION("TI OMAP4 ISS driver"); 1510MODULE_AUTHOR("Sergio Aguirre <sergio.a.aguirre@gmail.com>"); 1511MODULE_LICENSE("GPL"); 1512MODULE_VERSION(ISS_VIDEO_DRIVER_VERSION); 1513