1/* 2 * ispccp2.c 3 * 4 * TI OMAP3 ISP - CCP2 module 5 * 6 * Copyright (C) 2010 Nokia Corporation 7 * Copyright (C) 2010 Texas Instruments, Inc. 8 * 9 * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com> 10 * Sakari Ailus <sakari.ailus@iki.fi> 11 * 12 * This program is free software; you can redistribute it and/or modify 13 * it under the terms of the GNU General Public License version 2 as 14 * published by the Free Software Foundation. 15 */ 16 17#include <linux/delay.h> 18#include <linux/device.h> 19#include <linux/mm.h> 20#include <linux/module.h> 21#include <linux/mutex.h> 22#include <linux/uaccess.h> 23#include <linux/regulator/consumer.h> 24 25#include "isp.h" 26#include "ispreg.h" 27#include "ispccp2.h" 28 29/* Number of LCX channels */ 30#define CCP2_LCx_CHANS_NUM 3 31/* Max/Min size for CCP2 video port */ 32#define ISPCCP2_DAT_START_MIN 0 33#define ISPCCP2_DAT_START_MAX 4095 34#define ISPCCP2_DAT_SIZE_MIN 0 35#define ISPCCP2_DAT_SIZE_MAX 4095 36#define ISPCCP2_VPCLK_FRACDIV 65536 37#define ISPCCP2_LCx_CTRL_FORMAT_RAW8_DPCM10_VP 0x12 38#define ISPCCP2_LCx_CTRL_FORMAT_RAW10_VP 0x16 39/* Max/Min size for CCP2 memory channel */ 40#define ISPCCP2_LCM_HSIZE_COUNT_MIN 16 41#define ISPCCP2_LCM_HSIZE_COUNT_MAX 8191 42#define ISPCCP2_LCM_HSIZE_SKIP_MIN 0 43#define ISPCCP2_LCM_HSIZE_SKIP_MAX 8191 44#define ISPCCP2_LCM_VSIZE_MIN 1 45#define ISPCCP2_LCM_VSIZE_MAX 8191 46#define ISPCCP2_LCM_HWORDS_MIN 1 47#define ISPCCP2_LCM_HWORDS_MAX 4095 48#define ISPCCP2_LCM_CTRL_BURST_SIZE_32X 5 49#define ISPCCP2_LCM_CTRL_READ_THROTTLE_FULL 0 50#define ISPCCP2_LCM_CTRL_SRC_DECOMPR_DPCM10 2 51#define ISPCCP2_LCM_CTRL_SRC_FORMAT_RAW8 2 52#define ISPCCP2_LCM_CTRL_SRC_FORMAT_RAW10 3 53#define ISPCCP2_LCM_CTRL_DST_FORMAT_RAW10 3 54#define ISPCCP2_LCM_CTRL_DST_PORT_VP 0 55#define ISPCCP2_LCM_CTRL_DST_PORT_MEM 1 56 57/* Set only the required bits */ 58#define BIT_SET(var, shift, mask, val) \ 59 do { \ 60 var = ((var) & ~((mask) << (shift))) \ 61 | ((val) << (shift)); \ 62 } while (0) 63 64/* 65 * ccp2_print_status - Print current CCP2 module register values. 66 */ 67#define CCP2_PRINT_REGISTER(isp, name)\ 68 dev_dbg(isp->dev, "###CCP2 " #name "=0x%08x\n", \ 69 isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_##name)) 70 71static void ccp2_print_status(struct isp_ccp2_device *ccp2) 72{ 73 struct isp_device *isp = to_isp_device(ccp2); 74 75 dev_dbg(isp->dev, "-------------CCP2 Register dump-------------\n"); 76 77 CCP2_PRINT_REGISTER(isp, SYSCONFIG); 78 CCP2_PRINT_REGISTER(isp, SYSSTATUS); 79 CCP2_PRINT_REGISTER(isp, LC01_IRQENABLE); 80 CCP2_PRINT_REGISTER(isp, LC01_IRQSTATUS); 81 CCP2_PRINT_REGISTER(isp, LC23_IRQENABLE); 82 CCP2_PRINT_REGISTER(isp, LC23_IRQSTATUS); 83 CCP2_PRINT_REGISTER(isp, LCM_IRQENABLE); 84 CCP2_PRINT_REGISTER(isp, LCM_IRQSTATUS); 85 CCP2_PRINT_REGISTER(isp, CTRL); 86 CCP2_PRINT_REGISTER(isp, LCx_CTRL(0)); 87 CCP2_PRINT_REGISTER(isp, LCx_CODE(0)); 88 CCP2_PRINT_REGISTER(isp, LCx_STAT_START(0)); 89 CCP2_PRINT_REGISTER(isp, LCx_STAT_SIZE(0)); 90 CCP2_PRINT_REGISTER(isp, LCx_SOF_ADDR(0)); 91 CCP2_PRINT_REGISTER(isp, LCx_EOF_ADDR(0)); 92 CCP2_PRINT_REGISTER(isp, LCx_DAT_START(0)); 93 CCP2_PRINT_REGISTER(isp, LCx_DAT_SIZE(0)); 94 CCP2_PRINT_REGISTER(isp, LCx_DAT_PING_ADDR(0)); 95 CCP2_PRINT_REGISTER(isp, LCx_DAT_PONG_ADDR(0)); 96 CCP2_PRINT_REGISTER(isp, LCx_DAT_OFST(0)); 97 CCP2_PRINT_REGISTER(isp, LCM_CTRL); 98 CCP2_PRINT_REGISTER(isp, LCM_VSIZE); 99 CCP2_PRINT_REGISTER(isp, LCM_HSIZE); 100 CCP2_PRINT_REGISTER(isp, LCM_PREFETCH); 101 CCP2_PRINT_REGISTER(isp, LCM_SRC_ADDR); 102 CCP2_PRINT_REGISTER(isp, LCM_SRC_OFST); 103 CCP2_PRINT_REGISTER(isp, LCM_DST_ADDR); 104 CCP2_PRINT_REGISTER(isp, LCM_DST_OFST); 105 106 dev_dbg(isp->dev, "--------------------------------------------\n"); 107} 108 109/* 110 * ccp2_reset - Reset the CCP2 111 * @ccp2: pointer to ISP CCP2 device 112 */ 113static void ccp2_reset(struct isp_ccp2_device *ccp2) 114{ 115 struct isp_device *isp = to_isp_device(ccp2); 116 int i = 0; 117 118 /* Reset the CSI1/CCP2B and wait for reset to complete */ 119 isp_reg_set(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_SYSCONFIG, 120 ISPCCP2_SYSCONFIG_SOFT_RESET); 121 while (!(isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_SYSSTATUS) & 122 ISPCCP2_SYSSTATUS_RESET_DONE)) { 123 udelay(10); 124 if (i++ > 10) { /* try read 10 times */ 125 dev_warn(isp->dev, 126 "omap3_isp: timeout waiting for ccp2 reset\n"); 127 break; 128 } 129 } 130} 131 132/* 133 * ccp2_pwr_cfg - Configure the power mode settings 134 * @ccp2: pointer to ISP CCP2 device 135 */ 136static void ccp2_pwr_cfg(struct isp_ccp2_device *ccp2) 137{ 138 struct isp_device *isp = to_isp_device(ccp2); 139 140 isp_reg_writel(isp, ISPCCP2_SYSCONFIG_MSTANDBY_MODE_SMART | 141 ((isp->revision == ISP_REVISION_15_0 && isp->autoidle) ? 142 ISPCCP2_SYSCONFIG_AUTO_IDLE : 0), 143 OMAP3_ISP_IOMEM_CCP2, ISPCCP2_SYSCONFIG); 144} 145 146/* 147 * ccp2_if_enable - Enable CCP2 interface. 148 * @ccp2: pointer to ISP CCP2 device 149 * @enable: enable/disable flag 150 */ 151static int ccp2_if_enable(struct isp_ccp2_device *ccp2, u8 enable) 152{ 153 struct isp_device *isp = to_isp_device(ccp2); 154 int ret; 155 int i; 156 157 if (enable && ccp2->vdds_csib) { 158 ret = regulator_enable(ccp2->vdds_csib); 159 if (ret < 0) 160 return ret; 161 } 162 163 /* Enable/Disable all the LCx channels */ 164 for (i = 0; i < CCP2_LCx_CHANS_NUM; i++) 165 isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LCx_CTRL(i), 166 ISPCCP2_LCx_CTRL_CHAN_EN, 167 enable ? ISPCCP2_LCx_CTRL_CHAN_EN : 0); 168 169 /* Enable/Disable ccp2 interface in ccp2 mode */ 170 isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_CTRL, 171 ISPCCP2_CTRL_MODE | ISPCCP2_CTRL_IF_EN, 172 enable ? (ISPCCP2_CTRL_MODE | ISPCCP2_CTRL_IF_EN) : 0); 173 174 if (!enable && ccp2->vdds_csib) 175 regulator_disable(ccp2->vdds_csib); 176 177 return 0; 178} 179 180/* 181 * ccp2_mem_enable - Enable CCP2 memory interface. 182 * @ccp2: pointer to ISP CCP2 device 183 * @enable: enable/disable flag 184 */ 185static void ccp2_mem_enable(struct isp_ccp2_device *ccp2, u8 enable) 186{ 187 struct isp_device *isp = to_isp_device(ccp2); 188 189 if (enable) 190 ccp2_if_enable(ccp2, 0); 191 192 /* Enable/Disable ccp2 interface in ccp2 mode */ 193 isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_CTRL, 194 ISPCCP2_CTRL_MODE, enable ? ISPCCP2_CTRL_MODE : 0); 195 196 isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LCM_CTRL, 197 ISPCCP2_LCM_CTRL_CHAN_EN, 198 enable ? ISPCCP2_LCM_CTRL_CHAN_EN : 0); 199} 200 201/* 202 * ccp2_phyif_config - Initialize CCP2 phy interface config 203 * @ccp2: Pointer to ISP CCP2 device 204 * @buscfg: CCP2 platform data 205 * 206 * Configure the CCP2 physical interface module from platform data. 207 * 208 * Returns -EIO if strobe is chosen in CSI1 mode, or 0 on success. 209 */ 210static int ccp2_phyif_config(struct isp_ccp2_device *ccp2, 211 const struct isp_ccp2_cfg *buscfg) 212{ 213 struct isp_device *isp = to_isp_device(ccp2); 214 u32 val; 215 216 /* CCP2B mode */ 217 val = isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_CTRL) | 218 ISPCCP2_CTRL_IO_OUT_SEL | ISPCCP2_CTRL_MODE; 219 /* Data/strobe physical layer */ 220 BIT_SET(val, ISPCCP2_CTRL_PHY_SEL_SHIFT, ISPCCP2_CTRL_PHY_SEL_MASK, 221 buscfg->phy_layer); 222 BIT_SET(val, ISPCCP2_CTRL_INV_SHIFT, ISPCCP2_CTRL_INV_MASK, 223 buscfg->strobe_clk_pol); 224 isp_reg_writel(isp, val, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_CTRL); 225 226 val = isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_CTRL); 227 if (!(val & ISPCCP2_CTRL_MODE)) { 228 if (buscfg->ccp2_mode == ISP_CCP2_MODE_CCP2) 229 dev_warn(isp->dev, "OMAP3 CCP2 bus not available\n"); 230 if (buscfg->phy_layer == ISP_CCP2_PHY_DATA_STROBE) 231 /* Strobe mode requires CCP2 */ 232 return -EIO; 233 } 234 235 return 0; 236} 237 238/* 239 * ccp2_vp_config - Initialize CCP2 video port interface. 240 * @ccp2: Pointer to ISP CCP2 device 241 * @vpclk_div: Video port divisor 242 * 243 * Configure the CCP2 video port with the given clock divisor. The valid divisor 244 * values depend on the ISP revision: 245 * 246 * - revision 1.0 and 2.0 1 to 4 247 * - revision 15.0 1 to 65536 248 * 249 * The exact divisor value used might differ from the requested value, as ISP 250 * revision 15.0 represent the divisor by 65536 divided by an integer. 251 */ 252static void ccp2_vp_config(struct isp_ccp2_device *ccp2, 253 unsigned int vpclk_div) 254{ 255 struct isp_device *isp = to_isp_device(ccp2); 256 u32 val; 257 258 /* ISPCCP2_CTRL Video port */ 259 val = isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_CTRL); 260 val |= ISPCCP2_CTRL_VP_ONLY_EN; /* Disable the memory write port */ 261 262 if (isp->revision == ISP_REVISION_15_0) { 263 vpclk_div = clamp_t(unsigned int, vpclk_div, 1, 65536); 264 vpclk_div = min(ISPCCP2_VPCLK_FRACDIV / vpclk_div, 65535U); 265 BIT_SET(val, ISPCCP2_CTRL_VPCLK_DIV_SHIFT, 266 ISPCCP2_CTRL_VPCLK_DIV_MASK, vpclk_div); 267 } else { 268 vpclk_div = clamp_t(unsigned int, vpclk_div, 1, 4); 269 BIT_SET(val, ISPCCP2_CTRL_VP_OUT_CTRL_SHIFT, 270 ISPCCP2_CTRL_VP_OUT_CTRL_MASK, vpclk_div - 1); 271 } 272 273 isp_reg_writel(isp, val, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_CTRL); 274} 275 276/* 277 * ccp2_lcx_config - Initialize CCP2 logical channel interface. 278 * @ccp2: Pointer to ISP CCP2 device 279 * @config: Pointer to ISP LCx config structure. 280 * 281 * This will analyze the parameters passed by the interface config 282 * and configure CSI1/CCP2 logical channel 283 * 284 */ 285static void ccp2_lcx_config(struct isp_ccp2_device *ccp2, 286 struct isp_interface_lcx_config *config) 287{ 288 struct isp_device *isp = to_isp_device(ccp2); 289 u32 val, format; 290 291 switch (config->format) { 292 case MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8: 293 format = ISPCCP2_LCx_CTRL_FORMAT_RAW8_DPCM10_VP; 294 break; 295 case MEDIA_BUS_FMT_SGRBG10_1X10: 296 default: 297 format = ISPCCP2_LCx_CTRL_FORMAT_RAW10_VP; /* RAW10+VP */ 298 break; 299 } 300 /* ISPCCP2_LCx_CTRL logical channel #0 */ 301 val = isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LCx_CTRL(0)) 302 | (ISPCCP2_LCx_CTRL_REGION_EN); /* Region */ 303 304 if (isp->revision == ISP_REVISION_15_0) { 305 /* CRC */ 306 BIT_SET(val, ISPCCP2_LCx_CTRL_CRC_SHIFT_15_0, 307 ISPCCP2_LCx_CTRL_CRC_MASK, 308 config->crc); 309 /* Format = RAW10+VP or RAW8+DPCM10+VP*/ 310 BIT_SET(val, ISPCCP2_LCx_CTRL_FORMAT_SHIFT_15_0, 311 ISPCCP2_LCx_CTRL_FORMAT_MASK_15_0, format); 312 } else { 313 BIT_SET(val, ISPCCP2_LCx_CTRL_CRC_SHIFT, 314 ISPCCP2_LCx_CTRL_CRC_MASK, 315 config->crc); 316 317 BIT_SET(val, ISPCCP2_LCx_CTRL_FORMAT_SHIFT, 318 ISPCCP2_LCx_CTRL_FORMAT_MASK, format); 319 } 320 isp_reg_writel(isp, val, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LCx_CTRL(0)); 321 322 /* ISPCCP2_DAT_START for logical channel #0 */ 323 isp_reg_writel(isp, config->data_start << ISPCCP2_LCx_DAT_SHIFT, 324 OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LCx_DAT_START(0)); 325 326 /* ISPCCP2_DAT_SIZE for logical channel #0 */ 327 isp_reg_writel(isp, config->data_size << ISPCCP2_LCx_DAT_SHIFT, 328 OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LCx_DAT_SIZE(0)); 329 330 /* Enable error IRQs for logical channel #0 */ 331 val = ISPCCP2_LC01_IRQSTATUS_LC0_FIFO_OVF_IRQ | 332 ISPCCP2_LC01_IRQSTATUS_LC0_CRC_IRQ | 333 ISPCCP2_LC01_IRQSTATUS_LC0_FSP_IRQ | 334 ISPCCP2_LC01_IRQSTATUS_LC0_FW_IRQ | 335 ISPCCP2_LC01_IRQSTATUS_LC0_FSC_IRQ | 336 ISPCCP2_LC01_IRQSTATUS_LC0_SSC_IRQ; 337 338 isp_reg_writel(isp, val, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LC01_IRQSTATUS); 339 isp_reg_set(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LC01_IRQENABLE, val); 340} 341 342/* 343 * ccp2_if_configure - Configure ccp2 with data from sensor 344 * @ccp2: Pointer to ISP CCP2 device 345 * 346 * Return 0 on success or a negative error code 347 */ 348static int ccp2_if_configure(struct isp_ccp2_device *ccp2) 349{ 350 const struct isp_bus_cfg *buscfg; 351 struct v4l2_mbus_framefmt *format; 352 struct media_pad *pad; 353 struct v4l2_subdev *sensor; 354 u32 lines = 0; 355 int ret; 356 357 ccp2_pwr_cfg(ccp2); 358 359 pad = media_entity_remote_pad(&ccp2->pads[CCP2_PAD_SINK]); 360 sensor = media_entity_to_v4l2_subdev(pad->entity); 361 buscfg = sensor->host_priv; 362 363 ret = ccp2_phyif_config(ccp2, &buscfg->bus.ccp2); 364 if (ret < 0) 365 return ret; 366 367 ccp2_vp_config(ccp2, buscfg->bus.ccp2.vpclk_div + 1); 368 369 v4l2_subdev_call(sensor, sensor, g_skip_top_lines, &lines); 370 371 format = &ccp2->formats[CCP2_PAD_SINK]; 372 373 ccp2->if_cfg.data_start = lines; 374 ccp2->if_cfg.crc = buscfg->bus.ccp2.crc; 375 ccp2->if_cfg.format = format->code; 376 ccp2->if_cfg.data_size = format->height; 377 378 ccp2_lcx_config(ccp2, &ccp2->if_cfg); 379 380 return 0; 381} 382 383static int ccp2_adjust_bandwidth(struct isp_ccp2_device *ccp2) 384{ 385 struct isp_pipeline *pipe = to_isp_pipeline(&ccp2->subdev.entity); 386 struct isp_device *isp = to_isp_device(ccp2); 387 const struct v4l2_mbus_framefmt *ofmt = &ccp2->formats[CCP2_PAD_SOURCE]; 388 unsigned long l3_ick = pipe->l3_ick; 389 struct v4l2_fract *timeperframe; 390 unsigned int vpclk_div = 2; 391 unsigned int value; 392 u64 bound; 393 u64 area; 394 395 /* Compute the minimum clock divisor, based on the pipeline maximum 396 * data rate. This is an absolute lower bound if we don't want SBL 397 * overflows, so round the value up. 398 */ 399 vpclk_div = max_t(unsigned int, DIV_ROUND_UP(l3_ick, pipe->max_rate), 400 vpclk_div); 401 402 /* Compute the maximum clock divisor, based on the requested frame rate. 403 * This is a soft lower bound to achieve a frame rate equal or higher 404 * than the requested value, so round the value down. 405 */ 406 timeperframe = &pipe->max_timeperframe; 407 408 if (timeperframe->numerator) { 409 area = ofmt->width * ofmt->height; 410 bound = div_u64(area * timeperframe->denominator, 411 timeperframe->numerator); 412 value = min_t(u64, bound, l3_ick); 413 vpclk_div = max_t(unsigned int, l3_ick / value, vpclk_div); 414 } 415 416 dev_dbg(isp->dev, "%s: minimum clock divisor = %u\n", __func__, 417 vpclk_div); 418 419 return vpclk_div; 420} 421 422/* 423 * ccp2_mem_configure - Initialize CCP2 memory input/output interface 424 * @ccp2: Pointer to ISP CCP2 device 425 * @config: Pointer to ISP mem interface config structure 426 * 427 * This will analyze the parameters passed by the interface config 428 * structure, and configure the respective registers for proper 429 * CSI1/CCP2 memory input. 430 */ 431static void ccp2_mem_configure(struct isp_ccp2_device *ccp2, 432 struct isp_interface_mem_config *config) 433{ 434 struct isp_device *isp = to_isp_device(ccp2); 435 u32 sink_pixcode = ccp2->formats[CCP2_PAD_SINK].code; 436 u32 source_pixcode = ccp2->formats[CCP2_PAD_SOURCE].code; 437 unsigned int dpcm_decompress = 0; 438 u32 val, hwords; 439 440 if (sink_pixcode != source_pixcode && 441 sink_pixcode == MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8) 442 dpcm_decompress = 1; 443 444 ccp2_pwr_cfg(ccp2); 445 446 /* Hsize, Skip */ 447 isp_reg_writel(isp, ISPCCP2_LCM_HSIZE_SKIP_MIN | 448 (config->hsize_count << ISPCCP2_LCM_HSIZE_SHIFT), 449 OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LCM_HSIZE); 450 451 /* Vsize, no. of lines */ 452 isp_reg_writel(isp, config->vsize_count << ISPCCP2_LCM_VSIZE_SHIFT, 453 OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LCM_VSIZE); 454 455 if (ccp2->video_in.bpl_padding == 0) 456 config->src_ofst = 0; 457 else 458 config->src_ofst = ccp2->video_in.bpl_value; 459 460 isp_reg_writel(isp, config->src_ofst, OMAP3_ISP_IOMEM_CCP2, 461 ISPCCP2_LCM_SRC_OFST); 462 463 /* Source and Destination formats */ 464 val = ISPCCP2_LCM_CTRL_DST_FORMAT_RAW10 << 465 ISPCCP2_LCM_CTRL_DST_FORMAT_SHIFT; 466 467 if (dpcm_decompress) { 468 /* source format is RAW8 */ 469 val |= ISPCCP2_LCM_CTRL_SRC_FORMAT_RAW8 << 470 ISPCCP2_LCM_CTRL_SRC_FORMAT_SHIFT; 471 472 /* RAW8 + DPCM10 - simple predictor */ 473 val |= ISPCCP2_LCM_CTRL_SRC_DPCM_PRED; 474 475 /* enable source DPCM decompression */ 476 val |= ISPCCP2_LCM_CTRL_SRC_DECOMPR_DPCM10 << 477 ISPCCP2_LCM_CTRL_SRC_DECOMPR_SHIFT; 478 } else { 479 /* source format is RAW10 */ 480 val |= ISPCCP2_LCM_CTRL_SRC_FORMAT_RAW10 << 481 ISPCCP2_LCM_CTRL_SRC_FORMAT_SHIFT; 482 } 483 484 /* Burst size to 32x64 */ 485 val |= ISPCCP2_LCM_CTRL_BURST_SIZE_32X << 486 ISPCCP2_LCM_CTRL_BURST_SIZE_SHIFT; 487 488 isp_reg_writel(isp, val, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LCM_CTRL); 489 490 /* Prefetch setup */ 491 if (dpcm_decompress) 492 hwords = (ISPCCP2_LCM_HSIZE_SKIP_MIN + 493 config->hsize_count) >> 3; 494 else 495 hwords = (ISPCCP2_LCM_HSIZE_SKIP_MIN + 496 config->hsize_count) >> 2; 497 498 isp_reg_writel(isp, hwords << ISPCCP2_LCM_PREFETCH_SHIFT, 499 OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LCM_PREFETCH); 500 501 /* Video port */ 502 isp_reg_set(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_CTRL, 503 ISPCCP2_CTRL_IO_OUT_SEL | ISPCCP2_CTRL_MODE); 504 ccp2_vp_config(ccp2, ccp2_adjust_bandwidth(ccp2)); 505 506 /* Clear LCM interrupts */ 507 isp_reg_writel(isp, ISPCCP2_LCM_IRQSTATUS_OCPERROR_IRQ | 508 ISPCCP2_LCM_IRQSTATUS_EOF_IRQ, 509 OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LCM_IRQSTATUS); 510 511 /* Enable LCM interrupts */ 512 isp_reg_set(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LCM_IRQENABLE, 513 ISPCCP2_LCM_IRQSTATUS_EOF_IRQ | 514 ISPCCP2_LCM_IRQSTATUS_OCPERROR_IRQ); 515} 516 517/* 518 * ccp2_set_inaddr - Sets memory address of input frame. 519 * @ccp2: Pointer to ISP CCP2 device 520 * @addr: 32bit memory address aligned on 32byte boundary. 521 * 522 * Configures the memory address from which the input frame is to be read. 523 */ 524static void ccp2_set_inaddr(struct isp_ccp2_device *ccp2, u32 addr) 525{ 526 struct isp_device *isp = to_isp_device(ccp2); 527 528 isp_reg_writel(isp, addr, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LCM_SRC_ADDR); 529} 530 531/* ----------------------------------------------------------------------------- 532 * Interrupt handling 533 */ 534 535static void ccp2_isr_buffer(struct isp_ccp2_device *ccp2) 536{ 537 struct isp_pipeline *pipe = to_isp_pipeline(&ccp2->subdev.entity); 538 struct isp_buffer *buffer; 539 540 buffer = omap3isp_video_buffer_next(&ccp2->video_in); 541 if (buffer != NULL) 542 ccp2_set_inaddr(ccp2, buffer->dma); 543 544 pipe->state |= ISP_PIPELINE_IDLE_INPUT; 545 546 if (ccp2->state == ISP_PIPELINE_STREAM_SINGLESHOT) { 547 if (isp_pipeline_ready(pipe)) 548 omap3isp_pipeline_set_stream(pipe, 549 ISP_PIPELINE_STREAM_SINGLESHOT); 550 } 551} 552 553/* 554 * omap3isp_ccp2_isr - Handle ISP CCP2 interrupts 555 * @ccp2: Pointer to ISP CCP2 device 556 * 557 * This will handle the CCP2 interrupts 558 */ 559void omap3isp_ccp2_isr(struct isp_ccp2_device *ccp2) 560{ 561 struct isp_pipeline *pipe = to_isp_pipeline(&ccp2->subdev.entity); 562 struct isp_device *isp = to_isp_device(ccp2); 563 static const u32 ISPCCP2_LC01_ERROR = 564 ISPCCP2_LC01_IRQSTATUS_LC0_FIFO_OVF_IRQ | 565 ISPCCP2_LC01_IRQSTATUS_LC0_CRC_IRQ | 566 ISPCCP2_LC01_IRQSTATUS_LC0_FSP_IRQ | 567 ISPCCP2_LC01_IRQSTATUS_LC0_FW_IRQ | 568 ISPCCP2_LC01_IRQSTATUS_LC0_FSC_IRQ | 569 ISPCCP2_LC01_IRQSTATUS_LC0_SSC_IRQ; 570 u32 lcx_irqstatus, lcm_irqstatus; 571 572 /* First clear the interrupts */ 573 lcx_irqstatus = isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCP2, 574 ISPCCP2_LC01_IRQSTATUS); 575 isp_reg_writel(isp, lcx_irqstatus, OMAP3_ISP_IOMEM_CCP2, 576 ISPCCP2_LC01_IRQSTATUS); 577 578 lcm_irqstatus = isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCP2, 579 ISPCCP2_LCM_IRQSTATUS); 580 isp_reg_writel(isp, lcm_irqstatus, OMAP3_ISP_IOMEM_CCP2, 581 ISPCCP2_LCM_IRQSTATUS); 582 /* Errors */ 583 if (lcx_irqstatus & ISPCCP2_LC01_ERROR) { 584 pipe->error = true; 585 dev_dbg(isp->dev, "CCP2 err:%x\n", lcx_irqstatus); 586 return; 587 } 588 589 if (lcm_irqstatus & ISPCCP2_LCM_IRQSTATUS_OCPERROR_IRQ) { 590 pipe->error = true; 591 dev_dbg(isp->dev, "CCP2 OCP err:%x\n", lcm_irqstatus); 592 } 593 594 if (omap3isp_module_sync_is_stopping(&ccp2->wait, &ccp2->stopping)) 595 return; 596 597 /* Handle queued buffers on frame end interrupts */ 598 if (lcm_irqstatus & ISPCCP2_LCM_IRQSTATUS_EOF_IRQ) 599 ccp2_isr_buffer(ccp2); 600} 601 602/* ----------------------------------------------------------------------------- 603 * V4L2 subdev operations 604 */ 605 606static const unsigned int ccp2_fmts[] = { 607 MEDIA_BUS_FMT_SGRBG10_1X10, 608 MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8, 609}; 610 611/* 612 * __ccp2_get_format - helper function for getting ccp2 format 613 * @ccp2 : Pointer to ISP CCP2 device 614 * @cfg: V4L2 subdev pad configuration 615 * @pad : pad number 616 * @which : wanted subdev format 617 * return format structure or NULL on error 618 */ 619static struct v4l2_mbus_framefmt * 620__ccp2_get_format(struct isp_ccp2_device *ccp2, struct v4l2_subdev_pad_config *cfg, 621 unsigned int pad, enum v4l2_subdev_format_whence which) 622{ 623 if (which == V4L2_SUBDEV_FORMAT_TRY) 624 return v4l2_subdev_get_try_format(&ccp2->subdev, cfg, pad); 625 else 626 return &ccp2->formats[pad]; 627} 628 629/* 630 * ccp2_try_format - Handle try format by pad subdev method 631 * @ccp2 : Pointer to ISP CCP2 device 632 * @cfg: V4L2 subdev pad configuration 633 * @pad : pad num 634 * @fmt : pointer to v4l2 mbus format structure 635 * @which : wanted subdev format 636 */ 637static void ccp2_try_format(struct isp_ccp2_device *ccp2, 638 struct v4l2_subdev_pad_config *cfg, unsigned int pad, 639 struct v4l2_mbus_framefmt *fmt, 640 enum v4l2_subdev_format_whence which) 641{ 642 struct v4l2_mbus_framefmt *format; 643 644 switch (pad) { 645 case CCP2_PAD_SINK: 646 if (fmt->code != MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8) 647 fmt->code = MEDIA_BUS_FMT_SGRBG10_1X10; 648 649 if (ccp2->input == CCP2_INPUT_SENSOR) { 650 fmt->width = clamp_t(u32, fmt->width, 651 ISPCCP2_DAT_START_MIN, 652 ISPCCP2_DAT_START_MAX); 653 fmt->height = clamp_t(u32, fmt->height, 654 ISPCCP2_DAT_SIZE_MIN, 655 ISPCCP2_DAT_SIZE_MAX); 656 } else if (ccp2->input == CCP2_INPUT_MEMORY) { 657 fmt->width = clamp_t(u32, fmt->width, 658 ISPCCP2_LCM_HSIZE_COUNT_MIN, 659 ISPCCP2_LCM_HSIZE_COUNT_MAX); 660 fmt->height = clamp_t(u32, fmt->height, 661 ISPCCP2_LCM_VSIZE_MIN, 662 ISPCCP2_LCM_VSIZE_MAX); 663 } 664 break; 665 666 case CCP2_PAD_SOURCE: 667 /* Source format - copy sink format and change pixel code 668 * to SGRBG10_1X10 as we don't support CCP2 write to memory. 669 * When CCP2 write to memory feature will be added this 670 * should be changed properly. 671 */ 672 format = __ccp2_get_format(ccp2, cfg, CCP2_PAD_SINK, which); 673 memcpy(fmt, format, sizeof(*fmt)); 674 fmt->code = MEDIA_BUS_FMT_SGRBG10_1X10; 675 break; 676 } 677 678 fmt->field = V4L2_FIELD_NONE; 679 fmt->colorspace = V4L2_COLORSPACE_SRGB; 680} 681 682/* 683 * ccp2_enum_mbus_code - Handle pixel format enumeration 684 * @sd : pointer to v4l2 subdev structure 685 * @cfg: V4L2 subdev pad configuration 686 * @code : pointer to v4l2_subdev_mbus_code_enum structure 687 * return -EINVAL or zero on success 688 */ 689static int ccp2_enum_mbus_code(struct v4l2_subdev *sd, 690 struct v4l2_subdev_pad_config *cfg, 691 struct v4l2_subdev_mbus_code_enum *code) 692{ 693 struct isp_ccp2_device *ccp2 = v4l2_get_subdevdata(sd); 694 struct v4l2_mbus_framefmt *format; 695 696 if (code->pad == CCP2_PAD_SINK) { 697 if (code->index >= ARRAY_SIZE(ccp2_fmts)) 698 return -EINVAL; 699 700 code->code = ccp2_fmts[code->index]; 701 } else { 702 if (code->index != 0) 703 return -EINVAL; 704 705 format = __ccp2_get_format(ccp2, cfg, CCP2_PAD_SINK, 706 code->which); 707 code->code = format->code; 708 } 709 710 return 0; 711} 712 713static int ccp2_enum_frame_size(struct v4l2_subdev *sd, 714 struct v4l2_subdev_pad_config *cfg, 715 struct v4l2_subdev_frame_size_enum *fse) 716{ 717 struct isp_ccp2_device *ccp2 = v4l2_get_subdevdata(sd); 718 struct v4l2_mbus_framefmt format; 719 720 if (fse->index != 0) 721 return -EINVAL; 722 723 format.code = fse->code; 724 format.width = 1; 725 format.height = 1; 726 ccp2_try_format(ccp2, cfg, fse->pad, &format, fse->which); 727 fse->min_width = format.width; 728 fse->min_height = format.height; 729 730 if (format.code != fse->code) 731 return -EINVAL; 732 733 format.code = fse->code; 734 format.width = -1; 735 format.height = -1; 736 ccp2_try_format(ccp2, cfg, fse->pad, &format, fse->which); 737 fse->max_width = format.width; 738 fse->max_height = format.height; 739 740 return 0; 741} 742 743/* 744 * ccp2_get_format - Handle get format by pads subdev method 745 * @sd : pointer to v4l2 subdev structure 746 * @cfg: V4L2 subdev pad configuration 747 * @fmt : pointer to v4l2 subdev format structure 748 * return -EINVAL or zero on success 749 */ 750static int ccp2_get_format(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, 751 struct v4l2_subdev_format *fmt) 752{ 753 struct isp_ccp2_device *ccp2 = v4l2_get_subdevdata(sd); 754 struct v4l2_mbus_framefmt *format; 755 756 format = __ccp2_get_format(ccp2, cfg, fmt->pad, fmt->which); 757 if (format == NULL) 758 return -EINVAL; 759 760 fmt->format = *format; 761 return 0; 762} 763 764/* 765 * ccp2_set_format - Handle set format by pads subdev method 766 * @sd : pointer to v4l2 subdev structure 767 * @cfg: V4L2 subdev pad configuration 768 * @fmt : pointer to v4l2 subdev format structure 769 * returns zero 770 */ 771static int ccp2_set_format(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, 772 struct v4l2_subdev_format *fmt) 773{ 774 struct isp_ccp2_device *ccp2 = v4l2_get_subdevdata(sd); 775 struct v4l2_mbus_framefmt *format; 776 777 format = __ccp2_get_format(ccp2, cfg, fmt->pad, fmt->which); 778 if (format == NULL) 779 return -EINVAL; 780 781 ccp2_try_format(ccp2, cfg, fmt->pad, &fmt->format, fmt->which); 782 *format = fmt->format; 783 784 /* Propagate the format from sink to source */ 785 if (fmt->pad == CCP2_PAD_SINK) { 786 format = __ccp2_get_format(ccp2, cfg, CCP2_PAD_SOURCE, 787 fmt->which); 788 *format = fmt->format; 789 ccp2_try_format(ccp2, cfg, CCP2_PAD_SOURCE, format, fmt->which); 790 } 791 792 return 0; 793} 794 795/* 796 * ccp2_init_formats - Initialize formats on all pads 797 * @sd: ISP CCP2 V4L2 subdevice 798 * @fh: V4L2 subdev file handle 799 * 800 * Initialize all pad formats with default values. If fh is not NULL, try 801 * formats are initialized on the file handle. Otherwise active formats are 802 * initialized on the device. 803 */ 804static int ccp2_init_formats(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) 805{ 806 struct v4l2_subdev_format format; 807 808 memset(&format, 0, sizeof(format)); 809 format.pad = CCP2_PAD_SINK; 810 format.which = fh ? V4L2_SUBDEV_FORMAT_TRY : V4L2_SUBDEV_FORMAT_ACTIVE; 811 format.format.code = MEDIA_BUS_FMT_SGRBG10_1X10; 812 format.format.width = 4096; 813 format.format.height = 4096; 814 ccp2_set_format(sd, fh ? fh->pad : NULL, &format); 815 816 return 0; 817} 818 819/* 820 * ccp2_s_stream - Enable/Disable streaming on ccp2 subdev 821 * @sd : pointer to v4l2 subdev structure 822 * @enable: 1 == Enable, 0 == Disable 823 * return zero 824 */ 825static int ccp2_s_stream(struct v4l2_subdev *sd, int enable) 826{ 827 struct isp_ccp2_device *ccp2 = v4l2_get_subdevdata(sd); 828 struct isp_device *isp = to_isp_device(ccp2); 829 struct device *dev = to_device(ccp2); 830 int ret; 831 832 if (ccp2->state == ISP_PIPELINE_STREAM_STOPPED) { 833 if (enable == ISP_PIPELINE_STREAM_STOPPED) 834 return 0; 835 atomic_set(&ccp2->stopping, 0); 836 } 837 838 switch (enable) { 839 case ISP_PIPELINE_STREAM_CONTINUOUS: 840 if (ccp2->phy) { 841 ret = omap3isp_csiphy_acquire(ccp2->phy); 842 if (ret < 0) 843 return ret; 844 } 845 846 ccp2_if_configure(ccp2); 847 ccp2_print_status(ccp2); 848 849 /* Enable CSI1/CCP2 interface */ 850 ret = ccp2_if_enable(ccp2, 1); 851 if (ret < 0) { 852 if (ccp2->phy) 853 omap3isp_csiphy_release(ccp2->phy); 854 return ret; 855 } 856 break; 857 858 case ISP_PIPELINE_STREAM_SINGLESHOT: 859 if (ccp2->state != ISP_PIPELINE_STREAM_SINGLESHOT) { 860 struct v4l2_mbus_framefmt *format; 861 862 format = &ccp2->formats[CCP2_PAD_SINK]; 863 864 ccp2->mem_cfg.hsize_count = format->width; 865 ccp2->mem_cfg.vsize_count = format->height; 866 ccp2->mem_cfg.src_ofst = 0; 867 868 ccp2_mem_configure(ccp2, &ccp2->mem_cfg); 869 omap3isp_sbl_enable(isp, OMAP3_ISP_SBL_CSI1_READ); 870 ccp2_print_status(ccp2); 871 } 872 ccp2_mem_enable(ccp2, 1); 873 break; 874 875 case ISP_PIPELINE_STREAM_STOPPED: 876 if (omap3isp_module_sync_idle(&sd->entity, &ccp2->wait, 877 &ccp2->stopping)) 878 dev_dbg(dev, "%s: module stop timeout.\n", sd->name); 879 if (ccp2->input == CCP2_INPUT_MEMORY) { 880 ccp2_mem_enable(ccp2, 0); 881 omap3isp_sbl_disable(isp, OMAP3_ISP_SBL_CSI1_READ); 882 } else if (ccp2->input == CCP2_INPUT_SENSOR) { 883 /* Disable CSI1/CCP2 interface */ 884 ccp2_if_enable(ccp2, 0); 885 if (ccp2->phy) 886 omap3isp_csiphy_release(ccp2->phy); 887 } 888 break; 889 } 890 891 ccp2->state = enable; 892 return 0; 893} 894 895/* subdev video operations */ 896static const struct v4l2_subdev_video_ops ccp2_sd_video_ops = { 897 .s_stream = ccp2_s_stream, 898}; 899 900/* subdev pad operations */ 901static const struct v4l2_subdev_pad_ops ccp2_sd_pad_ops = { 902 .enum_mbus_code = ccp2_enum_mbus_code, 903 .enum_frame_size = ccp2_enum_frame_size, 904 .get_fmt = ccp2_get_format, 905 .set_fmt = ccp2_set_format, 906}; 907 908/* subdev operations */ 909static const struct v4l2_subdev_ops ccp2_sd_ops = { 910 .video = &ccp2_sd_video_ops, 911 .pad = &ccp2_sd_pad_ops, 912}; 913 914/* subdev internal operations */ 915static const struct v4l2_subdev_internal_ops ccp2_sd_internal_ops = { 916 .open = ccp2_init_formats, 917}; 918 919/* -------------------------------------------------------------------------- 920 * ISP ccp2 video device node 921 */ 922 923/* 924 * ccp2_video_queue - Queue video buffer. 925 * @video : Pointer to isp video structure 926 * @buffer: Pointer to isp_buffer structure 927 * return -EIO or zero on success 928 */ 929static int ccp2_video_queue(struct isp_video *video, struct isp_buffer *buffer) 930{ 931 struct isp_ccp2_device *ccp2 = &video->isp->isp_ccp2; 932 933 ccp2_set_inaddr(ccp2, buffer->dma); 934 return 0; 935} 936 937static const struct isp_video_operations ccp2_video_ops = { 938 .queue = ccp2_video_queue, 939}; 940 941/* ----------------------------------------------------------------------------- 942 * Media entity operations 943 */ 944 945/* 946 * ccp2_link_setup - Setup ccp2 connections. 947 * @entity : Pointer to media entity structure 948 * @local : Pointer to local pad array 949 * @remote : Pointer to remote pad array 950 * @flags : Link flags 951 * return -EINVAL on error or zero on success 952 */ 953static int ccp2_link_setup(struct media_entity *entity, 954 const struct media_pad *local, 955 const struct media_pad *remote, u32 flags) 956{ 957 struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity); 958 struct isp_ccp2_device *ccp2 = v4l2_get_subdevdata(sd); 959 960 switch (local->index | media_entity_type(remote->entity)) { 961 case CCP2_PAD_SINK | MEDIA_ENT_T_DEVNODE: 962 /* read from memory */ 963 if (flags & MEDIA_LNK_FL_ENABLED) { 964 if (ccp2->input == CCP2_INPUT_SENSOR) 965 return -EBUSY; 966 ccp2->input = CCP2_INPUT_MEMORY; 967 } else { 968 if (ccp2->input == CCP2_INPUT_MEMORY) 969 ccp2->input = CCP2_INPUT_NONE; 970 } 971 break; 972 973 case CCP2_PAD_SINK | MEDIA_ENT_T_V4L2_SUBDEV: 974 /* read from sensor/phy */ 975 if (flags & MEDIA_LNK_FL_ENABLED) { 976 if (ccp2->input == CCP2_INPUT_MEMORY) 977 return -EBUSY; 978 ccp2->input = CCP2_INPUT_SENSOR; 979 } else { 980 if (ccp2->input == CCP2_INPUT_SENSOR) 981 ccp2->input = CCP2_INPUT_NONE; 982 } break; 983 984 case CCP2_PAD_SOURCE | MEDIA_ENT_T_V4L2_SUBDEV: 985 /* write to video port/ccdc */ 986 if (flags & MEDIA_LNK_FL_ENABLED) 987 ccp2->output = CCP2_OUTPUT_CCDC; 988 else 989 ccp2->output = CCP2_OUTPUT_NONE; 990 break; 991 992 default: 993 return -EINVAL; 994 } 995 996 return 0; 997} 998 999/* media operations */ 1000static const struct media_entity_operations ccp2_media_ops = { 1001 .link_setup = ccp2_link_setup, 1002 .link_validate = v4l2_subdev_link_validate, 1003}; 1004 1005/* 1006 * omap3isp_ccp2_unregister_entities - Unregister media entities: subdev 1007 * @ccp2: Pointer to ISP CCP2 device 1008 */ 1009void omap3isp_ccp2_unregister_entities(struct isp_ccp2_device *ccp2) 1010{ 1011 v4l2_device_unregister_subdev(&ccp2->subdev); 1012 omap3isp_video_unregister(&ccp2->video_in); 1013} 1014 1015/* 1016 * omap3isp_ccp2_register_entities - Register the subdev media entity 1017 * @ccp2: Pointer to ISP CCP2 device 1018 * @vdev: Pointer to v4l device 1019 * return negative error code or zero on success 1020 */ 1021 1022int omap3isp_ccp2_register_entities(struct isp_ccp2_device *ccp2, 1023 struct v4l2_device *vdev) 1024{ 1025 int ret; 1026 1027 /* Register the subdev and video nodes. */ 1028 ret = v4l2_device_register_subdev(vdev, &ccp2->subdev); 1029 if (ret < 0) 1030 goto error; 1031 1032 ret = omap3isp_video_register(&ccp2->video_in, vdev); 1033 if (ret < 0) 1034 goto error; 1035 1036 return 0; 1037 1038error: 1039 omap3isp_ccp2_unregister_entities(ccp2); 1040 return ret; 1041} 1042 1043/* ----------------------------------------------------------------------------- 1044 * ISP ccp2 initialisation and cleanup 1045 */ 1046 1047/* 1048 * ccp2_init_entities - Initialize ccp2 subdev and media entity. 1049 * @ccp2: Pointer to ISP CCP2 device 1050 * return negative error code or zero on success 1051 */ 1052static int ccp2_init_entities(struct isp_ccp2_device *ccp2) 1053{ 1054 struct v4l2_subdev *sd = &ccp2->subdev; 1055 struct media_pad *pads = ccp2->pads; 1056 struct media_entity *me = &sd->entity; 1057 int ret; 1058 1059 ccp2->input = CCP2_INPUT_NONE; 1060 ccp2->output = CCP2_OUTPUT_NONE; 1061 1062 v4l2_subdev_init(sd, &ccp2_sd_ops); 1063 sd->internal_ops = &ccp2_sd_internal_ops; 1064 strlcpy(sd->name, "OMAP3 ISP CCP2", sizeof(sd->name)); 1065 sd->grp_id = 1 << 16; /* group ID for isp subdevs */ 1066 v4l2_set_subdevdata(sd, ccp2); 1067 sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; 1068 1069 pads[CCP2_PAD_SINK].flags = MEDIA_PAD_FL_SINK 1070 | MEDIA_PAD_FL_MUST_CONNECT; 1071 pads[CCP2_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE; 1072 1073 me->ops = &ccp2_media_ops; 1074 ret = media_entity_init(me, CCP2_PADS_NUM, pads, 0); 1075 if (ret < 0) 1076 return ret; 1077 1078 ccp2_init_formats(sd, NULL); 1079 1080 /* 1081 * The CCP2 has weird line alignment requirements, possibly caused by 1082 * DPCM8 decompression. Line length for data read from memory must be a 1083 * multiple of 128 bits (16 bytes) in continuous mode (when no padding 1084 * is present at end of lines). Additionally, if padding is used, the 1085 * padded line length must be a multiple of 32 bytes. To simplify the 1086 * implementation we use a fixed 32 bytes alignment regardless of the 1087 * input format and width. If strict 128 bits alignment support is 1088 * required ispvideo will need to be made aware of this special dual 1089 * alignment requirements. 1090 */ 1091 ccp2->video_in.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; 1092 ccp2->video_in.bpl_alignment = 32; 1093 ccp2->video_in.bpl_max = 0xffffffe0; 1094 ccp2->video_in.isp = to_isp_device(ccp2); 1095 ccp2->video_in.ops = &ccp2_video_ops; 1096 ccp2->video_in.capture_mem = PAGE_ALIGN(4096 * 4096) * 3; 1097 1098 ret = omap3isp_video_init(&ccp2->video_in, "CCP2"); 1099 if (ret < 0) 1100 goto error_video; 1101 1102 /* Connect the video node to the ccp2 subdev. */ 1103 ret = media_entity_create_link(&ccp2->video_in.video.entity, 0, 1104 &ccp2->subdev.entity, CCP2_PAD_SINK, 0); 1105 if (ret < 0) 1106 goto error_link; 1107 1108 return 0; 1109 1110error_link: 1111 omap3isp_video_cleanup(&ccp2->video_in); 1112error_video: 1113 media_entity_cleanup(&ccp2->subdev.entity); 1114 return ret; 1115} 1116 1117/* 1118 * omap3isp_ccp2_init - CCP2 initialization. 1119 * @isp : Pointer to ISP device 1120 * return negative error code or zero on success 1121 */ 1122int omap3isp_ccp2_init(struct isp_device *isp) 1123{ 1124 struct isp_ccp2_device *ccp2 = &isp->isp_ccp2; 1125 int ret; 1126 1127 init_waitqueue_head(&ccp2->wait); 1128 1129 /* 1130 * On the OMAP34xx the CSI1 receiver is operated in the CSIb IO 1131 * complex, which is powered by vdds_csib power rail. Hence the 1132 * request for the regulator. 1133 * 1134 * On the OMAP36xx, the CCP2 uses the CSI PHY1 or PHY2, shared with 1135 * the CSI2c or CSI2a receivers. The PHY then needs to be explicitly 1136 * configured. 1137 * 1138 * TODO: Don't hardcode the usage of PHY1 (shared with CSI2c). 1139 */ 1140 if (isp->revision == ISP_REVISION_2_0) { 1141 ccp2->vdds_csib = devm_regulator_get(isp->dev, "vdds_csib"); 1142 if (IS_ERR(ccp2->vdds_csib)) { 1143 dev_dbg(isp->dev, 1144 "Could not get regulator vdds_csib\n"); 1145 ccp2->vdds_csib = NULL; 1146 } 1147 } else if (isp->revision == ISP_REVISION_15_0) { 1148 ccp2->phy = &isp->isp_csiphy1; 1149 } 1150 1151 ret = ccp2_init_entities(ccp2); 1152 if (ret < 0) 1153 return ret; 1154 1155 ccp2_reset(ccp2); 1156 return 0; 1157} 1158 1159/* 1160 * omap3isp_ccp2_cleanup - CCP2 un-initialization 1161 * @isp : Pointer to ISP device 1162 */ 1163void omap3isp_ccp2_cleanup(struct isp_device *isp) 1164{ 1165 struct isp_ccp2_device *ccp2 = &isp->isp_ccp2; 1166 1167 omap3isp_video_cleanup(&ccp2->video_in); 1168 media_entity_cleanup(&ccp2->subdev.entity); 1169} 1170