Lines Matching +full:8 +full:- +full:ch

16 #include <linux/dma-mapping.h>
35 /* ----------------------------------------------------------------------------
41 #define LDBCR_UPF(n) (1 << ((n) + 8))
65 #define LDBBSIFR_SWPB (1 << 8)
94 #define LDBBSAYR_FG1G_MASK (0xff << 8)
95 #define LDBBSAYR_FG1G_SHIFT 8
103 #define LDBBSACR_FG2G_MASK (0xff << 8)
104 #define LDBBSACR_FG2G_SHIFT 8
112 #define LDBBSAAR_GY_MASK (0xff << 8)
113 #define LDBBSAAR_GY_SHIFT 8
121 #define LDBBPPCR_GY_MASK (0xff << 8)
122 #define LDBBPPCR_GY_SHIFT 8
130 #define LDBBBGCL_BGG_MASK (0xff << 8)
131 #define LDBBBGCL_BGG_SHIFT 8
147 * struct sh_mobile_lcdc_overlay - LCDC display overlay
152 * @index: Overlay index (0-3)
156 * @alpha: Global alpha blending value (0-255, for alpha blending mode)
213 struct sh_mobile_lcdc_chan ch[2]; member
220 /* -----------------------------------------------------------------------------
284 return chan->cfg->chan == LCDC_CHAN_SUBLCD; in lcdc_chan_is_sublcd()
290 iowrite32(data, chan->lcdc->base + chan->reg_offs[reg_nr]); in lcdc_write_chan()
292 iowrite32(data, chan->lcdc->base + chan->reg_offs[reg_nr] + in lcdc_write_chan()
299 iowrite32(data, chan->lcdc->base + chan->reg_offs[reg_nr] + in lcdc_write_chan_mirror()
306 return ioread32(chan->lcdc->base + chan->reg_offs[reg_nr]); in lcdc_read_chan()
312 iowrite32(data, ovl->channel->lcdc->base + reg); in lcdc_write_overlay()
313 iowrite32(data, ovl->channel->lcdc->base + reg + SIDE_B_OFFSET); in lcdc_write_overlay()
319 iowrite32(data, priv->base + reg_offs); in lcdc_write()
325 return ioread32(priv->base + reg_offs); in lcdc_read()
336 /* -----------------------------------------------------------------------------
342 if (atomic_inc_and_test(&priv->hw_usecnt)) { in sh_mobile_lcdc_clk_on()
343 clk_prepare_enable(priv->dot_clk); in sh_mobile_lcdc_clk_on()
344 pm_runtime_get_sync(priv->dev); in sh_mobile_lcdc_clk_on()
350 if (atomic_sub_return(1, &priv->hw_usecnt) == -1) { in sh_mobile_lcdc_clk_off()
351 pm_runtime_put(priv->dev); in sh_mobile_lcdc_clk_off()
352 clk_disable_unprepare(priv->dot_clk); in sh_mobile_lcdc_clk_off()
365 priv->lddckr = LDDCKR_ICKSEL_BUS; in sh_mobile_lcdc_setup_clocks()
369 priv->lddckr = LDDCKR_ICKSEL_MIPI; in sh_mobile_lcdc_setup_clocks()
373 priv->lddckr = LDDCKR_ICKSEL_HDMI; in sh_mobile_lcdc_setup_clocks()
376 return -EINVAL; in sh_mobile_lcdc_setup_clocks()
382 clk = clk_get(priv->dev, str); in sh_mobile_lcdc_setup_clocks()
384 dev_err(priv->dev, "cannot get dot clock %s\n", str); in sh_mobile_lcdc_setup_clocks()
388 priv->dot_clk = clk; in sh_mobile_lcdc_setup_clocks()
392 /* -----------------------------------------------------------------------------
398 struct sh_mobile_lcdc_chan *ch = handle; in lcdc_sys_write_index() local
400 lcdc_write(ch->lcdc, _LDDWD0R, data | LDDWDxR_WDACT); in lcdc_sys_write_index()
401 lcdc_wait_bit(ch->lcdc, _LDSR, LDSR_AS, 0); in lcdc_sys_write_index()
402 lcdc_write(ch->lcdc, _LDDWAR, LDDWAR_WA | in lcdc_sys_write_index()
403 (lcdc_chan_is_sublcd(ch) ? 2 : 0)); in lcdc_sys_write_index()
404 lcdc_wait_bit(ch->lcdc, _LDSR, LDSR_AS, 0); in lcdc_sys_write_index()
409 struct sh_mobile_lcdc_chan *ch = handle; in lcdc_sys_write_data() local
411 lcdc_write(ch->lcdc, _LDDWD0R, data | LDDWDxR_WDACT | LDDWDxR_RSW); in lcdc_sys_write_data()
412 lcdc_wait_bit(ch->lcdc, _LDSR, LDSR_AS, 0); in lcdc_sys_write_data()
413 lcdc_write(ch->lcdc, _LDDWAR, LDDWAR_WA | in lcdc_sys_write_data()
414 (lcdc_chan_is_sublcd(ch) ? 2 : 0)); in lcdc_sys_write_data()
415 lcdc_wait_bit(ch->lcdc, _LDSR, LDSR_AS, 0); in lcdc_sys_write_data()
420 struct sh_mobile_lcdc_chan *ch = handle; in lcdc_sys_read_data() local
422 lcdc_write(ch->lcdc, _LDDRDR, LDDRDR_RSR); in lcdc_sys_read_data()
423 lcdc_wait_bit(ch->lcdc, _LDSR, LDSR_AS, 0); in lcdc_sys_read_data()
424 lcdc_write(ch->lcdc, _LDDRAR, LDDRAR_RA | in lcdc_sys_read_data()
425 (lcdc_chan_is_sublcd(ch) ? 2 : 0)); in lcdc_sys_read_data()
427 lcdc_wait_bit(ch->lcdc, _LDSR, LDSR_AS, 0); in lcdc_sys_read_data()
429 return lcdc_read(ch->lcdc, _LDDRDR) & LDDRDR_DRD_MASK; in lcdc_sys_read_data()
440 struct sh_mobile_lcdc_chan *ch = info->par; in sh_mobile_lcdc_sginit() local
441 unsigned int nr_pages_max = ch->fb_size >> PAGE_SHIFT; in sh_mobile_lcdc_sginit()
445 sg_init_table(ch->sglist, nr_pages_max); in sh_mobile_lcdc_sginit()
448 sg_set_page(&ch->sglist[nr_pages++], pageref->page, PAGE_SIZE, 0); in sh_mobile_lcdc_sginit()
456 struct sh_mobile_lcdc_chan *ch = info->par; in sh_mobile_lcdc_deferred_io() local
457 const struct sh_mobile_lcdc_panel_cfg *panel = &ch->cfg->panel_cfg; in sh_mobile_lcdc_deferred_io()
460 sh_mobile_lcdc_clk_on(ch->lcdc); in sh_mobile_lcdc_deferred_io()
481 dma_map_sg(ch->lcdc->dev, ch->sglist, nr_pages, DMA_TO_DEVICE); in sh_mobile_lcdc_deferred_io()
482 if (panel->start_transfer) in sh_mobile_lcdc_deferred_io()
483 panel->start_transfer(ch, &sh_mobile_lcdc_sys_bus_ops); in sh_mobile_lcdc_deferred_io()
484 lcdc_write_chan(ch, LDSM2R, LDSM2R_OSTRG); in sh_mobile_lcdc_deferred_io()
485 dma_unmap_sg(ch->lcdc->dev, ch->sglist, nr_pages, in sh_mobile_lcdc_deferred_io()
488 if (panel->start_transfer) in sh_mobile_lcdc_deferred_io()
489 panel->start_transfer(ch, &sh_mobile_lcdc_sys_bus_ops); in sh_mobile_lcdc_deferred_io()
490 lcdc_write_chan(ch, LDSM2R, LDSM2R_OSTRG); in sh_mobile_lcdc_deferred_io()
496 struct fb_deferred_io *fbdefio = info->fbdefio; in sh_mobile_lcdc_deferred_io_touch()
499 schedule_delayed_work(&info->deferred_work, fbdefio->delay); in sh_mobile_lcdc_deferred_io_touch()
502 static void sh_mobile_lcdc_display_on(struct sh_mobile_lcdc_chan *ch) in sh_mobile_lcdc_display_on() argument
504 const struct sh_mobile_lcdc_panel_cfg *panel = &ch->cfg->panel_cfg; in sh_mobile_lcdc_display_on()
506 if (ch->tx_dev) { in sh_mobile_lcdc_display_on()
509 ret = ch->tx_dev->ops->display_on(ch->tx_dev); in sh_mobile_lcdc_display_on()
514 ch->info->state = FBINFO_STATE_SUSPENDED; in sh_mobile_lcdc_display_on()
518 if (panel->display_on) in sh_mobile_lcdc_display_on()
519 panel->display_on(); in sh_mobile_lcdc_display_on()
522 static void sh_mobile_lcdc_display_off(struct sh_mobile_lcdc_chan *ch) in sh_mobile_lcdc_display_off() argument
524 const struct sh_mobile_lcdc_panel_cfg *panel = &ch->cfg->panel_cfg; in sh_mobile_lcdc_display_off()
526 if (panel->display_off) in sh_mobile_lcdc_display_off()
527 panel->display_off(); in sh_mobile_lcdc_display_off()
529 if (ch->tx_dev) in sh_mobile_lcdc_display_off()
530 ch->tx_dev->ops->display_off(ch->tx_dev); in sh_mobile_lcdc_display_off()
533 /* -----------------------------------------------------------------------------
608 if (var->grayscale > 1) in sh_mobile_format_fourcc()
609 return var->grayscale; in sh_mobile_format_fourcc()
611 switch (var->bits_per_pixel) { in sh_mobile_format_fourcc()
625 return var->grayscale > 1; in sh_mobile_format_is_fourcc()
628 /* -----------------------------------------------------------------------------
635 struct sh_mobile_lcdc_chan *ch; in sh_mobile_lcdc_irq() local
648 for (k = 0; k < ARRAY_SIZE(priv->ch); k++) { in sh_mobile_lcdc_irq()
649 ch = &priv->ch[k]; in sh_mobile_lcdc_irq()
651 if (!ch->enabled) in sh_mobile_lcdc_irq()
656 if (is_sub == lcdc_chan_is_sublcd(ch)) { in sh_mobile_lcdc_irq()
657 ch->frame_end = 1; in sh_mobile_lcdc_irq()
658 wake_up(&ch->frame_end_wait); in sh_mobile_lcdc_irq()
666 complete(&ch->vsync_completion); in sh_mobile_lcdc_irq()
672 static int sh_mobile_lcdc_wait_for_vsync(struct sh_mobile_lcdc_chan *ch) in sh_mobile_lcdc_wait_for_vsync() argument
680 ldintr = lcdc_read(ch->lcdc, _LDINTR); in sh_mobile_lcdc_wait_for_vsync()
682 lcdc_write(ch->lcdc, _LDINTR, ldintr); in sh_mobile_lcdc_wait_for_vsync()
684 ret = wait_for_completion_interruptible_timeout(&ch->vsync_completion, in sh_mobile_lcdc_wait_for_vsync()
687 return -ETIMEDOUT; in sh_mobile_lcdc_wait_for_vsync()
705 for (k = 0; k < ARRAY_SIZE(priv->ch); k++) in sh_mobile_lcdc_start_stop()
706 if (lcdc_read(priv, _LDCNT2R) & priv->ch[k].enabled) in sh_mobile_lcdc_start_stop()
708 tmp = lcdc_read_chan(&priv->ch[k], LDPMR) in sh_mobile_lcdc_start_stop()
721 static void sh_mobile_lcdc_geometry(struct sh_mobile_lcdc_chan *ch) in sh_mobile_lcdc_geometry() argument
723 const struct fb_var_screeninfo *var = &ch->info->var; in sh_mobile_lcdc_geometry()
724 const struct fb_videomode *mode = &ch->display.mode; in sh_mobile_lcdc_geometry()
728 tmp = ch->ldmt1r_value; in sh_mobile_lcdc_geometry()
729 tmp |= (var->sync & FB_SYNC_VERT_HIGH_ACT) ? 0 : LDMT1R_VPOL; in sh_mobile_lcdc_geometry()
730 tmp |= (var->sync & FB_SYNC_HOR_HIGH_ACT) ? 0 : LDMT1R_HPOL; in sh_mobile_lcdc_geometry()
731 tmp |= (ch->cfg->flags & LCDC_FLAGS_DWPOL) ? LDMT1R_DWPOL : 0; in sh_mobile_lcdc_geometry()
732 tmp |= (ch->cfg->flags & LCDC_FLAGS_DIPOL) ? LDMT1R_DIPOL : 0; in sh_mobile_lcdc_geometry()
733 tmp |= (ch->cfg->flags & LCDC_FLAGS_DAPOL) ? LDMT1R_DAPOL : 0; in sh_mobile_lcdc_geometry()
734 tmp |= (ch->cfg->flags & LCDC_FLAGS_HSCNT) ? LDMT1R_HSCNT : 0; in sh_mobile_lcdc_geometry()
735 tmp |= (ch->cfg->flags & LCDC_FLAGS_DWCNT) ? LDMT1R_DWCNT : 0; in sh_mobile_lcdc_geometry()
736 lcdc_write_chan(ch, LDMT1R, tmp); in sh_mobile_lcdc_geometry()
739 lcdc_write_chan(ch, LDMT2R, ch->cfg->sys_bus_cfg.ldmt2r); in sh_mobile_lcdc_geometry()
740 lcdc_write_chan(ch, LDMT3R, ch->cfg->sys_bus_cfg.ldmt3r); in sh_mobile_lcdc_geometry()
743 h_total = mode->xres + mode->hsync_len + mode->left_margin in sh_mobile_lcdc_geometry()
744 + mode->right_margin; in sh_mobile_lcdc_geometry()
745 tmp = h_total / 8; /* HTCN */ in sh_mobile_lcdc_geometry()
746 tmp |= (min(mode->xres, ch->xres) / 8) << 16; /* HDCN */ in sh_mobile_lcdc_geometry()
747 lcdc_write_chan(ch, LDHCNR, tmp); in sh_mobile_lcdc_geometry()
749 hsync_pos = mode->xres + mode->right_margin; in sh_mobile_lcdc_geometry()
750 tmp = hsync_pos / 8; /* HSYNP */ in sh_mobile_lcdc_geometry()
751 tmp |= (mode->hsync_len / 8) << 16; /* HSYNW */ in sh_mobile_lcdc_geometry()
752 lcdc_write_chan(ch, LDHSYNR, tmp); in sh_mobile_lcdc_geometry()
755 tmp = mode->yres + mode->vsync_len + mode->upper_margin in sh_mobile_lcdc_geometry()
756 + mode->lower_margin; /* VTLN */ in sh_mobile_lcdc_geometry()
757 tmp |= min(mode->yres, ch->yres) << 16; /* VDLN */ in sh_mobile_lcdc_geometry()
758 lcdc_write_chan(ch, LDVLNR, tmp); in sh_mobile_lcdc_geometry()
760 tmp = mode->yres + mode->lower_margin; /* VSYNP */ in sh_mobile_lcdc_geometry()
761 tmp |= mode->vsync_len << 16; /* VSYNW */ in sh_mobile_lcdc_geometry()
762 lcdc_write_chan(ch, LDVSYNR, tmp); in sh_mobile_lcdc_geometry()
765 display_h_total = mode->xres + mode->hsync_len + mode->left_margin in sh_mobile_lcdc_geometry()
766 + mode->right_margin; in sh_mobile_lcdc_geometry()
767 tmp = ((mode->xres & 7) << 24) | ((display_h_total & 7) << 16) in sh_mobile_lcdc_geometry()
768 | ((mode->hsync_len & 7) << 8) | (hsync_pos & 7); in sh_mobile_lcdc_geometry()
769 lcdc_write_chan(ch, LDHAJR, tmp); in sh_mobile_lcdc_geometry()
770 lcdc_write_chan_mirror(ch, LDHAJR, tmp); in sh_mobile_lcdc_geometry()
777 if (!ovl->enabled) { in sh_mobile_lcdc_overlay_setup()
778 lcdc_write(ovl->channel->lcdc, LDBCR, LDBCR_UPC(ovl->index)); in sh_mobile_lcdc_overlay_setup()
779 lcdc_write_overlay(ovl, LDBnBSIFR(ovl->index), 0); in sh_mobile_lcdc_overlay_setup()
780 lcdc_write(ovl->channel->lcdc, LDBCR, in sh_mobile_lcdc_overlay_setup()
781 LDBCR_UPF(ovl->index) | LDBCR_UPD(ovl->index)); in sh_mobile_lcdc_overlay_setup()
785 ovl->base_addr_y = ovl->dma_handle; in sh_mobile_lcdc_overlay_setup()
786 ovl->base_addr_c = ovl->dma_handle in sh_mobile_lcdc_overlay_setup()
787 + ovl->xres_virtual * ovl->yres_virtual; in sh_mobile_lcdc_overlay_setup()
789 switch (ovl->mode) { in sh_mobile_lcdc_overlay_setup()
791 format = LDBBSIFR_EN | (ovl->alpha << LDBBSIFR_LAY_SHIFT); in sh_mobile_lcdc_overlay_setup()
796 | (ovl->rop3 << LDBBSIFR_ROP3_SHIFT); in sh_mobile_lcdc_overlay_setup()
800 switch (ovl->format->fourcc) { in sh_mobile_lcdc_overlay_setup()
819 switch (ovl->format->fourcc) { in sh_mobile_lcdc_overlay_setup()
843 lcdc_write(ovl->channel->lcdc, LDBCR, LDBCR_UPC(ovl->index)); in sh_mobile_lcdc_overlay_setup()
845 lcdc_write_overlay(ovl, LDBnBSIFR(ovl->index), format); in sh_mobile_lcdc_overlay_setup()
847 lcdc_write_overlay(ovl, LDBnBSSZR(ovl->index), in sh_mobile_lcdc_overlay_setup()
848 (ovl->yres << LDBBSSZR_BVSS_SHIFT) | in sh_mobile_lcdc_overlay_setup()
849 (ovl->xres << LDBBSSZR_BHSS_SHIFT)); in sh_mobile_lcdc_overlay_setup()
850 lcdc_write_overlay(ovl, LDBnBLOCR(ovl->index), in sh_mobile_lcdc_overlay_setup()
851 (ovl->pos_y << LDBBLOCR_CVLC_SHIFT) | in sh_mobile_lcdc_overlay_setup()
852 (ovl->pos_x << LDBBLOCR_CHLC_SHIFT)); in sh_mobile_lcdc_overlay_setup()
853 lcdc_write_overlay(ovl, LDBnBSMWR(ovl->index), in sh_mobile_lcdc_overlay_setup()
854 ovl->pitch << LDBBSMWR_BSMW_SHIFT); in sh_mobile_lcdc_overlay_setup()
856 lcdc_write_overlay(ovl, LDBnBSAYR(ovl->index), ovl->base_addr_y); in sh_mobile_lcdc_overlay_setup()
857 lcdc_write_overlay(ovl, LDBnBSACR(ovl->index), ovl->base_addr_c); in sh_mobile_lcdc_overlay_setup()
859 lcdc_write(ovl->channel->lcdc, LDBCR, in sh_mobile_lcdc_overlay_setup()
860 LDBCR_UPF(ovl->index) | LDBCR_UPD(ovl->index)); in sh_mobile_lcdc_overlay_setup()
864 * __sh_mobile_lcdc_start - Configure and start the LCDC
872 struct sh_mobile_lcdc_chan *ch; in __sh_mobile_lcdc_start() local
879 lcdc_write(priv, _LDCNT2R, priv->ch[0].enabled | priv->ch[1].enabled); in __sh_mobile_lcdc_start()
886 tmp = priv->lddckr; in __sh_mobile_lcdc_start()
887 for (k = 0; k < ARRAY_SIZE(priv->ch); k++) { in __sh_mobile_lcdc_start()
888 ch = &priv->ch[k]; in __sh_mobile_lcdc_start()
889 if (!ch->enabled) in __sh_mobile_lcdc_start()
893 lcdc_write_chan(ch, LDPMR, 0); in __sh_mobile_lcdc_start()
895 m = ch->cfg->clock_divider; in __sh_mobile_lcdc_start()
902 lcdc_write_chan(ch, LDDCKPAT1R, 0); in __sh_mobile_lcdc_start()
903 lcdc_write_chan(ch, LDDCKPAT2R, (1 << (m/2)) - 1); in __sh_mobile_lcdc_start()
907 tmp |= m << (lcdc_chan_is_sublcd(ch) ? 8 : 0); in __sh_mobile_lcdc_start()
915 for (k = 0; k < ARRAY_SIZE(priv->ch); k++) { in __sh_mobile_lcdc_start()
916 ch = &priv->ch[k]; in __sh_mobile_lcdc_start()
917 if (!ch->enabled) in __sh_mobile_lcdc_start()
920 sh_mobile_lcdc_geometry(ch); in __sh_mobile_lcdc_start()
922 tmp = ch->format->lddfr; in __sh_mobile_lcdc_start()
924 if (ch->format->yuv) { in __sh_mobile_lcdc_start()
925 switch (ch->colorspace) { in __sh_mobile_lcdc_start()
935 lcdc_write_chan(ch, LDDFR, tmp); in __sh_mobile_lcdc_start()
936 lcdc_write_chan(ch, LDMLSR, ch->line_size); in __sh_mobile_lcdc_start()
937 lcdc_write_chan(ch, LDSA1R, ch->base_addr_y); in __sh_mobile_lcdc_start()
938 if (ch->format->yuv) in __sh_mobile_lcdc_start()
939 lcdc_write_chan(ch, LDSA2R, ch->base_addr_c); in __sh_mobile_lcdc_start()
941 /* When using deferred I/O mode, configure the LCDC for one-shot in __sh_mobile_lcdc_start()
945 if (ch->ldmt1r_value & LDMT1R_IFM && in __sh_mobile_lcdc_start()
946 ch->cfg->sys_bus_cfg.deferred_io_msec) { in __sh_mobile_lcdc_start()
947 lcdc_write_chan(ch, LDSM1R, LDSM1R_OS); in __sh_mobile_lcdc_start()
950 lcdc_write_chan(ch, LDSM1R, 0); in __sh_mobile_lcdc_start()
955 switch (priv->ch[0].format->fourcc) { in __sh_mobile_lcdc_start()
978 priv->started = 1; in __sh_mobile_lcdc_start()
983 struct sh_mobile_lcdc_chan *ch; in sh_mobile_lcdc_start() local
989 for (k = 0; k < ARRAY_SIZE(priv->ch); k++) { in sh_mobile_lcdc_start()
990 if (priv->ch[k].enabled) in sh_mobile_lcdc_start()
998 for (k = 0; k < ARRAY_SIZE(priv->ch); k++) { in sh_mobile_lcdc_start()
1001 ch = &priv->ch[k]; in sh_mobile_lcdc_start()
1002 if (!ch->enabled) in sh_mobile_lcdc_start()
1005 panel = &ch->cfg->panel_cfg; in sh_mobile_lcdc_start()
1006 if (panel->setup_sys) { in sh_mobile_lcdc_start()
1007 ret = panel->setup_sys(ch, &sh_mobile_lcdc_sys_bus_ops); in sh_mobile_lcdc_start()
1014 for (k = 0; k < ARRAY_SIZE(priv->ch); k++) { in sh_mobile_lcdc_start()
1015 ch = &priv->ch[k]; in sh_mobile_lcdc_start()
1016 if (!ch->enabled) in sh_mobile_lcdc_start()
1019 ch->base_addr_y = ch->dma_handle; in sh_mobile_lcdc_start()
1020 ch->base_addr_c = ch->dma_handle in sh_mobile_lcdc_start()
1021 + ch->xres_virtual * ch->yres_virtual; in sh_mobile_lcdc_start()
1022 ch->line_size = ch->pitch; in sh_mobile_lcdc_start()
1025 for (k = 0; k < ARRAY_SIZE(priv->overlays); ++k) { in sh_mobile_lcdc_start()
1026 struct sh_mobile_lcdc_overlay *ovl = &priv->overlays[k]; in sh_mobile_lcdc_start()
1036 for (k = 0; k < ARRAY_SIZE(priv->ch); k++) { in sh_mobile_lcdc_start()
1037 ch = &priv->ch[k]; in sh_mobile_lcdc_start()
1038 if (!ch->enabled) in sh_mobile_lcdc_start()
1041 tmp = ch->cfg->sys_bus_cfg.deferred_io_msec; in sh_mobile_lcdc_start()
1042 if (ch->ldmt1r_value & LDMT1R_IFM && tmp) { in sh_mobile_lcdc_start()
1043 ch->defio.deferred_io = sh_mobile_lcdc_deferred_io; in sh_mobile_lcdc_start()
1044 ch->defio.delay = msecs_to_jiffies(tmp); in sh_mobile_lcdc_start()
1045 ch->info->fbdefio = &ch->defio; in sh_mobile_lcdc_start()
1046 fb_deferred_io_init(ch->info); in sh_mobile_lcdc_start()
1049 sh_mobile_lcdc_display_on(ch); in sh_mobile_lcdc_start()
1051 if (ch->bl) { in sh_mobile_lcdc_start()
1052 ch->bl->props.power = FB_BLANK_UNBLANK; in sh_mobile_lcdc_start()
1053 backlight_update_status(ch->bl); in sh_mobile_lcdc_start()
1062 struct sh_mobile_lcdc_chan *ch; in sh_mobile_lcdc_stop() local
1066 for (k = 0; k < ARRAY_SIZE(priv->ch); k++) { in sh_mobile_lcdc_stop()
1067 ch = &priv->ch[k]; in sh_mobile_lcdc_stop()
1068 if (!ch->enabled) in sh_mobile_lcdc_stop()
1075 if (ch->info && ch->info->fbdefio) { in sh_mobile_lcdc_stop()
1076 ch->frame_end = 0; in sh_mobile_lcdc_stop()
1077 schedule_delayed_work(&ch->info->deferred_work, 0); in sh_mobile_lcdc_stop()
1078 wait_event(ch->frame_end_wait, ch->frame_end); in sh_mobile_lcdc_stop()
1079 fb_deferred_io_cleanup(ch->info); in sh_mobile_lcdc_stop()
1080 ch->info->fbdefio = NULL; in sh_mobile_lcdc_stop()
1084 if (ch->bl) { in sh_mobile_lcdc_stop()
1085 ch->bl->props.power = FB_BLANK_POWERDOWN; in sh_mobile_lcdc_stop()
1086 backlight_update_status(ch->bl); in sh_mobile_lcdc_stop()
1089 sh_mobile_lcdc_display_off(ch); in sh_mobile_lcdc_stop()
1093 if (priv->started) { in sh_mobile_lcdc_stop()
1095 priv->started = 0; in sh_mobile_lcdc_stop()
1099 for (k = 0; k < ARRAY_SIZE(priv->ch); k++) in sh_mobile_lcdc_stop()
1100 if (priv->ch[k].enabled) in sh_mobile_lcdc_stop()
1107 if (var->xres > MAX_XRES || var->yres > MAX_YRES) in __sh_mobile_lcdc_check_var()
1108 return -EINVAL; in __sh_mobile_lcdc_check_var()
1113 if (var->xres_virtual < var->xres) in __sh_mobile_lcdc_check_var()
1114 var->xres_virtual = var->xres; in __sh_mobile_lcdc_check_var()
1115 if (var->yres_virtual < var->yres) in __sh_mobile_lcdc_check_var()
1116 var->yres_virtual = var->yres; in __sh_mobile_lcdc_check_var()
1121 format = sh_mobile_format_info(var->grayscale); in __sh_mobile_lcdc_check_var()
1123 return -EINVAL; in __sh_mobile_lcdc_check_var()
1124 var->bits_per_pixel = format->bpp; in __sh_mobile_lcdc_check_var()
1126 /* Default to RGB and JPEG color-spaces for RGB and YUV formats in __sh_mobile_lcdc_check_var()
1129 if (!format->yuv) in __sh_mobile_lcdc_check_var()
1130 var->colorspace = V4L2_COLORSPACE_SRGB; in __sh_mobile_lcdc_check_var()
1131 else if (var->colorspace != V4L2_COLORSPACE_REC709) in __sh_mobile_lcdc_check_var()
1132 var->colorspace = V4L2_COLORSPACE_JPEG; in __sh_mobile_lcdc_check_var()
1134 if (var->bits_per_pixel <= 16) { /* RGB 565 */ in __sh_mobile_lcdc_check_var()
1135 var->bits_per_pixel = 16; in __sh_mobile_lcdc_check_var()
1136 var->red.offset = 11; in __sh_mobile_lcdc_check_var()
1137 var->red.length = 5; in __sh_mobile_lcdc_check_var()
1138 var->green.offset = 5; in __sh_mobile_lcdc_check_var()
1139 var->green.length = 6; in __sh_mobile_lcdc_check_var()
1140 var->blue.offset = 0; in __sh_mobile_lcdc_check_var()
1141 var->blue.length = 5; in __sh_mobile_lcdc_check_var()
1142 var->transp.offset = 0; in __sh_mobile_lcdc_check_var()
1143 var->transp.length = 0; in __sh_mobile_lcdc_check_var()
1144 } else if (var->bits_per_pixel <= 24) { /* RGB 888 */ in __sh_mobile_lcdc_check_var()
1145 var->bits_per_pixel = 24; in __sh_mobile_lcdc_check_var()
1146 var->red.offset = 16; in __sh_mobile_lcdc_check_var()
1147 var->red.length = 8; in __sh_mobile_lcdc_check_var()
1148 var->green.offset = 8; in __sh_mobile_lcdc_check_var()
1149 var->green.length = 8; in __sh_mobile_lcdc_check_var()
1150 var->blue.offset = 0; in __sh_mobile_lcdc_check_var()
1151 var->blue.length = 8; in __sh_mobile_lcdc_check_var()
1152 var->transp.offset = 0; in __sh_mobile_lcdc_check_var()
1153 var->transp.length = 0; in __sh_mobile_lcdc_check_var()
1154 } else if (var->bits_per_pixel <= 32) { /* RGBA 888 */ in __sh_mobile_lcdc_check_var()
1155 var->bits_per_pixel = 32; in __sh_mobile_lcdc_check_var()
1156 var->red.offset = 16; in __sh_mobile_lcdc_check_var()
1157 var->red.length = 8; in __sh_mobile_lcdc_check_var()
1158 var->green.offset = 8; in __sh_mobile_lcdc_check_var()
1159 var->green.length = 8; in __sh_mobile_lcdc_check_var()
1160 var->blue.offset = 0; in __sh_mobile_lcdc_check_var()
1161 var->blue.length = 8; in __sh_mobile_lcdc_check_var()
1162 var->transp.offset = 24; in __sh_mobile_lcdc_check_var()
1163 var->transp.length = 8; in __sh_mobile_lcdc_check_var()
1165 return -EINVAL; in __sh_mobile_lcdc_check_var()
1167 var->red.msb_right = 0; in __sh_mobile_lcdc_check_var()
1168 var->green.msb_right = 0; in __sh_mobile_lcdc_check_var()
1169 var->blue.msb_right = 0; in __sh_mobile_lcdc_check_var()
1170 var->transp.msb_right = 0; in __sh_mobile_lcdc_check_var()
1174 if (var->xres_virtual * var->yres_virtual * var->bits_per_pixel / 8 > in __sh_mobile_lcdc_check_var()
1175 info->fix.smem_len) in __sh_mobile_lcdc_check_var()
1176 return -EINVAL; in __sh_mobile_lcdc_check_var()
1181 /* -----------------------------------------------------------------------------
1182 * Frame buffer operations - Overlays
1189 struct sh_mobile_lcdc_overlay *ovl = info->par; in overlay_alpha_show()
1191 return sysfs_emit(buf, "%u\n", ovl->alpha); in overlay_alpha_show()
1199 struct sh_mobile_lcdc_overlay *ovl = info->par; in overlay_alpha_store()
1207 if (endp - buf != count) in overlay_alpha_store()
1208 return -EINVAL; in overlay_alpha_store()
1211 return -EINVAL; in overlay_alpha_store()
1213 if (ovl->alpha != alpha) { in overlay_alpha_store()
1214 ovl->alpha = alpha; in overlay_alpha_store()
1216 if (ovl->mode == LCDC_OVERLAY_BLEND && ovl->enabled) in overlay_alpha_store()
1227 struct sh_mobile_lcdc_overlay *ovl = info->par; in overlay_mode_show()
1229 return sysfs_emit(buf, "%u\n", ovl->mode); in overlay_mode_show()
1237 struct sh_mobile_lcdc_overlay *ovl = info->par; in overlay_mode_store()
1245 if (endp - buf != count) in overlay_mode_store()
1246 return -EINVAL; in overlay_mode_store()
1249 return -EINVAL; in overlay_mode_store()
1251 if (ovl->mode != mode) { in overlay_mode_store()
1252 ovl->mode = mode; in overlay_mode_store()
1254 if (ovl->enabled) in overlay_mode_store()
1266 struct sh_mobile_lcdc_overlay *ovl = info->par; in overlay_position_show()
1268 return sysfs_emit(buf, "%d,%d\n", ovl->pos_x, ovl->pos_y); in overlay_position_show()
1276 struct sh_mobile_lcdc_overlay *ovl = info->par; in overlay_position_store()
1283 return -EINVAL; in overlay_position_store()
1289 if (endp - buf != count) in overlay_position_store()
1290 return -EINVAL; in overlay_position_store()
1292 if (ovl->pos_x != pos_x || ovl->pos_y != pos_y) { in overlay_position_store()
1293 ovl->pos_x = pos_x; in overlay_position_store()
1294 ovl->pos_y = pos_y; in overlay_position_store()
1296 if (ovl->enabled) in overlay_position_store()
1307 struct sh_mobile_lcdc_overlay *ovl = info->par; in overlay_rop3_show()
1309 return sysfs_emit(buf, "%u\n", ovl->rop3); in overlay_rop3_show()
1317 struct sh_mobile_lcdc_overlay *ovl = info->par; in overlay_rop3_store()
1325 if (endp - buf != count) in overlay_rop3_store()
1326 return -EINVAL; in overlay_rop3_store()
1329 return -EINVAL; in overlay_rop3_store()
1331 if (ovl->rop3 != rop3) { in overlay_rop3_store()
1332 ovl->rop3 = rop3; in overlay_rop3_store()
1334 if (ovl->mode == LCDC_OVERLAY_ROP3 && ovl->enabled) in overlay_rop3_store()
1366 struct sh_mobile_lcdc_overlay *ovl = info->par; in sh_mobile_lcdc_overlay_pan()
1372 if (!ovl->format->yuv) { in sh_mobile_lcdc_overlay_pan()
1373 y_offset = (var->yoffset * ovl->xres_virtual + var->xoffset) in sh_mobile_lcdc_overlay_pan()
1374 * ovl->format->bpp / 8; in sh_mobile_lcdc_overlay_pan()
1377 unsigned int xsub = ovl->format->bpp < 24 ? 2 : 1; in sh_mobile_lcdc_overlay_pan()
1378 unsigned int ysub = ovl->format->bpp < 16 ? 2 : 1; in sh_mobile_lcdc_overlay_pan()
1380 y_offset = var->yoffset * ovl->xres_virtual + var->xoffset; in sh_mobile_lcdc_overlay_pan()
1381 c_offset = var->yoffset / ysub * ovl->xres_virtual * 2 / xsub in sh_mobile_lcdc_overlay_pan()
1382 + var->xoffset * 2 / xsub; in sh_mobile_lcdc_overlay_pan()
1388 if (y_offset == ovl->pan_y_offset) in sh_mobile_lcdc_overlay_pan()
1392 base_addr_y = ovl->dma_handle + y_offset; in sh_mobile_lcdc_overlay_pan()
1393 base_addr_c = ovl->dma_handle + ovl->xres_virtual * ovl->yres_virtual in sh_mobile_lcdc_overlay_pan()
1396 ovl->base_addr_y = base_addr_y; in sh_mobile_lcdc_overlay_pan()
1397 ovl->base_addr_c = base_addr_c; in sh_mobile_lcdc_overlay_pan()
1398 ovl->pan_y_offset = y_offset; in sh_mobile_lcdc_overlay_pan()
1400 lcdc_write(ovl->channel->lcdc, LDBCR, LDBCR_UPC(ovl->index)); in sh_mobile_lcdc_overlay_pan()
1402 lcdc_write_overlay(ovl, LDBnBSAYR(ovl->index), ovl->base_addr_y); in sh_mobile_lcdc_overlay_pan()
1403 lcdc_write_overlay(ovl, LDBnBSACR(ovl->index), ovl->base_addr_c); in sh_mobile_lcdc_overlay_pan()
1405 lcdc_write(ovl->channel->lcdc, LDBCR, in sh_mobile_lcdc_overlay_pan()
1406 LDBCR_UPF(ovl->index) | LDBCR_UPD(ovl->index)); in sh_mobile_lcdc_overlay_pan()
1414 struct sh_mobile_lcdc_overlay *ovl = info->par; in sh_mobile_lcdc_overlay_ioctl()
1418 return sh_mobile_lcdc_wait_for_vsync(ovl->channel); in sh_mobile_lcdc_overlay_ioctl()
1421 return -ENOIOCTLCMD; in sh_mobile_lcdc_overlay_ioctl()
1433 struct sh_mobile_lcdc_overlay *ovl = info->par; in sh_mobile_lcdc_overlay_set_par()
1435 ovl->format = in sh_mobile_lcdc_overlay_set_par()
1436 sh_mobile_format_info(sh_mobile_format_fourcc(&info->var)); in sh_mobile_lcdc_overlay_set_par()
1438 ovl->xres = info->var.xres; in sh_mobile_lcdc_overlay_set_par()
1439 ovl->xres_virtual = info->var.xres_virtual; in sh_mobile_lcdc_overlay_set_par()
1440 ovl->yres = info->var.yres; in sh_mobile_lcdc_overlay_set_par()
1441 ovl->yres_virtual = info->var.yres_virtual; in sh_mobile_lcdc_overlay_set_par()
1443 if (ovl->format->yuv) in sh_mobile_lcdc_overlay_set_par()
1444 ovl->pitch = info->var.xres_virtual; in sh_mobile_lcdc_overlay_set_par()
1446 ovl->pitch = info->var.xres_virtual * ovl->format->bpp / 8; in sh_mobile_lcdc_overlay_set_par()
1450 info->fix.line_length = ovl->pitch; in sh_mobile_lcdc_overlay_set_par()
1452 if (sh_mobile_format_is_fourcc(&info->var)) { in sh_mobile_lcdc_overlay_set_par()
1453 info->fix.type = FB_TYPE_FOURCC; in sh_mobile_lcdc_overlay_set_par()
1454 info->fix.visual = FB_VISUAL_FOURCC; in sh_mobile_lcdc_overlay_set_par()
1456 info->fix.type = FB_TYPE_PACKED_PIXELS; in sh_mobile_lcdc_overlay_set_par()
1457 info->fix.visual = FB_VISUAL_TRUECOLOR; in sh_mobile_lcdc_overlay_set_par()
1466 struct sh_mobile_lcdc_overlay *ovl = info->par; in sh_mobile_lcdc_overlay_blank()
1468 ovl->enabled = !blank; in sh_mobile_lcdc_overlay_blank()
1472 * a non-zero value. in sh_mobile_lcdc_overlay_blank()
1480 struct sh_mobile_lcdc_overlay *ovl = info->par; in sh_mobile_lcdc_overlay_mmap()
1482 if (info->fbdefio) in sh_mobile_lcdc_overlay_mmap()
1485 return dma_mmap_coherent(ovl->channel->lcdc->dev, vma, ovl->fb_mem, in sh_mobile_lcdc_overlay_mmap()
1486 ovl->dma_handle, ovl->fb_size); in sh_mobile_lcdc_overlay_mmap()
1507 struct fb_info *info = ovl->info; in sh_mobile_lcdc_overlay_fb_unregister()
1509 if (info == NULL || info->dev == NULL) in sh_mobile_lcdc_overlay_fb_unregister()
1512 unregister_framebuffer(ovl->info); in sh_mobile_lcdc_overlay_fb_unregister()
1518 struct sh_mobile_lcdc_priv *lcdc = ovl->channel->lcdc; in sh_mobile_lcdc_overlay_fb_register()
1519 struct fb_info *info = ovl->info; in sh_mobile_lcdc_overlay_fb_register()
1530 dev_info(lcdc->dev, "registered %s/overlay %u as %dx%d %dbpp.\n", in sh_mobile_lcdc_overlay_fb_register()
1531 dev_name(lcdc->dev), ovl->index, info->var.xres, in sh_mobile_lcdc_overlay_fb_register()
1532 info->var.yres, info->var.bits_per_pixel); in sh_mobile_lcdc_overlay_fb_register()
1535 ret = device_create_file(info->dev, &overlay_sysfs_attrs[i]); in sh_mobile_lcdc_overlay_fb_register()
1546 struct fb_info *info = ovl->info; in sh_mobile_lcdc_overlay_fb_cleanup()
1548 if (info == NULL || info->device == NULL) in sh_mobile_lcdc_overlay_fb_cleanup()
1557 struct sh_mobile_lcdc_priv *priv = ovl->channel->lcdc; in sh_mobile_lcdc_overlay_fb_init()
1562 info = framebuffer_alloc(0, priv->dev); in sh_mobile_lcdc_overlay_fb_init()
1564 return -ENOMEM; in sh_mobile_lcdc_overlay_fb_init()
1566 ovl->info = info; in sh_mobile_lcdc_overlay_fb_init()
1568 info->fbops = &sh_mobile_lcdc_overlay_ops; in sh_mobile_lcdc_overlay_fb_init()
1569 info->device = priv->dev; in sh_mobile_lcdc_overlay_fb_init()
1570 info->screen_buffer = ovl->fb_mem; in sh_mobile_lcdc_overlay_fb_init()
1571 info->par = ovl; in sh_mobile_lcdc_overlay_fb_init()
1576 info->fix = sh_mobile_lcdc_overlay_fix; in sh_mobile_lcdc_overlay_fb_init()
1577 snprintf(info->fix.id, sizeof(info->fix.id), in sh_mobile_lcdc_overlay_fb_init()
1578 "SHMobile ovl %u", ovl->index); in sh_mobile_lcdc_overlay_fb_init()
1579 info->fix.smem_start = ovl->dma_handle; in sh_mobile_lcdc_overlay_fb_init()
1580 info->fix.smem_len = ovl->fb_size; in sh_mobile_lcdc_overlay_fb_init()
1581 info->fix.line_length = ovl->pitch; in sh_mobile_lcdc_overlay_fb_init()
1583 if (ovl->format->yuv) in sh_mobile_lcdc_overlay_fb_init()
1584 info->fix.visual = FB_VISUAL_FOURCC; in sh_mobile_lcdc_overlay_fb_init()
1586 info->fix.visual = FB_VISUAL_TRUECOLOR; in sh_mobile_lcdc_overlay_fb_init()
1588 switch (ovl->format->fourcc) { in sh_mobile_lcdc_overlay_fb_init()
1591 info->fix.ypanstep = 2; in sh_mobile_lcdc_overlay_fb_init()
1595 info->fix.xpanstep = 2; in sh_mobile_lcdc_overlay_fb_init()
1599 var = &info->var; in sh_mobile_lcdc_overlay_fb_init()
1601 var->xres = ovl->xres; in sh_mobile_lcdc_overlay_fb_init()
1602 var->yres = ovl->yres; in sh_mobile_lcdc_overlay_fb_init()
1603 var->xres_virtual = ovl->xres_virtual; in sh_mobile_lcdc_overlay_fb_init()
1604 var->yres_virtual = ovl->yres_virtual; in sh_mobile_lcdc_overlay_fb_init()
1605 var->activate = FB_ACTIVATE_NOW; in sh_mobile_lcdc_overlay_fb_init()
1610 if (!ovl->format->yuv) in sh_mobile_lcdc_overlay_fb_init()
1611 var->bits_per_pixel = ovl->format->bpp; in sh_mobile_lcdc_overlay_fb_init()
1613 var->grayscale = ovl->format->fourcc; in sh_mobile_lcdc_overlay_fb_init()
1618 /* -----------------------------------------------------------------------------
1619 * Frame buffer operations - main frame buffer
1626 u32 *palette = info->pseudo_palette; in sh_mobile_lcdc_setcolreg()
1629 return -EINVAL; in sh_mobile_lcdc_setcolreg()
1633 red >>= 16 - info->var.red.length; in sh_mobile_lcdc_setcolreg()
1634 green >>= 16 - info->var.green.length; in sh_mobile_lcdc_setcolreg()
1635 blue >>= 16 - info->var.blue.length; in sh_mobile_lcdc_setcolreg()
1636 transp >>= 16 - info->var.transp.length; in sh_mobile_lcdc_setcolreg()
1638 palette[regno] = (red << info->var.red.offset) | in sh_mobile_lcdc_setcolreg()
1639 (green << info->var.green.offset) | in sh_mobile_lcdc_setcolreg()
1640 (blue << info->var.blue.offset) | in sh_mobile_lcdc_setcolreg()
1641 (transp << info->var.transp.offset); in sh_mobile_lcdc_setcolreg()
1681 struct sh_mobile_lcdc_chan *ch = info->par; in sh_mobile_lcdc_pan() local
1682 struct sh_mobile_lcdc_priv *priv = ch->lcdc; in sh_mobile_lcdc_pan()
1688 if (!ch->format->yuv) { in sh_mobile_lcdc_pan()
1689 y_offset = (var->yoffset * ch->xres_virtual + var->xoffset) in sh_mobile_lcdc_pan()
1690 * ch->format->bpp / 8; in sh_mobile_lcdc_pan()
1693 unsigned int xsub = ch->format->bpp < 24 ? 2 : 1; in sh_mobile_lcdc_pan()
1694 unsigned int ysub = ch->format->bpp < 16 ? 2 : 1; in sh_mobile_lcdc_pan()
1696 y_offset = var->yoffset * ch->xres_virtual + var->xoffset; in sh_mobile_lcdc_pan()
1697 c_offset = var->yoffset / ysub * ch->xres_virtual * 2 / xsub in sh_mobile_lcdc_pan()
1698 + var->xoffset * 2 / xsub; in sh_mobile_lcdc_pan()
1704 if (y_offset == ch->pan_y_offset) in sh_mobile_lcdc_pan()
1708 base_addr_y = ch->dma_handle + y_offset; in sh_mobile_lcdc_pan()
1709 base_addr_c = ch->dma_handle + ch->xres_virtual * ch->yres_virtual in sh_mobile_lcdc_pan()
1712 ch->base_addr_y = base_addr_y; in sh_mobile_lcdc_pan()
1713 ch->base_addr_c = base_addr_c; in sh_mobile_lcdc_pan()
1714 ch->pan_y_offset = y_offset; in sh_mobile_lcdc_pan()
1716 lcdc_write_chan_mirror(ch, LDSA1R, base_addr_y); in sh_mobile_lcdc_pan()
1717 if (ch->format->yuv) in sh_mobile_lcdc_pan()
1718 lcdc_write_chan_mirror(ch, LDSA2R, base_addr_c); in sh_mobile_lcdc_pan()
1721 if (lcdc_chan_is_sublcd(ch)) in sh_mobile_lcdc_pan()
1722 lcdc_write(ch->lcdc, _LDRCNTR, ldrcntr ^ LDRCNTR_SRS); in sh_mobile_lcdc_pan()
1724 lcdc_write(ch->lcdc, _LDRCNTR, ldrcntr ^ LDRCNTR_MRS); in sh_mobile_lcdc_pan()
1735 struct sh_mobile_lcdc_chan *ch = info->par; in sh_mobile_lcdc_ioctl() local
1740 retval = sh_mobile_lcdc_wait_for_vsync(ch); in sh_mobile_lcdc_ioctl()
1744 retval = -ENOIOCTLCMD; in sh_mobile_lcdc_ioctl()
1752 struct sh_mobile_lcdc_chan *ch = info->par; in sh_mobile_fb_reconfig() local
1756 if (ch->use_count > 1 || (ch->use_count == 1 && !info->fbcon_par)) in sh_mobile_fb_reconfig()
1760 fb_var_to_videomode(&mode, &info->var); in sh_mobile_fb_reconfig()
1762 if (fb_mode_is_equal(&ch->display.mode, &mode)) in sh_mobile_fb_reconfig()
1765 /* Display has been re-plugged, framebuffer is free now, reconfigure */ in sh_mobile_fb_reconfig()
1766 var = info->var; in sh_mobile_fb_reconfig()
1767 fb_videomode_to_var(&var, &ch->display.mode); in sh_mobile_fb_reconfig()
1768 var.width = ch->display.width; in sh_mobile_fb_reconfig()
1769 var.height = ch->display.height; in sh_mobile_fb_reconfig()
1780 * Locking: both .fb_release() and .fb_open() are called with info->lock held if
1785 struct sh_mobile_lcdc_chan *ch = info->par; in sh_mobile_lcdc_release() local
1787 mutex_lock(&ch->open_lock); in sh_mobile_lcdc_release()
1788 dev_dbg(info->dev, "%s(): %d users\n", __func__, ch->use_count); in sh_mobile_lcdc_release()
1790 ch->use_count--; in sh_mobile_lcdc_release()
1799 mutex_unlock(&ch->open_lock); in sh_mobile_lcdc_release()
1806 struct sh_mobile_lcdc_chan *ch = info->par; in sh_mobile_lcdc_open() local
1808 mutex_lock(&ch->open_lock); in sh_mobile_lcdc_open()
1809 ch->use_count++; in sh_mobile_lcdc_open()
1811 dev_dbg(info->dev, "%s(): %d users\n", __func__, ch->use_count); in sh_mobile_lcdc_open()
1812 mutex_unlock(&ch->open_lock); in sh_mobile_lcdc_open()
1820 struct sh_mobile_lcdc_chan *ch = info->par; in sh_mobile_lcdc_check_var() local
1821 struct sh_mobile_lcdc_priv *p = ch->lcdc; in sh_mobile_lcdc_check_var()
1822 unsigned int best_dist = (unsigned int)-1; in sh_mobile_lcdc_check_var()
1831 * non-overlapping parts of the two rectangles. in sh_mobile_lcdc_check_var()
1833 for (i = 0; i < ch->cfg->num_modes; ++i) { in sh_mobile_lcdc_check_var()
1834 const struct fb_videomode *mode = &ch->cfg->lcd_modes[i]; in sh_mobile_lcdc_check_var()
1838 if (var->xres > mode->xres || var->yres > mode->yres) in sh_mobile_lcdc_check_var()
1841 dist = var->xres * var->yres + mode->xres * mode->yres in sh_mobile_lcdc_check_var()
1842 - 2 * min(var->xres, mode->xres) in sh_mobile_lcdc_check_var()
1843 * min(var->yres, mode->yres); in sh_mobile_lcdc_check_var()
1846 best_xres = mode->xres; in sh_mobile_lcdc_check_var()
1847 best_yres = mode->yres; in sh_mobile_lcdc_check_var()
1853 if (ch->cfg->num_modes != 0) { in sh_mobile_lcdc_check_var()
1854 if (best_dist == (unsigned int)-1) in sh_mobile_lcdc_check_var()
1855 return -EINVAL; in sh_mobile_lcdc_check_var()
1857 var->xres = best_xres; in sh_mobile_lcdc_check_var()
1858 var->yres = best_yres; in sh_mobile_lcdc_check_var()
1866 if (p->forced_fourcc && in sh_mobile_lcdc_check_var()
1867 p->forced_fourcc != sh_mobile_format_fourcc(var)) in sh_mobile_lcdc_check_var()
1868 return -EINVAL; in sh_mobile_lcdc_check_var()
1875 struct sh_mobile_lcdc_chan *ch = info->par; in sh_mobile_lcdc_set_par() local
1878 sh_mobile_lcdc_stop(ch->lcdc); in sh_mobile_lcdc_set_par()
1880 ch->format = sh_mobile_format_info(sh_mobile_format_fourcc(&info->var)); in sh_mobile_lcdc_set_par()
1881 ch->colorspace = info->var.colorspace; in sh_mobile_lcdc_set_par()
1883 ch->xres = info->var.xres; in sh_mobile_lcdc_set_par()
1884 ch->xres_virtual = info->var.xres_virtual; in sh_mobile_lcdc_set_par()
1885 ch->yres = info->var.yres; in sh_mobile_lcdc_set_par()
1886 ch->yres_virtual = info->var.yres_virtual; in sh_mobile_lcdc_set_par()
1888 if (ch->format->yuv) in sh_mobile_lcdc_set_par()
1889 ch->pitch = info->var.xres_virtual; in sh_mobile_lcdc_set_par()
1891 ch->pitch = info->var.xres_virtual * ch->format->bpp / 8; in sh_mobile_lcdc_set_par()
1893 ret = sh_mobile_lcdc_start(ch->lcdc); in sh_mobile_lcdc_set_par()
1895 dev_err(info->dev, "%s: unable to restart LCDC\n", __func__); in sh_mobile_lcdc_set_par()
1897 info->fix.line_length = ch->pitch; in sh_mobile_lcdc_set_par()
1899 if (sh_mobile_format_is_fourcc(&info->var)) { in sh_mobile_lcdc_set_par()
1900 info->fix.type = FB_TYPE_FOURCC; in sh_mobile_lcdc_set_par()
1901 info->fix.visual = FB_VISUAL_FOURCC; in sh_mobile_lcdc_set_par()
1903 info->fix.type = FB_TYPE_PACKED_PIXELS; in sh_mobile_lcdc_set_par()
1904 info->fix.visual = FB_VISUAL_TRUECOLOR; in sh_mobile_lcdc_set_par()
1920 struct sh_mobile_lcdc_chan *ch = info->par; in sh_mobile_lcdc_blank() local
1921 struct sh_mobile_lcdc_priv *p = ch->lcdc; in sh_mobile_lcdc_blank()
1924 if (blank > FB_BLANK_UNBLANK && ch->blank_status == FB_BLANK_UNBLANK) { in sh_mobile_lcdc_blank()
1926 .width = ch->xres, in sh_mobile_lcdc_blank()
1927 .height = ch->yres, in sh_mobile_lcdc_blank()
1932 if (blank <= FB_BLANK_NORMAL && ch->blank_status > FB_BLANK_NORMAL) { in sh_mobile_lcdc_blank()
1936 if (blank > FB_BLANK_NORMAL && ch->blank_status <= FB_BLANK_NORMAL) { in sh_mobile_lcdc_blank()
1942 if (!info->fbdefio) { in sh_mobile_lcdc_blank()
1943 sh_mobile_lcdc_wait_for_vsync(ch); in sh_mobile_lcdc_blank()
1944 sh_mobile_lcdc_wait_for_vsync(ch); in sh_mobile_lcdc_blank()
1949 ch->blank_status = blank; in sh_mobile_lcdc_blank()
1956 struct sh_mobile_lcdc_chan *ch = info->par; in sh_mobile_lcdc_mmap() local
1958 if (info->fbdefio) in sh_mobile_lcdc_mmap()
1961 return dma_mmap_coherent(ch->lcdc->dev, vma, ch->fb_mem, in sh_mobile_lcdc_mmap()
1962 ch->dma_handle, ch->fb_size); in sh_mobile_lcdc_mmap()
1984 sh_mobile_lcdc_channel_fb_unregister(struct sh_mobile_lcdc_chan *ch) in sh_mobile_lcdc_channel_fb_unregister() argument
1986 if (ch->info && ch->info->dev) in sh_mobile_lcdc_channel_fb_unregister()
1987 unregister_framebuffer(ch->info); in sh_mobile_lcdc_channel_fb_unregister()
1991 sh_mobile_lcdc_channel_fb_register(struct sh_mobile_lcdc_chan *ch) in sh_mobile_lcdc_channel_fb_register() argument
1993 struct fb_info *info = ch->info; in sh_mobile_lcdc_channel_fb_register()
1996 if (info->fbdefio) { in sh_mobile_lcdc_channel_fb_register()
1997 ch->sglist = vmalloc(sizeof(struct scatterlist) * in sh_mobile_lcdc_channel_fb_register()
1998 ch->fb_size >> PAGE_SHIFT); in sh_mobile_lcdc_channel_fb_register()
1999 if (!ch->sglist) in sh_mobile_lcdc_channel_fb_register()
2000 return -ENOMEM; in sh_mobile_lcdc_channel_fb_register()
2003 info->bl_dev = ch->bl; in sh_mobile_lcdc_channel_fb_register()
2009 dev_info(ch->lcdc->dev, "registered %s/%s as %dx%d %dbpp.\n", in sh_mobile_lcdc_channel_fb_register()
2010 dev_name(ch->lcdc->dev), (ch->cfg->chan == LCDC_CHAN_MAINLCD) ? in sh_mobile_lcdc_channel_fb_register()
2011 "mainlcd" : "sublcd", info->var.xres, info->var.yres, in sh_mobile_lcdc_channel_fb_register()
2012 info->var.bits_per_pixel); in sh_mobile_lcdc_channel_fb_register()
2015 if (info->fbdefio || info->state == FBINFO_STATE_SUSPENDED) in sh_mobile_lcdc_channel_fb_register()
2016 sh_mobile_lcdc_clk_off(ch->lcdc); in sh_mobile_lcdc_channel_fb_register()
2022 sh_mobile_lcdc_channel_fb_cleanup(struct sh_mobile_lcdc_chan *ch) in sh_mobile_lcdc_channel_fb_cleanup() argument
2024 struct fb_info *info = ch->info; in sh_mobile_lcdc_channel_fb_cleanup()
2026 if (!info || !info->device) in sh_mobile_lcdc_channel_fb_cleanup()
2029 vfree(ch->sglist); in sh_mobile_lcdc_channel_fb_cleanup()
2031 fb_dealloc_cmap(&info->cmap); in sh_mobile_lcdc_channel_fb_cleanup()
2036 sh_mobile_lcdc_channel_fb_init(struct sh_mobile_lcdc_chan *ch, in sh_mobile_lcdc_channel_fb_init() argument
2040 struct sh_mobile_lcdc_priv *priv = ch->lcdc; in sh_mobile_lcdc_channel_fb_init()
2048 info = framebuffer_alloc(0, priv->dev); in sh_mobile_lcdc_channel_fb_init()
2050 return -ENOMEM; in sh_mobile_lcdc_channel_fb_init()
2052 ch->info = info; in sh_mobile_lcdc_channel_fb_init()
2054 info->fbops = &sh_mobile_lcdc_ops; in sh_mobile_lcdc_channel_fb_init()
2055 info->device = priv->dev; in sh_mobile_lcdc_channel_fb_init()
2056 info->screen_buffer = ch->fb_mem; in sh_mobile_lcdc_channel_fb_init()
2057 info->pseudo_palette = &ch->pseudo_palette; in sh_mobile_lcdc_channel_fb_init()
2058 info->par = ch; in sh_mobile_lcdc_channel_fb_init()
2060 fb_videomode_to_modelist(modes, num_modes, &info->modelist); in sh_mobile_lcdc_channel_fb_init()
2062 ret = fb_alloc_cmap(&info->cmap, PALETTE_NR, 0); in sh_mobile_lcdc_channel_fb_init()
2064 dev_err(priv->dev, "unable to allocate cmap\n"); in sh_mobile_lcdc_channel_fb_init()
2071 info->fix = sh_mobile_lcdc_fix; in sh_mobile_lcdc_channel_fb_init()
2072 info->fix.smem_start = ch->dma_handle; in sh_mobile_lcdc_channel_fb_init()
2073 info->fix.smem_len = ch->fb_size; in sh_mobile_lcdc_channel_fb_init()
2074 info->fix.line_length = ch->pitch; in sh_mobile_lcdc_channel_fb_init()
2076 if (ch->format->yuv) in sh_mobile_lcdc_channel_fb_init()
2077 info->fix.visual = FB_VISUAL_FOURCC; in sh_mobile_lcdc_channel_fb_init()
2079 info->fix.visual = FB_VISUAL_TRUECOLOR; in sh_mobile_lcdc_channel_fb_init()
2081 switch (ch->format->fourcc) { in sh_mobile_lcdc_channel_fb_init()
2084 info->fix.ypanstep = 2; in sh_mobile_lcdc_channel_fb_init()
2088 info->fix.xpanstep = 2; in sh_mobile_lcdc_channel_fb_init()
2094 var = &info->var; in sh_mobile_lcdc_channel_fb_init()
2096 var->width = ch->display.width; in sh_mobile_lcdc_channel_fb_init()
2097 var->height = ch->display.height; in sh_mobile_lcdc_channel_fb_init()
2098 var->xres_virtual = ch->xres_virtual; in sh_mobile_lcdc_channel_fb_init()
2099 var->yres_virtual = ch->yres_virtual; in sh_mobile_lcdc_channel_fb_init()
2100 var->activate = FB_ACTIVATE_NOW; in sh_mobile_lcdc_channel_fb_init()
2105 if (!ch->format->yuv) in sh_mobile_lcdc_channel_fb_init()
2106 var->bits_per_pixel = ch->format->bpp; in sh_mobile_lcdc_channel_fb_init()
2108 var->grayscale = ch->format->fourcc; in sh_mobile_lcdc_channel_fb_init()
2117 /* -----------------------------------------------------------------------------
2123 struct sh_mobile_lcdc_chan *ch = bl_get_data(bdev); in sh_mobile_lcdc_update_bl() local
2124 int brightness = bdev->props.brightness; in sh_mobile_lcdc_update_bl()
2126 if (bdev->props.power != FB_BLANK_UNBLANK || in sh_mobile_lcdc_update_bl()
2127 bdev->props.state & (BL_CORE_SUSPENDED | BL_CORE_FBBLANK)) in sh_mobile_lcdc_update_bl()
2130 ch->bl_brightness = brightness; in sh_mobile_lcdc_update_bl()
2131 return ch->cfg->bl_info.set_brightness(brightness); in sh_mobile_lcdc_update_bl()
2136 struct sh_mobile_lcdc_chan *ch = bl_get_data(bdev); in sh_mobile_lcdc_get_brightness() local
2138 return ch->bl_brightness; in sh_mobile_lcdc_get_brightness()
2144 return (info->bl_dev == bdev); in sh_mobile_lcdc_check_fb()
2155 struct sh_mobile_lcdc_chan *ch) in sh_mobile_lcdc_bl_probe() argument
2159 bl = backlight_device_register(ch->cfg->bl_info.name, parent, ch, in sh_mobile_lcdc_bl_probe()
2167 bl->props.max_brightness = ch->cfg->bl_info.max_brightness; in sh_mobile_lcdc_bl_probe()
2168 bl->props.brightness = bl->props.max_brightness; in sh_mobile_lcdc_bl_probe()
2179 /* -----------------------------------------------------------------------------
2224 /* -----------------------------------------------------------------------------
2228 /* -----------------------------------------------------------------------------
2255 for (i = 0; i < ARRAY_SIZE(priv->overlays); i++) in sh_mobile_lcdc_remove()
2256 sh_mobile_lcdc_overlay_fb_unregister(&priv->overlays[i]); in sh_mobile_lcdc_remove()
2257 for (i = 0; i < ARRAY_SIZE(priv->ch); i++) in sh_mobile_lcdc_remove()
2258 sh_mobile_lcdc_channel_fb_unregister(&priv->ch[i]); in sh_mobile_lcdc_remove()
2262 for (i = 0; i < ARRAY_SIZE(priv->overlays); i++) { in sh_mobile_lcdc_remove()
2263 struct sh_mobile_lcdc_overlay *ovl = &priv->overlays[i]; in sh_mobile_lcdc_remove()
2267 if (ovl->fb_mem) in sh_mobile_lcdc_remove()
2268 dma_free_coherent(&pdev->dev, ovl->fb_size, in sh_mobile_lcdc_remove()
2269 ovl->fb_mem, ovl->dma_handle); in sh_mobile_lcdc_remove()
2272 for (i = 0; i < ARRAY_SIZE(priv->ch); i++) { in sh_mobile_lcdc_remove()
2273 struct sh_mobile_lcdc_chan *ch = &priv->ch[i]; in sh_mobile_lcdc_remove() local
2275 if (ch->tx_dev) { in sh_mobile_lcdc_remove()
2276 ch->tx_dev->lcdc = NULL; in sh_mobile_lcdc_remove()
2277 module_put(ch->cfg->tx_dev->dev.driver->owner); in sh_mobile_lcdc_remove()
2280 sh_mobile_lcdc_channel_fb_cleanup(ch); in sh_mobile_lcdc_remove()
2282 if (ch->fb_mem) in sh_mobile_lcdc_remove()
2283 dma_free_coherent(&pdev->dev, ch->fb_size, in sh_mobile_lcdc_remove()
2284 ch->fb_mem, ch->dma_handle); in sh_mobile_lcdc_remove()
2287 for (i = 0; i < ARRAY_SIZE(priv->ch); i++) { in sh_mobile_lcdc_remove()
2288 struct sh_mobile_lcdc_chan *ch = &priv->ch[i]; in sh_mobile_lcdc_remove() local
2290 if (ch->bl) in sh_mobile_lcdc_remove()
2291 sh_mobile_lcdc_bl_remove(ch->bl); in sh_mobile_lcdc_remove()
2292 mutex_destroy(&ch->open_lock); in sh_mobile_lcdc_remove()
2295 if (priv->dot_clk) { in sh_mobile_lcdc_remove()
2296 pm_runtime_disable(&pdev->dev); in sh_mobile_lcdc_remove()
2297 clk_put(priv->dot_clk); in sh_mobile_lcdc_remove()
2300 if (priv->base) in sh_mobile_lcdc_remove()
2301 iounmap(priv->base); in sh_mobile_lcdc_remove()
2303 if (priv->irq) in sh_mobile_lcdc_remove()
2304 free_irq(priv->irq, priv); in sh_mobile_lcdc_remove()
2308 static int sh_mobile_lcdc_check_interface(struct sh_mobile_lcdc_chan *ch) in sh_mobile_lcdc_check_interface() argument
2310 int interface_type = ch->cfg->interface_type; in sh_mobile_lcdc_check_interface()
2333 return -EINVAL; in sh_mobile_lcdc_check_interface()
2337 if (lcdc_chan_is_sublcd(ch)) { in sh_mobile_lcdc_check_interface()
2339 return -EINVAL; in sh_mobile_lcdc_check_interface()
2344 ch->ldmt1r_value = interface_type; in sh_mobile_lcdc_check_interface()
2352 struct device *dev = ovl->channel->lcdc->dev; in sh_mobile_lcdc_overlay_init()
2355 if (ovl->cfg->fourcc == 0) in sh_mobile_lcdc_overlay_init()
2359 format = sh_mobile_format_info(ovl->cfg->fourcc); in sh_mobile_lcdc_overlay_init()
2361 dev_err(dev, "Invalid FOURCC %08x\n", ovl->cfg->fourcc); in sh_mobile_lcdc_overlay_init()
2362 return -EINVAL; in sh_mobile_lcdc_overlay_init()
2365 ovl->enabled = false; in sh_mobile_lcdc_overlay_init()
2366 ovl->mode = LCDC_OVERLAY_BLEND; in sh_mobile_lcdc_overlay_init()
2367 ovl->alpha = 255; in sh_mobile_lcdc_overlay_init()
2368 ovl->rop3 = 0; in sh_mobile_lcdc_overlay_init()
2369 ovl->pos_x = 0; in sh_mobile_lcdc_overlay_init()
2370 ovl->pos_y = 0; in sh_mobile_lcdc_overlay_init()
2373 * double-buffering. in sh_mobile_lcdc_overlay_init()
2375 ovl->format = format; in sh_mobile_lcdc_overlay_init()
2376 ovl->xres = ovl->cfg->max_xres; in sh_mobile_lcdc_overlay_init()
2377 ovl->xres_virtual = ovl->xres; in sh_mobile_lcdc_overlay_init()
2378 ovl->yres = ovl->cfg->max_yres; in sh_mobile_lcdc_overlay_init()
2379 ovl->yres_virtual = ovl->yres * 2; in sh_mobile_lcdc_overlay_init()
2381 if (!format->yuv) in sh_mobile_lcdc_overlay_init()
2382 ovl->pitch = ovl->xres_virtual * format->bpp / 8; in sh_mobile_lcdc_overlay_init()
2384 ovl->pitch = ovl->xres_virtual; in sh_mobile_lcdc_overlay_init()
2387 ovl->fb_size = ovl->cfg->max_xres * ovl->cfg->max_yres in sh_mobile_lcdc_overlay_init()
2388 * format->bpp / 8 * 2; in sh_mobile_lcdc_overlay_init()
2389 ovl->fb_mem = dma_alloc_coherent(dev, ovl->fb_size, &ovl->dma_handle, in sh_mobile_lcdc_overlay_init()
2391 if (!ovl->fb_mem) { in sh_mobile_lcdc_overlay_init()
2393 return -ENOMEM; in sh_mobile_lcdc_overlay_init()
2404 sh_mobile_lcdc_channel_init(struct sh_mobile_lcdc_chan *ch) in sh_mobile_lcdc_channel_init() argument
2407 const struct sh_mobile_lcdc_chan_cfg *cfg = ch->cfg; in sh_mobile_lcdc_channel_init()
2408 struct device *dev = ch->lcdc->dev; in sh_mobile_lcdc_channel_init()
2416 format = sh_mobile_format_info(cfg->fourcc); in sh_mobile_lcdc_channel_init()
2418 dev_err(dev, "Invalid FOURCC %08x.\n", cfg->fourcc); in sh_mobile_lcdc_channel_init()
2419 return -EINVAL; in sh_mobile_lcdc_channel_init()
2428 for (i = 0, mode = cfg->lcd_modes; i < cfg->num_modes; i++, mode++) { in sh_mobile_lcdc_channel_init()
2429 unsigned int size = mode->yres * mode->xres; in sh_mobile_lcdc_channel_init()
2432 if ((cfg->fourcc == V4L2_PIX_FMT_NV12 || in sh_mobile_lcdc_channel_init()
2433 cfg->fourcc == V4L2_PIX_FMT_NV21) && (mode->yres & 0x1)) { in sh_mobile_lcdc_channel_init()
2436 return -EINVAL; in sh_mobile_lcdc_channel_init()
2449 max_mode->xres, max_mode->yres); in sh_mobile_lcdc_channel_init()
2451 if (cfg->lcd_modes == NULL) { in sh_mobile_lcdc_channel_init()
2455 mode = cfg->lcd_modes; in sh_mobile_lcdc_channel_init()
2456 num_modes = cfg->num_modes; in sh_mobile_lcdc_channel_init()
2460 * twice the panel size to allow for double-buffering. in sh_mobile_lcdc_channel_init()
2462 ch->format = format; in sh_mobile_lcdc_channel_init()
2463 ch->xres = mode->xres; in sh_mobile_lcdc_channel_init()
2464 ch->xres_virtual = mode->xres; in sh_mobile_lcdc_channel_init()
2465 ch->yres = mode->yres; in sh_mobile_lcdc_channel_init()
2466 ch->yres_virtual = mode->yres * 2; in sh_mobile_lcdc_channel_init()
2468 if (!format->yuv) { in sh_mobile_lcdc_channel_init()
2469 ch->colorspace = V4L2_COLORSPACE_SRGB; in sh_mobile_lcdc_channel_init()
2470 ch->pitch = ch->xres_virtual * format->bpp / 8; in sh_mobile_lcdc_channel_init()
2472 ch->colorspace = V4L2_COLORSPACE_REC709; in sh_mobile_lcdc_channel_init()
2473 ch->pitch = ch->xres_virtual; in sh_mobile_lcdc_channel_init()
2476 ch->display.width = cfg->panel_cfg.width; in sh_mobile_lcdc_channel_init()
2477 ch->display.height = cfg->panel_cfg.height; in sh_mobile_lcdc_channel_init()
2478 ch->display.mode = *mode; in sh_mobile_lcdc_channel_init()
2481 ch->fb_size = max_size * format->bpp / 8 * 2; in sh_mobile_lcdc_channel_init()
2482 ch->fb_mem = dma_alloc_coherent(dev, ch->fb_size, &ch->dma_handle, in sh_mobile_lcdc_channel_init()
2484 if (ch->fb_mem == NULL) { in sh_mobile_lcdc_channel_init()
2486 return -ENOMEM; in sh_mobile_lcdc_channel_init()
2490 if (cfg->tx_dev) { in sh_mobile_lcdc_channel_init()
2491 if (!cfg->tx_dev->dev.driver || in sh_mobile_lcdc_channel_init()
2492 !try_module_get(cfg->tx_dev->dev.driver->owner)) { in sh_mobile_lcdc_channel_init()
2494 return -EINVAL; in sh_mobile_lcdc_channel_init()
2496 ch->tx_dev = platform_get_drvdata(cfg->tx_dev); in sh_mobile_lcdc_channel_init()
2497 ch->tx_dev->lcdc = ch; in sh_mobile_lcdc_channel_init()
2498 ch->tx_dev->def_mode = *mode; in sh_mobile_lcdc_channel_init()
2501 return sh_mobile_lcdc_channel_fb_init(ch, mode, num_modes); in sh_mobile_lcdc_channel_init()
2506 struct sh_mobile_lcdc_info *pdata = pdev->dev.platform_data; in sh_mobile_lcdc_probe()
2514 dev_err(&pdev->dev, "no platform data defined\n"); in sh_mobile_lcdc_probe()
2515 return -EINVAL; in sh_mobile_lcdc_probe()
2521 dev_err(&pdev->dev, "cannot get platform resources\n"); in sh_mobile_lcdc_probe()
2522 return -ENOENT; in sh_mobile_lcdc_probe()
2527 return -ENOMEM; in sh_mobile_lcdc_probe()
2529 priv->dev = &pdev->dev; in sh_mobile_lcdc_probe()
2531 for (i = 0; i < ARRAY_SIZE(priv->ch); i++) in sh_mobile_lcdc_probe()
2532 mutex_init(&priv->ch[i].open_lock); in sh_mobile_lcdc_probe()
2536 dev_name(&pdev->dev), priv); in sh_mobile_lcdc_probe()
2538 dev_err(&pdev->dev, "unable to request irq\n"); in sh_mobile_lcdc_probe()
2542 priv->irq = irq; in sh_mobile_lcdc_probe()
2543 atomic_set(&priv->hw_usecnt, -1); in sh_mobile_lcdc_probe()
2545 for (i = 0, num_channels = 0; i < ARRAY_SIZE(pdata->ch); i++) { in sh_mobile_lcdc_probe()
2546 struct sh_mobile_lcdc_chan *ch = priv->ch + num_channels; in sh_mobile_lcdc_probe() local
2548 ch->lcdc = priv; in sh_mobile_lcdc_probe()
2549 ch->cfg = &pdata->ch[i]; in sh_mobile_lcdc_probe()
2551 error = sh_mobile_lcdc_check_interface(ch); in sh_mobile_lcdc_probe()
2553 dev_err(&pdev->dev, "unsupported interface type\n"); in sh_mobile_lcdc_probe()
2556 init_waitqueue_head(&ch->frame_end_wait); in sh_mobile_lcdc_probe()
2557 init_completion(&ch->vsync_completion); in sh_mobile_lcdc_probe()
2560 if (ch->cfg->bl_info.max_brightness) in sh_mobile_lcdc_probe()
2561 ch->bl = sh_mobile_lcdc_bl_probe(&pdev->dev, ch); in sh_mobile_lcdc_probe()
2563 switch (pdata->ch[i].chan) { in sh_mobile_lcdc_probe()
2565 ch->enabled = LDCNT2R_ME; in sh_mobile_lcdc_probe()
2566 ch->reg_offs = lcdc_offs_mainlcd; in sh_mobile_lcdc_probe()
2570 ch->enabled = LDCNT2R_SE; in sh_mobile_lcdc_probe()
2571 ch->reg_offs = lcdc_offs_sublcd; in sh_mobile_lcdc_probe()
2578 dev_err(&pdev->dev, "no channels defined\n"); in sh_mobile_lcdc_probe()
2579 error = -EINVAL; in sh_mobile_lcdc_probe()
2585 priv->forced_fourcc = pdata->ch[0].fourcc; in sh_mobile_lcdc_probe()
2587 priv->base = ioremap(res->start, resource_size(res)); in sh_mobile_lcdc_probe()
2588 if (!priv->base) { in sh_mobile_lcdc_probe()
2589 error = -ENOMEM; in sh_mobile_lcdc_probe()
2593 error = sh_mobile_lcdc_setup_clocks(priv, pdata->clock_source); in sh_mobile_lcdc_probe()
2595 dev_err(&pdev->dev, "unable to setup clocks\n"); in sh_mobile_lcdc_probe()
2600 pm_runtime_enable(&pdev->dev); in sh_mobile_lcdc_probe()
2603 struct sh_mobile_lcdc_chan *ch = &priv->ch[i]; in sh_mobile_lcdc_probe() local
2605 error = sh_mobile_lcdc_channel_init(ch); in sh_mobile_lcdc_probe()
2610 for (i = 0; i < ARRAY_SIZE(pdata->overlays); i++) { in sh_mobile_lcdc_probe()
2611 struct sh_mobile_lcdc_overlay *ovl = &priv->overlays[i]; in sh_mobile_lcdc_probe()
2613 ovl->cfg = &pdata->overlays[i]; in sh_mobile_lcdc_probe()
2614 ovl->channel = &priv->ch[0]; in sh_mobile_lcdc_probe()
2623 dev_err(&pdev->dev, "unable to start hardware\n"); in sh_mobile_lcdc_probe()
2628 struct sh_mobile_lcdc_chan *ch = priv->ch + i; in sh_mobile_lcdc_probe() local
2630 error = sh_mobile_lcdc_channel_fb_register(ch); in sh_mobile_lcdc_probe()
2635 for (i = 0; i < ARRAY_SIZE(pdata->overlays); i++) { in sh_mobile_lcdc_probe()
2636 struct sh_mobile_lcdc_overlay *ovl = &priv->overlays[i]; in sh_mobile_lcdc_probe()