1 /* 2 * Porting to u-boot: 3 * 4 * (C) Copyright 2010 5 * Stefano Babic, DENX Software Engineering, sbabic@denx.de 6 * 7 * Linux IPU driver for MX51: 8 * 9 * (C) Copyright 2005-2010 Freescale Semiconductor, Inc. 10 * 11 * SPDX-License-Identifier: GPL-2.0+ 12 */ 13 14 /* #define DEBUG */ 15 #include <common.h> 16 #include <linux/types.h> 17 #include <linux/err.h> 18 #include <asm/io.h> 19 #include <asm/errno.h> 20 #include <asm/arch/imx-regs.h> 21 #include <asm/arch/crm_regs.h> 22 #include "ipu.h" 23 #include "ipu_regs.h" 24 25 extern struct mxc_ccm_reg *mxc_ccm; 26 extern u32 *ipu_cpmem_base; 27 28 struct ipu_ch_param_word { 29 uint32_t data[5]; 30 uint32_t res[3]; 31 }; 32 33 struct ipu_ch_param { 34 struct ipu_ch_param_word word[2]; 35 }; 36 37 #define ipu_ch_param_addr(ch) (((struct ipu_ch_param *)ipu_cpmem_base) + (ch)) 38 39 #define _param_word(base, w) \ 40 (((struct ipu_ch_param *)(base))->word[(w)].data) 41 42 #define ipu_ch_param_set_field(base, w, bit, size, v) { \ 43 int i = (bit) / 32; \ 44 int off = (bit) % 32; \ 45 _param_word(base, w)[i] |= (v) << off; \ 46 if (((bit) + (size) - 1) / 32 > i) { \ 47 _param_word(base, w)[i + 1] |= (v) >> (off ? (32 - off) : 0); \ 48 } \ 49 } 50 51 #define ipu_ch_param_mod_field(base, w, bit, size, v) { \ 52 int i = (bit) / 32; \ 53 int off = (bit) % 32; \ 54 u32 mask = (1UL << size) - 1; \ 55 u32 temp = _param_word(base, w)[i]; \ 56 temp &= ~(mask << off); \ 57 _param_word(base, w)[i] = temp | (v) << off; \ 58 if (((bit) + (size) - 1) / 32 > i) { \ 59 temp = _param_word(base, w)[i + 1]; \ 60 temp &= ~(mask >> (32 - off)); \ 61 _param_word(base, w)[i + 1] = \ 62 temp | ((v) >> (off ? (32 - off) : 0)); \ 63 } \ 64 } 65 66 #define ipu_ch_param_read_field(base, w, bit, size) ({ \ 67 u32 temp2; \ 68 int i = (bit) / 32; \ 69 int off = (bit) % 32; \ 70 u32 mask = (1UL << size) - 1; \ 71 u32 temp1 = _param_word(base, w)[i]; \ 72 temp1 = mask & (temp1 >> off); \ 73 if (((bit)+(size) - 1) / 32 > i) { \ 74 temp2 = _param_word(base, w)[i + 1]; \ 75 temp2 &= mask >> (off ? (32 - off) : 0); \ 76 temp1 |= temp2 << (off ? (32 - off) : 0); \ 77 } \ 78 temp1; \ 79 }) 80 81 #define IPU_SW_RST_TOUT_USEC (10000) 82 83 void clk_enable(struct clk *clk) 84 { 85 if (clk) { 86 if (clk->usecount++ == 0) { 87 clk->enable(clk); 88 } 89 } 90 } 91 92 void clk_disable(struct clk *clk) 93 { 94 if (clk) { 95 if (!(--clk->usecount)) { 96 if (clk->disable) 97 clk->disable(clk); 98 } 99 } 100 } 101 102 int clk_get_usecount(struct clk *clk) 103 { 104 if (clk == NULL) 105 return 0; 106 107 return clk->usecount; 108 } 109 110 u32 clk_get_rate(struct clk *clk) 111 { 112 if (!clk) 113 return 0; 114 115 return clk->rate; 116 } 117 118 struct clk *clk_get_parent(struct clk *clk) 119 { 120 if (!clk) 121 return 0; 122 123 return clk->parent; 124 } 125 126 int clk_set_rate(struct clk *clk, unsigned long rate) 127 { 128 if (clk && clk->set_rate) 129 clk->set_rate(clk, rate); 130 return clk->rate; 131 } 132 133 long clk_round_rate(struct clk *clk, unsigned long rate) 134 { 135 if (clk == NULL || !clk->round_rate) 136 return 0; 137 138 return clk->round_rate(clk, rate); 139 } 140 141 int clk_set_parent(struct clk *clk, struct clk *parent) 142 { 143 clk->parent = parent; 144 if (clk->set_parent) 145 return clk->set_parent(clk, parent); 146 return 0; 147 } 148 149 static int clk_ipu_enable(struct clk *clk) 150 { 151 u32 reg; 152 153 reg = __raw_readl(clk->enable_reg); 154 reg |= MXC_CCM_CCGR_CG_MASK << clk->enable_shift; 155 __raw_writel(reg, clk->enable_reg); 156 157 #if defined(CONFIG_MX51) || defined(CONFIG_MX53) 158 /* Handshake with IPU when certain clock rates are changed. */ 159 reg = __raw_readl(&mxc_ccm->ccdr); 160 reg &= ~MXC_CCM_CCDR_IPU_HS_MASK; 161 __raw_writel(reg, &mxc_ccm->ccdr); 162 163 /* Handshake with IPU when LPM is entered as its enabled. */ 164 reg = __raw_readl(&mxc_ccm->clpcr); 165 reg &= ~MXC_CCM_CLPCR_BYPASS_IPU_LPM_HS; 166 __raw_writel(reg, &mxc_ccm->clpcr); 167 #endif 168 return 0; 169 } 170 171 static void clk_ipu_disable(struct clk *clk) 172 { 173 u32 reg; 174 175 reg = __raw_readl(clk->enable_reg); 176 reg &= ~(MXC_CCM_CCGR_CG_MASK << clk->enable_shift); 177 __raw_writel(reg, clk->enable_reg); 178 179 #if defined(CONFIG_MX51) || defined(CONFIG_MX53) 180 /* 181 * No handshake with IPU whe dividers are changed 182 * as its not enabled. 183 */ 184 reg = __raw_readl(&mxc_ccm->ccdr); 185 reg |= MXC_CCM_CCDR_IPU_HS_MASK; 186 __raw_writel(reg, &mxc_ccm->ccdr); 187 188 /* No handshake with IPU when LPM is entered as its not enabled. */ 189 reg = __raw_readl(&mxc_ccm->clpcr); 190 reg |= MXC_CCM_CLPCR_BYPASS_IPU_LPM_HS; 191 __raw_writel(reg, &mxc_ccm->clpcr); 192 #endif 193 } 194 195 196 static struct clk ipu_clk = { 197 .name = "ipu_clk", 198 .rate = CONFIG_IPUV3_CLK, 199 #if defined(CONFIG_MX51) || defined(CONFIG_MX53) 200 .enable_reg = (u32 *)(CCM_BASE_ADDR + 201 offsetof(struct mxc_ccm_reg, CCGR5)), 202 .enable_shift = MXC_CCM_CCGR5_IPU_OFFSET, 203 #else 204 .enable_reg = (u32 *)(CCM_BASE_ADDR + 205 offsetof(struct mxc_ccm_reg, CCGR3)), 206 .enable_shift = MXC_CCM_CCGR3_IPU1_IPU_DI0_OFFSET, 207 #endif 208 .enable = clk_ipu_enable, 209 .disable = clk_ipu_disable, 210 .usecount = 0, 211 }; 212 213 #if !defined CONFIG_SYS_LDB_CLOCK 214 #define CONFIG_SYS_LDB_CLOCK 65000000 215 #endif 216 217 static struct clk ldb_clk = { 218 .name = "ldb_clk", 219 .rate = CONFIG_SYS_LDB_CLOCK, 220 .usecount = 0, 221 }; 222 223 /* Globals */ 224 struct clk *g_ipu_clk; 225 struct clk *g_ldb_clk; 226 unsigned char g_ipu_clk_enabled; 227 struct clk *g_di_clk[2]; 228 struct clk *g_pixel_clk[2]; 229 unsigned char g_dc_di_assignment[10]; 230 uint32_t g_channel_init_mask; 231 uint32_t g_channel_enable_mask; 232 233 static int ipu_dc_use_count; 234 static int ipu_dp_use_count; 235 static int ipu_dmfc_use_count; 236 static int ipu_di_use_count[2]; 237 238 u32 *ipu_cpmem_base; 239 u32 *ipu_dc_tmpl_reg; 240 241 /* Static functions */ 242 243 static inline void ipu_ch_param_set_high_priority(uint32_t ch) 244 { 245 ipu_ch_param_mod_field(ipu_ch_param_addr(ch), 1, 93, 2, 1); 246 }; 247 248 static inline uint32_t channel_2_dma(ipu_channel_t ch, ipu_buffer_t type) 249 { 250 return ((uint32_t) ch >> (6 * type)) & 0x3F; 251 }; 252 253 /* Either DP BG or DP FG can be graphic window */ 254 static inline int ipu_is_dp_graphic_chan(uint32_t dma_chan) 255 { 256 return (dma_chan == 23 || dma_chan == 27); 257 } 258 259 static inline int ipu_is_dmfc_chan(uint32_t dma_chan) 260 { 261 return ((dma_chan >= 23) && (dma_chan <= 29)); 262 } 263 264 265 static inline void ipu_ch_param_set_buffer(uint32_t ch, int bufNum, 266 dma_addr_t phyaddr) 267 { 268 ipu_ch_param_mod_field(ipu_ch_param_addr(ch), 1, 29 * bufNum, 29, 269 phyaddr / 8); 270 }; 271 272 #define idma_is_valid(ch) (ch != NO_DMA) 273 #define idma_mask(ch) (idma_is_valid(ch) ? (1UL << (ch & 0x1F)) : 0) 274 #define idma_is_set(reg, dma) (__raw_readl(reg(dma)) & idma_mask(dma)) 275 276 static void ipu_pixel_clk_recalc(struct clk *clk) 277 { 278 u32 div = __raw_readl(DI_BS_CLKGEN0(clk->id)); 279 if (div == 0) 280 clk->rate = 0; 281 else 282 clk->rate = (clk->parent->rate * 16) / div; 283 } 284 285 static unsigned long ipu_pixel_clk_round_rate(struct clk *clk, 286 unsigned long rate) 287 { 288 u32 div, div1; 289 u32 tmp; 290 /* 291 * Calculate divider 292 * Fractional part is 4 bits, 293 * so simply multiply by 2^4 to get fractional part. 294 */ 295 tmp = (clk->parent->rate * 16); 296 div = tmp / rate; 297 298 if (div < 0x10) /* Min DI disp clock divider is 1 */ 299 div = 0x10; 300 if (div & ~0xFEF) 301 div &= 0xFF8; 302 else { 303 div1 = div & 0xFE0; 304 if ((tmp/div1 - tmp/div) < rate / 4) 305 div = div1; 306 else 307 div &= 0xFF8; 308 } 309 return (clk->parent->rate * 16) / div; 310 } 311 312 static int ipu_pixel_clk_set_rate(struct clk *clk, unsigned long rate) 313 { 314 u32 div = (clk->parent->rate * 16) / rate; 315 316 __raw_writel(div, DI_BS_CLKGEN0(clk->id)); 317 318 /* Setup pixel clock timing */ 319 __raw_writel((div / 16) << 16, DI_BS_CLKGEN1(clk->id)); 320 321 clk->rate = (clk->parent->rate * 16) / div; 322 return 0; 323 } 324 325 static int ipu_pixel_clk_enable(struct clk *clk) 326 { 327 u32 disp_gen = __raw_readl(IPU_DISP_GEN); 328 disp_gen |= clk->id ? DI1_COUNTER_RELEASE : DI0_COUNTER_RELEASE; 329 __raw_writel(disp_gen, IPU_DISP_GEN); 330 331 return 0; 332 } 333 334 static void ipu_pixel_clk_disable(struct clk *clk) 335 { 336 u32 disp_gen = __raw_readl(IPU_DISP_GEN); 337 disp_gen &= clk->id ? ~DI1_COUNTER_RELEASE : ~DI0_COUNTER_RELEASE; 338 __raw_writel(disp_gen, IPU_DISP_GEN); 339 340 } 341 342 static int ipu_pixel_clk_set_parent(struct clk *clk, struct clk *parent) 343 { 344 u32 di_gen = __raw_readl(DI_GENERAL(clk->id)); 345 346 if (parent == g_ipu_clk) 347 di_gen &= ~DI_GEN_DI_CLK_EXT; 348 else if (!IS_ERR(g_di_clk[clk->id]) && parent == g_ldb_clk) 349 di_gen |= DI_GEN_DI_CLK_EXT; 350 else 351 return -EINVAL; 352 353 __raw_writel(di_gen, DI_GENERAL(clk->id)); 354 ipu_pixel_clk_recalc(clk); 355 return 0; 356 } 357 358 static struct clk pixel_clk[] = { 359 { 360 .name = "pixel_clk", 361 .id = 0, 362 .recalc = ipu_pixel_clk_recalc, 363 .set_rate = ipu_pixel_clk_set_rate, 364 .round_rate = ipu_pixel_clk_round_rate, 365 .set_parent = ipu_pixel_clk_set_parent, 366 .enable = ipu_pixel_clk_enable, 367 .disable = ipu_pixel_clk_disable, 368 .usecount = 0, 369 }, 370 { 371 .name = "pixel_clk", 372 .id = 1, 373 .recalc = ipu_pixel_clk_recalc, 374 .set_rate = ipu_pixel_clk_set_rate, 375 .round_rate = ipu_pixel_clk_round_rate, 376 .set_parent = ipu_pixel_clk_set_parent, 377 .enable = ipu_pixel_clk_enable, 378 .disable = ipu_pixel_clk_disable, 379 .usecount = 0, 380 }, 381 }; 382 383 /* 384 * This function resets IPU 385 */ 386 static void ipu_reset(void) 387 { 388 u32 *reg; 389 u32 value; 390 int timeout = IPU_SW_RST_TOUT_USEC; 391 392 reg = (u32 *)SRC_BASE_ADDR; 393 value = __raw_readl(reg); 394 value = value | SW_IPU_RST; 395 __raw_writel(value, reg); 396 397 while (__raw_readl(reg) & SW_IPU_RST) { 398 udelay(1); 399 if (!(timeout--)) { 400 printf("ipu software reset timeout\n"); 401 break; 402 } 403 }; 404 } 405 406 /* 407 * This function is called by the driver framework to initialize the IPU 408 * hardware. 409 * 410 * @param dev The device structure for the IPU passed in by the 411 * driver framework. 412 * 413 * @return Returns 0 on success or negative error code on error 414 */ 415 int ipu_probe(void) 416 { 417 unsigned long ipu_base; 418 #if defined CONFIG_MX51 419 u32 temp; 420 421 u32 *reg_hsc_mcd = (u32 *)MIPI_HSC_BASE_ADDR; 422 u32 *reg_hsc_mxt_conf = (u32 *)(MIPI_HSC_BASE_ADDR + 0x800); 423 424 __raw_writel(0xF00, reg_hsc_mcd); 425 426 /* CSI mode reserved*/ 427 temp = __raw_readl(reg_hsc_mxt_conf); 428 __raw_writel(temp | 0x0FF, reg_hsc_mxt_conf); 429 430 temp = __raw_readl(reg_hsc_mxt_conf); 431 __raw_writel(temp | 0x10000, reg_hsc_mxt_conf); 432 #endif 433 434 ipu_base = IPU_CTRL_BASE_ADDR; 435 ipu_cpmem_base = (u32 *)(ipu_base + IPU_CPMEM_REG_BASE); 436 ipu_dc_tmpl_reg = (u32 *)(ipu_base + IPU_DC_TMPL_REG_BASE); 437 438 g_pixel_clk[0] = &pixel_clk[0]; 439 g_pixel_clk[1] = &pixel_clk[1]; 440 441 g_ipu_clk = &ipu_clk; 442 debug("ipu_clk = %u\n", clk_get_rate(g_ipu_clk)); 443 g_ldb_clk = &ldb_clk; 444 debug("ldb_clk = %u\n", clk_get_rate(g_ldb_clk)); 445 ipu_reset(); 446 447 clk_set_parent(g_pixel_clk[0], g_ipu_clk); 448 clk_set_parent(g_pixel_clk[1], g_ipu_clk); 449 clk_enable(g_ipu_clk); 450 451 g_di_clk[0] = NULL; 452 g_di_clk[1] = NULL; 453 454 __raw_writel(0x807FFFFF, IPU_MEM_RST); 455 while (__raw_readl(IPU_MEM_RST) & 0x80000000) 456 ; 457 458 ipu_init_dc_mappings(); 459 460 __raw_writel(0, IPU_INT_CTRL(5)); 461 __raw_writel(0, IPU_INT_CTRL(6)); 462 __raw_writel(0, IPU_INT_CTRL(9)); 463 __raw_writel(0, IPU_INT_CTRL(10)); 464 465 /* DMFC Init */ 466 ipu_dmfc_init(DMFC_NORMAL, 1); 467 468 /* Set sync refresh channels as high priority */ 469 __raw_writel(0x18800000L, IDMAC_CHA_PRI(0)); 470 471 /* Set MCU_T to divide MCU access window into 2 */ 472 __raw_writel(0x00400000L | (IPU_MCU_T_DEFAULT << 18), IPU_DISP_GEN); 473 474 clk_disable(g_ipu_clk); 475 476 return 0; 477 } 478 479 void ipu_dump_registers(void) 480 { 481 debug("IPU_CONF = \t0x%08X\n", __raw_readl(IPU_CONF)); 482 debug("IDMAC_CONF = \t0x%08X\n", __raw_readl(IDMAC_CONF)); 483 debug("IDMAC_CHA_EN1 = \t0x%08X\n", 484 __raw_readl(IDMAC_CHA_EN(0))); 485 debug("IDMAC_CHA_EN2 = \t0x%08X\n", 486 __raw_readl(IDMAC_CHA_EN(32))); 487 debug("IDMAC_CHA_PRI1 = \t0x%08X\n", 488 __raw_readl(IDMAC_CHA_PRI(0))); 489 debug("IDMAC_CHA_PRI2 = \t0x%08X\n", 490 __raw_readl(IDMAC_CHA_PRI(32))); 491 debug("IPU_CHA_DB_MODE_SEL0 = \t0x%08X\n", 492 __raw_readl(IPU_CHA_DB_MODE_SEL(0))); 493 debug("IPU_CHA_DB_MODE_SEL1 = \t0x%08X\n", 494 __raw_readl(IPU_CHA_DB_MODE_SEL(32))); 495 debug("DMFC_WR_CHAN = \t0x%08X\n", 496 __raw_readl(DMFC_WR_CHAN)); 497 debug("DMFC_WR_CHAN_DEF = \t0x%08X\n", 498 __raw_readl(DMFC_WR_CHAN_DEF)); 499 debug("DMFC_DP_CHAN = \t0x%08X\n", 500 __raw_readl(DMFC_DP_CHAN)); 501 debug("DMFC_DP_CHAN_DEF = \t0x%08X\n", 502 __raw_readl(DMFC_DP_CHAN_DEF)); 503 debug("DMFC_IC_CTRL = \t0x%08X\n", 504 __raw_readl(DMFC_IC_CTRL)); 505 debug("IPU_FS_PROC_FLOW1 = \t0x%08X\n", 506 __raw_readl(IPU_FS_PROC_FLOW1)); 507 debug("IPU_FS_PROC_FLOW2 = \t0x%08X\n", 508 __raw_readl(IPU_FS_PROC_FLOW2)); 509 debug("IPU_FS_PROC_FLOW3 = \t0x%08X\n", 510 __raw_readl(IPU_FS_PROC_FLOW3)); 511 debug("IPU_FS_DISP_FLOW1 = \t0x%08X\n", 512 __raw_readl(IPU_FS_DISP_FLOW1)); 513 } 514 515 /* 516 * This function is called to initialize a logical IPU channel. 517 * 518 * @param channel Input parameter for the logical channel ID to init. 519 * 520 * @param params Input parameter containing union of channel 521 * initialization parameters. 522 * 523 * @return Returns 0 on success or negative error code on fail 524 */ 525 int32_t ipu_init_channel(ipu_channel_t channel, ipu_channel_params_t *params) 526 { 527 int ret = 0; 528 uint32_t ipu_conf; 529 530 debug("init channel = %d\n", IPU_CHAN_ID(channel)); 531 532 if (g_ipu_clk_enabled == 0) { 533 g_ipu_clk_enabled = 1; 534 clk_enable(g_ipu_clk); 535 } 536 537 538 if (g_channel_init_mask & (1L << IPU_CHAN_ID(channel))) { 539 printf("Warning: channel already initialized %d\n", 540 IPU_CHAN_ID(channel)); 541 } 542 543 ipu_conf = __raw_readl(IPU_CONF); 544 545 switch (channel) { 546 case MEM_DC_SYNC: 547 if (params->mem_dc_sync.di > 1) { 548 ret = -EINVAL; 549 goto err; 550 } 551 552 g_dc_di_assignment[1] = params->mem_dc_sync.di; 553 ipu_dc_init(1, params->mem_dc_sync.di, 554 params->mem_dc_sync.interlaced); 555 ipu_di_use_count[params->mem_dc_sync.di]++; 556 ipu_dc_use_count++; 557 ipu_dmfc_use_count++; 558 break; 559 case MEM_BG_SYNC: 560 if (params->mem_dp_bg_sync.di > 1) { 561 ret = -EINVAL; 562 goto err; 563 } 564 565 g_dc_di_assignment[5] = params->mem_dp_bg_sync.di; 566 ipu_dp_init(channel, params->mem_dp_bg_sync.in_pixel_fmt, 567 params->mem_dp_bg_sync.out_pixel_fmt); 568 ipu_dc_init(5, params->mem_dp_bg_sync.di, 569 params->mem_dp_bg_sync.interlaced); 570 ipu_di_use_count[params->mem_dp_bg_sync.di]++; 571 ipu_dc_use_count++; 572 ipu_dp_use_count++; 573 ipu_dmfc_use_count++; 574 break; 575 case MEM_FG_SYNC: 576 ipu_dp_init(channel, params->mem_dp_fg_sync.in_pixel_fmt, 577 params->mem_dp_fg_sync.out_pixel_fmt); 578 579 ipu_dc_use_count++; 580 ipu_dp_use_count++; 581 ipu_dmfc_use_count++; 582 break; 583 default: 584 printf("Missing channel initialization\n"); 585 break; 586 } 587 588 /* Enable IPU sub module */ 589 g_channel_init_mask |= 1L << IPU_CHAN_ID(channel); 590 if (ipu_dc_use_count == 1) 591 ipu_conf |= IPU_CONF_DC_EN; 592 if (ipu_dp_use_count == 1) 593 ipu_conf |= IPU_CONF_DP_EN; 594 if (ipu_dmfc_use_count == 1) 595 ipu_conf |= IPU_CONF_DMFC_EN; 596 if (ipu_di_use_count[0] == 1) { 597 ipu_conf |= IPU_CONF_DI0_EN; 598 } 599 if (ipu_di_use_count[1] == 1) { 600 ipu_conf |= IPU_CONF_DI1_EN; 601 } 602 603 __raw_writel(ipu_conf, IPU_CONF); 604 605 err: 606 return ret; 607 } 608 609 /* 610 * This function is called to uninitialize a logical IPU channel. 611 * 612 * @param channel Input parameter for the logical channel ID to uninit. 613 */ 614 void ipu_uninit_channel(ipu_channel_t channel) 615 { 616 uint32_t reg; 617 uint32_t in_dma, out_dma = 0; 618 uint32_t ipu_conf; 619 620 if ((g_channel_init_mask & (1L << IPU_CHAN_ID(channel))) == 0) { 621 debug("Channel already uninitialized %d\n", 622 IPU_CHAN_ID(channel)); 623 return; 624 } 625 626 /* 627 * Make sure channel is disabled 628 * Get input and output dma channels 629 */ 630 in_dma = channel_2_dma(channel, IPU_OUTPUT_BUFFER); 631 out_dma = channel_2_dma(channel, IPU_VIDEO_IN_BUFFER); 632 633 if (idma_is_set(IDMAC_CHA_EN, in_dma) || 634 idma_is_set(IDMAC_CHA_EN, out_dma)) { 635 printf( 636 "Channel %d is not disabled, disable first\n", 637 IPU_CHAN_ID(channel)); 638 return; 639 } 640 641 ipu_conf = __raw_readl(IPU_CONF); 642 643 /* Reset the double buffer */ 644 reg = __raw_readl(IPU_CHA_DB_MODE_SEL(in_dma)); 645 __raw_writel(reg & ~idma_mask(in_dma), IPU_CHA_DB_MODE_SEL(in_dma)); 646 reg = __raw_readl(IPU_CHA_DB_MODE_SEL(out_dma)); 647 __raw_writel(reg & ~idma_mask(out_dma), IPU_CHA_DB_MODE_SEL(out_dma)); 648 649 switch (channel) { 650 case MEM_DC_SYNC: 651 ipu_dc_uninit(1); 652 ipu_di_use_count[g_dc_di_assignment[1]]--; 653 ipu_dc_use_count--; 654 ipu_dmfc_use_count--; 655 break; 656 case MEM_BG_SYNC: 657 ipu_dp_uninit(channel); 658 ipu_dc_uninit(5); 659 ipu_di_use_count[g_dc_di_assignment[5]]--; 660 ipu_dc_use_count--; 661 ipu_dp_use_count--; 662 ipu_dmfc_use_count--; 663 break; 664 case MEM_FG_SYNC: 665 ipu_dp_uninit(channel); 666 ipu_dc_use_count--; 667 ipu_dp_use_count--; 668 ipu_dmfc_use_count--; 669 break; 670 default: 671 break; 672 } 673 674 g_channel_init_mask &= ~(1L << IPU_CHAN_ID(channel)); 675 676 if (ipu_dc_use_count == 0) 677 ipu_conf &= ~IPU_CONF_DC_EN; 678 if (ipu_dp_use_count == 0) 679 ipu_conf &= ~IPU_CONF_DP_EN; 680 if (ipu_dmfc_use_count == 0) 681 ipu_conf &= ~IPU_CONF_DMFC_EN; 682 if (ipu_di_use_count[0] == 0) { 683 ipu_conf &= ~IPU_CONF_DI0_EN; 684 } 685 if (ipu_di_use_count[1] == 0) { 686 ipu_conf &= ~IPU_CONF_DI1_EN; 687 } 688 689 __raw_writel(ipu_conf, IPU_CONF); 690 691 if (ipu_conf == 0) { 692 clk_disable(g_ipu_clk); 693 g_ipu_clk_enabled = 0; 694 } 695 696 } 697 698 static inline void ipu_ch_param_dump(int ch) 699 { 700 #ifdef DEBUG 701 struct ipu_ch_param *p = ipu_ch_param_addr(ch); 702 debug("ch %d word 0 - %08X %08X %08X %08X %08X\n", ch, 703 p->word[0].data[0], p->word[0].data[1], p->word[0].data[2], 704 p->word[0].data[3], p->word[0].data[4]); 705 debug("ch %d word 1 - %08X %08X %08X %08X %08X\n", ch, 706 p->word[1].data[0], p->word[1].data[1], p->word[1].data[2], 707 p->word[1].data[3], p->word[1].data[4]); 708 debug("PFS 0x%x, ", 709 ipu_ch_param_read_field(ipu_ch_param_addr(ch), 1, 85, 4)); 710 debug("BPP 0x%x, ", 711 ipu_ch_param_read_field(ipu_ch_param_addr(ch), 0, 107, 3)); 712 debug("NPB 0x%x\n", 713 ipu_ch_param_read_field(ipu_ch_param_addr(ch), 1, 78, 7)); 714 715 debug("FW %d, ", 716 ipu_ch_param_read_field(ipu_ch_param_addr(ch), 0, 125, 13)); 717 debug("FH %d, ", 718 ipu_ch_param_read_field(ipu_ch_param_addr(ch), 0, 138, 12)); 719 debug("Stride %d\n", 720 ipu_ch_param_read_field(ipu_ch_param_addr(ch), 1, 102, 14)); 721 722 debug("Width0 %d+1, ", 723 ipu_ch_param_read_field(ipu_ch_param_addr(ch), 1, 116, 3)); 724 debug("Width1 %d+1, ", 725 ipu_ch_param_read_field(ipu_ch_param_addr(ch), 1, 119, 3)); 726 debug("Width2 %d+1, ", 727 ipu_ch_param_read_field(ipu_ch_param_addr(ch), 1, 122, 3)); 728 debug("Width3 %d+1, ", 729 ipu_ch_param_read_field(ipu_ch_param_addr(ch), 1, 125, 3)); 730 debug("Offset0 %d, ", 731 ipu_ch_param_read_field(ipu_ch_param_addr(ch), 1, 128, 5)); 732 debug("Offset1 %d, ", 733 ipu_ch_param_read_field(ipu_ch_param_addr(ch), 1, 133, 5)); 734 debug("Offset2 %d, ", 735 ipu_ch_param_read_field(ipu_ch_param_addr(ch), 1, 138, 5)); 736 debug("Offset3 %d\n", 737 ipu_ch_param_read_field(ipu_ch_param_addr(ch), 1, 143, 5)); 738 #endif 739 } 740 741 static inline void ipu_ch_params_set_packing(struct ipu_ch_param *p, 742 int red_width, int red_offset, 743 int green_width, int green_offset, 744 int blue_width, int blue_offset, 745 int alpha_width, int alpha_offset) 746 { 747 /* Setup red width and offset */ 748 ipu_ch_param_set_field(p, 1, 116, 3, red_width - 1); 749 ipu_ch_param_set_field(p, 1, 128, 5, red_offset); 750 /* Setup green width and offset */ 751 ipu_ch_param_set_field(p, 1, 119, 3, green_width - 1); 752 ipu_ch_param_set_field(p, 1, 133, 5, green_offset); 753 /* Setup blue width and offset */ 754 ipu_ch_param_set_field(p, 1, 122, 3, blue_width - 1); 755 ipu_ch_param_set_field(p, 1, 138, 5, blue_offset); 756 /* Setup alpha width and offset */ 757 ipu_ch_param_set_field(p, 1, 125, 3, alpha_width - 1); 758 ipu_ch_param_set_field(p, 1, 143, 5, alpha_offset); 759 } 760 761 static void ipu_ch_param_init(int ch, 762 uint32_t pixel_fmt, uint32_t width, 763 uint32_t height, uint32_t stride, 764 uint32_t u, uint32_t v, 765 uint32_t uv_stride, dma_addr_t addr0, 766 dma_addr_t addr1) 767 { 768 uint32_t u_offset = 0; 769 uint32_t v_offset = 0; 770 struct ipu_ch_param params; 771 772 memset(¶ms, 0, sizeof(params)); 773 774 ipu_ch_param_set_field(¶ms, 0, 125, 13, width - 1); 775 776 if ((ch == 8) || (ch == 9) || (ch == 10)) { 777 ipu_ch_param_set_field(¶ms, 0, 138, 12, (height / 2) - 1); 778 ipu_ch_param_set_field(¶ms, 1, 102, 14, (stride * 2) - 1); 779 } else { 780 ipu_ch_param_set_field(¶ms, 0, 138, 12, height - 1); 781 ipu_ch_param_set_field(¶ms, 1, 102, 14, stride - 1); 782 } 783 784 ipu_ch_param_set_field(¶ms, 1, 0, 29, addr0 >> 3); 785 ipu_ch_param_set_field(¶ms, 1, 29, 29, addr1 >> 3); 786 787 switch (pixel_fmt) { 788 case IPU_PIX_FMT_GENERIC: 789 /*Represents 8-bit Generic data */ 790 ipu_ch_param_set_field(¶ms, 0, 107, 3, 5); /* bits/pixel */ 791 ipu_ch_param_set_field(¶ms, 1, 85, 4, 6); /* pix format */ 792 ipu_ch_param_set_field(¶ms, 1, 78, 7, 63); /* burst size */ 793 794 break; 795 case IPU_PIX_FMT_GENERIC_32: 796 /*Represents 32-bit Generic data */ 797 break; 798 case IPU_PIX_FMT_RGB565: 799 ipu_ch_param_set_field(¶ms, 0, 107, 3, 3); /* bits/pixel */ 800 ipu_ch_param_set_field(¶ms, 1, 85, 4, 7); /* pix format */ 801 ipu_ch_param_set_field(¶ms, 1, 78, 7, 15); /* burst size */ 802 803 ipu_ch_params_set_packing(¶ms, 5, 0, 6, 5, 5, 11, 8, 16); 804 break; 805 case IPU_PIX_FMT_BGR24: 806 ipu_ch_param_set_field(¶ms, 0, 107, 3, 1); /* bits/pixel */ 807 ipu_ch_param_set_field(¶ms, 1, 85, 4, 7); /* pix format */ 808 ipu_ch_param_set_field(¶ms, 1, 78, 7, 19); /* burst size */ 809 810 ipu_ch_params_set_packing(¶ms, 8, 0, 8, 8, 8, 16, 8, 24); 811 break; 812 case IPU_PIX_FMT_RGB24: 813 case IPU_PIX_FMT_YUV444: 814 ipu_ch_param_set_field(¶ms, 0, 107, 3, 1); /* bits/pixel */ 815 ipu_ch_param_set_field(¶ms, 1, 85, 4, 7); /* pix format */ 816 ipu_ch_param_set_field(¶ms, 1, 78, 7, 19); /* burst size */ 817 818 ipu_ch_params_set_packing(¶ms, 8, 16, 8, 8, 8, 0, 8, 24); 819 break; 820 case IPU_PIX_FMT_BGRA32: 821 case IPU_PIX_FMT_BGR32: 822 ipu_ch_param_set_field(¶ms, 0, 107, 3, 0); /* bits/pixel */ 823 ipu_ch_param_set_field(¶ms, 1, 85, 4, 7); /* pix format */ 824 ipu_ch_param_set_field(¶ms, 1, 78, 7, 15); /* burst size */ 825 826 ipu_ch_params_set_packing(¶ms, 8, 8, 8, 16, 8, 24, 8, 0); 827 break; 828 case IPU_PIX_FMT_RGBA32: 829 case IPU_PIX_FMT_RGB32: 830 ipu_ch_param_set_field(¶ms, 0, 107, 3, 0); /* bits/pixel */ 831 ipu_ch_param_set_field(¶ms, 1, 85, 4, 7); /* pix format */ 832 ipu_ch_param_set_field(¶ms, 1, 78, 7, 15); /* burst size */ 833 834 ipu_ch_params_set_packing(¶ms, 8, 24, 8, 16, 8, 8, 8, 0); 835 break; 836 case IPU_PIX_FMT_ABGR32: 837 ipu_ch_param_set_field(¶ms, 0, 107, 3, 0); /* bits/pixel */ 838 ipu_ch_param_set_field(¶ms, 1, 85, 4, 7); /* pix format */ 839 840 ipu_ch_params_set_packing(¶ms, 8, 0, 8, 8, 8, 16, 8, 24); 841 break; 842 case IPU_PIX_FMT_UYVY: 843 ipu_ch_param_set_field(¶ms, 0, 107, 3, 3); /* bits/pixel */ 844 ipu_ch_param_set_field(¶ms, 1, 85, 4, 0xA); /* pix format */ 845 ipu_ch_param_set_field(¶ms, 1, 78, 7, 15); /* burst size */ 846 break; 847 case IPU_PIX_FMT_YUYV: 848 ipu_ch_param_set_field(¶ms, 0, 107, 3, 3); /* bits/pixel */ 849 ipu_ch_param_set_field(¶ms, 1, 85, 4, 0x8); /* pix format */ 850 ipu_ch_param_set_field(¶ms, 1, 78, 7, 31); /* burst size */ 851 break; 852 case IPU_PIX_FMT_YUV420P2: 853 case IPU_PIX_FMT_YUV420P: 854 ipu_ch_param_set_field(¶ms, 1, 85, 4, 2); /* pix format */ 855 856 if (uv_stride < stride / 2) 857 uv_stride = stride / 2; 858 859 u_offset = stride * height; 860 v_offset = u_offset + (uv_stride * height / 2); 861 /* burst size */ 862 if ((ch == 8) || (ch == 9) || (ch == 10)) { 863 ipu_ch_param_set_field(¶ms, 1, 78, 7, 15); 864 uv_stride = uv_stride*2; 865 } else { 866 ipu_ch_param_set_field(¶ms, 1, 78, 7, 31); 867 } 868 break; 869 case IPU_PIX_FMT_YVU422P: 870 /* BPP & pixel format */ 871 ipu_ch_param_set_field(¶ms, 1, 85, 4, 1); /* pix format */ 872 ipu_ch_param_set_field(¶ms, 1, 78, 7, 31); /* burst size */ 873 874 if (uv_stride < stride / 2) 875 uv_stride = stride / 2; 876 877 v_offset = (v == 0) ? stride * height : v; 878 u_offset = (u == 0) ? v_offset + v_offset / 2 : u; 879 break; 880 case IPU_PIX_FMT_YUV422P: 881 /* BPP & pixel format */ 882 ipu_ch_param_set_field(¶ms, 1, 85, 4, 1); /* pix format */ 883 ipu_ch_param_set_field(¶ms, 1, 78, 7, 31); /* burst size */ 884 885 if (uv_stride < stride / 2) 886 uv_stride = stride / 2; 887 888 u_offset = (u == 0) ? stride * height : u; 889 v_offset = (v == 0) ? u_offset + u_offset / 2 : v; 890 break; 891 case IPU_PIX_FMT_NV12: 892 /* BPP & pixel format */ 893 ipu_ch_param_set_field(¶ms, 1, 85, 4, 4); /* pix format */ 894 ipu_ch_param_set_field(¶ms, 1, 78, 7, 31); /* burst size */ 895 uv_stride = stride; 896 u_offset = (u == 0) ? stride * height : u; 897 break; 898 default: 899 puts("mxc ipu: unimplemented pixel format\n"); 900 break; 901 } 902 903 904 if (uv_stride) 905 ipu_ch_param_set_field(¶ms, 1, 128, 14, uv_stride - 1); 906 907 /* Get the uv offset from user when need cropping */ 908 if (u || v) { 909 u_offset = u; 910 v_offset = v; 911 } 912 913 /* UBO and VBO are 22-bit */ 914 if (u_offset/8 > 0x3fffff) 915 puts("The value of U offset exceeds IPU limitation\n"); 916 if (v_offset/8 > 0x3fffff) 917 puts("The value of V offset exceeds IPU limitation\n"); 918 919 ipu_ch_param_set_field(¶ms, 0, 46, 22, u_offset / 8); 920 ipu_ch_param_set_field(¶ms, 0, 68, 22, v_offset / 8); 921 922 debug("initializing idma ch %d @ %p\n", ch, ipu_ch_param_addr(ch)); 923 memcpy(ipu_ch_param_addr(ch), ¶ms, sizeof(params)); 924 }; 925 926 /* 927 * This function is called to initialize a buffer for logical IPU channel. 928 * 929 * @param channel Input parameter for the logical channel ID. 930 * 931 * @param type Input parameter which buffer to initialize. 932 * 933 * @param pixel_fmt Input parameter for pixel format of buffer. 934 * Pixel format is a FOURCC ASCII code. 935 * 936 * @param width Input parameter for width of buffer in pixels. 937 * 938 * @param height Input parameter for height of buffer in pixels. 939 * 940 * @param stride Input parameter for stride length of buffer 941 * in pixels. 942 * 943 * @param phyaddr_0 Input parameter buffer 0 physical address. 944 * 945 * @param phyaddr_1 Input parameter buffer 1 physical address. 946 * Setting this to a value other than NULL enables 947 * double buffering mode. 948 * 949 * @param u private u offset for additional cropping, 950 * zero if not used. 951 * 952 * @param v private v offset for additional cropping, 953 * zero if not used. 954 * 955 * @return Returns 0 on success or negative error code on fail 956 */ 957 int32_t ipu_init_channel_buffer(ipu_channel_t channel, ipu_buffer_t type, 958 uint32_t pixel_fmt, 959 uint16_t width, uint16_t height, 960 uint32_t stride, 961 dma_addr_t phyaddr_0, dma_addr_t phyaddr_1, 962 uint32_t u, uint32_t v) 963 { 964 uint32_t reg; 965 uint32_t dma_chan; 966 967 dma_chan = channel_2_dma(channel, type); 968 if (!idma_is_valid(dma_chan)) 969 return -EINVAL; 970 971 if (stride < width * bytes_per_pixel(pixel_fmt)) 972 stride = width * bytes_per_pixel(pixel_fmt); 973 974 if (stride % 4) { 975 printf( 976 "Stride not 32-bit aligned, stride = %d\n", stride); 977 return -EINVAL; 978 } 979 /* Build parameter memory data for DMA channel */ 980 ipu_ch_param_init(dma_chan, pixel_fmt, width, height, stride, u, v, 0, 981 phyaddr_0, phyaddr_1); 982 983 if (ipu_is_dmfc_chan(dma_chan)) { 984 ipu_dmfc_set_wait4eot(dma_chan, width); 985 } 986 987 if (idma_is_set(IDMAC_CHA_PRI, dma_chan)) 988 ipu_ch_param_set_high_priority(dma_chan); 989 990 ipu_ch_param_dump(dma_chan); 991 992 reg = __raw_readl(IPU_CHA_DB_MODE_SEL(dma_chan)); 993 if (phyaddr_1) 994 reg |= idma_mask(dma_chan); 995 else 996 reg &= ~idma_mask(dma_chan); 997 __raw_writel(reg, IPU_CHA_DB_MODE_SEL(dma_chan)); 998 999 /* Reset to buffer 0 */ 1000 __raw_writel(idma_mask(dma_chan), IPU_CHA_CUR_BUF(dma_chan)); 1001 1002 return 0; 1003 } 1004 1005 /* 1006 * This function enables a logical channel. 1007 * 1008 * @param channel Input parameter for the logical channel ID. 1009 * 1010 * @return This function returns 0 on success or negative error code on 1011 * fail. 1012 */ 1013 int32_t ipu_enable_channel(ipu_channel_t channel) 1014 { 1015 uint32_t reg; 1016 uint32_t in_dma; 1017 uint32_t out_dma; 1018 1019 if (g_channel_enable_mask & (1L << IPU_CHAN_ID(channel))) { 1020 printf("Warning: channel already enabled %d\n", 1021 IPU_CHAN_ID(channel)); 1022 } 1023 1024 /* Get input and output dma channels */ 1025 out_dma = channel_2_dma(channel, IPU_OUTPUT_BUFFER); 1026 in_dma = channel_2_dma(channel, IPU_VIDEO_IN_BUFFER); 1027 1028 if (idma_is_valid(in_dma)) { 1029 reg = __raw_readl(IDMAC_CHA_EN(in_dma)); 1030 __raw_writel(reg | idma_mask(in_dma), IDMAC_CHA_EN(in_dma)); 1031 } 1032 if (idma_is_valid(out_dma)) { 1033 reg = __raw_readl(IDMAC_CHA_EN(out_dma)); 1034 __raw_writel(reg | idma_mask(out_dma), IDMAC_CHA_EN(out_dma)); 1035 } 1036 1037 if ((channel == MEM_DC_SYNC) || (channel == MEM_BG_SYNC) || 1038 (channel == MEM_FG_SYNC)) 1039 ipu_dp_dc_enable(channel); 1040 1041 g_channel_enable_mask |= 1L << IPU_CHAN_ID(channel); 1042 1043 return 0; 1044 } 1045 1046 /* 1047 * This function clear buffer ready for a logical channel. 1048 * 1049 * @param channel Input parameter for the logical channel ID. 1050 * 1051 * @param type Input parameter which buffer to clear. 1052 * 1053 * @param bufNum Input parameter for which buffer number clear 1054 * ready state. 1055 * 1056 */ 1057 void ipu_clear_buffer_ready(ipu_channel_t channel, ipu_buffer_t type, 1058 uint32_t bufNum) 1059 { 1060 uint32_t dma_ch = channel_2_dma(channel, type); 1061 1062 if (!idma_is_valid(dma_ch)) 1063 return; 1064 1065 __raw_writel(0xF0000000, IPU_GPR); /* write one to clear */ 1066 if (bufNum == 0) { 1067 if (idma_is_set(IPU_CHA_BUF0_RDY, dma_ch)) { 1068 __raw_writel(idma_mask(dma_ch), 1069 IPU_CHA_BUF0_RDY(dma_ch)); 1070 } 1071 } else { 1072 if (idma_is_set(IPU_CHA_BUF1_RDY, dma_ch)) { 1073 __raw_writel(idma_mask(dma_ch), 1074 IPU_CHA_BUF1_RDY(dma_ch)); 1075 } 1076 } 1077 __raw_writel(0x0, IPU_GPR); /* write one to set */ 1078 } 1079 1080 /* 1081 * This function disables a logical channel. 1082 * 1083 * @param channel Input parameter for the logical channel ID. 1084 * 1085 * @param wait_for_stop Flag to set whether to wait for channel end 1086 * of frame or return immediately. 1087 * 1088 * @return This function returns 0 on success or negative error code on 1089 * fail. 1090 */ 1091 int32_t ipu_disable_channel(ipu_channel_t channel) 1092 { 1093 uint32_t reg; 1094 uint32_t in_dma; 1095 uint32_t out_dma; 1096 1097 if ((g_channel_enable_mask & (1L << IPU_CHAN_ID(channel))) == 0) { 1098 debug("Channel already disabled %d\n", 1099 IPU_CHAN_ID(channel)); 1100 return 0; 1101 } 1102 1103 /* Get input and output dma channels */ 1104 out_dma = channel_2_dma(channel, IPU_OUTPUT_BUFFER); 1105 in_dma = channel_2_dma(channel, IPU_VIDEO_IN_BUFFER); 1106 1107 if ((idma_is_valid(in_dma) && 1108 !idma_is_set(IDMAC_CHA_EN, in_dma)) 1109 && (idma_is_valid(out_dma) && 1110 !idma_is_set(IDMAC_CHA_EN, out_dma))) 1111 return -EINVAL; 1112 1113 if ((channel == MEM_BG_SYNC) || (channel == MEM_FG_SYNC) || 1114 (channel == MEM_DC_SYNC)) { 1115 ipu_dp_dc_disable(channel, 0); 1116 } 1117 1118 /* Disable DMA channel(s) */ 1119 if (idma_is_valid(in_dma)) { 1120 reg = __raw_readl(IDMAC_CHA_EN(in_dma)); 1121 __raw_writel(reg & ~idma_mask(in_dma), IDMAC_CHA_EN(in_dma)); 1122 __raw_writel(idma_mask(in_dma), IPU_CHA_CUR_BUF(in_dma)); 1123 } 1124 if (idma_is_valid(out_dma)) { 1125 reg = __raw_readl(IDMAC_CHA_EN(out_dma)); 1126 __raw_writel(reg & ~idma_mask(out_dma), IDMAC_CHA_EN(out_dma)); 1127 __raw_writel(idma_mask(out_dma), IPU_CHA_CUR_BUF(out_dma)); 1128 } 1129 1130 g_channel_enable_mask &= ~(1L << IPU_CHAN_ID(channel)); 1131 1132 /* Set channel buffers NOT to be ready */ 1133 if (idma_is_valid(in_dma)) { 1134 ipu_clear_buffer_ready(channel, IPU_VIDEO_IN_BUFFER, 0); 1135 ipu_clear_buffer_ready(channel, IPU_VIDEO_IN_BUFFER, 1); 1136 } 1137 if (idma_is_valid(out_dma)) { 1138 ipu_clear_buffer_ready(channel, IPU_OUTPUT_BUFFER, 0); 1139 ipu_clear_buffer_ready(channel, IPU_OUTPUT_BUFFER, 1); 1140 } 1141 1142 return 0; 1143 } 1144 1145 uint32_t bytes_per_pixel(uint32_t fmt) 1146 { 1147 switch (fmt) { 1148 case IPU_PIX_FMT_GENERIC: /*generic data */ 1149 case IPU_PIX_FMT_RGB332: 1150 case IPU_PIX_FMT_YUV420P: 1151 case IPU_PIX_FMT_YUV422P: 1152 return 1; 1153 break; 1154 case IPU_PIX_FMT_RGB565: 1155 case IPU_PIX_FMT_YUYV: 1156 case IPU_PIX_FMT_UYVY: 1157 return 2; 1158 break; 1159 case IPU_PIX_FMT_BGR24: 1160 case IPU_PIX_FMT_RGB24: 1161 return 3; 1162 break; 1163 case IPU_PIX_FMT_GENERIC_32: /*generic data */ 1164 case IPU_PIX_FMT_BGR32: 1165 case IPU_PIX_FMT_BGRA32: 1166 case IPU_PIX_FMT_RGB32: 1167 case IPU_PIX_FMT_RGBA32: 1168 case IPU_PIX_FMT_ABGR32: 1169 return 4; 1170 break; 1171 default: 1172 return 1; 1173 break; 1174 } 1175 return 0; 1176 } 1177 1178 ipu_color_space_t format_to_colorspace(uint32_t fmt) 1179 { 1180 switch (fmt) { 1181 case IPU_PIX_FMT_RGB666: 1182 case IPU_PIX_FMT_RGB565: 1183 case IPU_PIX_FMT_BGR24: 1184 case IPU_PIX_FMT_RGB24: 1185 case IPU_PIX_FMT_BGR32: 1186 case IPU_PIX_FMT_BGRA32: 1187 case IPU_PIX_FMT_RGB32: 1188 case IPU_PIX_FMT_RGBA32: 1189 case IPU_PIX_FMT_ABGR32: 1190 case IPU_PIX_FMT_LVDS666: 1191 case IPU_PIX_FMT_LVDS888: 1192 return RGB; 1193 break; 1194 1195 default: 1196 return YCbCr; 1197 break; 1198 } 1199 return RGB; 1200 } 1201 1202 /* should be removed when clk framework is availiable */ 1203 int ipu_set_ldb_clock(int rate) 1204 { 1205 ldb_clk.rate = rate; 1206 1207 return 0; 1208 } 1209