* [WIP/RFC 19/31] fbdev: sh_mobile_lcdc: Merge board_cfg and lcd_size_cfg into panel_cfg
From: Laurent Pinchart @ 2011-09-19 0:27 UTC (permalink / raw)
To: linux-fbdev
Update board code accordingly.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
arch/arm/mach-shmobile/board-ag5evm.c | 6 ++--
arch/arm/mach-shmobile/board-ap4evb.c | 8 +++---
arch/arm/mach-shmobile/board-mackerel.c | 6 +++-
arch/sh/boards/mach-ap325rxa/setup.c | 6 +---
arch/sh/boards/mach-ecovec24/setup.c | 2 +-
arch/sh/boards/mach-kfr2r09/setup.c | 4 +--
arch/sh/boards/mach-migor/setup.c | 8 ++----
arch/sh/boards/mach-se/7724/setup.c | 2 +-
drivers/video/sh_mobile_lcdcfb.c | 35 +++++++++++++++----------------
include/video/sh_mobile_lcdc.h | 12 +++-------
10 files changed, 40 insertions(+), 49 deletions(-)
diff --git a/arch/arm/mach-shmobile/board-ag5evm.c b/arch/arm/mach-shmobile/board-ag5evm.c
index 139fbd1..c8b57a7 100644
--- a/arch/arm/mach-shmobile/board-ag5evm.c
+++ b/arch/arm/mach-shmobile/board-ag5evm.c
@@ -258,12 +258,12 @@ static struct sh_mobile_lcdc_info lcdc0_info = {
.interface_type = RGB24,
.clock_divider = 1,
.flags = LCDC_FLAGS_DWPOL,
- .lcd_size_cfg.width = 44,
- .lcd_size_cfg.height = 79,
.fourcc = V4L2_PIX_FMT_RGB565,
.lcd_cfg = lcdc0_modes,
.num_cfg = ARRAY_SIZE(lcdc0_modes),
- .board_cfg = {
+ .panel_cfg = {
+ .width = 44,
+ .height = 79,
.display_on = lcd_backlight_on,
.display_off = lcd_backlight_reset,
},
diff --git a/arch/arm/mach-shmobile/board-ap4evb.c b/arch/arm/mach-shmobile/board-ap4evb.c
index 851e1ac..f8d0b4d 100644
--- a/arch/arm/mach-shmobile/board-ap4evb.c
+++ b/arch/arm/mach-shmobile/board-ap4evb.c
@@ -1326,8 +1326,8 @@ static void __init ap4evb_init(void)
lcdc_info.ch[0].interface_type = RGB24;
lcdc_info.ch[0].clock_divider = 1;
lcdc_info.ch[0].flags = LCDC_FLAGS_DWPOL;
- lcdc_info.ch[0].lcd_size_cfg.width = 44;
- lcdc_info.ch[0].lcd_size_cfg.height = 79;
+ lcdc_info.ch[0].panel_cfg.width = 44;
+ lcdc_info.ch[0].panel_cfg.height = 79;
platform_add_devices(qhd_devices, ARRAY_SIZE(qhd_devices));
@@ -1368,8 +1368,8 @@ static void __init ap4evb_init(void)
lcdc_info.ch[0].interface_type = RGB18;
lcdc_info.ch[0].clock_divider = 3;
lcdc_info.ch[0].flags = 0;
- lcdc_info.ch[0].lcd_size_cfg.width = 152;
- lcdc_info.ch[0].lcd_size_cfg.height = 91;
+ lcdc_info.ch[0].panel_cfg.width = 152;
+ lcdc_info.ch[0].panel_cfg.height = 91;
/* enable TouchScreen */
irq_set_irq_type(IRQ7, IRQ_TYPE_LEVEL_LOW);
diff --git a/arch/arm/mach-shmobile/board-mackerel.c b/arch/arm/mach-shmobile/board-mackerel.c
index ecd1982..1bdcf61 100644
--- a/arch/arm/mach-shmobile/board-mackerel.c
+++ b/arch/arm/mach-shmobile/board-mackerel.c
@@ -393,8 +393,10 @@ static struct sh_mobile_lcdc_info lcdc_info = {
.interface_type = RGB24,
.clock_divider = 3,
.flags = 0,
- .lcd_size_cfg.width = 152,
- .lcd_size_cfg.height = 91,
+ .panel_cfg = {
+ .width = 152,
+ .height = 91,
+ },
.bl_info = {
.name = "sh_mobile_lcdc_bl",
.max_brightness = 1,
diff --git a/arch/sh/boards/mach-ap325rxa/setup.c b/arch/sh/boards/mach-ap325rxa/setup.c
index 315d79a..4d1df51 100644
--- a/arch/sh/boards/mach-ap325rxa/setup.c
+++ b/arch/sh/boards/mach-ap325rxa/setup.c
@@ -212,11 +212,9 @@ static struct sh_mobile_lcdc_info lcdc_info = {
.clock_divider = 1,
.lcd_cfg = ap325rxa_lcdc_modes,
.num_cfg = ARRAY_SIZE(ap325rxa_lcdc_modes),
- .lcd_size_cfg = { /* 7.0 inch */
- .width = 152,
+ .panel_cfg = {
+ .width = 152, /* 7.0 inch */
.height = 91,
- },
- .board_cfg = {
.display_on = ap320_wvga_power_on,
.display_off = ap320_wvga_power_off,
},
diff --git a/arch/sh/boards/mach-ecovec24/setup.c b/arch/sh/boards/mach-ecovec24/setup.c
index b957b54..3f3f2ec 100644
--- a/arch/sh/boards/mach-ecovec24/setup.c
+++ b/arch/sh/boards/mach-ecovec24/setup.c
@@ -327,7 +327,7 @@ static struct sh_mobile_lcdc_info lcdc_info = {
.interface_type = RGB18,
.chan = LCDC_CHAN_MAINLCD,
.fourcc = V4L2_PIX_FMT_RGB565,
- .lcd_size_cfg = { /* 7.0 inch */
+ .panel_cfg = { /* 7.0 inch */
.width = 152,
.height = 91,
},
diff --git a/arch/sh/boards/mach-kfr2r09/setup.c b/arch/sh/boards/mach-kfr2r09/setup.c
index 208c9b0..615cb4b 100644
--- a/arch/sh/boards/mach-kfr2r09/setup.c
+++ b/arch/sh/boards/mach-kfr2r09/setup.c
@@ -152,11 +152,9 @@ static struct sh_mobile_lcdc_info kfr2r09_sh_lcdc_info = {
.flags = LCDC_FLAGS_DWPOL,
.lcd_cfg = kfr2r09_lcdc_modes,
.num_cfg = ARRAY_SIZE(kfr2r09_lcdc_modes),
- .lcd_size_cfg = {
+ .panel_cfg = {
.width = 35,
.height = 58,
- },
- .board_cfg = {
.setup_sys = kfr2r09_lcd_setup,
.start_transfer = kfr2r09_lcd_start,
.display_on = kfr2r09_lcd_on,
diff --git a/arch/sh/boards/mach-migor/setup.c b/arch/sh/boards/mach-migor/setup.c
index 69f8d7d..b052946 100644
--- a/arch/sh/boards/mach-migor/setup.c
+++ b/arch/sh/boards/mach-migor/setup.c
@@ -249,7 +249,7 @@ static struct sh_mobile_lcdc_info sh_mobile_lcdc_info = {
.clock_divider = 2,
.lcd_cfg = migor_lcd_modes,
.num_cfg = ARRAY_SIZE(migor_lcd_modes),
- .lcd_size_cfg = { /* 7.0 inch */
+ .panel_cfg = { /* 7.0 inch */
.width = 152,
.height = 91,
},
@@ -263,11 +263,9 @@ static struct sh_mobile_lcdc_info sh_mobile_lcdc_info = {
.clock_divider = 10,
.lcd_cfg = migor_lcd_modes,
.num_cfg = ARRAY_SIZE(migor_lcd_modes),
- .lcd_size_cfg = { /* 2.4 inch */
- .width = 49,
+ .panel_cfg = {
+ .width = 49, /* 2.4 inch */
.height = 37,
- },
- .board_cfg = {
.setup_sys = migor_lcd_qvga_setup,
},
.sys_bus_cfg = {
diff --git a/arch/sh/boards/mach-se/7724/setup.c b/arch/sh/boards/mach-se/7724/setup.c
index 334b463..56e7361 100644
--- a/arch/sh/boards/mach-se/7724/setup.c
+++ b/arch/sh/boards/mach-se/7724/setup.c
@@ -181,7 +181,7 @@ static struct sh_mobile_lcdc_info lcdc_info = {
.chan = LCDC_CHAN_MAINLCD,
.fourcc = V4L2_PIX_FMT_RGB565,
.clock_divider = 1,
- .lcd_size_cfg = { /* 7.0 inch */
+ .panel_cfg = { /* 7.0 inch */
.width = 152,
.height = 91,
},
diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c
index a490c7a..eff475d 100644
--- a/drivers/video/sh_mobile_lcdcfb.c
+++ b/drivers/video/sh_mobile_lcdcfb.c
@@ -288,7 +288,7 @@ static void sh_mobile_lcdc_deferred_io(struct fb_info *info,
struct list_head *pagelist)
{
struct sh_mobile_lcdc_chan *ch = info->par;
- struct sh_mobile_lcdc_board_cfg *bcfg = &ch->cfg.board_cfg;
+ struct sh_mobile_lcdc_panel_cfg *panel = &ch->cfg.panel_cfg;
/* enable clocks before accessing hardware */
sh_mobile_lcdc_clk_on(ch->lcdc);
@@ -313,13 +313,13 @@ static void sh_mobile_lcdc_deferred_io(struct fb_info *info,
/* trigger panel update */
dma_map_sg(info->dev, ch->sglist, nr_pages, DMA_TO_DEVICE);
- if (bcfg->start_transfer)
- bcfg->start_transfer(ch, &sh_mobile_lcdc_sys_bus_ops);
+ if (panel->start_transfer)
+ panel->start_transfer(ch, &sh_mobile_lcdc_sys_bus_ops);
lcdc_write_chan(ch, LDSM2R, LDSM2R_OSTRG);
dma_unmap_sg(info->dev, ch->sglist, nr_pages, DMA_TO_DEVICE);
} else {
- if (bcfg->start_transfer)
- bcfg->start_transfer(ch, &sh_mobile_lcdc_sys_bus_ops);
+ if (panel->start_transfer)
+ panel->start_transfer(ch, &sh_mobile_lcdc_sys_bus_ops);
lcdc_write_chan(ch, LDSM2R, LDSM2R_OSTRG);
}
}
@@ -334,22 +334,22 @@ static void sh_mobile_lcdc_deferred_io_touch(struct fb_info *info)
static void sh_mobile_lcdc_display_on(struct sh_mobile_lcdc_chan *ch)
{
- struct sh_mobile_lcdc_board_cfg *board_cfg = &ch->cfg.board_cfg;
+ struct sh_mobile_lcdc_panel_cfg *panel = &ch->cfg.panel_cfg;
if (ch->tx_dev)
ch->tx_dev->ops->display_on(ch->tx_dev, ch->info);
/* HDMI must be enabled before LCDC configuration */
- if (board_cfg->display_on)
- board_cfg->display_on();
+ if (panel->display_on)
+ panel->display_on();
}
static void sh_mobile_lcdc_display_off(struct sh_mobile_lcdc_chan *ch)
{
- struct sh_mobile_lcdc_board_cfg *board_cfg = &ch->cfg.board_cfg;
+ struct sh_mobile_lcdc_panel_cfg *panel = &ch->cfg.panel_cfg;
- if (board_cfg->display_off)
- board_cfg->display_off();
+ if (panel->display_off)
+ panel->display_off();
if (ch->tx_dev)
ch->tx_dev->ops->display_off(ch->tx_dev);
@@ -679,16 +679,15 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
lcdc_wait_bit(priv, _LDCNT2R, LDCNT2R_BR, 0);
for (k = 0; k < ARRAY_SIZE(priv->ch); k++) {
- struct sh_mobile_lcdc_board_cfg *board_cfg;
+ struct sh_mobile_lcdc_panel_cfg *panel;
ch = &priv->ch[k];
if (!ch->enabled)
continue;
- board_cfg = &ch->cfg.board_cfg;
- if (board_cfg->setup_sys) {
- ret = board_cfg->setup_sys(ch,
- &sh_mobile_lcdc_sys_bus_ops);
+ panel = &ch->cfg.panel_cfg;
+ if (panel->setup_sys) {
+ ret = panel->setup_sys(ch, &sh_mobile_lcdc_sys_bus_ops);
if (ret)
return ret;
}
@@ -1654,8 +1653,8 @@ sh_mobile_lcdc_channel_init(struct sh_mobile_lcdc_priv *priv,
*/
var = &info->var;
fb_videomode_to_var(var, mode);
- var->width = cfg->lcd_size_cfg.width;
- var->height = cfg->lcd_size_cfg.height;
+ var->width = cfg->panel_cfg.width;
+ var->height = cfg->panel_cfg.height;
var->yres_virtual = var->yres * 2;
var->activate = FB_ACTIVATE_NOW;
diff --git a/include/video/sh_mobile_lcdc.h b/include/video/sh_mobile_lcdc.h
index 541b2b3..84163e4 100644
--- a/include/video/sh_mobile_lcdc.h
+++ b/include/video/sh_mobile_lcdc.h
@@ -147,7 +147,9 @@ struct sh_mobile_lcdc_sys_bus_ops {
unsigned long (*read_data)(void *handle);
};
-struct sh_mobile_lcdc_board_cfg {
+struct sh_mobile_lcdc_panel_cfg {
+ unsigned long width; /* Panel width in mm */
+ unsigned long height; /* Panel height in mm */
int (*setup_sys)(void *sys_ops_handle,
struct sh_mobile_lcdc_sys_bus_ops *sys_ops);
void (*start_transfer)(void *sys_ops_handle,
@@ -156,11 +158,6 @@ struct sh_mobile_lcdc_board_cfg {
void (*display_off)(void);
};
-struct sh_mobile_lcdc_lcd_size_cfg { /* width and height of panel in mm */
- unsigned long width;
- unsigned long height;
-};
-
/* backlight info */
struct sh_mobile_lcdc_bl_info {
const char *name;
@@ -178,8 +175,7 @@ struct sh_mobile_lcdc_chan_cfg {
unsigned long flags; /* LCDC_FLAGS_... */
const struct fb_videomode *lcd_cfg;
int num_cfg;
- struct sh_mobile_lcdc_lcd_size_cfg lcd_size_cfg;
- struct sh_mobile_lcdc_board_cfg board_cfg;
+ struct sh_mobile_lcdc_panel_cfg panel_cfg;
struct sh_mobile_lcdc_bl_info bl_info;
struct sh_mobile_lcdc_sys_bus_cfg sys_bus_cfg; /* only for SYSn I/F */
struct sh_mobile_meram_cfg *meram_cfg;
--
1.7.3.4
^ permalink raw reply related
* [WIP/RFC 18/31] fbdev: sh_mobile_lcdc: Move brightness ops to sh_mobile_lcdc_bl_info
From: Laurent Pinchart @ 2011-09-19 0:27 UTC (permalink / raw)
To: linux-fbdev
Update board code accordingly.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
arch/arm/mach-shmobile/board-mackerel.c | 6 ++----
arch/sh/boards/mach-ap325rxa/setup.c | 4 ++--
arch/sh/boards/mach-ecovec24/setup.c | 6 ++----
drivers/video/sh_mobile_lcdcfb.c | 6 ++----
include/video/sh_mobile_lcdc.h | 4 ++--
5 files changed, 10 insertions(+), 16 deletions(-)
diff --git a/arch/arm/mach-shmobile/board-mackerel.c b/arch/arm/mach-shmobile/board-mackerel.c
index 9d0d7b2..ecd1982 100644
--- a/arch/arm/mach-shmobile/board-mackerel.c
+++ b/arch/arm/mach-shmobile/board-mackerel.c
@@ -395,13 +395,11 @@ static struct sh_mobile_lcdc_info lcdc_info = {
.flags = 0,
.lcd_size_cfg.width = 152,
.lcd_size_cfg.height = 91,
- .board_cfg = {
- .set_brightness = mackerel_set_brightness,
- .get_brightness = mackerel_get_brightness,
- },
.bl_info = {
.name = "sh_mobile_lcdc_bl",
.max_brightness = 1,
+ .set_brightness = mackerel_set_brightness,
+ .get_brightness = mackerel_get_brightness,
},
.meram_cfg = &lcd_meram_cfg,
}
diff --git a/arch/sh/boards/mach-ap325rxa/setup.c b/arch/sh/boards/mach-ap325rxa/setup.c
index 477767e..315d79a 100644
--- a/arch/sh/boards/mach-ap325rxa/setup.c
+++ b/arch/sh/boards/mach-ap325rxa/setup.c
@@ -219,12 +219,12 @@ static struct sh_mobile_lcdc_info lcdc_info = {
.board_cfg = {
.display_on = ap320_wvga_power_on,
.display_off = ap320_wvga_power_off,
- .set_brightness = ap320_wvga_set_brightness,
- .get_brightness = ap320_wvga_get_brightness,
},
.bl_info = {
.name = "sh_mobile_lcdc_bl",
.max_brightness = 1,
+ .set_brightness = ap320_wvga_set_brightness,
+ .get_brightness = ap320_wvga_get_brightness,
},
}
};
diff --git a/arch/sh/boards/mach-ecovec24/setup.c b/arch/sh/boards/mach-ecovec24/setup.c
index 7c592f8..b957b54 100644
--- a/arch/sh/boards/mach-ecovec24/setup.c
+++ b/arch/sh/boards/mach-ecovec24/setup.c
@@ -331,13 +331,11 @@ static struct sh_mobile_lcdc_info lcdc_info = {
.width = 152,
.height = 91,
},
- .board_cfg = {
- .set_brightness = ecovec24_set_brightness,
- .get_brightness = ecovec24_get_brightness,
- },
.bl_info = {
.name = "sh_mobile_lcdc_bl",
.max_brightness = 1,
+ .set_brightness = ecovec24_set_brightness,
+ .get_brightness = ecovec24_get_brightness,
},
}
};
diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c
index cb0d9b6..a490c7a 100644
--- a/drivers/video/sh_mobile_lcdcfb.c
+++ b/drivers/video/sh_mobile_lcdcfb.c
@@ -1316,22 +1316,20 @@ static struct fb_ops sh_mobile_lcdc_ops = {
static int sh_mobile_lcdc_update_bl(struct backlight_device *bdev)
{
struct sh_mobile_lcdc_chan *ch = bl_get_data(bdev);
- struct sh_mobile_lcdc_board_cfg *cfg = &ch->cfg.board_cfg;
int brightness = bdev->props.brightness;
if (bdev->props.power != FB_BLANK_UNBLANK ||
bdev->props.state & (BL_CORE_SUSPENDED | BL_CORE_FBBLANK))
brightness = 0;
- return cfg->set_brightness(brightness);
+ return ch->cfg.bl_info.set_brightness(brightness);
}
static int sh_mobile_lcdc_get_brightness(struct backlight_device *bdev)
{
struct sh_mobile_lcdc_chan *ch = bl_get_data(bdev);
- struct sh_mobile_lcdc_board_cfg *cfg = &ch->cfg.board_cfg;
- return cfg->get_brightness();
+ return ch->cfg.bl_info.get_brightness();
}
static int sh_mobile_lcdc_check_fb(struct backlight_device *bdev,
diff --git a/include/video/sh_mobile_lcdc.h b/include/video/sh_mobile_lcdc.h
index a1e6596..541b2b3 100644
--- a/include/video/sh_mobile_lcdc.h
+++ b/include/video/sh_mobile_lcdc.h
@@ -154,8 +154,6 @@ struct sh_mobile_lcdc_board_cfg {
struct sh_mobile_lcdc_sys_bus_ops *sys_ops);
void (*display_on)(void);
void (*display_off)(void);
- int (*set_brightness)(int brightness);
- int (*get_brightness)(void);
};
struct sh_mobile_lcdc_lcd_size_cfg { /* width and height of panel in mm */
@@ -167,6 +165,8 @@ struct sh_mobile_lcdc_lcd_size_cfg { /* width and height of panel in mm */
struct sh_mobile_lcdc_bl_info {
const char *name;
int max_brightness;
+ int (*set_brightness)(int brightness);
+ int (*get_brightness)(void);
};
struct sh_mobile_lcdc_chan_cfg {
--
1.7.3.4
^ permalink raw reply related
* [WIP/RFC 17/31] fbdev: sh_mobile_lcdc: Remove board configuration board_data field
From: Laurent Pinchart @ 2011-09-19 0:27 UTC (permalink / raw)
To: linux-fbdev
The field is unused, remove it. Update board code accordingly.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
arch/arm/mach-shmobile/board-ag5evm.c | 14 ++------------
arch/arm/mach-shmobile/board-mackerel.c | 4 ++--
arch/sh/boards/mach-ap325rxa/setup.c | 8 ++++----
arch/sh/boards/mach-ecovec24/setup.c | 4 ++--
arch/sh/boards/mach-kfr2r09/lcd_wqvga.c | 10 ++++------
arch/sh/boards/mach-migor/lcd_qvga.c | 3 +--
arch/sh/boards/mach-se/7724/setup.c | 2 --
arch/sh/include/mach-kfr2r09/mach/kfr2r09.h | 16 ++++++++--------
arch/sh/include/mach-migor/mach/migor.h | 2 +-
drivers/video/sh_mobile_lcdcfb.c | 16 +++++++---------
include/video/sh_mobile_lcdc.h | 13 ++++++-------
11 files changed, 37 insertions(+), 55 deletions(-)
diff --git a/arch/arm/mach-shmobile/board-ag5evm.c b/arch/arm/mach-shmobile/board-ag5evm.c
index d0c30a4..139fbd1 100644
--- a/arch/arm/mach-shmobile/board-ag5evm.c
+++ b/arch/arm/mach-shmobile/board-ag5evm.c
@@ -235,16 +235,6 @@ static void lcd_backlight_reset(void)
gpio_set_value(GPIO_PORT235, 1);
}
-static void lcd_on(void *board_data, struct fb_info *info)
-{
- lcd_backlight_on();
-}
-
-static void lcd_off(void *board_data)
-{
- lcd_backlight_reset();
-}
-
/* LCDC0 */
static const struct fb_videomode lcdc0_modes[] = {
{
@@ -274,8 +264,8 @@ static struct sh_mobile_lcdc_info lcdc0_info = {
.lcd_cfg = lcdc0_modes,
.num_cfg = ARRAY_SIZE(lcdc0_modes),
.board_cfg = {
- .display_on = lcd_on,
- .display_off = lcd_off,
+ .display_on = lcd_backlight_on,
+ .display_off = lcd_backlight_reset,
},
}
};
diff --git a/arch/arm/mach-shmobile/board-mackerel.c b/arch/arm/mach-shmobile/board-mackerel.c
index 332f07e..9d0d7b2 100644
--- a/arch/arm/mach-shmobile/board-mackerel.c
+++ b/arch/arm/mach-shmobile/board-mackerel.c
@@ -355,14 +355,14 @@ static struct fb_videomode mackerel_lcdc_modes[] = {
},
};
-static int mackerel_set_brightness(void *board_data, int brightness)
+static int mackerel_set_brightness(int brightness)
{
gpio_set_value(GPIO_PORT31, brightness);
return 0;
}
-static int mackerel_get_brightness(void *board_data)
+static int mackerel_get_brightness(void)
{
return gpio_get_value(GPIO_PORT31);
}
diff --git a/arch/sh/boards/mach-ap325rxa/setup.c b/arch/sh/boards/mach-ap325rxa/setup.c
index 0a53ecd..477767e 100644
--- a/arch/sh/boards/mach-ap325rxa/setup.c
+++ b/arch/sh/boards/mach-ap325rxa/setup.c
@@ -156,7 +156,7 @@ static struct platform_device nand_flash_device = {
#define PORT_DRVCRA 0xA405018A
#define PORT_DRVCRB 0xA405018C
-static int ap320_wvga_set_brightness(void *board_data, int brightness)
+static int ap320_wvga_set_brightness(int brightness)
{
if (brightness) {
gpio_set_value(GPIO_PTS3, 0);
@@ -169,12 +169,12 @@ static int ap320_wvga_set_brightness(void *board_data, int brightness)
return 0;
}
-static int ap320_wvga_get_brightness(void *board_data)
+static int ap320_wvga_get_brightness(void)
{
return gpio_get_value(GPIO_PTS3);
}
-static void ap320_wvga_power_on(void *board_data, struct fb_info *info)
+static void ap320_wvga_power_on(void)
{
msleep(100);
@@ -182,7 +182,7 @@ static void ap320_wvga_power_on(void *board_data, struct fb_info *info)
__raw_writew(FPGA_LCDREG_VAL, FPGA_LCDREG);
}
-static void ap320_wvga_power_off(void *board_data)
+static void ap320_wvga_power_off(void)
{
/* ASD AP-320/325 LCD OFF */
__raw_writew(0, FPGA_LCDREG);
diff --git a/arch/sh/boards/mach-ecovec24/setup.c b/arch/sh/boards/mach-ecovec24/setup.c
index 75e466f..7c592f8 100644
--- a/arch/sh/boards/mach-ecovec24/setup.c
+++ b/arch/sh/boards/mach-ecovec24/setup.c
@@ -310,14 +310,14 @@ static const struct fb_videomode ecovec_dvi_modes[] = {
},
};
-static int ecovec24_set_brightness(void *board_data, int brightness)
+static int ecovec24_set_brightness(int brightness)
{
gpio_set_value(GPIO_PTR1, brightness);
return 0;
}
-static int ecovec24_get_brightness(void *board_data)
+static int ecovec24_get_brightness(void)
{
return gpio_get_value(GPIO_PTR1);
}
diff --git a/arch/sh/boards/mach-kfr2r09/lcd_wqvga.c b/arch/sh/boards/mach-kfr2r09/lcd_wqvga.c
index 25e145f..c148b36 100644
--- a/arch/sh/boards/mach-kfr2r09/lcd_wqvga.c
+++ b/arch/sh/boards/mach-kfr2r09/lcd_wqvga.c
@@ -251,8 +251,7 @@ static void display_on(void *sohandle,
write_memory_start(sohandle, so);
}
-int kfr2r09_lcd_setup(void *board_data, void *sohandle,
- struct sh_mobile_lcdc_sys_bus_ops *so)
+int kfr2r09_lcd_setup(void *sohandle, struct sh_mobile_lcdc_sys_bus_ops *so)
{
/* power on */
gpio_set_value(GPIO_PTF4, 0); /* PROTECT/ -> L */
@@ -273,8 +272,7 @@ int kfr2r09_lcd_setup(void *board_data, void *sohandle,
return 0;
}
-void kfr2r09_lcd_start(void *board_data, void *sohandle,
- struct sh_mobile_lcdc_sys_bus_ops *so)
+void kfr2r09_lcd_start(void *sohandle, struct sh_mobile_lcdc_sys_bus_ops *so)
{
write_memory_start(sohandle, so);
}
@@ -327,12 +325,12 @@ static int kfr2r09_lcd_backlight(int on)
return 0;
}
-void kfr2r09_lcd_on(void *board_data, struct fb_info *info)
+void kfr2r09_lcd_on(void)
{
kfr2r09_lcd_backlight(1);
}
-void kfr2r09_lcd_off(void *board_data)
+void kfr2r09_lcd_off(void)
{
kfr2r09_lcd_backlight(0);
}
diff --git a/arch/sh/boards/mach-migor/lcd_qvga.c b/arch/sh/boards/mach-migor/lcd_qvga.c
index de9014a..8bccd34 100644
--- a/arch/sh/boards/mach-migor/lcd_qvga.c
+++ b/arch/sh/boards/mach-migor/lcd_qvga.c
@@ -113,8 +113,7 @@ static const unsigned short magic3_data[] = {
0x0010, 0x16B0, 0x0011, 0x0111, 0x0007, 0x0061,
};
-int migor_lcd_qvga_setup(void *board_data, void *sohandle,
- struct sh_mobile_lcdc_sys_bus_ops *so)
+int migor_lcd_qvga_setup(void *sohandle, struct sh_mobile_lcdc_sys_bus_ops *so)
{
unsigned long xres = 320;
unsigned long yres = 240;
diff --git a/arch/sh/boards/mach-se/7724/setup.c b/arch/sh/boards/mach-se/7724/setup.c
index ab81abd..334b463 100644
--- a/arch/sh/boards/mach-se/7724/setup.c
+++ b/arch/sh/boards/mach-se/7724/setup.c
@@ -185,8 +185,6 @@ static struct sh_mobile_lcdc_info lcdc_info = {
.width = 152,
.height = 91,
},
- .board_cfg = {
- },
}
};
diff --git a/arch/sh/include/mach-kfr2r09/mach/kfr2r09.h b/arch/sh/include/mach-kfr2r09/mach/kfr2r09.h
index 07e635b..ba3d93d 100644
--- a/arch/sh/include/mach-kfr2r09/mach/kfr2r09.h
+++ b/arch/sh/include/mach-kfr2r09/mach/kfr2r09.h
@@ -4,21 +4,21 @@
#include <video/sh_mobile_lcdc.h>
#if defined(CONFIG_FB_SH_MOBILE_LCDC) || defined(CONFIG_FB_SH_MOBILE_LCDC_MODULE)
-void kfr2r09_lcd_on(void *board_data, struct fb_info *info);
-void kfr2r09_lcd_off(void *board_data);
-int kfr2r09_lcd_setup(void *board_data, void *sys_ops_handle,
+void kfr2r09_lcd_on(void);
+void kfr2r09_lcd_off(void);
+int kfr2r09_lcd_setup(void *sys_ops_handle,
struct sh_mobile_lcdc_sys_bus_ops *sys_ops);
-void kfr2r09_lcd_start(void *board_data, void *sys_ops_handle,
+void kfr2r09_lcd_start(void *sys_ops_handle,
struct sh_mobile_lcdc_sys_bus_ops *sys_ops);
#else
-static void kfr2r09_lcd_on(void *board_data) {}
-static void kfr2r09_lcd_off(void *board_data) {}
-static int kfr2r09_lcd_setup(void *board_data, void *sys_ops_handle,
+static void kfr2r09_lcd_on(void) {}
+static void kfr2r09_lcd_off(void) {}
+static int kfr2r09_lcd_setup(void *sys_ops_handle,
struct sh_mobile_lcdc_sys_bus_ops *sys_ops)
{
return -ENODEV;
}
-static void kfr2r09_lcd_start(void *board_data, void *sys_ops_handle,
+static void kfr2r09_lcd_start(void *sys_ops_handle,
struct sh_mobile_lcdc_sys_bus_ops *sys_ops)
{
}
diff --git a/arch/sh/include/mach-migor/mach/migor.h b/arch/sh/include/mach-migor/mach/migor.h
index 42fccf9..7de7bb7 100644
--- a/arch/sh/include/mach-migor/mach/migor.h
+++ b/arch/sh/include/mach-migor/mach/migor.h
@@ -9,7 +9,7 @@
#include <video/sh_mobile_lcdc.h>
-int migor_lcd_qvga_setup(void *board_data, void *sys_ops_handle,
+int migor_lcd_qvga_setup(void *sys_ops_handle,
struct sh_mobile_lcdc_sys_bus_ops *sys_ops);
#endif /* __ASM_SH_MIGOR_H */
diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c
index 543f957..cb0d9b6 100644
--- a/drivers/video/sh_mobile_lcdcfb.c
+++ b/drivers/video/sh_mobile_lcdcfb.c
@@ -314,14 +314,12 @@ static void sh_mobile_lcdc_deferred_io(struct fb_info *info,
/* trigger panel update */
dma_map_sg(info->dev, ch->sglist, nr_pages, DMA_TO_DEVICE);
if (bcfg->start_transfer)
- bcfg->start_transfer(bcfg->board_data, ch,
- &sh_mobile_lcdc_sys_bus_ops);
+ bcfg->start_transfer(ch, &sh_mobile_lcdc_sys_bus_ops);
lcdc_write_chan(ch, LDSM2R, LDSM2R_OSTRG);
dma_unmap_sg(info->dev, ch->sglist, nr_pages, DMA_TO_DEVICE);
} else {
if (bcfg->start_transfer)
- bcfg->start_transfer(bcfg->board_data, ch,
- &sh_mobile_lcdc_sys_bus_ops);
+ bcfg->start_transfer(ch, &sh_mobile_lcdc_sys_bus_ops);
lcdc_write_chan(ch, LDSM2R, LDSM2R_OSTRG);
}
}
@@ -343,7 +341,7 @@ static void sh_mobile_lcdc_display_on(struct sh_mobile_lcdc_chan *ch)
/* HDMI must be enabled before LCDC configuration */
if (board_cfg->display_on)
- board_cfg->display_on(board_cfg->board_data, ch->info);
+ board_cfg->display_on();
}
static void sh_mobile_lcdc_display_off(struct sh_mobile_lcdc_chan *ch)
@@ -351,7 +349,7 @@ static void sh_mobile_lcdc_display_off(struct sh_mobile_lcdc_chan *ch)
struct sh_mobile_lcdc_board_cfg *board_cfg = &ch->cfg.board_cfg;
if (board_cfg->display_off)
- board_cfg->display_off(board_cfg->board_data);
+ board_cfg->display_off();
if (ch->tx_dev)
ch->tx_dev->ops->display_off(ch->tx_dev);
@@ -689,7 +687,7 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
board_cfg = &ch->cfg.board_cfg;
if (board_cfg->setup_sys) {
- ret = board_cfg->setup_sys(board_cfg->board_data, ch,
+ ret = board_cfg->setup_sys(ch,
&sh_mobile_lcdc_sys_bus_ops);
if (ret)
return ret;
@@ -1325,7 +1323,7 @@ static int sh_mobile_lcdc_update_bl(struct backlight_device *bdev)
bdev->props.state & (BL_CORE_SUSPENDED | BL_CORE_FBBLANK))
brightness = 0;
- return cfg->set_brightness(cfg->board_data, brightness);
+ return cfg->set_brightness(brightness);
}
static int sh_mobile_lcdc_get_brightness(struct backlight_device *bdev)
@@ -1333,7 +1331,7 @@ static int sh_mobile_lcdc_get_brightness(struct backlight_device *bdev)
struct sh_mobile_lcdc_chan *ch = bl_get_data(bdev);
struct sh_mobile_lcdc_board_cfg *cfg = &ch->cfg.board_cfg;
- return cfg->get_brightness(cfg->board_data);
+ return cfg->get_brightness();
}
static int sh_mobile_lcdc_check_fb(struct backlight_device *bdev,
diff --git a/include/video/sh_mobile_lcdc.h b/include/video/sh_mobile_lcdc.h
index b1b3e8d..a1e6596 100644
--- a/include/video/sh_mobile_lcdc.h
+++ b/include/video/sh_mobile_lcdc.h
@@ -148,15 +148,14 @@ struct sh_mobile_lcdc_sys_bus_ops {
};
struct sh_mobile_lcdc_board_cfg {
- void *board_data;
- int (*setup_sys)(void *board_data, void *sys_ops_handle,
+ int (*setup_sys)(void *sys_ops_handle,
struct sh_mobile_lcdc_sys_bus_ops *sys_ops);
- void (*start_transfer)(void *board_data, void *sys_ops_handle,
+ void (*start_transfer)(void *sys_ops_handle,
struct sh_mobile_lcdc_sys_bus_ops *sys_ops);
- void (*display_on)(void *board_data, struct fb_info *info);
- void (*display_off)(void *board_data);
- int (*set_brightness)(void *board_data, int brightness);
- int (*get_brightness)(void *board_data);
+ void (*display_on)(void);
+ void (*display_off)(void);
+ int (*set_brightness)(int brightness);
+ int (*get_brightness)(void);
};
struct sh_mobile_lcdc_lcd_size_cfg { /* width and height of panel in mm */
--
1.7.3.4
^ permalink raw reply related
* [WIP/RFC 16/31] fbdev: sh_mobile_lcdc: Remove board configuration owner field
From: Laurent Pinchart @ 2011-09-19 0:27 UTC (permalink / raw)
To: linux-fbdev
The field is unused, remove it.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
drivers/video/sh_mobile_lcdcfb.c | 8 ++------
include/video/sh_mobile_lcdc.h | 2 --
2 files changed, 2 insertions(+), 8 deletions(-)
diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c
index 9fd93f7..543f957 100644
--- a/drivers/video/sh_mobile_lcdcfb.c
+++ b/drivers/video/sh_mobile_lcdcfb.c
@@ -342,20 +342,16 @@ static void sh_mobile_lcdc_display_on(struct sh_mobile_lcdc_chan *ch)
ch->tx_dev->ops->display_on(ch->tx_dev, ch->info);
/* HDMI must be enabled before LCDC configuration */
- if (board_cfg->display_on && try_module_get(board_cfg->owner)) {
+ if (board_cfg->display_on)
board_cfg->display_on(board_cfg->board_data, ch->info);
- module_put(board_cfg->owner);
- }
}
static void sh_mobile_lcdc_display_off(struct sh_mobile_lcdc_chan *ch)
{
struct sh_mobile_lcdc_board_cfg *board_cfg = &ch->cfg.board_cfg;
- if (board_cfg->display_off && try_module_get(board_cfg->owner)) {
+ if (board_cfg->display_off)
board_cfg->display_off(board_cfg->board_data);
- module_put(board_cfg->owner);
- }
if (ch->tx_dev)
ch->tx_dev->ops->display_off(ch->tx_dev);
diff --git a/include/video/sh_mobile_lcdc.h b/include/video/sh_mobile_lcdc.h
index 0ec59e1..b1b3e8d 100644
--- a/include/video/sh_mobile_lcdc.h
+++ b/include/video/sh_mobile_lcdc.h
@@ -147,9 +147,7 @@ struct sh_mobile_lcdc_sys_bus_ops {
unsigned long (*read_data)(void *handle);
};
-struct module;
struct sh_mobile_lcdc_board_cfg {
- struct module *owner;
void *board_data;
int (*setup_sys)(void *board_data, void *sys_ops_handle,
struct sh_mobile_lcdc_sys_bus_ops *sys_ops);
--
1.7.3.4
^ permalink raw reply related
* [WIP/RFC 15/31] fbdev: sh_mobile_hdmi: Remove sh_mobile_hdmi_info lcd_chan field
From: Laurent Pinchart @ 2011-09-19 0:27 UTC (permalink / raw)
To: linux-fbdev
The field is unused, remove it.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
include/video/sh_mobile_hdmi.h | 1 -
1 files changed, 0 insertions(+), 1 deletions(-)
diff --git a/include/video/sh_mobile_hdmi.h b/include/video/sh_mobile_hdmi.h
index 0b8d2cf..728f9de 100644
--- a/include/video/sh_mobile_hdmi.h
+++ b/include/video/sh_mobile_hdmi.h
@@ -31,7 +31,6 @@ struct clk;
#define HDMI_SND_SRC_HBR (3 << 0)
struct sh_mobile_hdmi_info {
- struct sh_mobile_lcdc_chan_cfg *lcd_chan;
unsigned int flags;
long (*clk_optimize_parent)(unsigned long target, unsigned long *best_freq,
unsigned long *parent_freq);
--
1.7.3.4
^ permalink raw reply related
* [WIP/RFC 14/31] arm: mach-shmobile: Don't initialize the hdmi_info lcd_chan field
From: Laurent Pinchart @ 2011-09-19 0:27 UTC (permalink / raw)
To: linux-fbdev
The field is unused and will be removed. Don't initialize it.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
arch/arm/mach-shmobile/board-ap4evb.c | 3 ---
arch/arm/mach-shmobile/board-mackerel.c | 3 ---
2 files changed, 0 insertions(+), 6 deletions(-)
diff --git a/arch/arm/mach-shmobile/board-ap4evb.c b/arch/arm/mach-shmobile/board-ap4evb.c
index 7085966..851e1ac 100644
--- a/arch/arm/mach-shmobile/board-ap4evb.c
+++ b/arch/arm/mach-shmobile/board-ap4evb.c
@@ -774,10 +774,7 @@ static struct platform_device fsi_ak4643_device = {
static long ap4evb_clk_optimize(unsigned long target, unsigned long *best_freq,
unsigned long *parent_freq);
-static struct sh_mobile_lcdc_info sh_mobile_lcdc1_info;
-
static struct sh_mobile_hdmi_info hdmi_info = {
- .lcd_chan = &sh_mobile_lcdc1_info.ch[0],
.flags = HDMI_SND_SRC_SPDIF,
.clk_optimize_parent = ap4evb_clk_optimize,
};
diff --git a/arch/arm/mach-shmobile/board-mackerel.c b/arch/arm/mach-shmobile/board-mackerel.c
index fbb88a5..332f07e 100644
--- a/arch/arm/mach-shmobile/board-mackerel.c
+++ b/arch/arm/mach-shmobile/board-mackerel.c
@@ -431,10 +431,7 @@ static struct platform_device lcdc_device = {
};
/* HDMI */
-static struct sh_mobile_lcdc_info hdmi_lcdc_info;
-
static struct sh_mobile_hdmi_info hdmi_info = {
- .lcd_chan = &hdmi_lcdc_info.ch[0],
.flags = HDMI_SND_SRC_SPDIF,
};
--
1.7.3.4
^ permalink raw reply related
* [WIP/RFC 13/31] fbdev: sh_mobile_hdmi: Don't hook up into board_cfg display operations
From: Laurent Pinchart @ 2011-09-19 0:27 UTC (permalink / raw)
To: linux-fbdev
The display_on/off operations are now accessed through the
sh_mobile_lcdc_entity operations.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
drivers/video/sh_mobile_hdmi.c | 35 +++++------------------------------
1 files changed, 5 insertions(+), 30 deletions(-)
diff --git a/drivers/video/sh_mobile_hdmi.c b/drivers/video/sh_mobile_hdmi.c
index ce858d6..d89645e 100644
--- a/drivers/video/sh_mobile_hdmi.c
+++ b/drivers/video/sh_mobile_hdmi.c
@@ -1004,7 +1004,7 @@ static irqreturn_t sh_hdmi_hotplug(int irq, void *dev_id)
}
/* locking: called with info->lock held, or before register_framebuffer() */
-static void __sh_hdmi_display_on(struct sh_mobile_lcdc_entity *entity,
+static void sh_hdmi_display_on(struct sh_mobile_lcdc_entity *entity,
struct fb_info *info)
{
/*
@@ -1038,13 +1038,8 @@ static void __sh_hdmi_display_on(struct sh_mobile_lcdc_entity *entity,
}
}
-static void sh_hdmi_display_on(void *arg, struct fb_info *info)
-{
- __sh_hdmi_display_on(arg, info);
-}
-
/* locking: called with info->lock held */
-static void __sh_hdmi_display_off(struct sh_mobile_lcdc_entity *entity)
+static void sh_hdmi_display_off(struct sh_mobile_lcdc_entity *entity)
{
struct sh_hdmi *hdmi = entity_to_sh_hdmi(entity);
@@ -1053,14 +1048,9 @@ static void __sh_hdmi_display_off(struct sh_mobile_lcdc_entity *entity)
hdmi_write(hdmi, 0x10, HDMI_SYSTEM_CTRL);
}
-static void sh_hdmi_display_off(void *arg)
-{
- __sh_hdmi_display_off(arg);
-}
-
static const struct sh_mobile_lcdc_entity_ops sh_hdmi_ops = {
- .display_on = __sh_hdmi_display_on,
- .display_off = __sh_hdmi_display_off,
+ .display_on = sh_hdmi_display_on,
+ .display_off = sh_hdmi_display_off,
};
static bool sh_hdmi_must_reconfigure(struct sh_hdmi *hdmi)
@@ -1174,7 +1164,7 @@ static void sh_hdmi_edid_work_fn(struct work_struct *work)
if (lock_fb_info(info)) {
info->var.width = hdmi->var.width;
info->var.height = hdmi->var.height;
- __sh_hdmi_display_on(&hdmi->entity, info);
+ sh_hdmi_display_on(&hdmi->entity, info);
unlock_fb_info(info);
}
} else {
@@ -1248,7 +1238,6 @@ static int __init sh_hdmi_probe(struct platform_device *pdev)
{
struct sh_mobile_hdmi_info *pdata = pdev->dev.platform_data;
struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- struct sh_mobile_lcdc_board_cfg *board_cfg;
int irq = platform_get_irq(pdev, 0), ret;
struct sh_hdmi *hdmi;
long rate;
@@ -1308,13 +1297,6 @@ static int __init sh_hdmi_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, &hdmi->entity);
- /* Set up LCDC callbacks */
- board_cfg = &pdata->lcd_chan->board_cfg;
- board_cfg->owner = THIS_MODULE;
- board_cfg->board_data = &hdmi->entity;
- board_cfg->display_on = sh_hdmi_display_on;
- board_cfg->display_off = sh_hdmi_display_off;
-
INIT_DELAYED_WORK(&hdmi->edid_work, sh_hdmi_edid_work_fn);
pm_runtime_enable(&pdev->dev);
@@ -1364,21 +1346,14 @@ egetclk:
static int __exit sh_hdmi_remove(struct platform_device *pdev)
{
- struct sh_mobile_hdmi_info *pdata = pdev->dev.platform_data;
struct sh_hdmi *hdmi = entity_to_sh_hdmi(platform_get_drvdata(pdev));
struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- struct sh_mobile_lcdc_board_cfg *board_cfg = &pdata->lcd_chan->board_cfg;
int irq = platform_get_irq(pdev, 0);
snd_soc_unregister_codec(&pdev->dev);
fb_unregister_client(&hdmi->notifier);
- board_cfg->display_on = NULL;
- board_cfg->display_off = NULL;
- board_cfg->board_data = NULL;
- board_cfg->owner = NULL;
-
/* No new work will be scheduled, wait for running ISR */
free_irq(irq, hdmi);
/* Wait for already scheduled work */
--
1.7.3.4
^ permalink raw reply related
* [WIP/RFC 12/31] fbdev: sh_mipi_dsi: Don't hook up into board_cfg display operations
From: Laurent Pinchart @ 2011-09-19 0:27 UTC (permalink / raw)
To: linux-fbdev
The display_on/off operations are now accessed through the
sh_mobile_lcdc_entity operations.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
drivers/video/sh_mipi_dsi.c | 51 +++---------------------------------------
1 files changed, 4 insertions(+), 47 deletions(-)
diff --git a/drivers/video/sh_mipi_dsi.c b/drivers/video/sh_mipi_dsi.c
index 31a403d..e198067 100644
--- a/drivers/video/sh_mipi_dsi.c
+++ b/drivers/video/sh_mipi_dsi.c
@@ -56,10 +56,6 @@ struct sh_mipi {
struct clk *dsit_clk;
struct clk *dsip_clk;
struct device *dev;
-
- void *next_board_data;
- void (*next_display_on)(void *board_data, struct fb_info *info);
- void (*next_display_off)(void *board_data);
};
#define to_sh_mipi(e) container_of(e, struct sh_mipi, entity)
@@ -129,7 +125,7 @@ static void sh_mipi_shutdown(struct platform_device *pdev)
sh_mipi_dsi_enable(mipi, false);
}
-static void __mipi_display_on(struct sh_mobile_lcdc_entity *entity,
+static void mipi_display_on(struct sh_mobile_lcdc_entity *entity,
struct fb_info *info)
{
struct sh_mipi *mipi = to_sh_mipi(entity);
@@ -138,18 +134,7 @@ static void __mipi_display_on(struct sh_mobile_lcdc_entity *entity,
sh_mipi_dsi_enable(mipi, true);
}
-static void mipi_display_on(void *arg, struct fb_info *info)
-{
- struct sh_mobile_lcdc_entity *entity = arg;
- struct sh_mipi *mipi = to_sh_mipi(entity);
-
- __mipi_display_on(entity, info);
-
- if (mipi->next_display_on)
- mipi->next_display_on(mipi->next_board_data, info);
-}
-
-static void __mipi_display_off(struct sh_mobile_lcdc_entity *entity)
+static void mipi_display_off(struct sh_mobile_lcdc_entity *entity)
{
struct sh_mipi *mipi = to_sh_mipi(entity);
@@ -157,20 +142,9 @@ static void __mipi_display_off(struct sh_mobile_lcdc_entity *entity)
pm_runtime_put(mipi->dev);
}
-static void mipi_display_off(void *arg)
-{
- struct sh_mobile_lcdc_entity *entity = arg;
- struct sh_mipi *mipi = to_sh_mipi(entity);
-
- if (mipi->next_display_off)
- mipi->next_display_off(mipi->next_board_data);
-
- __mipi_display_off(entity);
-}
-
static const struct sh_mobile_lcdc_entity_ops mipi_ops = {
- .display_on = __mipi_display_on,
- .display_off = __mipi_display_off,
+ .display_on = mipi_display_on,
+ .display_off = mipi_display_off,
};
static int __init sh_mipi_setup(struct sh_mipi *mipi,
@@ -499,17 +473,6 @@ static int __init sh_mipi_probe(struct platform_device *pdev)
mutex_unlock(&array_lock);
platform_set_drvdata(pdev, &mipi->entity);
- /* Save original LCDC callbacks */
- mipi->next_board_data = pdata->lcd_chan->board_cfg.board_data;
- mipi->next_display_on = pdata->lcd_chan->board_cfg.display_on;
- mipi->next_display_off = pdata->lcd_chan->board_cfg.display_off;
-
- /* Set up LCDC callbacks */
- pdata->lcd_chan->board_cfg.board_data = &mipi->entity;
- pdata->lcd_chan->board_cfg.display_on = mipi_display_on;
- pdata->lcd_chan->board_cfg.display_off = mipi_display_off;
- pdata->lcd_chan->board_cfg.owner = THIS_MODULE;
-
return 0;
emipisetup:
@@ -543,7 +506,6 @@ efindslot:
static int __exit sh_mipi_remove(struct platform_device *pdev)
{
- struct sh_mipi_dsi_info *pdata = pdev->dev.platform_data;
struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
struct resource *res2 = platform_get_resource(pdev, IORESOURCE_MEM, 1);
struct sh_mipi *mipi = to_sh_mipi(platform_get_drvdata(pdev));
@@ -566,11 +528,6 @@ static int __exit sh_mipi_remove(struct platform_device *pdev)
if (ret < 0)
return ret;
- pdata->lcd_chan->board_cfg.owner = NULL;
- pdata->lcd_chan->board_cfg.display_on = NULL;
- pdata->lcd_chan->board_cfg.display_off = NULL;
- pdata->lcd_chan->board_cfg.board_data = NULL;
-
pm_runtime_disable(&pdev->dev);
clk_disable(mipi->dsip_clk);
clk_disable(mipi->dsit_clk);
--
1.7.3.4
^ permalink raw reply related
* [WIP/RFC 11/31] arm: mach-shmobile: Add LCDC tx_dev field to platform data
From: Laurent Pinchart @ 2011-09-19 0:27 UTC (permalink / raw)
To: linux-fbdev
Make sure the transmitter devices get registered before the associated
LCDC devices.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
arch/arm/mach-shmobile/board-ap4evb.c | 272 ++++++++++++++++---------------
arch/arm/mach-shmobile/board-mackerel.c | 66 ++++----
2 files changed, 176 insertions(+), 162 deletions(-)
diff --git a/arch/arm/mach-shmobile/board-ap4evb.c b/arch/arm/mach-shmobile/board-ap4evb.c
index 485b151..7085966 100644
--- a/arch/arm/mach-shmobile/board-ap4evb.c
+++ b/arch/arm/mach-shmobile/board-ap4evb.c
@@ -443,82 +443,6 @@ static struct platform_device usb1_host_device = {
.resource = usb1_host_resources,
};
-static const struct fb_videomode ap4evb_lcdc_modes[] = {
- {
-#ifdef CONFIG_AP4EVB_QHD
- .name = "R63302(QHD)",
- .xres = 544,
- .yres = 961,
- .left_margin = 72,
- .right_margin = 600,
- .hsync_len = 16,
- .upper_margin = 8,
- .lower_margin = 8,
- .vsync_len = 2,
- .sync = FB_SYNC_VERT_HIGH_ACT | FB_SYNC_HOR_HIGH_ACT,
-#else
- .name = "WVGA Panel",
- .xres = 800,
- .yres = 480,
- .left_margin = 220,
- .right_margin = 110,
- .hsync_len = 70,
- .upper_margin = 20,
- .lower_margin = 5,
- .vsync_len = 5,
- .sync = 0,
-#endif
- },
-};
-static struct sh_mobile_meram_cfg lcd_meram_cfg = {
- .icb[0] = {
- .marker_icb = 28,
- .cache_icb = 24,
- .meram_offset = 0x0,
- .meram_size = 0x40,
- },
- .icb[1] = {
- .marker_icb = 29,
- .cache_icb = 25,
- .meram_offset = 0x40,
- .meram_size = 0x40,
- },
-};
-
-static struct sh_mobile_lcdc_info lcdc_info = {
- .meram_dev = &meram_info,
- .ch[0] = {
- .chan = LCDC_CHAN_MAINLCD,
- .fourcc = V4L2_PIX_FMT_RGB565,
- .lcd_cfg = ap4evb_lcdc_modes,
- .num_cfg = ARRAY_SIZE(ap4evb_lcdc_modes),
- .meram_cfg = &lcd_meram_cfg,
- }
-};
-
-static struct resource lcdc_resources[] = {
- [0] = {
- .name = "LCDC",
- .start = 0xfe940000, /* P4-only space */
- .end = 0xfe943fff,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = intcs_evt2irq(0x580),
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static struct platform_device lcdc_device = {
- .name = "sh_mobile_lcdc_fb",
- .num_resources = ARRAY_SIZE(lcdc_resources),
- .resource = lcdc_resources,
- .dev = {
- .platform_data = &lcdc_info,
- .coherent_dma_mask = ~0,
- },
-};
-
/*
* QHD display
*/
@@ -575,6 +499,8 @@ static struct resource mipidsi0_resources[] = {
},
};
+static struct sh_mobile_lcdc_info lcdc_info;
+
static struct sh_mipi_dsi_info mipidsi0_info = {
.data_format = MIPI_RGB888,
.lcd_chan = &lcdc_info.ch[0],
@@ -597,6 +523,86 @@ static struct platform_device *qhd_devices[] __initdata = {
};
#endif /* CONFIG_AP4EVB_QHD */
+/* LCDC0 */
+static const struct fb_videomode ap4evb_lcdc_modes[] = {
+ {
+#ifdef CONFIG_AP4EVB_QHD
+ .name = "R63302(QHD)",
+ .xres = 544,
+ .yres = 961,
+ .left_margin = 72,
+ .right_margin = 600,
+ .hsync_len = 16,
+ .upper_margin = 8,
+ .lower_margin = 8,
+ .vsync_len = 2,
+ .sync = FB_SYNC_VERT_HIGH_ACT | FB_SYNC_HOR_HIGH_ACT,
+#else
+ .name = "WVGA Panel",
+ .xres = 800,
+ .yres = 480,
+ .left_margin = 220,
+ .right_margin = 110,
+ .hsync_len = 70,
+ .upper_margin = 20,
+ .lower_margin = 5,
+ .vsync_len = 5,
+ .sync = 0,
+#endif
+ },
+};
+static struct sh_mobile_meram_cfg lcd_meram_cfg = {
+ .icb[0] = {
+ .marker_icb = 28,
+ .cache_icb = 24,
+ .meram_offset = 0x0,
+ .meram_size = 0x40,
+ },
+ .icb[1] = {
+ .marker_icb = 29,
+ .cache_icb = 25,
+ .meram_offset = 0x40,
+ .meram_size = 0x40,
+ },
+};
+
+static struct sh_mobile_lcdc_info lcdc_info = {
+ .meram_dev = &meram_info,
+ .ch[0] = {
+ .chan = LCDC_CHAN_MAINLCD,
+ .fourcc = V4L2_PIX_FMT_RGB565,
+ .lcd_cfg = ap4evb_lcdc_modes,
+ .num_cfg = ARRAY_SIZE(ap4evb_lcdc_modes),
+ .meram_cfg = &lcd_meram_cfg,
+#ifdef CONFIG_AP4EVB_QHD
+ .tx_dev = &mipidsi0_device,
+#endif
+ }
+};
+
+static struct resource lcdc_resources[] = {
+ [0] = {
+ .name = "LCDC",
+ .start = 0xfe940000, /* P4-only space */
+ .end = 0xfe943fff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = intcs_evt2irq(0x580),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device lcdc_device = {
+ .name = "sh_mobile_lcdc_fb",
+ .num_resources = ARRAY_SIZE(lcdc_resources),
+ .resource = lcdc_resources,
+ .dev = {
+ .platform_data = &lcdc_info,
+ .coherent_dma_mask = ~0,
+ },
+};
+
/* FSI */
#define IRQ_FSI evt2irq(0x1840)
static int __fsi_set_rate(struct clk *clk, long rate, int enable)
@@ -763,6 +769,62 @@ static struct platform_device fsi_device = {
static struct platform_device fsi_ak4643_device = {
.name = "sh_fsi2_a_ak4643",
};
+
+/* LCDC1 */
+static long ap4evb_clk_optimize(unsigned long target, unsigned long *best_freq,
+ unsigned long *parent_freq);
+
+static struct sh_mobile_lcdc_info sh_mobile_lcdc1_info;
+
+static struct sh_mobile_hdmi_info hdmi_info = {
+ .lcd_chan = &sh_mobile_lcdc1_info.ch[0],
+ .flags = HDMI_SND_SRC_SPDIF,
+ .clk_optimize_parent = ap4evb_clk_optimize,
+};
+
+static struct resource hdmi_resources[] = {
+ [0] = {
+ .name = "HDMI",
+ .start = 0xe6be0000,
+ .end = 0xe6be00ff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ /* There's also an HDMI interrupt on INTCS @ 0x18e0 */
+ .start = evt2irq(0x17e0),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device hdmi_device = {
+ .name = "sh-mobile-hdmi",
+ .num_resources = ARRAY_SIZE(hdmi_resources),
+ .resource = hdmi_resources,
+ .id = -1,
+ .dev = {
+ .platform_data = &hdmi_info,
+ },
+};
+
+static long ap4evb_clk_optimize(unsigned long target, unsigned long *best_freq,
+ unsigned long *parent_freq)
+{
+ struct clk *hdmi_ick = clk_get(&hdmi_device.dev, "ick");
+ long error;
+
+ if (IS_ERR(hdmi_ick)) {
+ int ret = PTR_ERR(hdmi_ick);
+ pr_err("Cannot get HDMI ICK: %d\n", ret);
+ return ret;
+ }
+
+ error = clk_round_parent(hdmi_ick, target, best_freq, parent_freq, 1, 64);
+
+ clk_put(hdmi_ick);
+
+ return error;
+}
+
static struct sh_mobile_meram_cfg hdmi_meram_cfg = {
.icb[0] = {
.marker_icb = 30,
@@ -788,6 +850,7 @@ static struct sh_mobile_lcdc_info sh_mobile_lcdc1_info = {
.clock_divider = 1,
.flags = LCDC_FLAGS_DWPOL,
.meram_cfg = &hdmi_meram_cfg,
+ .tx_dev = &hdmi_device,
}
};
@@ -815,63 +878,10 @@ static struct platform_device lcdc1_device = {
},
};
-static long ap4evb_clk_optimize(unsigned long target, unsigned long *best_freq,
- unsigned long *parent_freq);
-
-
-static struct sh_mobile_hdmi_info hdmi_info = {
- .lcd_chan = &sh_mobile_lcdc1_info.ch[0],
- .flags = HDMI_SND_SRC_SPDIF,
- .clk_optimize_parent = ap4evb_clk_optimize,
-};
-
-static struct resource hdmi_resources[] = {
- [0] = {
- .name = "HDMI",
- .start = 0xe6be0000,
- .end = 0xe6be00ff,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- /* There's also an HDMI interrupt on INTCS @ 0x18e0 */
- .start = evt2irq(0x17e0),
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static struct platform_device hdmi_device = {
- .name = "sh-mobile-hdmi",
- .num_resources = ARRAY_SIZE(hdmi_resources),
- .resource = hdmi_resources,
- .id = -1,
- .dev = {
- .platform_data = &hdmi_info,
- },
-};
-
static struct platform_device fsi_hdmi_device = {
.name = "sh_fsi2_b_hdmi",
};
-static long ap4evb_clk_optimize(unsigned long target, unsigned long *best_freq,
- unsigned long *parent_freq)
-{
- struct clk *hdmi_ick = clk_get(&hdmi_device.dev, "ick");
- long error;
-
- if (IS_ERR(hdmi_ick)) {
- int ret = PTR_ERR(hdmi_ick);
- pr_err("Cannot get HDMI ICK: %d\n", ret);
- return ret;
- }
-
- error = clk_round_parent(hdmi_ick, target, best_freq, parent_freq, 1, 64);
-
- clk_put(hdmi_ick);
-
- return error;
-}
-
static struct gpio_led ap4evb_leds[] = {
{
.name = "led4",
@@ -1006,9 +1016,9 @@ static struct platform_device *ap4evb_devices[] __initdata = {
&fsi_ak4643_device,
&fsi_hdmi_device,
&sh_mmcif_device,
- &lcdc1_device,
- &lcdc_device,
&hdmi_device,
+ &lcdc_device,
+ &lcdc1_device,
&ceu_device,
&ap4evb_camera,
&meram_device,
diff --git a/arch/arm/mach-shmobile/board-mackerel.c b/arch/arm/mach-shmobile/board-mackerel.c
index 6f42cd8..fbb88a5 100644
--- a/arch/arm/mach-shmobile/board-mackerel.c
+++ b/arch/arm/mach-shmobile/board-mackerel.c
@@ -430,6 +430,38 @@ static struct platform_device lcdc_device = {
},
};
+/* HDMI */
+static struct sh_mobile_lcdc_info hdmi_lcdc_info;
+
+static struct sh_mobile_hdmi_info hdmi_info = {
+ .lcd_chan = &hdmi_lcdc_info.ch[0],
+ .flags = HDMI_SND_SRC_SPDIF,
+};
+
+static struct resource hdmi_resources[] = {
+ [0] = {
+ .name = "HDMI",
+ .start = 0xe6be0000,
+ .end = 0xe6be00ff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ /* There's also an HDMI interrupt on INTCS @ 0x18e0 */
+ .start = evt2irq(0x17e0),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device hdmi_device = {
+ .name = "sh-mobile-hdmi",
+ .num_resources = ARRAY_SIZE(hdmi_resources),
+ .resource = hdmi_resources,
+ .id = -1,
+ .dev = {
+ .platform_data = &hdmi_info,
+ },
+};
+
static struct sh_mobile_meram_cfg hdmi_meram_cfg = {
.icb[0] = {
.marker_icb = 30,
@@ -444,7 +476,7 @@ static struct sh_mobile_meram_cfg hdmi_meram_cfg = {
.meram_size = 0x100,
},
};
-/* HDMI */
+
static struct sh_mobile_lcdc_info hdmi_lcdc_info = {
.meram_dev = &mackerel_meram_info,
.clock_source = LCDC_CLK_EXTERNAL,
@@ -455,6 +487,7 @@ static struct sh_mobile_lcdc_info hdmi_lcdc_info = {
.clock_divider = 1,
.flags = LCDC_FLAGS_DWPOL,
.meram_cfg = &hdmi_meram_cfg,
+ .tx_dev = &hdmi_device,
}
};
@@ -482,35 +515,6 @@ static struct platform_device hdmi_lcdc_device = {
},
};
-static struct sh_mobile_hdmi_info hdmi_info = {
- .lcd_chan = &hdmi_lcdc_info.ch[0],
- .flags = HDMI_SND_SRC_SPDIF,
-};
-
-static struct resource hdmi_resources[] = {
- [0] = {
- .name = "HDMI",
- .start = 0xe6be0000,
- .end = 0xe6be00ff,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- /* There's also an HDMI interrupt on INTCS @ 0x18e0 */
- .start = evt2irq(0x17e0),
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static struct platform_device hdmi_device = {
- .name = "sh-mobile-hdmi",
- .num_resources = ARRAY_SIZE(hdmi_resources),
- .resource = hdmi_resources,
- .id = -1,
- .dev = {
- .platform_data = &hdmi_info,
- },
-};
-
static struct platform_device fsi_hdmi_device = {
.name = "sh_fsi2_b_hdmi",
};
@@ -1304,8 +1308,8 @@ static struct platform_device *mackerel_devices[] __initdata = {
&sh_mmcif_device,
&ceu_device,
&mackerel_camera,
- &hdmi_lcdc_device,
&hdmi_device,
+ &hdmi_lcdc_device,
&meram_device,
};
--
1.7.3.4
^ permalink raw reply related
* [WIP/RFC 10/31] fbdev: sh_mobile_lcdc: Handle HDMI/MIPI transmitter device directly
From: Laurent Pinchart @ 2011-09-19 0:27 UTC (permalink / raw)
To: linux-fbdev
Pass a pointer to the transmitter device through platform data, retrieve
the corresponding sh_mobile_lcdc_entity structure in the probe method
and call the transmitter display_on/off methods directly.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
drivers/video/sh_mobile_lcdcfb.c | 29 ++++++++++++++++++++++++-----
drivers/video/sh_mobile_lcdcfb.h | 2 ++
include/video/sh_mobile_lcdc.h | 2 ++
3 files changed, 28 insertions(+), 5 deletions(-)
diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c
index 78f531c..9fd93f7 100644
--- a/drivers/video/sh_mobile_lcdcfb.c
+++ b/drivers/video/sh_mobile_lcdcfb.c
@@ -338,6 +338,9 @@ static void sh_mobile_lcdc_display_on(struct sh_mobile_lcdc_chan *ch)
{
struct sh_mobile_lcdc_board_cfg *board_cfg = &ch->cfg.board_cfg;
+ if (ch->tx_dev)
+ ch->tx_dev->ops->display_on(ch->tx_dev, ch->info);
+
/* HDMI must be enabled before LCDC configuration */
if (board_cfg->display_on && try_module_get(board_cfg->owner)) {
board_cfg->display_on(board_cfg->board_data, ch->info);
@@ -353,6 +356,9 @@ static void sh_mobile_lcdc_display_off(struct sh_mobile_lcdc_chan *ch)
board_cfg->display_off(board_cfg->board_data);
module_put(board_cfg->owner);
}
+
+ if (ch->tx_dev)
+ ch->tx_dev->ops->display_off(ch->tx_dev);
}
/* -----------------------------------------------------------------------------
@@ -1491,18 +1497,21 @@ static int sh_mobile_lcdc_remove(struct platform_device *pdev)
sh_mobile_lcdc_stop(priv);
for (i = 0; i < ARRAY_SIZE(priv->ch); i++) {
- info = priv->ch[i].info;
+ struct sh_mobile_lcdc_chan *ch = &priv->ch[i];
+ info = ch->info;
if (!info || !info->device)
continue;
- if (priv->ch[i].sglist)
- vfree(priv->ch[i].sglist);
+ if (ch->tx_dev)
+ module_put(ch->cfg.tx_dev->dev.driver->owner);
+
+ if (ch->sglist)
+ vfree(ch->sglist);
if (info->screen_base)
dma_free_coherent(&pdev->dev, info->fix.smem_len,
- info->screen_base,
- priv->ch[i].dma_handle);
+ info->screen_base, ch->dma_handle);
fb_dealloc_cmap(&info->cmap);
framebuffer_release(info);
}
@@ -1597,6 +1606,16 @@ sh_mobile_lcdc_channel_init(struct sh_mobile_lcdc_priv *priv,
info->pseudo_palette = &ch->pseudo_palette;
info->flags = FBINFO_FLAG_DEFAULT;
+ if (cfg->tx_dev) {
+ if (!cfg->tx_dev->dev.driver ||
+ !try_module_get(cfg->tx_dev->dev.driver->owner)) {
+ dev_warn(priv->dev, "unable to get transmitter "
+ "device\n");
+ return -EINVAL;
+ }
+ ch->tx_dev = platform_get_drvdata(cfg->tx_dev);
+ }
+
/* Iterate through the modes to validate them and find the highest
* resolution.
*/
diff --git a/drivers/video/sh_mobile_lcdcfb.h b/drivers/video/sh_mobile_lcdcfb.h
index f1451c6..c992a98 100644
--- a/drivers/video/sh_mobile_lcdcfb.h
+++ b/drivers/video/sh_mobile_lcdcfb.h
@@ -41,6 +41,8 @@ struct sh_mobile_lcdc_entity {
*/
struct sh_mobile_lcdc_chan {
struct sh_mobile_lcdc_priv *lcdc;
+ struct sh_mobile_lcdc_entity *tx_dev;
+
unsigned long *reg_offs;
unsigned long ldmt1r_value;
unsigned long enabled; /* ME and SE in LDCNT2R */
diff --git a/include/video/sh_mobile_lcdc.h b/include/video/sh_mobile_lcdc.h
index fe30b75..0ec59e1 100644
--- a/include/video/sh_mobile_lcdc.h
+++ b/include/video/sh_mobile_lcdc.h
@@ -186,6 +186,8 @@ struct sh_mobile_lcdc_chan_cfg {
struct sh_mobile_lcdc_bl_info bl_info;
struct sh_mobile_lcdc_sys_bus_cfg sys_bus_cfg; /* only for SYSn I/F */
struct sh_mobile_meram_cfg *meram_cfg;
+
+ struct platform_device *tx_dev; /* HDMI/MIPI transmitter device */
};
struct sh_mobile_lcdc_info {
--
1.7.3.4
^ permalink raw reply related
* [WIP/RFC 09/31] fbdev: sh_mipi_dsi: Implement sh_mobile_lcdc_entity interface
From: Laurent Pinchart @ 2011-09-19 0:27 UTC (permalink / raw)
To: linux-fbdev
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
drivers/video/sh_mipi_dsi.c | 49 +++++++++++++++++++++++++++++++++++--------
1 files changed, 40 insertions(+), 9 deletions(-)
diff --git a/drivers/video/sh_mipi_dsi.c b/drivers/video/sh_mipi_dsi.c
index 24640c8..31a403d 100644
--- a/drivers/video/sh_mipi_dsi.c
+++ b/drivers/video/sh_mipi_dsi.c
@@ -22,6 +22,8 @@
#include <video/sh_mipi_dsi.h>
#include <video/sh_mobile_lcdc.h>
+#include "sh_mobile_lcdcfb.h"
+
#define SYSCTRL 0x0000
#define SYSCONF 0x0004
#define TIMSET 0x0008
@@ -47,6 +49,8 @@
#define MAX_SH_MIPI_DSI 2
struct sh_mipi {
+ struct sh_mobile_lcdc_entity entity;
+
void __iomem *base;
void __iomem *linkbase;
struct clk *dsit_clk;
@@ -58,6 +62,8 @@ struct sh_mipi {
void (*next_display_off)(void *board_data);
};
+#define to_sh_mipi(e) container_of(e, struct sh_mipi, entity)
+
static struct sh_mipi *mipi_dsi[MAX_SH_MIPI_DSI];
/* Protect the above array */
@@ -118,33 +124,55 @@ static void sh_mipi_dsi_enable(struct sh_mipi *mipi, bool enable)
static void sh_mipi_shutdown(struct platform_device *pdev)
{
- struct sh_mipi *mipi = platform_get_drvdata(pdev);
+ struct sh_mipi *mipi = to_sh_mipi(platform_get_drvdata(pdev));
sh_mipi_dsi_enable(mipi, false);
}
-static void mipi_display_on(void *arg, struct fb_info *info)
+static void __mipi_display_on(struct sh_mobile_lcdc_entity *entity,
+ struct fb_info *info)
{
- struct sh_mipi *mipi = arg;
+ struct sh_mipi *mipi = to_sh_mipi(entity);
pm_runtime_get_sync(mipi->dev);
sh_mipi_dsi_enable(mipi, true);
+}
+
+static void mipi_display_on(void *arg, struct fb_info *info)
+{
+ struct sh_mobile_lcdc_entity *entity = arg;
+ struct sh_mipi *mipi = to_sh_mipi(entity);
+
+ __mipi_display_on(entity, info);
if (mipi->next_display_on)
mipi->next_display_on(mipi->next_board_data, info);
}
+static void __mipi_display_off(struct sh_mobile_lcdc_entity *entity)
+{
+ struct sh_mipi *mipi = to_sh_mipi(entity);
+
+ sh_mipi_dsi_enable(mipi, false);
+ pm_runtime_put(mipi->dev);
+}
+
static void mipi_display_off(void *arg)
{
- struct sh_mipi *mipi = arg;
+ struct sh_mobile_lcdc_entity *entity = arg;
+ struct sh_mipi *mipi = to_sh_mipi(entity);
if (mipi->next_display_off)
mipi->next_display_off(mipi->next_board_data);
- sh_mipi_dsi_enable(mipi, false);
- pm_runtime_put(mipi->dev);
+ __mipi_display_off(entity);
}
+static const struct sh_mobile_lcdc_entity_ops mipi_ops = {
+ .display_on = __mipi_display_on,
+ .display_off = __mipi_display_off,
+};
+
static int __init sh_mipi_setup(struct sh_mipi *mipi,
struct sh_mipi_dsi_info *pdata)
{
@@ -383,6 +411,9 @@ static int __init sh_mipi_probe(struct platform_device *pdev)
goto ealloc;
}
+ mipi->entity.owner = THIS_MODULE;
+ mipi->entity.ops = &mipi_ops;
+
if (!request_mem_region(res->start, resource_size(res), pdev->name)) {
dev_err(&pdev->dev, "MIPI register region already claimed\n");
ret = -EBUSY;
@@ -466,7 +497,7 @@ static int __init sh_mipi_probe(struct platform_device *pdev)
goto emipisetup;
mutex_unlock(&array_lock);
- platform_set_drvdata(pdev, mipi);
+ platform_set_drvdata(pdev, &mipi->entity);
/* Save original LCDC callbacks */
mipi->next_board_data = pdata->lcd_chan->board_cfg.board_data;
@@ -474,7 +505,7 @@ static int __init sh_mipi_probe(struct platform_device *pdev)
mipi->next_display_off = pdata->lcd_chan->board_cfg.display_off;
/* Set up LCDC callbacks */
- pdata->lcd_chan->board_cfg.board_data = mipi;
+ pdata->lcd_chan->board_cfg.board_data = &mipi->entity;
pdata->lcd_chan->board_cfg.display_on = mipi_display_on;
pdata->lcd_chan->board_cfg.display_off = mipi_display_off;
pdata->lcd_chan->board_cfg.owner = THIS_MODULE;
@@ -515,7 +546,7 @@ static int __exit sh_mipi_remove(struct platform_device *pdev)
struct sh_mipi_dsi_info *pdata = pdev->dev.platform_data;
struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
struct resource *res2 = platform_get_resource(pdev, IORESOURCE_MEM, 1);
- struct sh_mipi *mipi = platform_get_drvdata(pdev);
+ struct sh_mipi *mipi = to_sh_mipi(platform_get_drvdata(pdev));
int i, ret;
mutex_lock(&array_lock);
--
1.7.3.4
^ permalink raw reply related
* [WIP/RFC 08/31] fbdev: sh_mobile_hdmi: Implement sh_mobile_lcdc_entity interface
From: Laurent Pinchart @ 2011-09-19 0:27 UTC (permalink / raw)
To: linux-fbdev
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
drivers/video/sh_mobile_hdmi.c | 43 +++++++++++++++++++++++++++++----------
1 files changed, 32 insertions(+), 11 deletions(-)
diff --git a/drivers/video/sh_mobile_hdmi.c b/drivers/video/sh_mobile_hdmi.c
index e888081..ce858d6 100644
--- a/drivers/video/sh_mobile_hdmi.c
+++ b/drivers/video/sh_mobile_hdmi.c
@@ -208,6 +208,8 @@ enum hotplug_state {
};
struct sh_hdmi {
+ struct sh_mobile_lcdc_entity entity;
+
void __iomem *base;
enum hotplug_state hp_state; /* hot-plug status */
u8 preprogrammed_vic; /* use a pre-programmed VIC or
@@ -225,6 +227,9 @@ struct sh_hdmi {
struct notifier_block notifier;
};
+#define entity_to_sh_hdmi(e) container_of(e, struct sh_hdmi, entity)
+#define notifier_to_sh_hdmi(n) container_of(n, struct sh_hdmi, notifier)
+
static void hdmi_write(struct sh_hdmi *hdmi, u8 data, u8 reg)
{
iowrite8(data, hdmi->base + reg);
@@ -999,13 +1004,14 @@ static irqreturn_t sh_hdmi_hotplug(int irq, void *dev_id)
}
/* locking: called with info->lock held, or before register_framebuffer() */
-static void sh_hdmi_display_on(void *arg, struct fb_info *info)
+static void __sh_hdmi_display_on(struct sh_mobile_lcdc_entity *entity,
+ struct fb_info *info)
{
/*
* info is guaranteed to be valid, when we are called, because our
* FB_EVENT_FB_UNBIND notify is also called with info->lock held
*/
- struct sh_hdmi *hdmi = arg;
+ struct sh_hdmi *hdmi = entity_to_sh_hdmi(entity);
struct sh_mobile_lcdc_chan *ch = info->par;
dev_dbg(hdmi->dev, "%s(%p): state %x\n", __func__, hdmi, info->state);
@@ -1032,16 +1038,31 @@ static void sh_hdmi_display_on(void *arg, struct fb_info *info)
}
}
+static void sh_hdmi_display_on(void *arg, struct fb_info *info)
+{
+ __sh_hdmi_display_on(arg, info);
+}
+
/* locking: called with info->lock held */
-static void sh_hdmi_display_off(void *arg)
+static void __sh_hdmi_display_off(struct sh_mobile_lcdc_entity *entity)
{
- struct sh_hdmi *hdmi = arg;
+ struct sh_hdmi *hdmi = entity_to_sh_hdmi(entity);
dev_dbg(hdmi->dev, "%s(%p)\n", __func__, hdmi);
/* PS mode e->a */
hdmi_write(hdmi, 0x10, HDMI_SYSTEM_CTRL);
}
+static void sh_hdmi_display_off(void *arg)
+{
+ __sh_hdmi_display_off(arg);
+}
+
+static const struct sh_mobile_lcdc_entity_ops sh_hdmi_ops = {
+ .display_on = __sh_hdmi_display_on,
+ .display_off = __sh_hdmi_display_off,
+};
+
static bool sh_hdmi_must_reconfigure(struct sh_hdmi *hdmi)
{
struct fb_info *info = hdmi->info;
@@ -1153,7 +1174,7 @@ static void sh_hdmi_edid_work_fn(struct work_struct *work)
if (lock_fb_info(info)) {
info->var.width = hdmi->var.width;
info->var.height = hdmi->var.height;
- sh_hdmi_display_on(hdmi, info);
+ __sh_hdmi_display_on(&hdmi->entity, info);
unlock_fb_info(info);
}
} else {
@@ -1192,9 +1213,7 @@ static int sh_hdmi_notify(struct notifier_block *nb,
{
struct fb_event *event = data;
struct fb_info *info = event->info;
- struct sh_mobile_lcdc_chan *ch = info->par;
- struct sh_mobile_lcdc_board_cfg *board_cfg = &ch->cfg.board_cfg;
- struct sh_hdmi *hdmi = board_cfg->board_data;
+ struct sh_hdmi *hdmi = notifier_to_sh_hdmi(nb);
if (!hdmi || nb != &hdmi->notifier || hdmi->info != info)
return NOTIFY_DONE;
@@ -1246,6 +1265,8 @@ static int __init sh_hdmi_probe(struct platform_device *pdev)
mutex_init(&hdmi->mutex);
hdmi->dev = &pdev->dev;
+ hdmi->entity.owner = THIS_MODULE;
+ hdmi->entity.ops = &sh_hdmi_ops;
hdmi->hdmi_clk = clk_get(&pdev->dev, "ick");
if (IS_ERR(hdmi->hdmi_clk)) {
@@ -1285,12 +1306,12 @@ static int __init sh_hdmi_probe(struct platform_device *pdev)
goto emap;
}
- platform_set_drvdata(pdev, hdmi);
+ platform_set_drvdata(pdev, &hdmi->entity);
/* Set up LCDC callbacks */
board_cfg = &pdata->lcd_chan->board_cfg;
board_cfg->owner = THIS_MODULE;
- board_cfg->board_data = hdmi;
+ board_cfg->board_data = &hdmi->entity;
board_cfg->display_on = sh_hdmi_display_on;
board_cfg->display_off = sh_hdmi_display_off;
@@ -1344,7 +1365,7 @@ egetclk:
static int __exit sh_hdmi_remove(struct platform_device *pdev)
{
struct sh_mobile_hdmi_info *pdata = pdev->dev.platform_data;
- struct sh_hdmi *hdmi = platform_get_drvdata(pdev);
+ struct sh_hdmi *hdmi = entity_to_sh_hdmi(platform_get_drvdata(pdev));
struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
struct sh_mobile_lcdc_board_cfg *board_cfg = &pdata->lcd_chan->board_cfg;
int irq = platform_get_irq(pdev, 0);
--
1.7.3.4
^ permalink raw reply related
* [WIP/RFC 07/31] fbdev: sh_mobile_lcdc: Add sh_mobile_lcdc_entity definition
From: Laurent Pinchart @ 2011-09-19 0:27 UTC (permalink / raw)
To: linux-fbdev
The sh_mobile_lcdc_entity structure will be used to abstract operations
performed by transceivers (such as MIPI/DSI and HDMI).
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
drivers/video/sh_mobile_lcdcfb.h | 18 ++++++++++++++++--
1 files changed, 16 insertions(+), 2 deletions(-)
diff --git a/drivers/video/sh_mobile_lcdcfb.h b/drivers/video/sh_mobile_lcdcfb.h
index a58a0f3..f1451c6 100644
--- a/drivers/video/sh_mobile_lcdcfb.h
+++ b/drivers/video/sh_mobile_lcdcfb.h
@@ -14,9 +14,23 @@ enum { LDDCKPAT1R, LDDCKPAT2R, LDMT1R, LDMT2R, LDMT3R, LDDFR, LDSM1R,
#define PALETTE_NR 16
-struct sh_mobile_lcdc_priv;
-struct fb_info;
struct backlight_device;
+struct fb_info;
+struct module;
+struct sh_mobile_lcdc_entity;
+struct sh_mobile_lcdc_priv;
+
+struct sh_mobile_lcdc_entity_ops {
+ /* Display */
+ void (*display_on)(struct sh_mobile_lcdc_entity *entity,
+ struct fb_info *info);
+ void (*display_off)(struct sh_mobile_lcdc_entity *entity);
+};
+
+struct sh_mobile_lcdc_entity {
+ struct module *owner;
+ const struct sh_mobile_lcdc_entity_ops *ops;
+};
/*
* struct sh_mobile_lcdc_chan - LCDC display channel
--
1.7.3.4
^ permalink raw reply related
* [WIP/RFC 06/31] sh_mobile_hdmi: Remove platform data lcd_dev field
From: Laurent Pinchart @ 2011-09-19 0:27 UTC (permalink / raw)
To: linux-fbdev
The field is used to print debug messages only. Remove it.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
arch/arm/mach-shmobile/board-ap4evb.c | 1 -
arch/arm/mach-shmobile/board-mackerel.c | 1 -
drivers/video/sh_mobile_hdmi.c | 17 +++++------------
include/video/sh_mobile_hdmi.h | 1 -
4 files changed, 5 insertions(+), 15 deletions(-)
diff --git a/arch/arm/mach-shmobile/board-ap4evb.c b/arch/arm/mach-shmobile/board-ap4evb.c
index 1227903..485b151 100644
--- a/arch/arm/mach-shmobile/board-ap4evb.c
+++ b/arch/arm/mach-shmobile/board-ap4evb.c
@@ -821,7 +821,6 @@ static long ap4evb_clk_optimize(unsigned long target, unsigned long *best_freq,
static struct sh_mobile_hdmi_info hdmi_info = {
.lcd_chan = &sh_mobile_lcdc1_info.ch[0],
- .lcd_dev = &lcdc1_device.dev,
.flags = HDMI_SND_SRC_SPDIF,
.clk_optimize_parent = ap4evb_clk_optimize,
};
diff --git a/arch/arm/mach-shmobile/board-mackerel.c b/arch/arm/mach-shmobile/board-mackerel.c
index 199c2f1..6f42cd8 100644
--- a/arch/arm/mach-shmobile/board-mackerel.c
+++ b/arch/arm/mach-shmobile/board-mackerel.c
@@ -484,7 +484,6 @@ static struct platform_device hdmi_lcdc_device = {
static struct sh_mobile_hdmi_info hdmi_info = {
.lcd_chan = &hdmi_lcdc_info.ch[0],
- .lcd_dev = &hdmi_lcdc_device.dev,
.flags = HDMI_SND_SRC_SPDIF,
};
diff --git a/drivers/video/sh_mobile_hdmi.c b/drivers/video/sh_mobile_hdmi.c
index 7d54e2c..e888081 100644
--- a/drivers/video/sh_mobile_hdmi.c
+++ b/drivers/video/sh_mobile_hdmi.c
@@ -1006,11 +1006,9 @@ static void sh_hdmi_display_on(void *arg, struct fb_info *info)
* FB_EVENT_FB_UNBIND notify is also called with info->lock held
*/
struct sh_hdmi *hdmi = arg;
- struct sh_mobile_hdmi_info *pdata = hdmi->dev->platform_data;
struct sh_mobile_lcdc_chan *ch = info->par;
- dev_dbg(hdmi->dev, "%s(%p): state %x\n", __func__,
- pdata->lcd_dev, info->state);
+ dev_dbg(hdmi->dev, "%s(%p): state %x\n", __func__, hdmi, info->state);
/* No need to lock */
hdmi->info = info;
@@ -1038,9 +1036,8 @@ static void sh_hdmi_display_on(void *arg, struct fb_info *info)
static void sh_hdmi_display_off(void *arg)
{
struct sh_hdmi *hdmi = arg;
- struct sh_mobile_hdmi_info *pdata = hdmi->dev->platform_data;
- dev_dbg(hdmi->dev, "%s(%p)\n", __func__, pdata->lcd_dev);
+ dev_dbg(hdmi->dev, "%s(%p)\n", __func__, hdmi);
/* PS mode e->a */
hdmi_write(hdmi, 0x10, HDMI_SYSTEM_CTRL);
}
@@ -1111,15 +1108,11 @@ static long sh_hdmi_clk_configure(struct sh_hdmi *hdmi, unsigned long hdmi_rate,
static void sh_hdmi_edid_work_fn(struct work_struct *work)
{
struct sh_hdmi *hdmi = container_of(work, struct sh_hdmi, edid_work.work);
- struct sh_mobile_hdmi_info *pdata = hdmi->dev->platform_data;
struct sh_mobile_lcdc_chan *ch;
int ret;
- dev_dbg(hdmi->dev, "%s(%p): begin, hotplug status %d\n", __func__,
- pdata->lcd_dev, hdmi->hp_state);
-
- if (!pdata->lcd_dev)
- return;
+ dev_dbg(hdmi->dev, "%s(%p): begin, hotplug status %d\n", __func__, hdmi,
+ hdmi->hp_state);
mutex_lock(&hdmi->mutex);
@@ -1191,7 +1184,7 @@ out:
hdmi->hp_state = HDMI_HOTPLUG_DISCONNECTED;
mutex_unlock(&hdmi->mutex);
- dev_dbg(hdmi->dev, "%s(%p): end\n", __func__, pdata->lcd_dev);
+ dev_dbg(hdmi->dev, "%s(%p): end\n", __func__, hdmi);
}
static int sh_hdmi_notify(struct notifier_block *nb,
diff --git a/include/video/sh_mobile_hdmi.h b/include/video/sh_mobile_hdmi.h
index b569329..0b8d2cf 100644
--- a/include/video/sh_mobile_hdmi.h
+++ b/include/video/sh_mobile_hdmi.h
@@ -32,7 +32,6 @@ struct clk;
struct sh_mobile_hdmi_info {
struct sh_mobile_lcdc_chan_cfg *lcd_chan;
- struct device *lcd_dev;
unsigned int flags;
long (*clk_optimize_parent)(unsigned long target, unsigned long *best_freq,
unsigned long *parent_freq);
--
1.7.3.4
^ permalink raw reply related
* [WIP/RFC 05/31] fbdev: sh_mobile_lcdc: Create functions to turn the display on/off
From: Laurent Pinchart @ 2011-09-19 0:27 UTC (permalink / raw)
To: linux-fbdev
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
drivers/video/sh_mobile_lcdcfb.c | 53 ++++++++++++++++++++------------------
1 files changed, 28 insertions(+), 25 deletions(-)
diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c
index c7e6074..78f531c 100644
--- a/drivers/video/sh_mobile_lcdcfb.c
+++ b/drivers/video/sh_mobile_lcdcfb.c
@@ -223,7 +223,7 @@ static int sh_mobile_lcdc_setup_clocks(struct sh_mobile_lcdc_priv *priv,
}
/* -----------------------------------------------------------------------------
- * Sys panel and deferred I/O
+ * Display, panel and deferred I/O
*/
static void lcdc_sys_write_index(void *handle, unsigned long data)
@@ -334,6 +334,27 @@ static void sh_mobile_lcdc_deferred_io_touch(struct fb_info *info)
schedule_delayed_work(&info->deferred_work, fbdefio->delay);
}
+static void sh_mobile_lcdc_display_on(struct sh_mobile_lcdc_chan *ch)
+{
+ struct sh_mobile_lcdc_board_cfg *board_cfg = &ch->cfg.board_cfg;
+
+ /* HDMI must be enabled before LCDC configuration */
+ if (board_cfg->display_on && try_module_get(board_cfg->owner)) {
+ board_cfg->display_on(board_cfg->board_data, ch->info);
+ module_put(board_cfg->owner);
+ }
+}
+
+static void sh_mobile_lcdc_display_off(struct sh_mobile_lcdc_chan *ch)
+{
+ struct sh_mobile_lcdc_board_cfg *board_cfg = &ch->cfg.board_cfg;
+
+ if (board_cfg->display_off && try_module_get(board_cfg->owner)) {
+ board_cfg->display_off(board_cfg->board_data);
+ module_put(board_cfg->owner);
+ }
+}
+
/* -----------------------------------------------------------------------------
* Format helpers
*/
@@ -642,7 +663,6 @@ static void __sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
{
struct sh_mobile_meram_info *mdev = priv->meram_dev;
- struct sh_mobile_lcdc_board_cfg *board_cfg;
struct sh_mobile_lcdc_chan *ch;
unsigned long tmp;
int ret;
@@ -659,8 +679,9 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
lcdc_wait_bit(priv, _LDCNT2R, LDCNT2R_BR, 0);
for (k = 0; k < ARRAY_SIZE(priv->ch); k++) {
- ch = &priv->ch[k];
+ struct sh_mobile_lcdc_board_cfg *board_cfg;
+ ch = &priv->ch[k];
if (!ch->enabled)
continue;
@@ -748,11 +769,7 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
fb_deferred_io_init(ch->info);
}
- board_cfg = &ch->cfg.board_cfg;
- if (board_cfg->display_on && try_module_get(board_cfg->owner)) {
- board_cfg->display_on(board_cfg->board_data, ch->info);
- module_put(board_cfg->owner);
- }
+ sh_mobile_lcdc_display_on(ch);
if (ch->bl) {
ch->bl->props.power = FB_BLANK_UNBLANK;
@@ -766,7 +783,6 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
static void sh_mobile_lcdc_stop(struct sh_mobile_lcdc_priv *priv)
{
struct sh_mobile_lcdc_chan *ch;
- struct sh_mobile_lcdc_board_cfg *board_cfg;
int k;
/* clean up deferred io and ask board code to disable panel */
@@ -793,11 +809,7 @@ static void sh_mobile_lcdc_stop(struct sh_mobile_lcdc_priv *priv)
backlight_update_status(ch->bl);
}
- board_cfg = &ch->cfg.board_cfg;
- if (board_cfg->display_off && try_module_get(board_cfg->owner)) {
- board_cfg->display_off(board_cfg->board_data);
- module_put(board_cfg->owner);
- }
+ sh_mobile_lcdc_display_off(ch);
/* disable the meram */
if (ch->meram_enabled) {
@@ -1418,7 +1430,6 @@ static int sh_mobile_lcdc_notify(struct notifier_block *nb,
struct fb_event *event = data;
struct fb_info *info = event->info;
struct sh_mobile_lcdc_chan *ch = info->par;
- struct sh_mobile_lcdc_board_cfg *board_cfg = &ch->cfg.board_cfg;
if (&ch->lcdc->notifier != nb)
return NOTIFY_DONE;
@@ -1428,10 +1439,7 @@ static int sh_mobile_lcdc_notify(struct notifier_block *nb,
switch(action) {
case FB_EVENT_SUSPEND:
- if (board_cfg->display_off && try_module_get(board_cfg->owner)) {
- board_cfg->display_off(board_cfg->board_data);
- module_put(board_cfg->owner);
- }
+ sh_mobile_lcdc_display_off(ch);
sh_mobile_lcdc_stop(ch->lcdc);
break;
case FB_EVENT_RESUME:
@@ -1439,12 +1447,7 @@ static int sh_mobile_lcdc_notify(struct notifier_block *nb,
sh_mobile_fb_reconfig(info);
mutex_unlock(&ch->open_lock);
- /* HDMI must be enabled before LCDC configuration */
- if (board_cfg->display_on && try_module_get(board_cfg->owner)) {
- board_cfg->display_on(board_cfg->board_data, info);
- module_put(board_cfg->owner);
- }
-
+ sh_mobile_lcdc_display_on(ch);
sh_mobile_lcdc_start(ch->lcdc);
}
--
1.7.3.4
^ permalink raw reply related
* [WIP/RFC 04/31] fbdev: sh_mobile_lcdc: Don't pass struct device around
From: Laurent Pinchart @ 2011-09-19 0:27 UTC (permalink / raw)
To: linux-fbdev
Pass a pointer to a struct sh_mobile_lcdc_priv instead, which stores a
pointer to the device.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
drivers/video/sh_mobile_lcdcfb.c | 41 +++++++++++++++++++------------------
1 files changed, 21 insertions(+), 20 deletions(-)
diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c
index ae9c126..c7e6074 100644
--- a/drivers/video/sh_mobile_lcdcfb.c
+++ b/drivers/video/sh_mobile_lcdcfb.c
@@ -186,9 +186,8 @@ static void sh_mobile_lcdc_clk_off(struct sh_mobile_lcdc_priv *priv)
}
}
-static int sh_mobile_lcdc_setup_clocks(struct platform_device *pdev,
- int clock_source,
- struct sh_mobile_lcdc_priv *priv)
+static int sh_mobile_lcdc_setup_clocks(struct sh_mobile_lcdc_priv *priv,
+ int clock_source)
{
struct clk *clk;
char *str;
@@ -213,9 +212,9 @@ static int sh_mobile_lcdc_setup_clocks(struct platform_device *pdev,
if (str = NULL)
return 0;
- clk = clk_get(&pdev->dev, str);
+ clk = clk_get(priv->dev, str);
if (IS_ERR(clk)) {
- dev_err(&pdev->dev, "cannot get dot clock %s\n", str);
+ dev_err(priv->dev, "cannot get dot clock %s\n", str);
return PTR_ERR(clk);
}
@@ -1565,8 +1564,9 @@ sh_mobile_lcdc_check_interface(struct sh_mobile_lcdc_chan *ch)
return 0;
}
-static int __devinit sh_mobile_lcdc_channel_init(struct sh_mobile_lcdc_chan *ch,
- struct device *dev)
+static int __devinit
+sh_mobile_lcdc_channel_init(struct sh_mobile_lcdc_priv *priv,
+ struct sh_mobile_lcdc_chan *ch)
{
struct sh_mobile_lcdc_chan_cfg *cfg = &ch->cfg;
const struct fb_videomode *max_mode;
@@ -1582,9 +1582,9 @@ static int __devinit sh_mobile_lcdc_channel_init(struct sh_mobile_lcdc_chan *ch,
mutex_init(&ch->open_lock);
/* Allocate the frame buffer device. */
- ch->info = framebuffer_alloc(0, dev);
+ ch->info = framebuffer_alloc(0, priv->dev);
if (!ch->info) {
- dev_err(dev, "unable to allocate fb_info\n");
+ dev_err(priv->dev, "unable to allocate fb_info\n");
return -ENOMEM;
}
@@ -1606,8 +1606,8 @@ static int __devinit sh_mobile_lcdc_channel_init(struct sh_mobile_lcdc_chan *ch,
/* NV12/NV21 buffers must have even number of lines */
if ((cfg->fourcc = V4L2_PIX_FMT_NV12 ||
cfg->fourcc = V4L2_PIX_FMT_NV21) && (mode->yres & 0x1)) {
- dev_err(dev, "yres must be multiple of 2 for YCbCr420 "
- "mode.\n");
+ dev_err(priv->dev, "yres must be multiple of 2 for "
+ "YCbCr420 mode.\n");
return -EINVAL;
}
@@ -1620,7 +1620,7 @@ static int __devinit sh_mobile_lcdc_channel_init(struct sh_mobile_lcdc_chan *ch,
if (!max_size)
max_size = MAX_XRES * MAX_YRES;
else
- dev_dbg(dev, "Found largest videomode %ux%u\n",
+ dev_dbg(priv->dev, "Found largest videomode %ux%u\n",
max_mode->xres, max_mode->yres);
/* Create the mode list. */
@@ -1671,16 +1671,17 @@ static int __devinit sh_mobile_lcdc_channel_init(struct sh_mobile_lcdc_chan *ch,
max_size = max_size * var->bits_per_pixel / 8 * 2;
/* Allocate frame buffer memory and color map. */
- buf = dma_alloc_coherent(dev, max_size, &ch->dma_handle, GFP_KERNEL);
+ buf = dma_alloc_coherent(priv->dev, max_size, &ch->dma_handle,
+ GFP_KERNEL);
if (!buf) {
- dev_err(dev, "unable to allocate buffer\n");
+ dev_err(priv->dev, "unable to allocate buffer\n");
return -ENOMEM;
}
ret = fb_alloc_cmap(&info->cmap, PALETTE_NR, 0);
if (ret < 0) {
- dev_err(dev, "unable to allocate cmap\n");
- dma_free_coherent(dev, max_size, buf, ch->dma_handle);
+ dev_err(priv->dev, "unable to allocate cmap\n");
+ dma_free_coherent(priv->dev, max_size, buf, ch->dma_handle);
return ret;
}
@@ -1703,7 +1704,7 @@ static int __devinit sh_mobile_lcdc_channel_init(struct sh_mobile_lcdc_chan *ch,
}
info->screen_base = buf;
- info->device = dev;
+ info->device = priv->dev;
ch->display_var = *var;
return 0;
@@ -1797,7 +1798,7 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev)
if (!priv->base)
goto err1;
- error = sh_mobile_lcdc_setup_clocks(pdev, pdata->clock_source, priv);
+ error = sh_mobile_lcdc_setup_clocks(priv, pdata->clock_source);
if (error) {
dev_err(&pdev->dev, "unable to setup clocks\n");
goto err1;
@@ -1809,7 +1810,7 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev)
for (i = 0; i < num_channels; i++) {
struct sh_mobile_lcdc_chan *ch = priv->ch + i;
- error = sh_mobile_lcdc_channel_init(ch, &pdev->dev);
+ error = sh_mobile_lcdc_channel_init(priv, ch);
if (error)
goto err1;
}
@@ -1839,7 +1840,7 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev)
if (error < 0)
goto err1;
- dev_info(info->dev, "registered %s/%s as %dx%d %dbpp.\n",
+ dev_info(&pdev->dev, "registered %s/%s as %dx%d %dbpp.\n",
pdev->name, (ch->cfg.chan = LCDC_CHAN_MAINLCD) ?
"mainlcd" : "sublcd", info->var.xres, info->var.yres,
info->var.bits_per_pixel);
--
1.7.3.4
^ permalink raw reply related
* [WIP/RFC 03/31] fbdev: sh_mobile_lcdc: Move pm runtime enable to probe()
From: Laurent Pinchart @ 2011-09-19 0:27 UTC (permalink / raw)
To: linux-fbdev
The pm_runtime_enable() and pm_runtime_resume() calls don't belong to
sh_mobile_lcdc_setup_clocks(). Move them to the probe function. Remove
the unneeded pm_runtime_resume() call.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
drivers/video/sh_mobile_lcdcfb.c | 34 ++++++++++++++++------------------
1 files changed, 16 insertions(+), 18 deletions(-)
diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c
index 4a6bdc7..ae9c126 100644
--- a/drivers/video/sh_mobile_lcdcfb.c
+++ b/drivers/video/sh_mobile_lcdcfb.c
@@ -190,6 +190,7 @@ static int sh_mobile_lcdc_setup_clocks(struct platform_device *pdev,
int clock_source,
struct sh_mobile_lcdc_priv *priv)
{
+ struct clk *clk;
char *str;
switch (clock_source) {
@@ -209,21 +210,16 @@ static int sh_mobile_lcdc_setup_clocks(struct platform_device *pdev,
return -EINVAL;
}
- if (str) {
- priv->dot_clk = clk_get(&pdev->dev, str);
- if (IS_ERR(priv->dot_clk)) {
- dev_err(&pdev->dev, "cannot get dot clock %s\n", str);
- return PTR_ERR(priv->dot_clk);
- }
+ if (str = NULL)
+ return 0;
+
+ clk = clk_get(&pdev->dev, str);
+ if (IS_ERR(clk)) {
+ dev_err(&pdev->dev, "cannot get dot clock %s\n", str);
+ return PTR_ERR(clk);
}
- /* Runtime PM support involves two step for this driver:
- * 1) Enable Runtime PM
- * 2) Force Runtime PM Resume since hardware is accessed from probe()
- */
- priv->dev = &pdev->dev;
- pm_runtime_enable(priv->dev);
- pm_runtime_resume(priv->dev);
+ priv->dot_clk = clk;
return 0;
}
@@ -1514,11 +1510,10 @@ static int sh_mobile_lcdc_remove(struct platform_device *pdev)
sh_mobile_lcdc_bl_remove(priv->ch[i].bl);
}
- if (priv->dot_clk)
+ if (priv->dot_clk) {
+ pm_runtime_disable(&pdev->dev);
clk_put(priv->dot_clk);
-
- if (priv->dev)
- pm_runtime_disable(priv->dev);
+ }
if (priv->base)
iounmap(priv->base);
@@ -1741,6 +1736,8 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev)
return -ENOMEM;
}
+ priv->dev = &pdev->dev;
+ priv->meram_dev = pdata->meram_dev;
platform_set_drvdata(pdev, priv);
error = request_irq(i, sh_mobile_lcdc_irq, IRQF_DISABLED,
@@ -1806,7 +1803,8 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev)
goto err1;
}
- priv->meram_dev = pdata->meram_dev;
+ /* Enable runtime PM. */
+ pm_runtime_enable(&pdev->dev);
for (i = 0; i < num_channels; i++) {
struct sh_mobile_lcdc_chan *ch = priv->ch + i;
--
1.7.3.4
^ permalink raw reply related
* [WIP/RFC 02/31] fbdev: sh_mobile_lcdc: Mark init-only symbols with __devinit(const)
From: Laurent Pinchart @ 2011-09-19 0:27 UTC (permalink / raw)
To: linux-fbdev
default_720p and sh_mobile_lcdc_check_interface are used at device
initialization time only. Mark them as __devinitconst and __devinit
respectively.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
drivers/video/sh_mobile_lcdcfb.c | 5 +++--
1 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c
index cf57832..4a6bdc7 100644
--- a/drivers/video/sh_mobile_lcdcfb.c
+++ b/drivers/video/sh_mobile_lcdcfb.c
@@ -1460,7 +1460,7 @@ static int sh_mobile_lcdc_notify(struct notifier_block *nb,
* Probe/remove and driver init/exit
*/
-static const struct fb_videomode default_720p = {
+static const struct fb_videomode default_720p __devinitconst = {
.name = "HDMI 720p",
.xres = 1280,
.yres = 720,
@@ -1529,7 +1529,8 @@ static int sh_mobile_lcdc_remove(struct platform_device *pdev)
return 0;
}
-static int sh_mobile_lcdc_check_interface(struct sh_mobile_lcdc_chan *ch)
+static int __devinit
+sh_mobile_lcdc_check_interface(struct sh_mobile_lcdc_chan *ch)
{
int interface_type = ch->cfg.interface_type;
--
1.7.3.4
^ permalink raw reply related
* [WIP/RFC 01/31] fbdev: sh_mobile_lcdc: Reorder code into sections
From: Laurent Pinchart @ 2011-09-19 0:27 UTC (permalink / raw)
To: linux-fbdev
Make the driver more readable by reordering code and splitting it into
logical sections. Reorder the headers alphabetically.
No modification to the code have been performed.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
drivers/video/sh_mobile_lcdcfb.c | 409 +++++++++++++++++++++-----------------
1 files changed, 225 insertions(+), 184 deletions(-)
diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c
index 6e4c292..cf57832 100644
--- a/drivers/video/sh_mobile_lcdcfb.c
+++ b/drivers/video/sh_mobile_lcdcfb.c
@@ -8,25 +8,26 @@
* for more details.
*/
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/mm.h>
+#include <linux/atomic.h>
+#include <linux/backlight.h>
#include <linux/clk.h>
-#include <linux/pm_runtime.h>
-#include <linux/platform_device.h>
+#include <linux/console.h>
#include <linux/dma-mapping.h>
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/init.h>
#include <linux/interrupt.h>
-#include <linux/videodev2.h>
-#include <linux/vmalloc.h>
#include <linux/ioctl.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
#include <linux/slab.h>
-#include <linux/console.h>
-#include <linux/backlight.h>
-#include <linux/gpio.h>
+#include <linux/videodev2.h>
+#include <linux/vmalloc.h>
+
#include <video/sh_mobile_lcdc.h>
#include <video/sh_mobile_meram.h>
-#include <linux/atomic.h>
#include "sh_mobile_lcdcfb.h"
@@ -36,6 +37,24 @@
#define MAX_XRES 1920
#define MAX_YRES 1080
+struct sh_mobile_lcdc_priv {
+ void __iomem *base;
+ int irq;
+ atomic_t hw_usecnt;
+ struct device *dev;
+ struct clk *dot_clk;
+ unsigned long lddckr;
+ struct sh_mobile_lcdc_chan ch[2];
+ struct notifier_block notifier;
+ int started;
+ int forced_fourcc; /* 2 channel LCDC must share fourcc setting */
+ struct sh_mobile_meram_info *meram_dev;
+};
+
+/* -----------------------------------------------------------------------------
+ * Registers access
+ */
+
static unsigned long lcdc_offs_mainlcd[NR_CH_REGS] = {
[LDDCKPAT1R] = 0x400,
[LDDCKPAT2R] = 0x404,
@@ -74,38 +93,6 @@ static unsigned long lcdc_offs_sublcd[NR_CH_REGS] = {
[LDPMR] = 0x63c,
};
-static const struct fb_videomode default_720p = {
- .name = "HDMI 720p",
- .xres = 1280,
- .yres = 720,
-
- .left_margin = 220,
- .right_margin = 110,
- .hsync_len = 40,
-
- .upper_margin = 20,
- .lower_margin = 5,
- .vsync_len = 5,
-
- .pixclock = 13468,
- .refresh = 60,
- .sync = FB_SYNC_VERT_HIGH_ACT | FB_SYNC_HOR_HIGH_ACT,
-};
-
-struct sh_mobile_lcdc_priv {
- void __iomem *base;
- int irq;
- atomic_t hw_usecnt;
- struct device *dev;
- struct clk *dot_clk;
- unsigned long lddckr;
- struct sh_mobile_lcdc_chan ch[2];
- struct notifier_block notifier;
- int started;
- int forced_fourcc; /* 2 channel LCDC must share fourcc setting */
- struct sh_mobile_meram_info *meram_dev;
-};
-
static bool banked(int reg_nr)
{
switch (reg_nr) {
@@ -126,6 +113,11 @@ static bool banked(int reg_nr)
return false;
}
+static int lcdc_chan_is_sublcd(struct sh_mobile_lcdc_chan *chan)
+{
+ return chan->cfg.chan = LCDC_CHAN_SUBLCD;
+}
+
static void lcdc_write_chan(struct sh_mobile_lcdc_chan *chan,
int reg_nr, unsigned long data)
{
@@ -168,11 +160,77 @@ static void lcdc_wait_bit(struct sh_mobile_lcdc_priv *priv,
cpu_relax();
}
-static int lcdc_chan_is_sublcd(struct sh_mobile_lcdc_chan *chan)
+/* -----------------------------------------------------------------------------
+ * Clock management
+ */
+
+static void sh_mobile_lcdc_clk_on(struct sh_mobile_lcdc_priv *priv)
{
- return chan->cfg.chan = LCDC_CHAN_SUBLCD;
+ if (atomic_inc_and_test(&priv->hw_usecnt)) {
+ if (priv->dot_clk)
+ clk_enable(priv->dot_clk);
+ pm_runtime_get_sync(priv->dev);
+ if (priv->meram_dev && priv->meram_dev->pdev)
+ pm_runtime_get_sync(&priv->meram_dev->pdev->dev);
+ }
}
+static void sh_mobile_lcdc_clk_off(struct sh_mobile_lcdc_priv *priv)
+{
+ if (atomic_sub_return(1, &priv->hw_usecnt) = -1) {
+ if (priv->meram_dev && priv->meram_dev->pdev)
+ pm_runtime_put_sync(&priv->meram_dev->pdev->dev);
+ pm_runtime_put(priv->dev);
+ if (priv->dot_clk)
+ clk_disable(priv->dot_clk);
+ }
+}
+
+static int sh_mobile_lcdc_setup_clocks(struct platform_device *pdev,
+ int clock_source,
+ struct sh_mobile_lcdc_priv *priv)
+{
+ char *str;
+
+ switch (clock_source) {
+ case LCDC_CLK_BUS:
+ str = "bus_clk";
+ priv->lddckr = LDDCKR_ICKSEL_BUS;
+ break;
+ case LCDC_CLK_PERIPHERAL:
+ str = "peripheral_clk";
+ priv->lddckr = LDDCKR_ICKSEL_MIPI;
+ break;
+ case LCDC_CLK_EXTERNAL:
+ str = NULL;
+ priv->lddckr = LDDCKR_ICKSEL_HDMI;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ if (str) {
+ priv->dot_clk = clk_get(&pdev->dev, str);
+ if (IS_ERR(priv->dot_clk)) {
+ dev_err(&pdev->dev, "cannot get dot clock %s\n", str);
+ return PTR_ERR(priv->dot_clk);
+ }
+ }
+
+ /* Runtime PM support involves two step for this driver:
+ * 1) Enable Runtime PM
+ * 2) Force Runtime PM Resume since hardware is accessed from probe()
+ */
+ priv->dev = &pdev->dev;
+ pm_runtime_enable(priv->dev);
+ pm_runtime_resume(priv->dev);
+ return 0;
+}
+
+/* -----------------------------------------------------------------------------
+ * Sys panel and deferred I/O
+ */
+
static void lcdc_sys_write_index(void *handle, unsigned long data)
{
struct sh_mobile_lcdc_chan *ch = handle;
@@ -215,64 +273,6 @@ struct sh_mobile_lcdc_sys_bus_ops sh_mobile_lcdc_sys_bus_ops = {
lcdc_sys_read_data,
};
-static int sh_mobile_format_fourcc(const struct fb_var_screeninfo *var)
-{
- if (var->fourcc.fourcc > 1)
- return var->fourcc.fourcc;
-
- switch (var->bits_per_pixel) {
- case 16:
- return V4L2_PIX_FMT_RGB565;
- case 24:
- return V4L2_PIX_FMT_BGR24;
- case 32:
- return V4L2_PIX_FMT_BGR32;
- default:
- return 0;
- }
-}
-
-static bool sh_mobile_format_yuv(const struct fb_var_screeninfo *var)
-{
- if (var->fourcc.fourcc <= 1)
- return false;
-
- switch (var->fourcc.fourcc) {
- case V4L2_PIX_FMT_NV12:
- case V4L2_PIX_FMT_NV21:
- case V4L2_PIX_FMT_NV16:
- case V4L2_PIX_FMT_NV61:
- case V4L2_PIX_FMT_NV24:
- case V4L2_PIX_FMT_NV42:
- return true;
-
- default:
- return false;
- }
-}
-
-static void sh_mobile_lcdc_clk_on(struct sh_mobile_lcdc_priv *priv)
-{
- if (atomic_inc_and_test(&priv->hw_usecnt)) {
- if (priv->dot_clk)
- clk_enable(priv->dot_clk);
- pm_runtime_get_sync(priv->dev);
- if (priv->meram_dev && priv->meram_dev->pdev)
- pm_runtime_get_sync(&priv->meram_dev->pdev->dev);
- }
-}
-
-static void sh_mobile_lcdc_clk_off(struct sh_mobile_lcdc_priv *priv)
-{
- if (atomic_sub_return(1, &priv->hw_usecnt) = -1) {
- if (priv->meram_dev && priv->meram_dev->pdev)
- pm_runtime_put_sync(&priv->meram_dev->pdev->dev);
- pm_runtime_put(priv->dev);
- if (priv->dot_clk)
- clk_disable(priv->dot_clk);
- }
-}
-
static int sh_mobile_lcdc_sginit(struct fb_info *info,
struct list_head *pagelist)
{
@@ -339,6 +339,50 @@ static void sh_mobile_lcdc_deferred_io_touch(struct fb_info *info)
schedule_delayed_work(&info->deferred_work, fbdefio->delay);
}
+/* -----------------------------------------------------------------------------
+ * Format helpers
+ */
+
+static int sh_mobile_format_fourcc(const struct fb_var_screeninfo *var)
+{
+ if (var->fourcc.fourcc > 1)
+ return var->fourcc.fourcc;
+
+ switch (var->bits_per_pixel) {
+ case 16:
+ return V4L2_PIX_FMT_RGB565;
+ case 24:
+ return V4L2_PIX_FMT_BGR24;
+ case 32:
+ return V4L2_PIX_FMT_BGR32;
+ default:
+ return 0;
+ }
+}
+
+static bool sh_mobile_format_yuv(const struct fb_var_screeninfo *var)
+{
+ if (var->fourcc.fourcc <= 1)
+ return false;
+
+ switch (var->fourcc.fourcc) {
+ case V4L2_PIX_FMT_NV12:
+ case V4L2_PIX_FMT_NV21:
+ case V4L2_PIX_FMT_NV16:
+ case V4L2_PIX_FMT_NV61:
+ case V4L2_PIX_FMT_NV24:
+ case V4L2_PIX_FMT_NV42:
+ return true;
+
+ default:
+ return false;
+ }
+}
+
+/* -----------------------------------------------------------------------------
+ * Start, stop and IRQ
+ */
+
static irqreturn_t sh_mobile_lcdc_irq(int irq, void *data)
{
struct sh_mobile_lcdc_priv *priv = data;
@@ -784,86 +828,9 @@ static void sh_mobile_lcdc_stop(struct sh_mobile_lcdc_priv *priv)
sh_mobile_lcdc_clk_off(priv);
}
-static int sh_mobile_lcdc_check_interface(struct sh_mobile_lcdc_chan *ch)
-{
- int interface_type = ch->cfg.interface_type;
-
- switch (interface_type) {
- case RGB8:
- case RGB9:
- case RGB12A:
- case RGB12B:
- case RGB16:
- case RGB18:
- case RGB24:
- case SYS8A:
- case SYS8B:
- case SYS8C:
- case SYS8D:
- case SYS9:
- case SYS12:
- case SYS16A:
- case SYS16B:
- case SYS16C:
- case SYS18:
- case SYS24:
- break;
- default:
- return -EINVAL;
- }
-
- /* SUBLCD only supports SYS interface */
- if (lcdc_chan_is_sublcd(ch)) {
- if (!(interface_type & LDMT1R_IFM))
- return -EINVAL;
-
- interface_type &= ~LDMT1R_IFM;
- }
-
- ch->ldmt1r_value = interface_type;
- return 0;
-}
-
-static int sh_mobile_lcdc_setup_clocks(struct platform_device *pdev,
- int clock_source,
- struct sh_mobile_lcdc_priv *priv)
-{
- char *str;
-
- switch (clock_source) {
- case LCDC_CLK_BUS:
- str = "bus_clk";
- priv->lddckr = LDDCKR_ICKSEL_BUS;
- break;
- case LCDC_CLK_PERIPHERAL:
- str = "peripheral_clk";
- priv->lddckr = LDDCKR_ICKSEL_MIPI;
- break;
- case LCDC_CLK_EXTERNAL:
- str = NULL;
- priv->lddckr = LDDCKR_ICKSEL_HDMI;
- break;
- default:
- return -EINVAL;
- }
-
- if (str) {
- priv->dot_clk = clk_get(&pdev->dev, str);
- if (IS_ERR(priv->dot_clk)) {
- dev_err(&pdev->dev, "cannot get dot clock %s\n", str);
- return PTR_ERR(priv->dot_clk);
- }
- }
-
- /* Runtime PM support involves two step for this driver:
- * 1) Enable Runtime PM
- * 2) Force Runtime PM Resume since hardware is accessed from probe()
- */
- priv->dev = &pdev->dev;
- pm_runtime_enable(priv->dev);
- pm_runtime_resume(priv->dev);
- return 0;
-}
+/* -----------------------------------------------------------------------------
+ * Frame buffer operations
+ */
static int sh_mobile_lcdc_setcolreg(u_int regno,
u_int red, u_int green, u_int blue,
@@ -1335,6 +1302,10 @@ static struct fb_ops sh_mobile_lcdc_ops = {
.fb_set_par = sh_mobile_set_par,
};
+/* -----------------------------------------------------------------------------
+ * Backlight
+ */
+
static int sh_mobile_lcdc_update_bl(struct backlight_device *bdev)
{
struct sh_mobile_lcdc_chan *ch = bl_get_data(bdev);
@@ -1394,6 +1365,10 @@ static void sh_mobile_lcdc_bl_remove(struct backlight_device *bdev)
backlight_device_unregister(bdev);
}
+/* -----------------------------------------------------------------------------
+ * Power management
+ */
+
static int sh_mobile_lcdc_suspend(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
@@ -1437,6 +1412,10 @@ static const struct dev_pm_ops sh_mobile_lcdc_dev_pm_ops = {
.runtime_resume = sh_mobile_lcdc_runtime_resume,
};
+/* -----------------------------------------------------------------------------
+ * Framebuffer notifier
+ */
+
/* locking: called with info->lock held */
static int sh_mobile_lcdc_notify(struct notifier_block *nb,
unsigned long action, void *data)
@@ -1477,6 +1456,28 @@ static int sh_mobile_lcdc_notify(struct notifier_block *nb,
return NOTIFY_OK;
}
+/* -----------------------------------------------------------------------------
+ * Probe/remove and driver init/exit
+ */
+
+static const struct fb_videomode default_720p = {
+ .name = "HDMI 720p",
+ .xres = 1280,
+ .yres = 720,
+
+ .left_margin = 220,
+ .right_margin = 110,
+ .hsync_len = 40,
+
+ .upper_margin = 20,
+ .lower_margin = 5,
+ .vsync_len = 5,
+
+ .pixclock = 13468,
+ .refresh = 60,
+ .sync = FB_SYNC_VERT_HIGH_ACT | FB_SYNC_HOR_HIGH_ACT,
+};
+
static int sh_mobile_lcdc_remove(struct platform_device *pdev)
{
struct sh_mobile_lcdc_priv *priv = platform_get_drvdata(pdev);
@@ -1528,6 +1529,46 @@ static int sh_mobile_lcdc_remove(struct platform_device *pdev)
return 0;
}
+static int sh_mobile_lcdc_check_interface(struct sh_mobile_lcdc_chan *ch)
+{
+ int interface_type = ch->cfg.interface_type;
+
+ switch (interface_type) {
+ case RGB8:
+ case RGB9:
+ case RGB12A:
+ case RGB12B:
+ case RGB16:
+ case RGB18:
+ case RGB24:
+ case SYS8A:
+ case SYS8B:
+ case SYS8C:
+ case SYS8D:
+ case SYS9:
+ case SYS12:
+ case SYS16A:
+ case SYS16B:
+ case SYS16C:
+ case SYS18:
+ case SYS24:
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /* SUBLCD only supports SYS interface */
+ if (lcdc_chan_is_sublcd(ch)) {
+ if (!(interface_type & LDMT1R_IFM))
+ return -EINVAL;
+
+ interface_type &= ~LDMT1R_IFM;
+ }
+
+ ch->ldmt1r_value = interface_type;
+ return 0;
+}
+
static int __devinit sh_mobile_lcdc_channel_init(struct sh_mobile_lcdc_chan *ch,
struct device *dev)
{
--
1.7.3.4
^ permalink raw reply related
* [WIP/RFC 00/31] sh_mobile_lcdc: Media controller prototype
From: Laurent Pinchart @ 2011-09-19 0:27 UTC (permalink / raw)
To: linux-fbdev
Hi everybody,
I've tried to clean up the sh_mobile_lcdcfb driver and the associated HDMI and
MIPI transmitters drivers.
Both transmitter drivers hook up into the LCDC driver by hijacking the display
on/off operations pointers transparently, and accessing the LCDC fb_info
structure directly. Beside not being clean and very reusable, that approach is
prone to race conditions. In other words, I don't really like it.
With my V4L background, I've tried to implement a proof of concept of "fbdev
entities", currently limited to the sh_mobile_lcdcfb driver (hence the struct
sh_mobile_lcdc_entity instead of struct fb_entity). Here's the result, with an
implementation of the media controller API as the icing on the cake.
The idea behind those patches it to isolate the SH mobile HDMI and MIPI
transmitters drivers from the LCDC driver. To achieve this, the transmitters
create a struct sh_mobile_lcdc_entity instance and fill it with pointers to
abstract operations. The LCDC driver gets hold of a pointer to the associated
sh_mobile_lcdc_entity through platform data (this currently relies on probe
order and probably needs to be cleaned up), and calls those abstract operations
to control the display. It also fills the entity structure with a pointer to
itself (this should be replaced by an abstract fb_host/fb_master/fb_something)
to provide the transmitter drivers with a notification callback.
The last 6 patches implement the media controller API on top of that. The result
is the ability for userspace applications to discover the internal device
topology. Two (rather unimpressive :-)) topology examples generated
automatically can be found at http://www.ideasonboard.org/media/lcdc0.ps and
http://www.ideasonboard.org/media/lcdc1.ps. With more complex hardware (or with
support for more complex hardware features such as multiple overlays in the
sh_mobile_lcdcfb driver), the MC API will allow discovering overlays and other
hardware blocks, which is the first step required to control them.
Comments will be very warmly welcomed (provided that you don't start a flame
war :-)).
Laurent Pinchart (31):
fbdev: sh_mobile_lcdc: Reorder code into sections
fbdev: sh_mobile_lcdc: Mark init-only symbols with __devinit(const)
fbdev: sh_mobile_lcdc: Move pm runtime enable to probe()
fbdev: sh_mobile_lcdc: Don't pass struct device around
fbdev: sh_mobile_lcdc: Create functions to turn the display on/off
sh_mobile_hdmi: Remove platform data lcd_dev field
fbdev: sh_mobile_lcdc: Add sh_mobile_lcdc_entity definition
fbdev: sh_mobile_hdmi: Implement sh_mobile_lcdc_entity interface
fbdev: sh_mipi_dsi: Implement sh_mobile_lcdc_entity interface
fbdev: sh_mobile_lcdc: Handle HDMI/MIPI transmitter device directly
arm: mach-shmobile: Add LCDC tx_dev field to platform data
fbdev: sh_mipi_dsi: Don't hook up into board_cfg display operations
fbdev: sh_mobile_hdmi: Don't hook up into board_cfg display
operations
arm: mach-shmobile: Don't initialize the hdmi_info lcd_chan field
fbdev: sh_mobile_hdmi: Remove sh_mobile_hdmi_info lcd_chan field
fbdev: sh_mobile_lcdc: Remove board configuration owner field
fbdev: sh_mobile_lcdc: Remove board configuration board_data field
fbdev: sh_mobile_lcdc: Move brightness ops to sh_mobile_lcdc_bl_info
fbdev: sh_mobile_lcdc: Merge board_cfg and lcd_size_cfg into
panel_cfg
sh_mobile_lcdc: Add an lcdc channel pointer to sh_mobile_lcdc_entity
sh_mobile_hdmi: Use sh_mobile_lcdc_entity::channel to access fb_info
fbdev: sh_mobile_lcdc: Remove fb_info parameter to display_on
operation
fbdev: sh_mobile_lcdc: Return display connection state in display_on
sh_mobile_lcdc: Add display notify callback to sh_mobile_lcdc_chan
sh_mobile_hdmi: Use LCDC notification callback
media: Initialize media controller core with subsys_initcall
fbdev: Add media controller support
fbdev: sh_mobile_lcdc: Make LCDC entity inherit from media_entity
fbdev: sh_mipi_dsi: Add media controller support
fbdev: sh_mobile_hdmi: Add media controller support
fbdev: sh_mobile_lcdc: Add media controller support
arch/arm/mach-shmobile/board-ag5evm.c | 20 +-
arch/arm/mach-shmobile/board-ap4evb.c | 278 +++++-----
arch/arm/mach-shmobile/board-mackerel.c | 78 ++--
arch/sh/boards/mach-ap325rxa/setup.c | 18 +-
arch/sh/boards/mach-ecovec24/setup.c | 12 +-
arch/sh/boards/mach-kfr2r09/lcd_wqvga.c | 10 +-
arch/sh/boards/mach-kfr2r09/setup.c | 4 +-
arch/sh/boards/mach-migor/lcd_qvga.c | 3 +-
arch/sh/boards/mach-migor/setup.c | 8 +-
arch/sh/boards/mach-se/7724/setup.c | 4 +-
arch/sh/include/mach-kfr2r09/mach/kfr2r09.h | 16 +-
arch/sh/include/mach-migor/mach/migor.h | 2 +-
drivers/media/media-devnode.c | 4 +-
drivers/video/Kconfig | 1 +
drivers/video/fbmem.c | 21 +
drivers/video/fbsysfs.c | 11 +
drivers/video/sh_mipi_dsi.c | 72 ++--
drivers/video/sh_mobile_hdmi.c | 226 ++------
drivers/video/sh_mobile_lcdcfb.c | 744 ++++++++++++++++++---------
drivers/video/sh_mobile_lcdcfb.h | 41 ++-
include/linux/fb.h | 8 +
include/video/sh_mobile_hdmi.h | 2 -
include/video/sh_mobile_lcdc.h | 29 +-
23 files changed, 900 insertions(+), 712 deletions(-)
--
Regards,
Laurent Pinchart
^ permalink raw reply
* Re: Proposal for a low-level Linux display framework
From: Rob Clark @ 2011-09-19 0:09 UTC (permalink / raw)
To: Alan Cox
Cc: Laurent Pinchart, Keith Packard, linaro-dev,
Florian Tobias Schandinat, linux-kernel, dri-devel, Archit Taneja,
linux-fbdev, Alex Deucher
In-Reply-To: <20110918232329.6ff05d56@lxorguk.ukuu.org.uk>
On Sun, Sep 18, 2011 at 5:23 PM, Alan Cox <alan@lxorguk.ukuu.org.uk> wrote:
>> This would leave us with the issue of controlling formats and other parameters
>> on the pipelines. We could keep separate DRM, KMS, FB and V4L APIs for that,
>
> There are some other differences that matter. The exact state and
> behaviour of memory, sequencing of accesses, cache control and management
> are a critical part of DRM for most GPUs, as is the ability to have them
> in swap backed objects and to do memory management of them. Fences and
> the like are a big part of the logic of many renderers and the same
> fencing has to be applied between capture and GPU, and also in some cases
> between playback accelerators (eg MP4 playback) and GPU.
>
> To glue them together I think you'd need to support the use of GEM objects
> (maybe extended) in V4L. That may actually make life cleaner and simpler
> in some respects because GEM objects are refcounted nicely and have
> handles.
fwiw, I think the dmabuf proposal that linaro GWG is working on should
be sufficient for V4L to capture directly into a GEM buffer that can
be scanned out (overlay) or composited by GPU, etc, in cases where the
different dma initiators can all access some common memory:
http://lists.linaro.org/pipermail/linaro-mm-sig/2011-September/000616.html
The idea is that you could allocate a GEM buffer, export a dmabuf
handle for that buffer that could be passed to v4l2 camera device (ie.
V4L2_MEMORY_DMABUF), video encoder, etc.. the importing device should
bracket DMA to/from the buffer w/ get/put_scatterlist() so an unused
buffer could be unpinned if needed.
> DRM and KMS abstract out stuff into what is akin to V4L subdevices for
> the various objects the video card has that matter for display - from
> scanout buffers to the various video outputs, timings and the like.
>
> I don't know what it's like with OMAP but for some of the x86 stuff
> particularly low speed/power stuff the capture devices, GPU and overlays
> tend to be fairly incestuous in order to do things like 1080i/p preview
> while recording from the camera.
We don't like extra memcpy's, but something like dmabuf fits us
nicely.. and I expect it would work well in any sort of UMA system
where camera, encoder, GPU, overlay, etc all can share the same memory
and formats. I suspect the situation is similar in the x86 SoC
world.. but would be good to get some feedback on the proposal. (I
guess next version of the RFC would go out to more mailing lists for
broader review.)
BR,
-R
> GPU is also a bit weird in some ways because while its normally
> nonsensical to do things like use the capture facility one card to drive
> part of another, it's actually rather useful (although not supported
> really by DRM) to do exactly that with GPUs. A simple example is a dual
> headed box with a dumb frame buffer and an accelerated output both of
> which are using memory that can be hit by the accelerated card. Classic
> example being a USB plug in monitor.
>
> _______________________________________________
> linaro-dev mailing list
> linaro-dev@lists.linaro.org
> http://lists.linaro.org/mailman/listinfo/linaro-dev
>
^ permalink raw reply
* Re: Proposal for a low-level Linux display framework
From: Alan Cox @ 2011-09-18 22:23 UTC (permalink / raw)
To: Laurent Pinchart
Cc: Keith Packard, linaro-dev-cunTk1MwBs8s++Sfvej+rw,
Florian Tobias Schandinat, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW, Archit Taneja,
linux-fbdev-u79uwXL29TY76Z2rM5mHXA, Alex Deucher
In-Reply-To: <201109180112.15896.laurent.pinchart-ryLnwIuWjnjg/C1BVhZhaw@public.gmane.org>
> This would leave us with the issue of controlling formats and other parameters
> on the pipelines. We could keep separate DRM, KMS, FB and V4L APIs for that,
There are some other differences that matter. The exact state and
behaviour of memory, sequencing of accesses, cache control and management
are a critical part of DRM for most GPUs, as is the ability to have them
in swap backed objects and to do memory management of them. Fences and
the like are a big part of the logic of many renderers and the same
fencing has to be applied between capture and GPU, and also in some cases
between playback accelerators (eg MP4 playback) and GPU.
To glue them together I think you'd need to support the use of GEM objects
(maybe extended) in V4L. That may actually make life cleaner and simpler
in some respects because GEM objects are refcounted nicely and have
handles.
DRM and KMS abstract out stuff into what is akin to V4L subdevices for
the various objects the video card has that matter for display - from
scanout buffers to the various video outputs, timings and the like.
I don't know what it's like with OMAP but for some of the x86 stuff
particularly low speed/power stuff the capture devices, GPU and overlays
tend to be fairly incestuous in order to do things like 1080i/p preview
while recording from the camera.
GPU is also a bit weird in some ways because while its normally
nonsensical to do things like use the capture facility one card to drive
part of another, it's actually rather useful (although not supported
really by DRM) to do exactly that with GPUs. A simple example is a dual
headed box with a dumb frame buffer and an accelerated output both of
which are using memory that can be hit by the accelerated card. Classic
example being a USB plug in monitor.
^ permalink raw reply
* Re: Proposal for a low-level Linux display framework
From: Laurent Pinchart @ 2011-09-18 21:55 UTC (permalink / raw)
To: Rob Clark
Cc: linux-fbdev, linaro-dev, Florian Tobias Schandinat, linux-kernel,
dri-devel, Archit Taneja, Sakari Ailus, linux-media
In-Reply-To: <CAF6AEGs0vkL2HLWcihX-h8JPiEVj5nHjzdWie1oUaoDibEONHg@mail.gmail.com>
Hi Rob,
(CC'ing linux-media, as I believe this is very on-topic)
On Sunday 18 September 2011 18:14:26 Rob Clark wrote:
> On Sat, Sep 17, 2011 at 6:12 PM, Laurent Pinchart wrote:
> > On Thursday 15 September 2011 20:39:21 Florian Tobias Schandinat wrote:
> >> On 09/15/2011 05:52 PM, Alex Deucher wrote:
> >> > Please don't claim that the DRM developers do not want to cooperate.
> >> > I realize that people have strong opinions about existing APIs, put
> >> > there has been just as much, if not more obstinacy from the v4l and fb
> >> > people.
> >>
> >> Well, I think it's too late to really fix this thing. We now have 3 APIs
> >> in the kernel that have to be kept. Probably the best we can do now is
> >> figure out how we can reduce code duplication and do extensions to
> >> those APIs in a way that they are compatible with each other or
> >> completely independent and can be used across the APIs.
> >
> > Sorry for jumping late into the discussion. Let me try to shed some new
> > light on this.
> >
> > I've been thinking about the DRM/KMS/FB/V4L APIs overlap for quite some
> > time now. All of them have their share of issues, historical nonsense
> > and unique features. I don't think we can pick one of those APIs today
> > and decide to drop the others, but we certainly need to make DRM, KMS,
> > FB and V4L interoperable at various levels. The alternative is to keep
> > ignoring each other and let the market decice.
>
> I think we need to differentiate between V4L camera, and display..
>
> MC and subdev stuff clearly seem to be the way to go for complex
> camera / imaging subsystems. But that is a very different problem
> domain from GPU+display. We need to stop blurring the two topics.
I would agree with you if we were only talking about GPU, but display is
broader than that. Many hardware available today have complex display
pipelines with "deep tunneling" between other IP blocks (such as the camera
subsystem) and the display. Configuration of such pipelines isn't specific to
DRM/KMS.
> > Thinking that the market could pick something like OpenMAX
> > scares me, so I'd rather find a good compromise and move forward.
> >
> > Disclaimer: My DRM/KMS knowledge isn't as good as my FB and V4L
> > knowledge, so please feel free to correct my mistakes.
> >
> > All our video-related APIs started as solutions to different problems.
> > They all share an important feature: they assume that the devices they
> > control is more or less monolithic. For that reason they expose a single
> > device to userspace, and mix device configuration and data transfer on
> > the same device node.
> >
> > This shortcoming became painful in V4L a couple of years ago. When I
> > started working on the OMAP3 ISP (camera) driver I realized that trying
> > to configure a complex hardware pipeline without exposing its internals
> > to userspace applications wouldn't be possible. DRM, KMS and FB ran into
> > the exact same problem, just more recently, as showed by various RFCs
> > ([1], [2]).
>
> But I do think that overlays need to be part of the DRM/KMS interface,
> simply because flipping still needs to be synchronized w/ the GPU. I
> have some experience using V4L for display, and this is one (of
> several) broken aspects of that.
I agree that DRM/KMS must be used to address needs specific to display
hardware, but I don't think *all* display needs are specific to the display.
> > To fix this issue, the V4L community developed a new API called the Media
> > Controller [3]. In a nutshell, the MC aims at
> >
> > - exposing the device topology to userspace as an oriented graph of
> > entities connected with links through pads
> >
> > - controlling the device topology from userspace by enabling/disabling
> > links
> >
> > - giving userspace access to per-entity controls
> >
> > - configuring formats at individual points in the pipeline from
> > userspace.
> >
> > The MC API solves the first two problems. The last two require help from
> > V4L (which has been extended with new MC-aware ioctls), as MC is
> > media-agnostic and can't thus configure video formats.
> >
> > To support this, the V4L subsystem exposes an in-kernel API based around
> > the concept of sub-devices. A single high-level hardware device is
> > handled by multiple sub-devices, possibly controlled by different
> > drivers. For instance, in the OMAP3-based N900 digital camera, the OMAP3
> > ISP is made of 8 sub-devices (all controlled by the OMAP3 ISP driver),
> > and the two sensors, flash controller and lens controller all have their
> > own sub-device, each of them controlled by its own driver.
> >
> > All this infrastructure exposes the devices a the graph showed in [4] to
> > applications, and the V4L sub-device API can be used to set formats at
> > individual pads. This allows controlling scaling, cropping, composing and
> > other video-related operations on the pipeline.
> >
> > With the introduction of the media controller architecture, I now see V4L
> > as being made of three parts.
> >
> > 1. The V4L video nodes streaming API, used to manage video buffers
> > memory, map it to userspace, and control video streaming (and data
> > transfers).
> >
> > 2. The V4L sub-devices API, used to control parameters on individual
> > entities in the graph and configure formats.
> >
> > 3. The V4L video nodes formats and control API, used to perform the same
> > tasks as the V4L sub-devices API for drivers that don't support the
> > media controller API, or to provide support for pure V4L applications
> > with drivers that support the media controller API.
> >
> > V4L is made of those three parts, but I believe it helps to think about
> > them individually. With today's (and tomorrow's) devices, DRM, KMS and
> > FB are in a situation similar to what V4L experienced a couple of years
> > ago. They need to give control of complex pipelines to userspace, and I
> > believe this should be done by (logically) splitting DRM, KMS and FB
> > into a pipeline control part and a data flow part, as we did with V4L.
> >
> > Keeping the monolithic device model and handling pipeline control without
> > exposing the pipeline topology would in my opinion be a mistake. Even if
> > this could support today's hardware, I don't think it would be
> > future-proof. I would rather see the DRM, KMS and FB topologies being
> > exposed to applications by implementing the MC API in DRM, KMS and FB
> > drivers. I'm working on a proof of concept for the FB sh_mobile_lcdc
> > driver and will post patches soon. Something similar can be done for DRM
> > and KMS.
> >
> > This would leave us with the issue of controlling formats and other
> > parameters on the pipelines. We could keep separate DRM, KMS, FB and V4L
> > APIs for that, but would it really make sense ? I don't think so.
> > Obviously I would be happy to use the V4L API, as we already have a
> > working solution :-) I don't see that as being realistic though, we will
> > probably need to create a central graphics- related API here (possibly
> > close to what we already have in V4L if it can fulfil everybody's
> > needs).
> >
> > To paraphrase Alan, in my semi-perfect world vision the MC API would be
> > used to expose hardware pipelines to userspace, a common graphics API
> > would be used to control parameters on the pipeline shared by DRM, KMS,
> > FB and V4L, the individual APIs would control subsystem-specific
> > parameters and DRM, KMS, FB and V4L would be implemented on top of this
> > to manage memory, command queues and data transfers.
>
> I guess in theory it would be possible to let MC iterate the
> plane->crtc->encoder->connector topology.. I'm not entirely sure what
> benefit that would bring, other than change for the sake of change.
The MC API has been designed to expose pipeline topologies to userspace. In
the plane->crtc->encoder->connector case, DRM/KMS is probably enough. However,
many pipelines can't be described so simply. Reinventing the wheel doesn't
look like the best solution to me.
> V4L and DRM are very different APIs designed to solves very different
> problems. The KMS / mode-setting part may look somewhat similar to
> something you can express w/ a camera-like graph of nodes. But the
> memory management is very different. And display updates (like page
> flipping) need to be synchronized w/ GPU rendering.. etc. Trying to
> fit V4L here, just seems like trying to force a square peg in a round
> hole. You'd have to end up morphing V4L so much that in the end it
> looks like DRM. And that might not be the right thing for cameras.
>
> So V4L for camera, DRM for gpu/display. Those are the two APIs we need.
That's why I'm not advocating replacing DRM with V4L :-)
As explained in my previous mail, V4L and DRM started as monolithic APIs to
solve different needs. We now realize that they're actually made (or should be
made) of several sub-APIs. In the V4L case, that's pipeline discovery,
pipeline setup, format configuration (at the pad level in the pipeline,
including cropping, scaling and composing), controls (at the entity and/or pad
level in the pipeline), memory management and stream control (there are a
couple of other tasks we can add, but that's the basic idea). Some of those
tasks need to be performed for display hardware as well, and I believe we
should standardize a cross-subsystem (DRM, FB and V4L) API there. All the
display-specific needs that DRM has been designed to handle should continue to
be handled by DRM, I have no doubt about that.
To summarize my point, I don't want to fit V4L in DRM, but I would like to
find out which needs are common between V4L and DRM, and see if we can share
an API there.
--
Regards,
Laurent Pinchart
^ permalink raw reply
* Re: [PATCH v3 0/3] fbdev: Add FOURCC-based format configuration API
From: Laurent Pinchart @ 2011-09-18 20:49 UTC (permalink / raw)
To: Florian Tobias Schandinat
Cc: linux-fbdev, linux-media, magnus.damm, Mauro Carvalho Chehab
In-Reply-To: <4E764B35.2090009@gmx.de>
Hi Florian,
On Sunday 18 September 2011 21:49:09 Florian Tobias Schandinat wrote:
> Hi all,
>
> as there was no reaction to this patch series I am scheduling it for 3.3
> merge window (3.2 seems too close to me as this is an API change).
That's fine with me.
> As the second patch has nothing to do with fbdev it should go mainline via
> V4L2. Any problems/comments?
The NV24/42 patch will need to reach mainline before the sh_mobile_lcdc YUV
API patch, or compilation will break.
Mauro, what's your preference ? Should the patch go through the media tree ?
If so, how should we synchronize it with the fbdev tree ? Should I push it to
3.2 ?
--
Regards,
Laurent Pinchart
^ permalink raw reply
* Re: [PATCH 0/2] video: s3c-fb: Add window positioning support
From: Laurent Pinchart @ 2011-09-18 20:39 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <4E7646B5.6000000@gmx.de>
Hi Florian,
On Sunday 18 September 2011 21:29:57 Florian Tobias Schandinat wrote:
> On 09/07/2011 03:31 PM, Laurent Pinchart wrote:
> > On Thursday 01 September 2011 18:45:18 Florian Tobias Schandinat wrote:
> >> On 08/25/2011 07:51 PM, Ajay Kumar wrote:
> >>> Just as a note, there are many drivers like mx3fb.c, au1200fb.c and
> >>> OMAP seem to be doing window/plane positioning in their driver code.
> >>> Is it possible to have this window positioning support at a common
> >>> place?
> >>
> >> Good point. Congratulations for figuring out that I like to standardize
> >> things. But I think your suggestion is far from being enough to be
> >> useful for userspace (which is our goal so that applications can be
> >> reused along drivers and don't need to know about individual drivers).
> >
> > Beside standardizing things, do you also like to take them one level
> > higher to solve challenging issues ? I know the answer must be yes :-)
> >
> > The problem at hand here is something we have solved in V4L2
> > (theoretically only for part of it) with the media controller API, the
> > V4L2 subdevs and their pad-level format API.
> >
> > In a nutshell, the media controller lets drivers model hardware as a
> > graph of buliding blocks connected through their pads and expose that
> > description to userspace applications. In V4L2 most of those blocks are
> > V4L2 subdevs, which are abstract building blocks that implement sets of
> > standard operations. Those operations are exposed to userspace through
> > the V4L2 subdevs pad-level format API, allowing application to configure
> > sizes and selection rectangles at all pads in the graph. Selection
> > rectangles can be used to configure cropping and composing, which is
> > exactly what the window positioning API needs to do.
> >
> > Instead of creating a new fbdev-specific API to do the same, shouldn't we
> > try to join forces ?
>
> Okay, thanks for the pointer. After having a look at your API I understand
> that it would solve the problem to discover how many windows (in this
> case) are there and how they can be accessed. It looks fine for this
> purpose, powerful enough and not too complex. So if I get it correct we
> still need at least a way to configure the position of the
> windows/overlays/sink pads similar to what Ajay proposed.
Yes, the media controller API can only expose the topology to userspace, it
can't be used to configure FB-specific parameters on the pipeline.
> Additionally a way to get and/or set the z-position of the overlays if
> multiple overlays overlap and set/get how the overlays work (overdraw,
> constant alpha, source/destination color keying). Normally I'd consider
> these link properties but I think implementing them as properties of the
> source framebuffer or sink pad would work as well.
> Is this correct or did I miss something?
That's correct.
What bothers me is that both V4L2 and DRM/KMS have the exact same needs. I
don't think it makes sense to implement three different solutions to the same
problem in our three video-related APIs. What's your opinion about that ?
I've tried to raise the issue on the dri-devel mailing list ("Proposal for a
low-level Linux display framework"), but there's still a long way to go before
convincing everybody. Feel free to help me :-)
--
Regards,
Laurent Pinchart
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox