aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/sh_mobile_lcdcfb.c
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>2011-11-21 18:56:58 -0500
committerLaurent Pinchart <laurent.pinchart@ideasonboard.com>2012-03-12 17:41:12 -0400
commitb5ef967df13d4d243a2954c32bdd9181a1ee7382 (patch)
tree2c8259f90d5bd79aeb20f210aabd9f5459e352ff /drivers/video/sh_mobile_lcdcfb.c
parentd81d5fa8adfb0ba19f44bb6c4c04a2a23effac3f (diff)
fbdev: sh_mobile_lcdc: Don't store copy of platform data
Instead of copying the whole platform data structure to struct sh_mobile_lcdc_chan, store a const pointer to the channel platform data. MERAM configuration information needs to be changed at runtime, so copy it to struct sh_mobile_lcdc_chan. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Diffstat (limited to 'drivers/video/sh_mobile_lcdcfb.c')
-rw-r--r--drivers/video/sh_mobile_lcdcfb.c71
1 files changed, 35 insertions, 36 deletions
diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c
index d0c902699222..033851618323 100644
--- a/drivers/video/sh_mobile_lcdcfb.c
+++ b/drivers/video/sh_mobile_lcdcfb.c
@@ -116,7 +116,7 @@ static bool banked(int reg_nr)
116 116
117static int lcdc_chan_is_sublcd(struct sh_mobile_lcdc_chan *chan) 117static int lcdc_chan_is_sublcd(struct sh_mobile_lcdc_chan *chan)
118{ 118{
119 return chan->cfg.chan == LCDC_CHAN_SUBLCD; 119 return chan->cfg->chan == LCDC_CHAN_SUBLCD;
120} 120}
121 121
122static void lcdc_write_chan(struct sh_mobile_lcdc_chan *chan, 122static void lcdc_write_chan(struct sh_mobile_lcdc_chan *chan,
@@ -289,7 +289,7 @@ static void sh_mobile_lcdc_deferred_io(struct fb_info *info,
289 struct list_head *pagelist) 289 struct list_head *pagelist)
290{ 290{
291 struct sh_mobile_lcdc_chan *ch = info->par; 291 struct sh_mobile_lcdc_chan *ch = info->par;
292 struct sh_mobile_lcdc_panel_cfg *panel = &ch->cfg.panel_cfg; 292 const struct sh_mobile_lcdc_panel_cfg *panel = &ch->cfg->panel_cfg;
293 293
294 /* enable clocks before accessing hardware */ 294 /* enable clocks before accessing hardware */
295 sh_mobile_lcdc_clk_on(ch->lcdc); 295 sh_mobile_lcdc_clk_on(ch->lcdc);
@@ -336,7 +336,7 @@ static void sh_mobile_lcdc_deferred_io_touch(struct fb_info *info)
336 336
337static void sh_mobile_lcdc_display_on(struct sh_mobile_lcdc_chan *ch) 337static void sh_mobile_lcdc_display_on(struct sh_mobile_lcdc_chan *ch)
338{ 338{
339 struct sh_mobile_lcdc_panel_cfg *panel = &ch->cfg.panel_cfg; 339 const struct sh_mobile_lcdc_panel_cfg *panel = &ch->cfg->panel_cfg;
340 340
341 if (ch->tx_dev) { 341 if (ch->tx_dev) {
342 int ret; 342 int ret;
@@ -356,7 +356,7 @@ static void sh_mobile_lcdc_display_on(struct sh_mobile_lcdc_chan *ch)
356 356
357static void sh_mobile_lcdc_display_off(struct sh_mobile_lcdc_chan *ch) 357static void sh_mobile_lcdc_display_off(struct sh_mobile_lcdc_chan *ch)
358{ 358{
359 struct sh_mobile_lcdc_panel_cfg *panel = &ch->cfg.panel_cfg; 359 const struct sh_mobile_lcdc_panel_cfg *panel = &ch->cfg->panel_cfg;
360 360
361 if (panel->display_off) 361 if (panel->display_off)
362 panel->display_off(); 362 panel->display_off();
@@ -644,16 +644,16 @@ static void sh_mobile_lcdc_geometry(struct sh_mobile_lcdc_chan *ch)
644 tmp = ch->ldmt1r_value; 644 tmp = ch->ldmt1r_value;
645 tmp |= (var->sync & FB_SYNC_VERT_HIGH_ACT) ? 0 : LDMT1R_VPOL; 645 tmp |= (var->sync & FB_SYNC_VERT_HIGH_ACT) ? 0 : LDMT1R_VPOL;
646 tmp |= (var->sync & FB_SYNC_HOR_HIGH_ACT) ? 0 : LDMT1R_HPOL; 646 tmp |= (var->sync & FB_SYNC_HOR_HIGH_ACT) ? 0 : LDMT1R_HPOL;
647 tmp |= (ch->cfg.flags & LCDC_FLAGS_DWPOL) ? LDMT1R_DWPOL : 0; 647 tmp |= (ch->cfg->flags & LCDC_FLAGS_DWPOL) ? LDMT1R_DWPOL : 0;
648 tmp |= (ch->cfg.flags & LCDC_FLAGS_DIPOL) ? LDMT1R_DIPOL : 0; 648 tmp |= (ch->cfg->flags & LCDC_FLAGS_DIPOL) ? LDMT1R_DIPOL : 0;
649 tmp |= (ch->cfg.flags & LCDC_FLAGS_DAPOL) ? LDMT1R_DAPOL : 0; 649 tmp |= (ch->cfg->flags & LCDC_FLAGS_DAPOL) ? LDMT1R_DAPOL : 0;
650 tmp |= (ch->cfg.flags & LCDC_FLAGS_HSCNT) ? LDMT1R_HSCNT : 0; 650 tmp |= (ch->cfg->flags & LCDC_FLAGS_HSCNT) ? LDMT1R_HSCNT : 0;
651 tmp |= (ch->cfg.flags & LCDC_FLAGS_DWCNT) ? LDMT1R_DWCNT : 0; 651 tmp |= (ch->cfg->flags & LCDC_FLAGS_DWCNT) ? LDMT1R_DWCNT : 0;
652 lcdc_write_chan(ch, LDMT1R, tmp); 652 lcdc_write_chan(ch, LDMT1R, tmp);
653 653
654 /* setup SYS bus */ 654 /* setup SYS bus */
655 lcdc_write_chan(ch, LDMT2R, ch->cfg.sys_bus_cfg.ldmt2r); 655 lcdc_write_chan(ch, LDMT2R, ch->cfg->sys_bus_cfg.ldmt2r);
656 lcdc_write_chan(ch, LDMT3R, ch->cfg.sys_bus_cfg.ldmt3r); 656 lcdc_write_chan(ch, LDMT3R, ch->cfg->sys_bus_cfg.ldmt3r);
657 657
658 /* horizontal configuration */ 658 /* horizontal configuration */
659 h_total = mode->xres + mode->hsync_len + mode->left_margin 659 h_total = mode->xres + mode->hsync_len + mode->left_margin
@@ -717,7 +717,7 @@ static void __sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
717 /* Power supply */ 717 /* Power supply */
718 lcdc_write_chan(ch, LDPMR, 0); 718 lcdc_write_chan(ch, LDPMR, 0);
719 719
720 m = ch->cfg.clock_divider; 720 m = ch->cfg->clock_divider;
721 if (!m) 721 if (!m)
722 continue; 722 continue;
723 723
@@ -768,7 +768,7 @@ static void __sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
768 * continuous read mode. 768 * continuous read mode.
769 */ 769 */
770 if (ch->ldmt1r_value & LDMT1R_IFM && 770 if (ch->ldmt1r_value & LDMT1R_IFM &&
771 ch->cfg.sys_bus_cfg.deferred_io_msec) { 771 ch->cfg->sys_bus_cfg.deferred_io_msec) {
772 lcdc_write_chan(ch, LDSM1R, LDSM1R_OS); 772 lcdc_write_chan(ch, LDSM1R, LDSM1R_OS);
773 lcdc_write(priv, _LDINTR, LDINTR_FE); 773 lcdc_write(priv, _LDINTR, LDINTR_FE);
774 } else { 774 } else {
@@ -822,13 +822,13 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
822 lcdc_wait_bit(priv, _LDCNT2R, LDCNT2R_BR, 0); 822 lcdc_wait_bit(priv, _LDCNT2R, LDCNT2R_BR, 0);
823 823
824 for (k = 0; k < ARRAY_SIZE(priv->ch); k++) { 824 for (k = 0; k < ARRAY_SIZE(priv->ch); k++) {
825 struct sh_mobile_lcdc_panel_cfg *panel; 825 const struct sh_mobile_lcdc_panel_cfg *panel;
826 826
827 ch = &priv->ch[k]; 827 ch = &priv->ch[k];
828 if (!ch->enabled) 828 if (!ch->enabled)
829 continue; 829 continue;
830 830
831 panel = &ch->cfg.panel_cfg; 831 panel = &ch->cfg->panel_cfg;
832 if (panel->setup_sys) { 832 if (panel->setup_sys) {
833 ret = panel->setup_sys(ch, &sh_mobile_lcdc_sys_bus_ops); 833 ret = panel->setup_sys(ch, &sh_mobile_lcdc_sys_bus_ops);
834 if (ret) 834 if (ret)
@@ -838,7 +838,6 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
838 838
839 /* Compute frame buffer base address and pitch for each channel. */ 839 /* Compute frame buffer base address and pitch for each channel. */
840 for (k = 0; k < ARRAY_SIZE(priv->ch); k++) { 840 for (k = 0; k < ARRAY_SIZE(priv->ch); k++) {
841 struct sh_mobile_meram_cfg *cfg;
842 int pixelformat; 841 int pixelformat;
843 void *meram; 842 void *meram;
844 843
@@ -850,8 +849,8 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
850 ch->base_addr_c = ch->base_addr_y + ch->xres * ch->yres_virtual; 849 ch->base_addr_c = ch->base_addr_y + ch->xres * ch->yres_virtual;
851 850
852 /* Enable MERAM if possible. */ 851 /* Enable MERAM if possible. */
853 cfg = ch->cfg.meram_cfg; 852 if (mdev == NULL || mdev->ops == NULL ||
854 if (mdev == NULL || mdev->ops == NULL || cfg == NULL) 853 ch->cfg->meram_cfg == NULL)
855 continue; 854 continue;
856 855
857 /* we need to de-init configured ICBs before we can 856 /* we need to de-init configured ICBs before we can
@@ -881,8 +880,8 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
881 break; 880 break;
882 } 881 }
883 882
884 meram = mdev->ops->meram_register(mdev, cfg, ch->pitch, 883 meram = mdev->ops->meram_register(mdev, ch->cfg->meram_cfg,
885 ch->yres, pixelformat, 884 ch->pitch, ch->yres, pixelformat,
886 ch->base_addr_y, ch->base_addr_c, 885 ch->base_addr_y, ch->base_addr_c,
887 &ch->base_addr_y, &ch->base_addr_c, 886 &ch->base_addr_y, &ch->base_addr_c,
888 &ch->pitch); 887 &ch->pitch);
@@ -901,7 +900,7 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
901 if (!ch->enabled) 900 if (!ch->enabled)
902 continue; 901 continue;
903 902
904 tmp = ch->cfg.sys_bus_cfg.deferred_io_msec; 903 tmp = ch->cfg->sys_bus_cfg.deferred_io_msec;
905 if (ch->ldmt1r_value & LDMT1R_IFM && tmp) { 904 if (ch->ldmt1r_value & LDMT1R_IFM && tmp) {
906 ch->defio.deferred_io = sh_mobile_lcdc_deferred_io; 905 ch->defio.deferred_io = sh_mobile_lcdc_deferred_io;
907 ch->defio.delay = msecs_to_jiffies(tmp); 906 ch->defio.delay = msecs_to_jiffies(tmp);
@@ -1210,8 +1209,8 @@ static int sh_mobile_check_var(struct fb_var_screeninfo *var, struct fb_info *in
1210 * distance between two modes is defined as the size of the 1209 * distance between two modes is defined as the size of the
1211 * non-overlapping parts of the two rectangles. 1210 * non-overlapping parts of the two rectangles.
1212 */ 1211 */
1213 for (i = 0; i < ch->cfg.num_modes; ++i) { 1212 for (i = 0; i < ch->cfg->num_modes; ++i) {
1214 const struct fb_videomode *mode = &ch->cfg.lcd_modes[i]; 1213 const struct fb_videomode *mode = &ch->cfg->lcd_modes[i];
1215 unsigned int dist; 1214 unsigned int dist;
1216 1215
1217 /* We can only round up. */ 1216 /* We can only round up. */
@@ -1230,7 +1229,7 @@ static int sh_mobile_check_var(struct fb_var_screeninfo *var, struct fb_info *in
1230 } 1229 }
1231 1230
1232 /* If no available mode can be used, return an error. */ 1231 /* If no available mode can be used, return an error. */
1233 if (ch->cfg.num_modes != 0) { 1232 if (ch->cfg->num_modes != 0) {
1234 if (best_dist == (unsigned int)-1) 1233 if (best_dist == (unsigned int)-1)
1235 return -EINVAL; 1234 return -EINVAL;
1236 1235
@@ -1440,7 +1439,7 @@ sh_mobile_lcdc_channel_fb_register(struct sh_mobile_lcdc_chan *ch)
1440 return ret; 1439 return ret;
1441 1440
1442 dev_info(ch->lcdc->dev, "registered %s/%s as %dx%d %dbpp.\n", 1441 dev_info(ch->lcdc->dev, "registered %s/%s as %dx%d %dbpp.\n",
1443 dev_name(ch->lcdc->dev), (ch->cfg.chan == LCDC_CHAN_MAINLCD) ? 1442 dev_name(ch->lcdc->dev), (ch->cfg->chan == LCDC_CHAN_MAINLCD) ?
1444 "mainlcd" : "sublcd", info->var.xres, info->var.yres, 1443 "mainlcd" : "sublcd", info->var.xres, info->var.yres,
1445 info->var.bits_per_pixel); 1444 info->var.bits_per_pixel);
1446 1445
@@ -1525,8 +1524,8 @@ sh_mobile_lcdc_channel_fb_init(struct sh_mobile_lcdc_chan *ch,
1525 */ 1524 */
1526 var = &info->var; 1525 var = &info->var;
1527 fb_videomode_to_var(var, mode); 1526 fb_videomode_to_var(var, mode);
1528 var->width = ch->cfg.panel_cfg.width; 1527 var->width = ch->cfg->panel_cfg.width;
1529 var->height = ch->cfg.panel_cfg.height; 1528 var->height = ch->cfg->panel_cfg.height;
1530 var->yres_virtual = var->yres * 2; 1529 var->yres_virtual = var->yres * 2;
1531 var->activate = FB_ACTIVATE_NOW; 1530 var->activate = FB_ACTIVATE_NOW;
1532 1531
@@ -1558,14 +1557,14 @@ static int sh_mobile_lcdc_update_bl(struct backlight_device *bdev)
1558 bdev->props.state & (BL_CORE_SUSPENDED | BL_CORE_FBBLANK)) 1557 bdev->props.state & (BL_CORE_SUSPENDED | BL_CORE_FBBLANK))
1559 brightness = 0; 1558 brightness = 0;
1560 1559
1561 return ch->cfg.bl_info.set_brightness(brightness); 1560 return ch->cfg->bl_info.set_brightness(brightness);
1562} 1561}
1563 1562
1564static int sh_mobile_lcdc_get_brightness(struct backlight_device *bdev) 1563static int sh_mobile_lcdc_get_brightness(struct backlight_device *bdev)
1565{ 1564{
1566 struct sh_mobile_lcdc_chan *ch = bl_get_data(bdev); 1565 struct sh_mobile_lcdc_chan *ch = bl_get_data(bdev);
1567 1566
1568 return ch->cfg.bl_info.get_brightness(); 1567 return ch->cfg->bl_info.get_brightness();
1569} 1568}
1570 1569
1571static int sh_mobile_lcdc_check_fb(struct backlight_device *bdev, 1570static int sh_mobile_lcdc_check_fb(struct backlight_device *bdev,
@@ -1586,7 +1585,7 @@ static struct backlight_device *sh_mobile_lcdc_bl_probe(struct device *parent,
1586{ 1585{
1587 struct backlight_device *bl; 1586 struct backlight_device *bl;
1588 1587
1589 bl = backlight_device_register(ch->cfg.bl_info.name, parent, ch, 1588 bl = backlight_device_register(ch->cfg->bl_info.name, parent, ch,
1590 &sh_mobile_lcdc_bl_ops, NULL); 1589 &sh_mobile_lcdc_bl_ops, NULL);
1591 if (IS_ERR(bl)) { 1590 if (IS_ERR(bl)) {
1592 dev_err(parent, "unable to register backlight device: %ld\n", 1591 dev_err(parent, "unable to register backlight device: %ld\n",
@@ -1594,7 +1593,7 @@ static struct backlight_device *sh_mobile_lcdc_bl_probe(struct device *parent,
1594 return NULL; 1593 return NULL;
1595 } 1594 }
1596 1595
1597 bl->props.max_brightness = ch->cfg.bl_info.max_brightness; 1596 bl->props.max_brightness = ch->cfg->bl_info.max_brightness;
1598 bl->props.brightness = bl->props.max_brightness; 1597 bl->props.brightness = bl->props.max_brightness;
1599 backlight_update_status(bl); 1598 backlight_update_status(bl);
1600 1599
@@ -1727,7 +1726,7 @@ static int sh_mobile_lcdc_remove(struct platform_device *pdev)
1727 1726
1728 if (ch->tx_dev) { 1727 if (ch->tx_dev) {
1729 ch->tx_dev->lcdc = NULL; 1728 ch->tx_dev->lcdc = NULL;
1730 module_put(ch->cfg.tx_dev->dev.driver->owner); 1729 module_put(ch->cfg->tx_dev->dev.driver->owner);
1731 } 1730 }
1732 1731
1733 sh_mobile_lcdc_channel_fb_cleanup(ch); 1732 sh_mobile_lcdc_channel_fb_cleanup(ch);
@@ -1758,7 +1757,7 @@ static int sh_mobile_lcdc_remove(struct platform_device *pdev)
1758 1757
1759static int __devinit sh_mobile_lcdc_check_interface(struct sh_mobile_lcdc_chan *ch) 1758static int __devinit sh_mobile_lcdc_check_interface(struct sh_mobile_lcdc_chan *ch)
1760{ 1759{
1761 int interface_type = ch->cfg.interface_type; 1760 int interface_type = ch->cfg->interface_type;
1762 1761
1763 switch (interface_type) { 1762 switch (interface_type) {
1764 case RGB8: 1763 case RGB8:
@@ -1801,7 +1800,7 @@ sh_mobile_lcdc_channel_init(struct sh_mobile_lcdc_priv *priv,
1801 struct sh_mobile_lcdc_chan *ch) 1800 struct sh_mobile_lcdc_chan *ch)
1802{ 1801{
1803 const struct sh_mobile_lcdc_format_info *format; 1802 const struct sh_mobile_lcdc_format_info *format;
1804 struct sh_mobile_lcdc_chan_cfg *cfg = &ch->cfg; 1803 const struct sh_mobile_lcdc_chan_cfg *cfg = ch->cfg;
1805 const struct fb_videomode *max_mode; 1804 const struct fb_videomode *max_mode;
1806 const struct fb_videomode *mode; 1805 const struct fb_videomode *mode;
1807 unsigned int num_modes; 1806 unsigned int num_modes;
@@ -1944,7 +1943,7 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev)
1944 struct sh_mobile_lcdc_chan *ch = priv->ch + num_channels; 1943 struct sh_mobile_lcdc_chan *ch = priv->ch + num_channels;
1945 1944
1946 ch->lcdc = priv; 1945 ch->lcdc = priv;
1947 memcpy(&ch->cfg, &pdata->ch[i], sizeof(pdata->ch[i])); 1946 ch->cfg = &pdata->ch[i];
1948 1947
1949 error = sh_mobile_lcdc_check_interface(ch); 1948 error = sh_mobile_lcdc_check_interface(ch);
1950 if (error) { 1949 if (error) {
@@ -1956,7 +1955,7 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev)
1956 ch->pan_offset = 0; 1955 ch->pan_offset = 0;
1957 1956
1958 /* probe the backlight is there is one defined */ 1957 /* probe the backlight is there is one defined */
1959 if (ch->cfg.bl_info.max_brightness) 1958 if (ch->cfg->bl_info.max_brightness)
1960 ch->bl = sh_mobile_lcdc_bl_probe(&pdev->dev, ch); 1959 ch->bl = sh_mobile_lcdc_bl_probe(&pdev->dev, ch);
1961 1960
1962 switch (pdata->ch[i].chan) { 1961 switch (pdata->ch[i].chan) {