* [PATCH 08/10] video: da8xx-fb: store struct device *
From: Afzal Mohammed @ 2012-12-07 11:56 UTC (permalink / raw)
To: Florian Tobias Schandinat, Tomi Valkeinen
Cc: Vaibhav Hiremath, Sekhar Nori, linux-fbdev, linux-kernel,
Afzal Mohammed
In-Reply-To: <cover.1354874432.git.afzal@ti.com>
store struct device pointer so that dev_dbg/err can be used outside
of probe.
Signed-off-by: Afzal Mohammed <afzal@ti.com>
---
drivers/video/da8xx-fb.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
index 19ee560..663b3c5 100644
--- a/drivers/video/da8xx-fb.c
+++ b/drivers/video/da8xx-fb.c
@@ -154,6 +154,7 @@ static inline void lcdc_write(unsigned int val, unsigned int addr)
}
struct da8xx_fb_par {
+ struct device *dev;
resource_size_t p_palette_base;
unsigned char *v_palette_base;
dma_addr_t vram_phys;
@@ -1295,6 +1296,7 @@ static int __devinit fb_probe(struct platform_device *device)
}
par = da8xx_fb_info->par;
+ par->dev = &device->dev;
par->lcdc_clk = fb_clk;
par->lcd_fck_rate = clk_get_rate(fb_clk);
if (fb_pdata->panel_power_ctrl) {
--
1.7.12
^ permalink raw reply related
* [PATCH 07/10] video: da8xx-fb: pix clk and clk div handling cleanup
From: Afzal Mohammed @ 2012-12-07 11:56 UTC (permalink / raw)
To: Florian Tobias Schandinat, Tomi Valkeinen
Cc: Vaibhav Hiremath, Sekhar Nori, linux-fbdev, linux-kernel,
Afzal Mohammed
In-Reply-To: <cover.1354874432.git.afzal@ti.com>
Use the new modedb field to store pix clk. Reorganize existing clock
divider functions with names now corresponding to what they do, add
common function prefix.
Fix existing panel modedb pixclock to be in ps instead of Hz. This
needed a change in the way clock divider is calculated. As modedb
pixclock information is now in ps, override on "var" pixclock over
modedb to var conversion is removed.
Signed-off-by: Afzal Mohammed <afzal@ti.com>
---
drivers/video/da8xx-fb.c | 48 ++++++++++++++++++------------------------------
1 file changed, 18 insertions(+), 30 deletions(-)
diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
index e858438..19ee560 100644
--- a/drivers/video/da8xx-fb.c
+++ b/drivers/video/da8xx-fb.c
@@ -164,7 +164,6 @@ struct da8xx_fb_par {
struct clk *lcdc_clk;
int irq;
unsigned int palette_sz;
- unsigned int pxl_clk;
int blank;
wait_queue_head_t vsync_wait;
int vsync_flag;
@@ -205,7 +204,7 @@ static struct fb_videomode known_lcd_panels[] = {
.name = "Sharp_LCD035Q3DG01",
.xres = 320,
.yres = 240,
- .pixclock = 4608000,
+ .pixclock = 217014,
.left_margin = 6,
.right_margin = 8,
.upper_margin = 2,
@@ -220,7 +219,7 @@ static struct fb_videomode known_lcd_panels[] = {
.name = "Sharp_LK043T1DG01",
.xres = 480,
.yres = 272,
- .pixclock = 7833600,
+ .pixclock = 127655,
.left_margin = 2,
.right_margin = 2,
.upper_margin = 2,
@@ -235,7 +234,7 @@ static struct fb_videomode known_lcd_panels[] = {
.name = "SP10Q010",
.xres = 320,
.yres = 240,
- .pixclock = 7833600,
+ .pixclock = 127655,
.left_margin = 10,
.right_margin = 10,
.upper_margin = 10,
@@ -684,13 +683,14 @@ static void da8xx_fb_lcd_reset(void)
}
}
-static void lcd_calc_clk_divider(struct da8xx_fb_par *par)
+static inline unsigned da8xx_fb_calc_clk_divider(struct da8xx_fb_par *par,
+ unsigned pixclock)
{
- unsigned int lcd_clk, div;
-
- lcd_clk = clk_get_rate(par->lcdc_clk);
- div = lcd_clk / par->pxl_clk;
+ return par->lcd_fck_rate / (PICOS2KHZ(pixclock) * 1000);
+}
+static inline void da8xx_fb_config_clk_divider(unsigned div)
+{
/* Configure the LCD clock divisor. */
lcdc_write(LCD_CLK_DIVISOR(div) |
(LCD_RASTER_MODE & 0x1), LCD_CTRL_REG);
@@ -698,7 +698,14 @@ static void lcd_calc_clk_divider(struct da8xx_fb_par *par)
if (lcd_revision = LCD_VERSION_2)
lcdc_write(LCD_V2_DMA_CLK_EN | LCD_V2_LIDD_CLK_EN |
LCD_V2_CORE_CLK_EN, LCD_CLK_ENABLE_REG);
+}
+
+static inline void da8xx_fb_calc_config_clk_divider(struct da8xx_fb_par *par,
+ struct fb_videomode *mode)
+{
+ unsigned div = da8xx_fb_calc_clk_divider(par, mode->pixclock);
+ da8xx_fb_config_clk_divider(div);
}
static int lcd_init(struct da8xx_fb_par *par, const struct lcd_ctrl_config *cfg,
@@ -709,8 +716,7 @@ static int lcd_init(struct da8xx_fb_par *par, const struct lcd_ctrl_config *cfg,
da8xx_fb_lcd_reset();
- /* Calculate the divider */
- lcd_calc_clk_divider(par);
+ da8xx_fb_calc_config_clk_divider(par, panel);
if (panel->sync & FB_SYNC_CLK_INVERT)
lcdc_write((lcdc_read(LCD_RASTER_TIMING_2_REG) |
@@ -973,7 +979,7 @@ static int lcd_da8xx_cpufreq_transition(struct notifier_block *nb,
if (par->lcd_fck_rate != clk_get_rate(par->lcdc_clk)) {
par->lcd_fck_rate = clk_get_rate(par->lcdc_clk);
lcd_disable_raster(true);
- lcd_calc_clk_divider(par);
+ da8xx_fb_calc_config_clk_divider(par, &par->mode);
if (par->blank = FB_BLANK_UNBLANK)
lcd_enable_raster();
}
@@ -1199,22 +1205,6 @@ static struct fb_ops da8xx_fb_ops = {
.fb_blank = cfb_blank,
};
-/* Calculate and return pixel clock period in pico seconds */
-static unsigned int da8xxfb_pixel_clk_period(struct da8xx_fb_par *par)
-{
- unsigned int lcd_clk, div;
- unsigned int configured_pix_clk;
- unsigned long long pix_clk_period_picosec = 1000000000000ULL;
-
- lcd_clk = clk_get_rate(par->lcdc_clk);
- div = lcd_clk / par->pxl_clk;
- configured_pix_clk = (lcd_clk / div);
-
- do_div(pix_clk_period_picosec, configured_pix_clk);
-
- return pix_clk_period_picosec;
-}
-
static int __devinit fb_probe(struct platform_device *device)
{
struct da8xx_lcdc_platform_data *fb_pdata @@ -1307,7 +1297,6 @@ static int __devinit fb_probe(struct platform_device *device)
par = da8xx_fb_info->par;
par->lcdc_clk = fb_clk;
par->lcd_fck_rate = clk_get_rate(fb_clk);
- par->pxl_clk = lcdc_info->pixclock;
if (fb_pdata->panel_power_ctrl) {
par->panel_power_ctrl = fb_pdata->panel_power_ctrl;
par->panel_power_ctrl(1);
@@ -1372,7 +1361,6 @@ static int __devinit fb_probe(struct platform_device *device)
da8xx_fb_var.grayscale lcd_cfg->panel_shade = MONOCHROME ? 1 : 0;
da8xx_fb_var.bits_per_pixel = lcd_cfg->bpp;
- da8xx_fb_var.pixclock = da8xxfb_pixel_clk_period(par);
/* Initialize fbinfo */
da8xx_fb_info->flags = FBINFO_FLAG_DEFAULT;
--
1.7.12
^ permalink raw reply related
* [PATCH 06/10] video: da8xx-fb: store clk rate even if !CPUFREQ
From: Afzal Mohammed @ 2012-12-07 11:56 UTC (permalink / raw)
To: Florian Tobias Schandinat, Tomi Valkeinen
Cc: Vaibhav Hiremath, Sekhar Nori, linux-fbdev, linux-kernel,
Afzal Mohammed
In-Reply-To: <cover.1354874432.git.afzal@ti.com>
store lcd clk rate always, i.e. irrespective of whether CPUFREQ is
enabled or not. This can be used to get clk rate directly instead of
enquiring with clock framework with clk handle every time.
Signed-off-by: Afzal Mohammed <afzal@ti.com>
---
drivers/video/da8xx-fb.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
index 072074d..e858438 100644
--- a/drivers/video/da8xx-fb.c
+++ b/drivers/video/da8xx-fb.c
@@ -178,8 +178,8 @@ struct da8xx_fb_par {
unsigned int which_dma_channel_done;
#ifdef CONFIG_CPU_FREQ
struct notifier_block freq_transition;
- unsigned int lcd_fck_rate;
#endif
+ unsigned int lcd_fck_rate;
void (*panel_power_ctrl)(int);
u32 pseudo_palette[16];
struct fb_videomode mode;
@@ -1306,9 +1306,7 @@ static int __devinit fb_probe(struct platform_device *device)
par = da8xx_fb_info->par;
par->lcdc_clk = fb_clk;
-#ifdef CONFIG_CPU_FREQ
par->lcd_fck_rate = clk_get_rate(fb_clk);
-#endif
par->pxl_clk = lcdc_info->pixclock;
if (fb_pdata->panel_power_ctrl) {
par->panel_power_ctrl = fb_pdata->panel_power_ctrl;
--
1.7.12
^ permalink raw reply related
* [PATCH 05/10] video: da8xx-fb: store current display information
From: Afzal Mohammed @ 2012-12-07 11:56 UTC (permalink / raw)
To: Florian Tobias Schandinat, Tomi Valkeinen
Cc: Vaibhav Hiremath, Sekhar Nori, linux-fbdev, linux-kernel,
Afzal Mohammed
In-Reply-To: <cover.1354874432.git.afzal@ti.com>
store current videomode and controller data so that reconfiguring can
be done easily. Reconfiguring would be required in fb_set_par, which
is going to be added soon.
If these details are not stored, the work probe does to retrieve these
information would have to repeated at the place of reconfiguring and
modifying platform data would be necessary to handle controller data
changes like bpp.
Signed-off-by: Afzal Mohammed <afzal@ti.com>
---
drivers/video/da8xx-fb.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
index 79862ff..072074d 100644
--- a/drivers/video/da8xx-fb.c
+++ b/drivers/video/da8xx-fb.c
@@ -182,6 +182,8 @@ struct da8xx_fb_par {
#endif
void (*panel_power_ctrl)(int);
u32 pseudo_palette[16];
+ struct fb_videomode mode;
+ struct lcd_ctrl_config cfg;
};
static struct fb_var_screeninfo da8xx_fb_var;
@@ -1314,6 +1316,8 @@ static int __devinit fb_probe(struct platform_device *device)
}
fb_videomode_to_var(&da8xx_fb_var, lcdc_info);
+ fb_var_to_videomode(&par->mode, &da8xx_fb_var);
+ par->cfg = *lcd_cfg;
if (lcd_init(par, lcd_cfg, lcdc_info) < 0) {
dev_err(&device->dev, "lcd_init failed\n");
--
1.7.12
^ permalink raw reply related
* [PATCH 04/10] video: da8xx-fb: remove unneeded "var" initialization
From: Afzal Mohammed @ 2012-12-07 11:55 UTC (permalink / raw)
To: Florian Tobias Schandinat, Tomi Valkeinen
Cc: Vaibhav Hiremath, Sekhar Nori, linux-fbdev, linux-kernel,
Afzal Mohammed
In-Reply-To: <cover.1354874432.git.afzal@ti.com>
modedb helper now updates "var" information based on the detected
panel, remove the unnecessary initialization.
Signed-off-by: Afzal Mohammed <afzal@ti.com>
---
drivers/video/da8xx-fb.c | 18 +-----------------
1 file changed, 1 insertion(+), 17 deletions(-)
diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
index 0c404ed..79862ff 100644
--- a/drivers/video/da8xx-fb.c
+++ b/drivers/video/da8xx-fb.c
@@ -184,23 +184,7 @@ struct da8xx_fb_par {
u32 pseudo_palette[16];
};
-/* Variable Screen Information */
-static struct fb_var_screeninfo da8xx_fb_var __devinitdata = {
- .xoffset = 0,
- .yoffset = 0,
- .transp = {0, 0, 0},
- .nonstd = 0,
- .activate = 0,
- .height = -1,
- .width = -1,
- .accel_flags = 0,
- .left_margin = LEFT_MARGIN,
- .right_margin = RIGHT_MARGIN,
- .upper_margin = UPPER_MARGIN,
- .lower_margin = LOWER_MARGIN,
- .sync = 0,
- .vmode = FB_VMODE_NONINTERLACED
-};
+static struct fb_var_screeninfo da8xx_fb_var;
static struct fb_fix_screeninfo da8xx_fb_fix __devinitdata = {
.id = "DA8xx FB Drv",
--
1.7.12
^ permalink raw reply related
* [PATCH 03/10] video: da8xx-fb: use modedb helper to update var
From: Afzal Mohammed @ 2012-12-07 11:55 UTC (permalink / raw)
To: Florian Tobias Schandinat, Tomi Valkeinen
Cc: Vaibhav Hiremath, Sekhar Nori, linux-fbdev, linux-kernel,
Afzal Mohammed
In-Reply-To: <cover.1354874432.git.afzal@ti.com>
modedb structure is now used to store panel information, run modedb
helper over it for initial update of "var" information instead of
equating each fields.
While at it, remove redundant update of bits_per_pixel.
Note: pixclock is overridden with proper value using an existing code
as currently modedb is having it in Hz instead of ps, this would be
fixed in a later change and this overide would be removed.
Signed-off-by: Afzal Mohammed <afzal@ti.com>
---
drivers/video/da8xx-fb.c | 18 ++----------------
1 file changed, 2 insertions(+), 16 deletions(-)
diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
index c8e97de..0c404ed 100644
--- a/drivers/video/da8xx-fb.c
+++ b/drivers/video/da8xx-fb.c
@@ -1329,6 +1329,8 @@ static int __devinit fb_probe(struct platform_device *device)
par->panel_power_ctrl(1);
}
+ fb_videomode_to_var(&da8xx_fb_var, lcdc_info);
+
if (lcd_init(par, lcd_cfg, lcdc_info) < 0) {
dev_err(&device->dev, "lcd_init failed\n");
ret = -EFAULT;
@@ -1381,25 +1383,9 @@ static int __devinit fb_probe(struct platform_device *device)
goto err_release_pl_mem;
}
- /* Initialize par */
- da8xx_fb_info->var.bits_per_pixel = lcd_cfg->bpp;
-
- da8xx_fb_var.xres = lcdc_info->xres;
- da8xx_fb_var.xres_virtual = lcdc_info->xres;
-
- da8xx_fb_var.yres = lcdc_info->yres;
- da8xx_fb_var.yres_virtual = lcdc_info->yres * LCD_NUM_BUFFERS;
-
da8xx_fb_var.grayscale lcd_cfg->panel_shade = MONOCHROME ? 1 : 0;
da8xx_fb_var.bits_per_pixel = lcd_cfg->bpp;
-
- da8xx_fb_var.hsync_len = lcdc_info->hsync_len;
- da8xx_fb_var.vsync_len = lcdc_info->vsync_len;
- da8xx_fb_var.right_margin = lcdc_info->right_margin;
- da8xx_fb_var.left_margin = lcdc_info->left_margin;
- da8xx_fb_var.lower_margin = lcdc_info->lower_margin;
- da8xx_fb_var.upper_margin = lcdc_info->upper_margin;
da8xx_fb_var.pixclock = da8xxfb_pixel_clk_period(par);
/* Initialize fbinfo */
--
1.7.12
^ permalink raw reply related
* [PATCH 02/10] video: da8xx-fb: simplify lcd_reset
From: Afzal Mohammed @ 2012-12-07 11:55 UTC (permalink / raw)
To: Florian Tobias Schandinat, Tomi Valkeinen
Cc: Vaibhav Hiremath, Sekhar Nori, linux-fbdev, linux-kernel,
Afzal Mohammed
In-Reply-To: <cover.1354874432.git.afzal@ti.com>
lcd_reset function doesn't require any arguement, remove it.
Signed-off-by: Afzal Mohammed <afzal@ti.com>
---
drivers/video/da8xx-fb.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
index 89446aa..c8e97de 100644
--- a/drivers/video/da8xx-fb.c
+++ b/drivers/video/da8xx-fb.c
@@ -681,7 +681,7 @@ static int fb_setcolreg(unsigned regno, unsigned red, unsigned green,
}
#undef CNVT_TOHW
-static void lcd_reset(struct da8xx_fb_par *par)
+static void da8xx_fb_lcd_reset(void)
{
/* Disable the Raster if previously Enabled */
lcd_disable_raster(false);
@@ -721,7 +721,7 @@ static int lcd_init(struct da8xx_fb_par *par, const struct lcd_ctrl_config *cfg,
u32 bpp;
int ret = 0;
- lcd_reset(par);
+ da8xx_fb_lcd_reset();
/* Calculate the divider */
lcd_calc_clk_divider(par);
--
1.7.12
^ permalink raw reply related
* [PATCH 01/10] video: da8xx-fb: fb_check_var enhancement
From: Afzal Mohammed @ 2012-12-07 11:55 UTC (permalink / raw)
To: Florian Tobias Schandinat, Tomi Valkeinen
Cc: Vaibhav Hiremath, Sekhar Nori, linux-fbdev, linux-kernel,
Afzal Mohammed
In-Reply-To: <cover.1354874432.git.afzal@ti.com>
Check whether "struct fb_var_screeninfo" fields are sane, if not
update it to be within allowed limits.
If user sends down buggy "var" values, this will bring those within
allowable limits. And fb_set_par is not supposed to change "var"
values, fb_check_var has to ensure that values are proper.
Signed-off-by: Afzal Mohammed <afzal@ti.com>
---
drivers/video/da8xx-fb.c | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
index 46534e0..89446aa 100644
--- a/drivers/video/da8xx-fb.c
+++ b/drivers/video/da8xx-fb.c
@@ -888,6 +888,9 @@ static int fb_check_var(struct fb_var_screeninfo *var,
struct fb_info *info)
{
int err = 0;
+ struct da8xx_fb_par *par = info->par;
+ int bpp = var->bits_per_pixel >> 3;
+ unsigned long line_size = var->xres_virtual * bpp;
if (var->bits_per_pixel > 16 && lcd_revision = LCD_VERSION_1)
return -EINVAL;
@@ -955,6 +958,21 @@ static int fb_check_var(struct fb_var_screeninfo *var,
var->green.msb_right = 0;
var->blue.msb_right = 0;
var->transp.msb_right = 0;
+
+ if (line_size * var->yres_virtual > par->vram_size)
+ var->yres_virtual = par->vram_size / line_size;
+
+ if (var->yres > var->yres_virtual)
+ var->yres = var->yres_virtual;
+
+ if (var->xres > var->xres_virtual)
+ var->xres = var->xres_virtual;
+
+ if (var->xres + var->xoffset > var->xres_virtual)
+ var->xoffset = var->xres_virtual - var->xres;
+ if (var->yres + var->yoffset > var->yres_virtual)
+ var->yoffset = var->yres_virtual - var->yres;
+
return err;
}
--
1.7.12
^ permalink raw reply related
* [PATCH 00/10] video: da8xx-fb: runtime timing configuration and cleanup
From: Afzal Mohammed @ 2012-12-07 11:55 UTC (permalink / raw)
To: Florian Tobias Schandinat, Tomi Valkeinen
Cc: Vaibhav Hiremath, Sekhar Nori, linux-fbdev, linux-kernel
Hi,
This series makes da8xx-fb driver (device found on DaVinci and AM335x)
capable of handling runtime timing configuration by adding fb_set_par.
The last change adds actual fb_set_par support. Other preceeding
changes makes the way clear for it as well as does certain cleanup's
on the way.
This has been tested on DA850 EVM.
Not sure whether Florian or Tomi would be handling fbdev patches after
the coming merge window, as Tomi is queueing fbdev patches currently,
these changes has been made over Tomi Valkeinen's for-next branch.
Regards
Afzal
Afzal Mohammed (10):
video: da8xx-fb: fb_check_var enhancement
video: da8xx-fb: simplify lcd_reset
video: da8xx-fb: use modedb helper to update var
video: da8xx-fb: remove unneeded "var" initialization
video: da8xx-fb: store current display information
video: da8xx-fb: store clk rate even if !CPUFREQ
video: da8xx-fb: pix clk and clk div handling cleanup
video: da8xx-fb: store struct device *
video: da8xx-fb: report correct pixclock
video: da8xx-fb: fb_set_par support
drivers/video/da8xx-fb.c | 181 +++++++++++++++++++++++++++--------------------
1 file changed, 105 insertions(+), 76 deletions(-)
--
1.7.12
^ permalink raw reply
* [PATCH 5/5] OMAPFB: connect ovl managers to all dssdevs
From: Tomi Valkeinen @ 2012-12-07 11:55 UTC (permalink / raw)
To: Archit Taneja, linux-omap, linux-fbdev; +Cc: Tomi Valkeinen
In-Reply-To: <1354881309-17625-1-git-send-email-tomi.valkeinen@ti.com>
Commit 5d89bcc341771d95e3a2996218e5949a6627f59e (OMAPDSS: remove initial
display code from omapdss) moved setting up the initial overlay, overlay
manager, output and display connections from omapdss to omapfb.
However, currently omapfb only handles the connection related to the
default display, which means that no overlay managers are connected to
other displays.
This patch changes omapfb to go through all dssdevs, and connect an
overlay manager to them.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/omapfb/omapfb-main.c | 38 +++++++++++++++++++-----------
1 file changed, 24 insertions(+), 14 deletions(-)
diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c
index 1df973e..24739fc 100644
--- a/drivers/video/omap2/omapfb/omapfb-main.c
+++ b/drivers/video/omap2/omapfb/omapfb-main.c
@@ -2353,27 +2353,37 @@ static int omapfb_init_display(struct omapfb2_device *fbdev,
}
static int omapfb_init_connections(struct omapfb2_device *fbdev,
- struct omap_dss_device *dssdev)
+ struct omap_dss_device *def_dssdev)
{
int i, r;
- struct omap_overlay_manager *mgr = NULL;
+ struct omap_overlay_manager *mgr;
- for (i = 0; i < fbdev->num_managers; i++) {
- mgr = fbdev->managers[i];
-
- if (dssdev->channel = mgr->id)
- break;
+ if (!def_dssdev->output) {
+ dev_err(fbdev->dev, "no output for the default display\n");
+ return -EINVAL;
}
- if (i = fbdev->num_managers)
- return -ENODEV;
+ for (i = 0; i < fbdev->num_displays; ++i) {
+ struct omap_dss_device *dssdev = fbdev->displays[i].dssdev;
+ struct omap_dss_output *out = dssdev->output;
- if (mgr->output)
- mgr->unset_output(mgr);
+ mgr = omap_dss_get_overlay_manager(dssdev->channel);
- r = mgr->set_output(mgr, dssdev->output);
- if (r)
- return r;
+ if (!mgr || !out)
+ continue;
+
+ if (mgr->output)
+ mgr->unset_output(mgr);
+
+ mgr->set_output(mgr, out);
+ }
+
+ mgr = def_dssdev->output->manager;
+
+ if (!mgr) {
+ dev_err(fbdev->dev, "no ovl manager for the default display\n");
+ return -EINVAL;
+ }
for (i = 0; i < fbdev->num_overlays; i++) {
struct omap_overlay *ovl = fbdev->overlays[i];
--
1.7.10.4
^ permalink raw reply related
* [PATCH 4/5] OMAPDSS: manage output-dssdev connection in output drivers
From: Tomi Valkeinen @ 2012-12-07 11:55 UTC (permalink / raw)
To: Archit Taneja, linux-omap, linux-fbdev; +Cc: Tomi Valkeinen
In-Reply-To: <1354881309-17625-1-git-send-email-tomi.valkeinen@ti.com>
We currently attach an output to a dssdev in the initialization code for
dssdevices in display.c. This works, but doesn't quite make sense: an
output entity represents (surprisingly) an output of DSS, which is
managed by an output driver. The output driver also handles adding new
dssdev's for that particular output.
It makes more sense to make the output-dssdev connection in the output
driver. This is also in line with common display framework.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/display.c | 12 ------------
drivers/video/omap2/dss/dpi.c | 9 +++++++++
drivers/video/omap2/dss/dsi.c | 10 ++++++++++
drivers/video/omap2/dss/dss.h | 1 -
drivers/video/omap2/dss/hdmi.c | 9 +++++++++
drivers/video/omap2/dss/output.c | 33 ---------------------------------
drivers/video/omap2/dss/rfbi.c | 9 +++++++++
drivers/video/omap2/dss/sdi.c | 9 +++++++++
drivers/video/omap2/dss/venc.c | 9 +++++++++
9 files changed, 55 insertions(+), 46 deletions(-)
diff --git a/drivers/video/omap2/dss/display.c b/drivers/video/omap2/dss/display.c
index 008e9ee..05f21b6 100644
--- a/drivers/video/omap2/dss/display.c
+++ b/drivers/video/omap2/dss/display.c
@@ -79,17 +79,8 @@ EXPORT_SYMBOL(omapdss_default_get_timings);
int dss_init_device(struct platform_device *pdev,
struct omap_dss_device *dssdev)
{
- struct omap_dss_output *out;
int r;
- out = omapdss_get_output_from_dssdev(dssdev);
-
- r = omapdss_output_set_device(out, dssdev);
- if (r) {
- DSSERR("failed to connect output to new device\n");
- return r;
- }
-
r = display_init_sysfs(pdev, dssdev);
if (r) {
omapdss_output_unset_device(dssdev->output);
@@ -103,9 +94,6 @@ void dss_uninit_device(struct platform_device *pdev,
struct omap_dss_device *dssdev)
{
display_uninit_sysfs(pdev, dssdev);
-
- if (dssdev->output)
- omapdss_output_unset_device(dssdev->output);
}
static int dss_suspend_device(struct device *dev, void *data)
diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c
index c109fa6..d5bc47a 100644
--- a/drivers/video/omap2/dss/dpi.c
+++ b/drivers/video/omap2/dss/dpi.c
@@ -477,9 +477,18 @@ static void __init dpi_probe_pdata(struct platform_device *dpidev)
return;
}
+ r = omapdss_output_set_device(&dpi.output, dssdev);
+ if (r) {
+ DSSERR("failed to connect output to new device: %s\n",
+ dssdev->name);
+ dss_put_device(dssdev);
+ return;
+ }
+
r = dss_add_device(dssdev);
if (r) {
DSSERR("device %s register failed: %d\n", dssdev->name, r);
+ omapdss_output_unset_device(&dpi.output);
dss_put_device(dssdev);
return;
}
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index cf32dc7..db9663d 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -5146,6 +5146,7 @@ static struct omap_dss_device * __init dsi_find_dssdev(struct platform_device *p
static void __init dsi_probe_pdata(struct platform_device *dsidev)
{
+ struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
struct omap_dss_device *plat_dssdev;
struct omap_dss_device *dssdev;
int r;
@@ -5168,9 +5169,18 @@ static void __init dsi_probe_pdata(struct platform_device *dsidev)
return;
}
+ r = omapdss_output_set_device(&dsi->output, dssdev);
+ if (r) {
+ DSSERR("failed to connect output to new device: %s\n",
+ dssdev->name);
+ dss_put_device(dssdev);
+ return;
+ }
+
r = dss_add_device(dssdev);
if (r) {
DSSERR("device %s register failed: %d\n", dssdev->name, r);
+ omapdss_output_unset_device(&dsi->output);
dss_put_device(dssdev);
return;
}
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 4d6f325..bdf8431 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -212,7 +212,6 @@ int dss_ovl_unset_manager(struct omap_overlay *ovl);
/* output */
void dss_register_output(struct omap_dss_output *out);
void dss_unregister_output(struct omap_dss_output *out);
-struct omap_dss_output *omapdss_get_output_from_dssdev(struct omap_dss_device *dssdev);
/* display */
int dss_suspend_all_devices(void);
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
index 24a2eef..769d082 100644
--- a/drivers/video/omap2/dss/hdmi.c
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -1026,9 +1026,18 @@ static void __init hdmi_probe_pdata(struct platform_device *pdev)
return;
}
+ r = omapdss_output_set_device(&hdmi.output, dssdev);
+ if (r) {
+ DSSERR("failed to connect output to new device: %s\n",
+ dssdev->name);
+ dss_put_device(dssdev);
+ return;
+ }
+
r = dss_add_device(dssdev);
if (r) {
DSSERR("device %s register failed: %d\n", dssdev->name, r);
+ omapdss_output_unset_device(&hdmi.output);
hdmi_uninit_display(dssdev);
dss_put_device(dssdev);
return;
diff --git a/drivers/video/omap2/dss/output.c b/drivers/video/omap2/dss/output.c
index 813f266..1a84b79 100644
--- a/drivers/video/omap2/dss/output.c
+++ b/drivers/video/omap2/dss/output.c
@@ -113,36 +113,3 @@ struct omap_dss_output *omap_dss_get_output(enum omap_dss_output_id id)
return NULL;
}
-
-struct omap_dss_output *omapdss_get_output_from_dssdev(struct omap_dss_device *dssdev)
-{
- struct omap_dss_output *out = NULL;
- enum omap_dss_output_id id;
-
- switch (dssdev->type) {
- case OMAP_DISPLAY_TYPE_DPI:
- out = omap_dss_get_output(OMAP_DSS_OUTPUT_DPI);
- break;
- case OMAP_DISPLAY_TYPE_DBI:
- out = omap_dss_get_output(OMAP_DSS_OUTPUT_DBI);
- break;
- case OMAP_DISPLAY_TYPE_SDI:
- out = omap_dss_get_output(OMAP_DSS_OUTPUT_SDI);
- break;
- case OMAP_DISPLAY_TYPE_VENC:
- out = omap_dss_get_output(OMAP_DSS_OUTPUT_VENC);
- break;
- case OMAP_DISPLAY_TYPE_HDMI:
- out = omap_dss_get_output(OMAP_DSS_OUTPUT_HDMI);
- break;
- case OMAP_DISPLAY_TYPE_DSI:
- id = dssdev->phy.dsi.module = 0 ? OMAP_DSS_OUTPUT_DSI1 :
- OMAP_DSS_OUTPUT_DSI2;
- out = omap_dss_get_output(id);
- break;
- default:
- break;
- }
-
- return out;
-}
diff --git a/drivers/video/omap2/dss/rfbi.c b/drivers/video/omap2/dss/rfbi.c
index 7bfeb13..ec9fde5 100644
--- a/drivers/video/omap2/dss/rfbi.c
+++ b/drivers/video/omap2/dss/rfbi.c
@@ -999,9 +999,18 @@ static void __init rfbi_probe_pdata(struct platform_device *rfbidev)
return;
}
+ r = omapdss_output_set_device(&rfbi.output, dssdev);
+ if (r) {
+ DSSERR("failed to connect output to new device: %s\n",
+ dssdev->name);
+ dss_put_device(dssdev);
+ return;
+ }
+
r = dss_add_device(dssdev);
if (r) {
DSSERR("device %s register failed: %d\n", dssdev->name, r);
+ omapdss_output_unset_device(&rfbi.output);
dss_put_device(dssdev);
return;
}
diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/omap2/dss/sdi.c
index 882ce89..62b5374 100644
--- a/drivers/video/omap2/dss/sdi.c
+++ b/drivers/video/omap2/dss/sdi.c
@@ -254,9 +254,18 @@ static void __init sdi_probe_pdata(struct platform_device *sdidev)
return;
}
+ r = omapdss_output_set_device(&sdi.output, dssdev);
+ if (r) {
+ DSSERR("failed to connect output to new device: %s\n",
+ dssdev->name);
+ dss_put_device(dssdev);
+ return;
+ }
+
r = dss_add_device(dssdev);
if (r) {
DSSERR("device %s register failed: %d\n", dssdev->name, r);
+ omapdss_output_unset_device(&sdi.output);
dss_put_device(dssdev);
return;
}
diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c
index e8fddc9..006caf3 100644
--- a/drivers/video/omap2/dss/venc.c
+++ b/drivers/video/omap2/dss/venc.c
@@ -795,9 +795,18 @@ static void __init venc_probe_pdata(struct platform_device *vencdev)
return;
}
+ r = omapdss_output_set_device(&venc.output, dssdev);
+ if (r) {
+ DSSERR("failed to connect output to new device: %s\n",
+ dssdev->name);
+ dss_put_device(dssdev);
+ return;
+ }
+
r = dss_add_device(dssdev);
if (r) {
DSSERR("device %s register failed: %d\n", dssdev->name, r);
+ omapdss_output_unset_device(&venc.output);
dss_put_device(dssdev);
return;
}
--
1.7.10.4
^ permalink raw reply related
* [PATCH 3/5] OMAPFB: remove warning when trying to alloc at certain paddress
From: Tomi Valkeinen @ 2012-12-07 11:55 UTC (permalink / raw)
To: Archit Taneja, linux-omap, linux-fbdev; +Cc: Tomi Valkeinen
In-Reply-To: <1354881309-17625-1-git-send-email-tomi.valkeinen@ti.com>
omapfb gives a WARN_ONCE if a predefined physical address is given for
allocating the framebuffer memory, as this is not currently supported.
However, the same warning happens if omapfb fails to allocate memory
during runtime, as when the allocation has failed, omapfb tries to
re-allocate the old memory with the physical address of the old memory
area.
Remove the warning from omapfb_alloc_fbmem, as it serves no purpose on
the failure case above, and move it to omapfb_parse_vram_param, so that
we only warn if physical address is given via omapfb module parameters.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/omapfb/omapfb-main.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c
index 28b2a21..1df973e 100644
--- a/drivers/video/omap2/omapfb/omapfb-main.c
+++ b/drivers/video/omap2/omapfb/omapfb-main.c
@@ -1391,9 +1391,6 @@ static int omapfb_alloc_fbmem(struct fb_info *fbi, unsigned long size,
size = PAGE_ALIGN(size);
- WARN_ONCE(paddr,
- "reserving memory at predefined address not supported\n");
-
dma_set_attr(DMA_ATTR_WRITE_COMBINE, &attrs);
if (ofbi->rotation_type = OMAP_DSS_ROT_VRFB)
@@ -1521,6 +1518,9 @@ static int omapfb_parse_vram_param(const char *param, int max_entries,
}
+ WARN_ONCE(paddr,
+ "reserving memory at predefined address not supported\n");
+
paddrs[fbnum] = paddr;
sizes[fbnum] = size;
--
1.7.10.4
^ permalink raw reply related
* [PATCH 2/5] OMAPFB: simplify locking
From: Tomi Valkeinen @ 2012-12-07 11:55 UTC (permalink / raw)
To: Archit Taneja, linux-omap, linux-fbdev
Cc: Tomi Valkeinen, Ville Syrjälä
In-Reply-To: <1354881309-17625-1-git-send-email-tomi.valkeinen@ti.com>
Kernel lock verification code has lately detected possible circular
locking in omapfb. The exact problem is unclear, but omapfb's current
locking seems to be overly complex.
This patch simplifies the locking in the following ways:
- Remove explicit omapfb mem region locking. I couldn't figure out the
need for this, as long as we take care to take omapfb lock.
- Get omapfb lock always, even if the operation is possibly only related
to one fb_info. Better safe than sorry, and normally there's only one
user for the fb so this shouldn't matter.
- Make sure fb_info lock is taken first, then omapfb lock.
With this patch the warnings about possible circular locking does not
happen anymore.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
drivers/video/omap2/omapfb/omapfb-ioctl.c | 65 +++-------------------
drivers/video/omap2/omapfb/omapfb-main.c | 40 ++++----------
drivers/video/omap2/omapfb/omapfb-sysfs.c | 84 +++++++++++++++++++----------
drivers/video/omap2/omapfb/omapfb.h | 19 -------
4 files changed, 73 insertions(+), 135 deletions(-)
diff --git a/drivers/video/omap2/omapfb/omapfb-ioctl.c b/drivers/video/omap2/omapfb/omapfb-ioctl.c
index 94de47e..ae7aac7 100644
--- a/drivers/video/omap2/omapfb/omapfb-ioctl.c
+++ b/drivers/video/omap2/omapfb/omapfb-ioctl.c
@@ -85,16 +85,6 @@ static int omapfb_setup_plane(struct fb_info *fbi, struct omapfb_plane_info *pi)
goto out;
}
- /* Take the locks in a specific order to keep lockdep happy */
- if (old_rg->id < new_rg->id) {
- omapfb_get_mem_region(old_rg);
- omapfb_get_mem_region(new_rg);
- } else if (new_rg->id < old_rg->id) {
- omapfb_get_mem_region(new_rg);
- omapfb_get_mem_region(old_rg);
- } else
- omapfb_get_mem_region(old_rg);
-
if (pi->enabled && !new_rg->size) {
/*
* This plane's memory was freed, can't enable it
@@ -146,16 +136,6 @@ static int omapfb_setup_plane(struct fb_info *fbi, struct omapfb_plane_info *pi)
goto undo;
}
- /* Release the locks in a specific order to keep lockdep happy */
- if (old_rg->id > new_rg->id) {
- omapfb_put_mem_region(old_rg);
- omapfb_put_mem_region(new_rg);
- } else if (new_rg->id > old_rg->id) {
- omapfb_put_mem_region(new_rg);
- omapfb_put_mem_region(old_rg);
- } else
- omapfb_put_mem_region(old_rg);
-
return 0;
undo:
@@ -166,15 +146,6 @@ static int omapfb_setup_plane(struct fb_info *fbi, struct omapfb_plane_info *pi)
ovl->set_overlay_info(ovl, &old_info);
put_mem:
- /* Release the locks in a specific order to keep lockdep happy */
- if (old_rg->id > new_rg->id) {
- omapfb_put_mem_region(old_rg);
- omapfb_put_mem_region(new_rg);
- } else if (new_rg->id > old_rg->id) {
- omapfb_put_mem_region(new_rg);
- omapfb_put_mem_region(old_rg);
- } else
- omapfb_put_mem_region(old_rg);
out:
dev_err(fbdev->dev, "setup_plane failed\n");
@@ -222,9 +193,6 @@ static int omapfb_setup_mem(struct fb_info *fbi, struct omapfb_mem_info *mi)
rg = ofbi->region;
- down_write_nested(&rg->lock, rg->id);
- atomic_inc(&rg->lock_count);
-
if (rg->size = size && rg->type = mi->type)
goto out;
@@ -257,9 +225,6 @@ static int omapfb_setup_mem(struct fb_info *fbi, struct omapfb_mem_info *mi)
}
out:
- atomic_dec(&rg->lock_count);
- up_write(&rg->lock);
-
return r;
}
@@ -268,14 +233,12 @@ static int omapfb_query_mem(struct fb_info *fbi, struct omapfb_mem_info *mi)
struct omapfb_info *ofbi = FB2OFB(fbi);
struct omapfb2_mem_region *rg;
- rg = omapfb_get_mem_region(ofbi->region);
+ rg = ofbi->region;
memset(mi, 0, sizeof(*mi));
mi->size = rg->size;
mi->type = rg->type;
- omapfb_put_mem_region(rg);
-
return 0;
}
@@ -314,14 +277,10 @@ int omapfb_set_update_mode(struct fb_info *fbi,
if (mode != OMAPFB_AUTO_UPDATE && mode != OMAPFB_MANUAL_UPDATE)
return -EINVAL;
- omapfb_lock(fbdev);
-
d = get_display_data(fbdev, display);
- if (d->update_mode = mode) {
- omapfb_unlock(fbdev);
+ if (d->update_mode = mode)
return 0;
- }
r = 0;
@@ -337,8 +296,6 @@ int omapfb_set_update_mode(struct fb_info *fbi,
r = -EINVAL;
}
- omapfb_unlock(fbdev);
-
return r;
}
@@ -353,14 +310,10 @@ int omapfb_get_update_mode(struct fb_info *fbi,
if (!display)
return -EINVAL;
- omapfb_lock(fbdev);
-
d = get_display_data(fbdev, display);
*mode = d->update_mode;
- omapfb_unlock(fbdev);
-
return 0;
}
@@ -420,13 +373,10 @@ static int omapfb_set_color_key(struct fb_info *fbi,
struct omapfb_color_key *ck)
{
struct omapfb_info *ofbi = FB2OFB(fbi);
- struct omapfb2_device *fbdev = ofbi->fbdev;
int r;
int i;
struct omap_overlay_manager *mgr = NULL;
- omapfb_lock(fbdev);
-
for (i = 0; i < ofbi->num_overlays; i++) {
if (ofbi->overlays[i]->manager) {
mgr = ofbi->overlays[i]->manager;
@@ -441,8 +391,6 @@ static int omapfb_set_color_key(struct fb_info *fbi,
r = _omapfb_set_color_key(mgr, ck);
err:
- omapfb_unlock(fbdev);
-
return r;
}
@@ -450,13 +398,10 @@ static int omapfb_get_color_key(struct fb_info *fbi,
struct omapfb_color_key *ck)
{
struct omapfb_info *ofbi = FB2OFB(fbi);
- struct omapfb2_device *fbdev = ofbi->fbdev;
struct omap_overlay_manager *mgr = NULL;
int r = 0;
int i;
- omapfb_lock(fbdev);
-
for (i = 0; i < ofbi->num_overlays; i++) {
if (ofbi->overlays[i]->manager) {
mgr = ofbi->overlays[i]->manager;
@@ -471,8 +416,6 @@ static int omapfb_get_color_key(struct fb_info *fbi,
*ck = omapfb_color_keys[mgr->id];
err:
- omapfb_unlock(fbdev);
-
return r;
}
@@ -599,6 +542,8 @@ int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg)
int r = 0;
+ omapfb_lock(fbdev);
+
switch (cmd) {
case OMAPFB_SYNC_GFX:
DBG("ioctl SYNC_GFX\n");
@@ -904,6 +849,8 @@ int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg)
r = -EINVAL;
}
+ omapfb_unlock(fbdev);
+
if (r < 0)
DBG("ioctl failed: %d\n", r);
diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c
index 1a69d7c..28b2a21 100644
--- a/drivers/video/omap2/omapfb/omapfb-main.c
+++ b/drivers/video/omap2/omapfb/omapfb-main.c
@@ -672,8 +672,6 @@ int check_fb_var(struct fb_info *fbi, struct fb_var_screeninfo *var)
DBG("check_fb_var %d\n", ofbi->id);
- WARN_ON(!atomic_read(&ofbi->region->lock_count));
-
r = fb_mode_to_dss_mode(var, &mode);
if (r) {
DBG("cannot convert var to omap dss mode\n");
@@ -855,8 +853,6 @@ int omapfb_setup_overlay(struct fb_info *fbi, struct omap_overlay *ovl,
int rotation = var->rotate;
int i;
- WARN_ON(!atomic_read(&ofbi->region->lock_count));
-
for (i = 0; i < ofbi->num_overlays; i++) {
if (ovl != ofbi->overlays[i])
continue;
@@ -948,8 +944,6 @@ int omapfb_apply_changes(struct fb_info *fbi, int init)
fill_fb(fbi);
#endif
- WARN_ON(!atomic_read(&ofbi->region->lock_count));
-
for (i = 0; i < ofbi->num_overlays; i++) {
ovl = ofbi->overlays[i];
@@ -1008,15 +1002,16 @@ err:
static int omapfb_check_var(struct fb_var_screeninfo *var, struct fb_info *fbi)
{
struct omapfb_info *ofbi = FB2OFB(fbi);
+ struct omapfb2_device *fbdev = ofbi->fbdev;
int r;
DBG("check_var(%d)\n", FB2OFB(fbi)->id);
- omapfb_get_mem_region(ofbi->region);
+ omapfb_lock(fbdev);
r = check_fb_var(fbi, var);
- omapfb_put_mem_region(ofbi->region);
+ omapfb_unlock(fbdev);
return r;
}
@@ -1025,11 +1020,12 @@ static int omapfb_check_var(struct fb_var_screeninfo *var, struct fb_info *fbi)
static int omapfb_set_par(struct fb_info *fbi)
{
struct omapfb_info *ofbi = FB2OFB(fbi);
+ struct omapfb2_device *fbdev = ofbi->fbdev;
int r;
DBG("set_par(%d)\n", FB2OFB(fbi)->id);
- omapfb_get_mem_region(ofbi->region);
+ omapfb_lock(fbdev);
set_fb_fix(fbi);
@@ -1040,7 +1036,7 @@ static int omapfb_set_par(struct fb_info *fbi)
r = omapfb_apply_changes(fbi, 0);
out:
- omapfb_put_mem_region(ofbi->region);
+ omapfb_unlock(fbdev);
return r;
}
@@ -1049,6 +1045,7 @@ static int omapfb_pan_display(struct fb_var_screeninfo *var,
struct fb_info *fbi)
{
struct omapfb_info *ofbi = FB2OFB(fbi);
+ struct omapfb2_device *fbdev = ofbi->fbdev;
struct fb_var_screeninfo new_var;
int r;
@@ -1064,11 +1061,11 @@ static int omapfb_pan_display(struct fb_var_screeninfo *var,
fbi->var = new_var;
- omapfb_get_mem_region(ofbi->region);
+ omapfb_lock(fbdev);
r = omapfb_apply_changes(fbi, 0);
- omapfb_put_mem_region(ofbi->region);
+ omapfb_unlock(fbdev);
return r;
}
@@ -1077,18 +1074,14 @@ static void mmap_user_open(struct vm_area_struct *vma)
{
struct omapfb2_mem_region *rg = vma->vm_private_data;
- omapfb_get_mem_region(rg);
atomic_inc(&rg->map_count);
- omapfb_put_mem_region(rg);
}
static void mmap_user_close(struct vm_area_struct *vma)
{
struct omapfb2_mem_region *rg = vma->vm_private_data;
- omapfb_get_mem_region(rg);
atomic_dec(&rg->map_count);
- omapfb_put_mem_region(rg);
}
static struct vm_operations_struct mmap_user_ops = {
@@ -1112,7 +1105,7 @@ static int omapfb_mmap(struct fb_info *fbi, struct vm_area_struct *vma)
return -EINVAL;
off = vma->vm_pgoff << PAGE_SHIFT;
- rg = omapfb_get_mem_region(ofbi->region);
+ rg = ofbi->region;
start = omapfb_get_region_paddr(ofbi);
len = fix->smem_len;
@@ -1140,13 +1133,9 @@ static int omapfb_mmap(struct fb_info *fbi, struct vm_area_struct *vma)
/* vm_ops.open won't be called for mmap itself. */
atomic_inc(&rg->map_count);
- omapfb_put_mem_region(rg);
-
return 0;
error:
- omapfb_put_mem_region(ofbi->region);
-
return r;
}
@@ -1918,7 +1907,6 @@ static int omapfb_create_framebuffers(struct omapfb2_device *fbdev)
ofbi->region = &fbdev->regions[i];
ofbi->region->id = i;
- init_rwsem(&ofbi->region->lock);
/* assign these early, so that fb alloc can use them */
ofbi->rotation_type = def_vrfb ? OMAP_DSS_ROT_VRFB :
@@ -1950,12 +1938,8 @@ static int omapfb_create_framebuffers(struct omapfb2_device *fbdev)
/* setup fb_infos */
for (i = 0; i < fbdev->num_fbs; i++) {
struct fb_info *fbi = fbdev->fbs[i];
- struct omapfb_info *ofbi = FB2OFB(fbi);
- omapfb_get_mem_region(ofbi->region);
r = omapfb_fb_init(fbdev, fbi);
- omapfb_put_mem_region(ofbi->region);
-
if (r) {
dev_err(fbdev->dev, "failed to setup fb_info\n");
return r;
@@ -1987,12 +1971,8 @@ static int omapfb_create_framebuffers(struct omapfb2_device *fbdev)
for (i = 0; i < fbdev->num_fbs; i++) {
struct fb_info *fbi = fbdev->fbs[i];
- struct omapfb_info *ofbi = FB2OFB(fbi);
- omapfb_get_mem_region(ofbi->region);
r = omapfb_apply_changes(fbi, 1);
- omapfb_put_mem_region(ofbi->region);
-
if (r) {
dev_err(fbdev->dev, "failed to change mode\n");
return r;
diff --git a/drivers/video/omap2/omapfb/omapfb-sysfs.c b/drivers/video/omap2/omapfb/omapfb-sysfs.c
index 17aa174..6614462 100644
--- a/drivers/video/omap2/omapfb/omapfb-sysfs.c
+++ b/drivers/video/omap2/omapfb/omapfb-sysfs.c
@@ -49,6 +49,7 @@ static ssize_t store_rotate_type(struct device *dev,
{
struct fb_info *fbi = dev_get_drvdata(dev);
struct omapfb_info *ofbi = FB2OFB(fbi);
+ struct omapfb2_device *fbdev = ofbi->fbdev;
struct omapfb2_mem_region *rg;
int rot_type;
int r;
@@ -62,12 +63,13 @@ static ssize_t store_rotate_type(struct device *dev,
if (!lock_fb_info(fbi))
return -ENODEV;
+ omapfb_lock(fbdev);
r = 0;
if (rot_type = ofbi->rotation_type)
goto out;
- rg = omapfb_get_mem_region(ofbi->region);
+ rg = ofbi->region;
if (rg->size) {
r = -EBUSY;
@@ -81,8 +83,8 @@ static ssize_t store_rotate_type(struct device *dev,
* need to do any further parameter checking at this point.
*/
put_region:
- omapfb_put_mem_region(rg);
out:
+ omapfb_unlock(fbdev);
unlock_fb_info(fbi);
return r ? r : count;
@@ -104,6 +106,7 @@ static ssize_t store_mirror(struct device *dev,
{
struct fb_info *fbi = dev_get_drvdata(dev);
struct omapfb_info *ofbi = FB2OFB(fbi);
+ struct omapfb2_device *fbdev = ofbi->fbdev;
bool mirror;
int r;
struct fb_var_screeninfo new_var;
@@ -114,11 +117,10 @@ static ssize_t store_mirror(struct device *dev,
if (!lock_fb_info(fbi))
return -ENODEV;
+ omapfb_lock(fbdev);
ofbi->mirror = mirror;
- omapfb_get_mem_region(ofbi->region);
-
memcpy(&new_var, &fbi->var, sizeof(new_var));
r = check_fb_var(fbi, &new_var);
if (r)
@@ -133,8 +135,7 @@ static ssize_t store_mirror(struct device *dev,
r = count;
out:
- omapfb_put_mem_region(ofbi->region);
-
+ omapfb_unlock(fbdev);
unlock_fb_info(fbi);
return r;
@@ -273,15 +274,11 @@ static ssize_t store_overlays(struct device *dev, struct device_attribute *attr,
DBG("detaching %d\n", ofbi->overlays[i]->id);
- omapfb_get_mem_region(ofbi->region);
-
omapfb_overlay_enable(ovl, 0);
if (ovl->manager)
ovl->manager->apply(ovl->manager);
- omapfb_put_mem_region(ofbi->region);
-
for (t = i + 1; t < ofbi->num_overlays; t++) {
ofbi->rotation[t-1] = ofbi->rotation[t];
ofbi->overlays[t-1] = ofbi->overlays[t];
@@ -314,12 +311,8 @@ static ssize_t store_overlays(struct device *dev, struct device_attribute *attr,
}
if (added) {
- omapfb_get_mem_region(ofbi->region);
-
r = omapfb_apply_changes(fbi, 0);
- omapfb_put_mem_region(ofbi->region);
-
if (r)
goto out;
}
@@ -337,11 +330,13 @@ static ssize_t show_overlays_rotate(struct device *dev,
{
struct fb_info *fbi = dev_get_drvdata(dev);
struct omapfb_info *ofbi = FB2OFB(fbi);
+ struct omapfb2_device *fbdev = ofbi->fbdev;
ssize_t l = 0;
int t;
if (!lock_fb_info(fbi))
return -ENODEV;
+ omapfb_lock(fbdev);
for (t = 0; t < ofbi->num_overlays; t++) {
l += snprintf(buf + l, PAGE_SIZE - l, "%s%d",
@@ -350,6 +345,7 @@ static ssize_t show_overlays_rotate(struct device *dev,
l += snprintf(buf + l, PAGE_SIZE - l, "\n");
+ omapfb_unlock(fbdev);
unlock_fb_info(fbi);
return l;
@@ -360,6 +356,7 @@ static ssize_t store_overlays_rotate(struct device *dev,
{
struct fb_info *fbi = dev_get_drvdata(dev);
struct omapfb_info *ofbi = FB2OFB(fbi);
+ struct omapfb2_device *fbdev = ofbi->fbdev;
int num_ovls = 0, r, i;
int len;
bool changed = false;
@@ -371,6 +368,7 @@ static ssize_t store_overlays_rotate(struct device *dev,
if (!lock_fb_info(fbi))
return -ENODEV;
+ omapfb_lock(fbdev);
if (len > 0) {
char *p = (char *)buf;
@@ -407,12 +405,7 @@ static ssize_t store_overlays_rotate(struct device *dev,
for (i = 0; i < num_ovls; ++i)
ofbi->rotation[i] = rotation[i];
- omapfb_get_mem_region(ofbi->region);
-
r = omapfb_apply_changes(fbi, 0);
-
- omapfb_put_mem_region(ofbi->region);
-
if (r)
goto out;
@@ -421,6 +414,7 @@ static ssize_t store_overlays_rotate(struct device *dev,
r = count;
out:
+ omapfb_unlock(fbdev);
unlock_fb_info(fbi);
return r;
@@ -431,8 +425,19 @@ static ssize_t show_size(struct device *dev,
{
struct fb_info *fbi = dev_get_drvdata(dev);
struct omapfb_info *ofbi = FB2OFB(fbi);
+ struct omapfb2_device *fbdev = ofbi->fbdev;
+ int r;
+
+ if (!lock_fb_info(fbi))
+ return -ENODEV;
+ omapfb_lock(fbdev);
+
+ r = snprintf(buf, PAGE_SIZE, "%lu\n", ofbi->region->size);
- return snprintf(buf, PAGE_SIZE, "%lu\n", ofbi->region->size);
+ omapfb_unlock(fbdev);
+ unlock_fb_info(fbi);
+
+ return r;
}
static ssize_t store_size(struct device *dev, struct device_attribute *attr,
@@ -454,12 +459,10 @@ static ssize_t store_size(struct device *dev, struct device_attribute *attr,
if (!lock_fb_info(fbi))
return -ENODEV;
+ omapfb_lock(fbdev);
rg = ofbi->region;
- down_write_nested(&rg->lock, rg->id);
- atomic_inc(&rg->lock_count);
-
if (atomic_read(&rg->map_count)) {
r = -EBUSY;
goto out;
@@ -492,9 +495,7 @@ static ssize_t store_size(struct device *dev, struct device_attribute *attr,
r = count;
out:
- atomic_dec(&rg->lock_count);
- up_write(&rg->lock);
-
+ omapfb_unlock(fbdev);
unlock_fb_info(fbi);
return r;
@@ -505,8 +506,19 @@ static ssize_t show_phys(struct device *dev,
{
struct fb_info *fbi = dev_get_drvdata(dev);
struct omapfb_info *ofbi = FB2OFB(fbi);
+ struct omapfb2_device *fbdev = ofbi->fbdev;
+ int r;
- return snprintf(buf, PAGE_SIZE, "%0x\n", ofbi->region->paddr);
+ if (!lock_fb_info(fbi))
+ return -ENODEV;
+ omapfb_lock(fbdev);
+
+ r = snprintf(buf, PAGE_SIZE, "%0x\n", ofbi->region->paddr);
+
+ omapfb_unlock(fbdev);
+ unlock_fb_info(fbi);
+
+ return r;
}
static ssize_t show_virt(struct device *dev,
@@ -522,11 +534,20 @@ static ssize_t show_upd_mode(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct fb_info *fbi = dev_get_drvdata(dev);
+ struct omapfb_info *ofbi = FB2OFB(fbi);
+ struct omapfb2_device *fbdev = ofbi->fbdev;
enum omapfb_update_mode mode;
int r;
+ if (!lock_fb_info(fbi))
+ return -ENODEV;
+ omapfb_lock(fbdev);
+
r = omapfb_get_update_mode(fbi, &mode);
+ omapfb_unlock(fbdev);
+ unlock_fb_info(fbi);
+
if (r)
return r;
@@ -537,6 +558,8 @@ static ssize_t store_upd_mode(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
struct fb_info *fbi = dev_get_drvdata(dev);
+ struct omapfb_info *ofbi = FB2OFB(fbi);
+ struct omapfb2_device *fbdev = ofbi->fbdev;
unsigned mode;
int r;
@@ -544,10 +567,17 @@ static ssize_t store_upd_mode(struct device *dev, struct device_attribute *attr,
if (r)
return r;
+ if (!lock_fb_info(fbi))
+ return -ENODEV;
+ omapfb_lock(fbdev);
+
r = omapfb_set_update_mode(fbi, mode);
if (r)
return r;
+ omapfb_unlock(fbdev);
+ unlock_fb_info(fbi);
+
return count;
}
diff --git a/drivers/video/omap2/omapfb/omapfb.h b/drivers/video/omap2/omapfb/omapfb.h
index 5f72bf9..71cd8ba 100644
--- a/drivers/video/omap2/omapfb/omapfb.h
+++ b/drivers/video/omap2/omapfb/omapfb.h
@@ -62,8 +62,6 @@ struct omapfb2_mem_region {
bool alloc; /* allocated by the driver */
bool map; /* kernel mapped by the driver */
atomic_t map_count;
- struct rw_semaphore lock;
- atomic_t lock_count;
};
/* appended to fb_info */
@@ -129,9 +127,6 @@ void omapfb_remove_sysfs(struct omapfb2_device *fbdev);
int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg);
-int omapfb_update_window(struct fb_info *fbi,
- u32 x, u32 y, u32 w, u32 h);
-
int dss_mode_to_fb_mode(enum omap_color_mode dssmode,
struct fb_var_screeninfo *var);
@@ -194,18 +189,4 @@ static inline int omapfb_overlay_enable(struct omap_overlay *ovl,
return ovl->disable(ovl);
}
-static inline struct omapfb2_mem_region *
-omapfb_get_mem_region(struct omapfb2_mem_region *rg)
-{
- down_read_nested(&rg->lock, rg->id);
- atomic_inc(&rg->lock_count);
- return rg;
-}
-
-static inline void omapfb_put_mem_region(struct omapfb2_mem_region *rg)
-{
- atomic_dec(&rg->lock_count);
- up_read(&rg->lock);
-}
-
#endif
--
1.7.10.4
^ permalink raw reply related
* [PATCH 1/5] OMAPFB: remove exported udpate window
From: Tomi Valkeinen @ 2012-12-07 11:55 UTC (permalink / raw)
To: Archit Taneja, linux-omap, linux-fbdev; +Cc: Tomi Valkeinen
omapfb contains an exported omapfb_update_window function, which, at
some point in history, was used by a closed source SGX driver. This was
a hack even then, and should not be needed anymore. So remove it.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/omapfb/omapfb-ioctl.c | 27 +++------------------------
1 file changed, 3 insertions(+), 24 deletions(-)
diff --git a/drivers/video/omap2/omapfb/omapfb-ioctl.c b/drivers/video/omap2/omapfb/omapfb-ioctl.c
index 8b1e9e3..94de47e 100644
--- a/drivers/video/omap2/omapfb/omapfb-ioctl.c
+++ b/drivers/video/omap2/omapfb/omapfb-ioctl.c
@@ -279,7 +279,7 @@ static int omapfb_query_mem(struct fb_info *fbi, struct omapfb_mem_info *mi)
return 0;
}
-static int omapfb_update_window_nolock(struct fb_info *fbi,
+static int omapfb_update_window(struct fb_info *fbi,
u32 x, u32 y, u32 w, u32 h)
{
struct omap_dss_device *display = fb2display(fbi);
@@ -299,27 +299,6 @@ static int omapfb_update_window_nolock(struct fb_info *fbi,
return display->driver->update(display, x, y, w, h);
}
-/* This function is exported for SGX driver use */
-int omapfb_update_window(struct fb_info *fbi,
- u32 x, u32 y, u32 w, u32 h)
-{
- struct omapfb_info *ofbi = FB2OFB(fbi);
- struct omapfb2_device *fbdev = ofbi->fbdev;
- int r;
-
- if (!lock_fb_info(fbi))
- return -ENODEV;
- omapfb_lock(fbdev);
-
- r = omapfb_update_window_nolock(fbi, x, y, w, h);
-
- omapfb_unlock(fbdev);
- unlock_fb_info(fbi);
-
- return r;
-}
-EXPORT_SYMBOL(omapfb_update_window);
-
int omapfb_set_update_mode(struct fb_info *fbi,
enum omapfb_update_mode mode)
{
@@ -646,7 +625,7 @@ int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg)
break;
}
- r = omapfb_update_window_nolock(fbi, p.uwnd_o.x, p.uwnd_o.y,
+ r = omapfb_update_window(fbi, p.uwnd_o.x, p.uwnd_o.y,
p.uwnd_o.width, p.uwnd_o.height);
break;
@@ -663,7 +642,7 @@ int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg)
break;
}
- r = omapfb_update_window_nolock(fbi, p.uwnd.x, p.uwnd.y,
+ r = omapfb_update_window(fbi, p.uwnd.x, p.uwnd.y,
p.uwnd.width, p.uwnd.height);
break;
--
1.7.10.4
^ permalink raw reply related
* Re: [PATCHv15 2/7] video: add display_timing and videomode
From: Tomi Valkeinen @ 2012-12-07 8:49 UTC (permalink / raw)
To: Grant Likely, Steffen Trumtrar
Cc: linux-fbdev-u79uwXL29TY76Z2rM5mHXA, Florian Tobias Schandinat,
David Airlie, devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW, Laurent Pinchart,
kernel-bIcnvbaLZ9MEGnE8C9+IrQ, Guennady Liakhovetski,
linux-media-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20121206100718.C5C263E0EA4@localhost>
[-- Attachment #1: Type: text/plain, Size: 1286 bytes --]
On 2012-12-06 12:07, Grant Likely wrote:
> On Mon, 26 Nov 2012 16:39:58 +0100, Steffen Trumtrar <s.trumtrar@pengutronix.de> wrote:
>> On Mon, Nov 26, 2012 at 02:37:26PM +0200, Tomi Valkeinen wrote:
>>> On 2012-11-26 11:07, Steffen Trumtrar wrote:
>>>
>>>> +/*
>>>> + * Subsystem independent description of a videomode.
>>>> + * Can be generated from struct display_timing.
>>>> + */
>>>> +struct videomode {
>>>> + u32 pixelclock; /* pixelclock in Hz */
>>>
>>> I don't know if this is of any importance, but the linux clock framework
>>> manages clock rates with unsigned long. Would it be better to use the
>>> same type here?
>>>
>>
>> Hm, I don't know. Anyone? u32 should be large enough for a pixelclock.
>
> 4GHz is a pretty large pixel clock. I have no idea how conceivable it is
> that hardware will get to that speed. However, if it will ever be
> larger, then you'll need to account for that in the DT binding so that
> the pixel clock can be specified using 2 cells.
I didn't mention the type because of the size of the field, but only
because to me it makes sense to use the same type for clock rates all
around the kernel. In many cases the value will be passed to clk_set_rate().
I can't see any real issues with u32, though.
Tomi
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 899 bytes --]
^ permalink raw reply
* [PATCH] ARM HDLCD: Add HDLCD support to the ARM platforms that support it.
From: Liviu Dudau @ 2012-12-06 15:48 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1354808923-7416-1-git-send-email-Liviu.Dudau@arm.com>
The ARM HDLCD device is now found in various new Versatile Express
coretiles as well as new Fast Models.
This driver adds support for the device tree bindings and supports
allocation of the framebuffer memory either through the reservation
mechanism that device tree support or through the use of CMA.
---
Documentation/devicetree/bindings/fb/arm_hdlcd.txt | 30 +
arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts | 4 +
arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts | 1 +
arch/arm/boot/dts/vexpress-v2p-ca5s.dts | 4 +
arch/arm/mach-vexpress/v2m.c | 51 ++
drivers/video/Kconfig | 15 +
drivers/video/Makefile | 1 +
drivers/video/arm-hdlcd.c | 862 ++++++++++++++++++++
include/linux/arm-hdlcd.h | 128 +++
9 files changed, 1096 insertions(+)
create mode 100644 Documentation/devicetree/bindings/fb/arm_hdlcd.txt
create mode 100644 drivers/video/arm-hdlcd.c
create mode 100644 include/linux/arm-hdlcd.h
diff --git a/Documentation/devicetree/bindings/fb/arm_hdlcd.txt b/Documentation/devicetree/bindings/fb/arm_hdlcd.txt
new file mode 100644
index 0000000..d57f3af
--- /dev/null
+++ b/Documentation/devicetree/bindings/fb/arm_hdlcd.txt
@@ -0,0 +1,30 @@
+ARM HDLCD
+
+ARM HDLCD driver can use system memory for framebuffer that has been either
+reserved through the device tree /memreserve/ instruction or by using the
+Continuous Memory Allocator. The framebuffer memory needs to be contiguous
+and allocated in the first 4GB of physical space (for platforms that support
+LPAE).
+
+Required properties:
+- compatible: Should be "arm,hdlcd".
+- reg: Address and length of the register set.
+- interrupts: Should contain the interrupt used by the device.
+
+Optional properties:
+- mode: Should specify the initial video mode. Format as specified in
+ Documentation/fb/modedb.txt
+- framebuffer: Address and length of the physical memory allocated for buffer.
+
+
+Examples:
+
+ /memreserve/ 0xbf000000 0x01000000;
+
+ hdlcd@2b000000 {
+ compatible = "arm,hdlcd";
+ reg = <0 0x2b000000 0 0x1000>;
+ interrupts = <0 85 4>;
+ mode = "1024x768-16@60";
+ framebuffer = <0 0xff000000 0 0x01000000>;
+ };
diff --git a/arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts b/arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts
index d12b34c..63c501e 100644
--- a/arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts
+++ b/arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts
@@ -9,6 +9,8 @@
/dts-v1/;
+/memreserve/ 0xbf000000 0x01000000;
+
/ {
model = "V2P-CA15";
arm,hbi = <0x237>;
@@ -54,6 +56,8 @@
compatible = "arm,hdlcd";
reg = <0 0x2b000000 0 0x1000>;
interrupts = <0 85 4>;
+ mode = "1024x768-16@60";
+ framebuffer = <0 0xff000000 0 0x01000000>;
};
memory-controller@2b0a0000 {
diff --git a/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts b/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts
index 4890a81..754ceff 100644
--- a/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts
+++ b/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts
@@ -80,6 +80,7 @@
compatible = "arm,hdlcd";
reg = <0 0x2b000000 0 0x1000>;
interrupts = <0 85 4>;
+ mode = "1680x1050-32@60";
};
memory-controller@2b0a0000 {
diff --git a/arch/arm/boot/dts/vexpress-v2p-ca5s.dts b/arch/arm/boot/dts/vexpress-v2p-ca5s.dts
index 18917a0..dff0475 100644
--- a/arch/arm/boot/dts/vexpress-v2p-ca5s.dts
+++ b/arch/arm/boot/dts/vexpress-v2p-ca5s.dts
@@ -9,6 +9,8 @@
/dts-v1/;
+/memreserve/ 0xbf000000 0x01000000;
+
/ {
model = "V2P-CA5s";
arm,hbi = <0x225>;
@@ -56,6 +58,8 @@
compatible = "arm,hdlcd";
reg = <0x2a110000 0x1000>;
interrupts = <0 85 4>;
+ mode = "640x480-16@60";
+ framebuffer = <0xbf000000 0x01000000>;
};
memory-controller@2a150000 {
diff --git a/arch/arm/mach-vexpress/v2m.c b/arch/arm/mach-vexpress/v2m.c
index 560e0df..bfe33b5 100644
--- a/arch/arm/mach-vexpress/v2m.c
+++ b/arch/arm/mach-vexpress/v2m.c
@@ -7,6 +7,7 @@
#include <linux/io.h>
#include <linux/smp.h>
#include <linux/init.h>
+#include <linux/memblock.h>
#include <linux/of_address.h>
#include <linux/of_fdt.h>
#include <linux/of_irq.h>
@@ -391,6 +392,14 @@ static struct v2m_osc v2m_mb_osc1 = {
.rate_default = 23750000,
};
+static struct v2m_osc v2m_site_osc5 = {
+ .site = SYS_CFG_SITE_DB1,
+ .osc = 5,
+ .rate_min = 10000000,
+ .rate_max = 165000000,
+ .rate_default = 23750000,
+};
+
static const char *v2m_ref_clk_periphs[] __initconst = {
"mb:wdt", "1000f000.wdt", "1c0f0000.wdt", /* SP805 WDT */
};
@@ -409,6 +418,10 @@ static const char *v2m_osc2_periphs[] __initconst = {
"mb:uart3", "1000c000.uart", "1c0c0000.uart", /* PL011 UART3 */
};
+static const char *v2m_osc5_periphs[] __initconst = {
+ "mb:hdlcd", "2b000000.hdlcd", "2b000000.hdlcd", /* HDLCD */
+};
+
static void __init v2m_clk_init(void)
{
struct clk *clk;
@@ -436,6 +449,12 @@ static void __init v2m_clk_init(void)
CLK_IS_ROOT, 24000000);
for (i = 0; i < ARRAY_SIZE(v2m_osc2_periphs); i++)
WARN_ON(clk_register_clkdev(clk, NULL, v2m_osc2_periphs[i]));
+
+ /* Enable CoreTile OSC5 to be used by HDLCD */
+ v2m_site_osc5.site = v2m_get_master_site();
+ clk = v2m_osc_register("mb:osc5", &v2m_site_osc5);
+ for (i = 0; i < ARRAY_SIZE(v2m_osc5_periphs); i++)
+ WARN_ON(clk_register_clkdev(clk, NULL, v2m_osc5_periphs[i]));
}
static void __init v2m_timer_init(void)
@@ -542,6 +561,36 @@ MACHINE_START(VEXPRESS, "ARM-Versatile Express")
.restart = v2m_restart,
MACHINE_END
+static void __init v2m_dt_hdlcd_init(void)
+{
+#ifndef CONFIG_CMA
+ struct device_node *node;
+ int len, na, ns;
+ const __be32 *prop;
+ phys_addr_t fb_base, fb_size;
+
+ node = of_find_compatible_node(NULL, NULL, "arm,hdlcd");
+ if (!node)
+ return;
+
+ na = of_n_addr_cells(node);
+ ns = of_n_size_cells(node);
+
+ prop = of_get_property(node, "framebuffer", &len);
+ if (WARN_ON(!prop || len < (na + ns) * sizeof(*prop)))
+ return;
+
+ fb_base = of_read_number(prop, na);
+ fb_size = of_read_number(prop + na, ns);
+
+ if (WARN_ON(memblock_remove(fb_base, fb_size)))
+ return;
+#endif
+
+ v2m_cfg_write(SYS_CFG_MUXFPGA | SYS_CFG_SITE(SYS_CFG_SITE_MB),
+ v2m_get_master_site());
+};
+
static struct map_desc v2m_rs1_io_desc __initdata = {
.virtual = V2M_PERIPH,
.pfn = __phys_to_pfn(0x1c000000),
@@ -599,6 +648,8 @@ void __init v2m_dt_init_early(void)
pr_warning("vexpress: DT HBI (%x) is not matching "
"hardware (%x)!\n", dt_hbi, hbi);
}
+
+ v2m_dt_hdlcd_init();
}
static struct of_device_id vexpress_irq_match[] __initdata = {
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index d08d799..0cb7cb2 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -328,6 +328,21 @@ config FB_ARMCLCD
here and read <file:Documentation/kbuild/modules.txt>. The module
will be called amba-clcd.
+config FB_ARMHDLCD
+ tristate "ARM High Definition LCD support"
+ depends on FB && ARM
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ This framebuffer device driver is for the ARM High Definition
+ Colour LCD controller.
+
+ If you want to compile this as a module (=code which can be
+ inserted into and removed from the running kernel), say M
+ here and read <file:Documentation/kbuild/modules.txt>. The module
+ will be called arm-hdlcd.
+
config FB_ACORN
bool "Acorn VIDC support"
depends on (FB = y) && ARM && ARCH_ACORN
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index 23e948e..959ce1a 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -98,6 +98,7 @@ obj-$(CONFIG_FB_ATMEL) += atmel_lcdfb.o
obj-$(CONFIG_FB_PVR2) += pvr2fb.o
obj-$(CONFIG_FB_VOODOO1) += sstfb.o
obj-$(CONFIG_FB_ARMCLCD) += amba-clcd.o
+obj-$(CONFIG_FB_ARMHDLCD) += arm-hdlcd.o
obj-$(CONFIG_FB_68328) += 68328fb.o
obj-$(CONFIG_FB_GBE) += gbefb.o
obj-$(CONFIG_FB_CIRRUS) += cirrusfb.o
diff --git a/drivers/video/arm-hdlcd.c b/drivers/video/arm-hdlcd.c
new file mode 100644
index 0000000..84fef29
--- /dev/null
+++ b/drivers/video/arm-hdlcd.c
@@ -0,0 +1,862 @@
+/*
+ * drivers/video/arm-hdlcd.c
+ *
+ * Copyright (C) 2012 ARM Limited
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file COPYING in the main directory of this archive
+ * for more details.
+ *
+ * ARM HDLCD Controller
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/ctype.h>
+#include <linux/mm.h>
+#include <linux/delay.h>
+#include <linux/of.h>
+#include <linux/fb.h>
+#include <linux/clk.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
+#include <linux/memblock.h>
+#include <linux/arm-hdlcd.h>
+#ifdef HDLCD_COUNT_BUFFERUNDERRUNS
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+#endif
+
+#include "edid.h"
+
+#ifdef CONFIG_SERIAL_AMBA_PCU_UART
+int get_edid(u8 *msgbuf);
+#else
+#endif
+
+#define to_hdlcd_device(info) container_of(info, struct hdlcd_device, fb)
+
+static struct of_device_id hdlcd_of_matches[] = {
+ { .compatible = "arm,hdlcd" },
+ {},
+};
+
+/* Framebuffer size. */
+static unsigned long framebuffer_size = SZ_8M;
+
+/* declare prototype function */
+static int hdlcd_pan_display(struct fb_var_screeninfo *var, struct fb_info *info);
+
+#ifdef HDLCD_COUNT_BUFFERUNDERRUNS
+static unsigned long buffer_underrun_events;
+static DEFINE_SPINLOCK(hdlcd_underrun_lock);
+
+static void hdlcd_underrun_set(unsigned long val)
+{
+ spin_lock(&hdlcd_underrun_lock);
+ buffer_underrun_events = val;
+ spin_unlock(&hdlcd_underrun_lock);
+}
+
+static unsigned long hdlcd_underrun_get(void)
+{
+ unsigned long val;
+ spin_lock(&hdlcd_underrun_lock);
+ val = buffer_underrun_events;
+ spin_unlock(&hdlcd_underrun_lock);
+ return val;
+}
+
+#ifdef CONFIG_PROC_FS
+static int hdlcd_underrun_show(struct seq_file *m, void *v)
+{
+ unsigned char underrun_string[32];
+ snprintf(underrun_string, 32, "%lu\n", hdlcd_underrun_get());
+ seq_puts(m, underrun_string);
+ return 0;
+}
+
+static int proc_hdlcd_underrun_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, hdlcd_underrun_show, NULL);
+}
+
+static const struct file_operations proc_hdlcd_underrun_operations = {
+ .open = proc_hdlcd_underrun_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+static int hdlcd_underrun_init(void)
+{
+ hdlcd_underrun_set(0);
+ proc_create("hdlcd_underrun", 0, NULL, &proc_hdlcd_underrun_operations);
+ return 0;
+}
+static void hdlcd_underrun_close(void)
+{
+ remove_proc_entry("hdlcd_underrun", NULL);
+}
+#else
+static int hdlcd_underrun_init(void) { return 0; }
+static void hdlcd_underrun_close(void) { }
+#endif /* CONFIG_PROC_FS */
+#endif /* HDLCD_COUNT_BUFFERUNDERRUNS */
+
+static char *fb_mode = "1680x1050-32@60\0\0\0\0\0";
+
+static struct fb_var_screeninfo cached_var_screeninfo;
+
+static struct fb_videomode __devinitdata hdlcd_default_mode = {
+ .refresh = 60,
+ .xres = 1680,
+ .yres = 1050,
+ .pixclock = 8403,
+ .left_margin = 80,
+ .right_margin = 48,
+ .upper_margin = 21,
+ .lower_margin = 3,
+ .hsync_len = 32,
+ .vsync_len = 6,
+ .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+ .vmode = FB_VMODE_NONINTERLACED
+};
+
+static inline void hdlcd_enable(struct hdlcd_device *hdlcd)
+{
+ dev_dbg(hdlcd->dev, "HDLCD: output enabled\n");
+ writel(1, hdlcd->base + HDLCD_REG_COMMAND);
+}
+
+static inline void hdlcd_disable(struct hdlcd_device *hdlcd)
+{
+ dev_dbg(hdlcd->dev, "HDLCD: output disabled\n");
+ writel(0, hdlcd->base + HDLCD_REG_COMMAND);
+}
+
+static int hdlcd_set_bitfields(struct hdlcd_device *hdlcd,
+ struct fb_var_screeninfo *var)
+{
+ int ret = 0;
+
+ memset(&var->transp, 0, sizeof(var->transp));
+ var->red.msb_right = 0;
+ var->green.msb_right = 0;
+ var->blue.msb_right = 0;
+ var->blue.offset = 0;
+
+ switch (var->bits_per_pixel) {
+ case 8:
+ /* pseudocolor */
+ var->red.length = 8;
+ var->green.length = 8;
+ var->blue.length = 8;
+ break;
+ case 16:
+ /* 565 format */
+ var->red.length = 5;
+ var->green.length = 6;
+ var->blue.length = 5;
+ break;
+ case 32:
+ var->transp.length = 8;
+ case 24:
+ var->red.length = 8;
+ var->green.length = 8;
+ var->blue.length = 8;
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ if (!ret) {
+ var->green.offset = var->blue.length;
+ var->red.offset = var->green.offset + var->green.length;
+ }
+
+ return ret;
+}
+
+static int hdlcd_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
+{
+ struct hdlcd_device *hdlcd = to_hdlcd_device(info);
+ int bpp = var->bits_per_pixel / 8;
+
+#ifdef HDLCD_NO_VIRTUAL_SCREEN
+ var->yres_virtual = var->yres;
+#else
+ var->yres_virtual = 2 * var->yres;
+#endif
+
+ if ((var->xres_virtual * bpp * var->yres_virtual) > hdlcd->fb.fix.smem_len)
+ return -ENOMEM;
+
+ if (var->xres > HDLCD_MAX_XRES || var->yres > HDLCD_MAX_YRES)
+ return -EINVAL;
+
+ /* make sure the bitfields are set appropriately */
+ return hdlcd_set_bitfields(hdlcd, var);
+}
+
+#define WRITE_HDLCD_REG(reg, value) writel((value), hdlcd->base + (reg))
+#define READ_HDLCD_REG(reg) readl(hdlcd->base + (reg))
+
+static int hdlcd_set_par(struct fb_info *info)
+{
+ struct hdlcd_device *hdlcd = to_hdlcd_device(info);
+ int bpp = hdlcd->fb.var.bits_per_pixel / 8;
+ int polarities;
+ int old_yoffset;
+
+ /* check for shortcuts */
+ old_yoffset = cached_var_screeninfo.yoffset;
+ cached_var_screeninfo.yoffset = info->var.yoffset;
+ if (!memcmp(&info->var, &cached_var_screeninfo,
+ sizeof(struct fb_var_screeninfo))) {
+ if(old_yoffset != info->var.yoffset) {
+ hdlcd_pan_display(&info->var, info);
+ }
+ /* or no change */
+ return 0;
+ }
+
+ hdlcd->fb.fix.line_length = hdlcd->fb.var.xres * bpp;
+
+ if (hdlcd->fb.var.bits_per_pixel >= 16)
+ hdlcd->fb.fix.visual = FB_VISUAL_TRUECOLOR;
+ else
+ hdlcd->fb.fix.visual = FB_VISUAL_PSEUDOCOLOR;
+
+ memcpy(&cached_var_screeninfo, &info->var,
+ sizeof(struct fb_var_screeninfo));
+
+ polarities = HDLCD_POLARITY_DATAEN | HDLCD_POLARITY_PIXELCLK | HDLCD_POLARITY_DATA;
+ polarities |= (hdlcd->fb.var.sync & FB_SYNC_HOR_HIGH_ACT) ? HDLCD_POLARITY_HSYNC : 0;
+ polarities |= (hdlcd->fb.var.sync & FB_SYNC_VERT_HIGH_ACT) ? HDLCD_POLARITY_VSYNC : 0;
+
+ hdlcd_disable(hdlcd);
+
+ WRITE_HDLCD_REG(HDLCD_REG_FB_LINE_LENGTH, hdlcd->fb.var.xres * bpp);
+ WRITE_HDLCD_REG(HDLCD_REG_FB_LINE_PITCH, hdlcd->fb.var.xres * bpp);
+ WRITE_HDLCD_REG(HDLCD_REG_FB_LINE_COUNT, hdlcd->fb.var.yres - 1);
+ WRITE_HDLCD_REG(HDLCD_REG_V_SYNC, hdlcd->fb.var.vsync_len - 1);
+ WRITE_HDLCD_REG(HDLCD_REG_V_BACK_PORCH, hdlcd->fb.var.upper_margin - 1);
+ WRITE_HDLCD_REG(HDLCD_REG_V_DATA, hdlcd->fb.var.yres - 1);
+ WRITE_HDLCD_REG(HDLCD_REG_V_FRONT_PORCH, hdlcd->fb.var.lower_margin - 1);
+ WRITE_HDLCD_REG(HDLCD_REG_H_SYNC, hdlcd->fb.var.hsync_len - 1);
+ WRITE_HDLCD_REG(HDLCD_REG_H_BACK_PORCH, hdlcd->fb.var.left_margin - 1);
+ WRITE_HDLCD_REG(HDLCD_REG_H_DATA, hdlcd->fb.var.xres - 1);
+ WRITE_HDLCD_REG(HDLCD_REG_H_FRONT_PORCH, hdlcd->fb.var.right_margin - 1);
+ WRITE_HDLCD_REG(HDLCD_REG_POLARITIES, polarities);
+ WRITE_HDLCD_REG(HDLCD_REG_PIXEL_FORMAT, (bpp - 1) << 3);
+
+ /*
+ * The format of the HDLCD_REG_<color>_SELECT register is:
+ * - bits[23:16] - default value for that color component
+ * - bits[11:8] - number of bits to extract for each color component
+ * - bits[4:0] - index of the lowest bit to extract
+ *
+ * The default color value is used when bits[11:8] read zero, when the
+ * pixel is outside the visible frame area or when there is a
+ * buffer underrun.
+ */
+ WRITE_HDLCD_REG(HDLCD_REG_RED_SELECT, hdlcd->fb.var.red.offset | \
+ ((hdlcd->fb.var.red.length & 0xf) << 8));
+ WRITE_HDLCD_REG(HDLCD_REG_GREEN_SELECT, hdlcd->fb.var.green.offset | \
+ ((hdlcd->fb.var.green.length & 0xf) << 8));
+ WRITE_HDLCD_REG(HDLCD_REG_BLUE_SELECT, hdlcd->fb.var.blue.offset | \
+ ((hdlcd->fb.var.blue.length & 0xf) << 8));
+
+#ifdef HDLCD_SHOW_UNDERRUN
+ WRITE_HDLCD_REG(HDLCD_REG_RED_SELECT, (0x00ff0000 |
+ READ_HDLCD_REG(HDLCD_REG_RED_SELECT)));
+#endif
+
+ clk_prepare(hdlcd->clk);
+ clk_set_rate(hdlcd->clk, (1000000000 / hdlcd->fb.var.pixclock) * 1000);
+ clk_enable(hdlcd->clk);
+
+ hdlcd_enable(hdlcd);
+
+ return 0;
+}
+
+static int hdlcd_setcolreg(unsigned int regno, unsigned int red, unsigned int green,
+ unsigned int blue, unsigned int transp, struct fb_info *info)
+{
+ if (regno < 16) {
+ u32 *pal = info->pseudo_palette;
+
+ pal[regno] = ((red >> 8) << info->var.red.offset) |
+ ((green >> 8) << info->var.green.offset) |
+ ((blue >> 8) << info->var.blue.offset);
+ }
+
+ return 0;
+}
+
+static irqreturn_t hdlcd_irq(int irq, void *data)
+{
+ struct hdlcd_device *hdlcd = data;
+ unsigned long irq_mask, irq_status;
+
+ irq_mask = READ_HDLCD_REG(HDLCD_REG_INT_MASK);
+ irq_status = READ_HDLCD_REG(HDLCD_REG_INT_STATUS);
+
+ /* acknowledge interrupt(s) */
+ WRITE_HDLCD_REG(HDLCD_REG_INT_CLEAR, irq_status);
+#ifdef HDLCD_COUNT_BUFFERUNDERRUNS
+ if (irq_status & HDLCD_INTERRUPT_UNDERRUN) {
+ /* increment the count */
+ hdlcd_underrun_set(hdlcd_underrun_get() + 1);
+ }
+#endif
+ if (irq_status & HDLCD_INTERRUPT_VSYNC) {
+ /* disable future VSYNC interrupts */
+ WRITE_HDLCD_REG(HDLCD_REG_INT_MASK, irq_mask & ~HDLCD_INTERRUPT_VSYNC);
+
+ complete(&hdlcd->vsync_completion);
+ }
+
+ return IRQ_HANDLED;
+}
+
+static int hdlcd_wait_for_vsync(struct fb_info *info)
+{
+ struct hdlcd_device *hdlcd = to_hdlcd_device(info);
+ unsigned long irq_mask;
+ int err;
+
+ /* enable VSYNC interrupt */
+ irq_mask = READ_HDLCD_REG(HDLCD_REG_INT_MASK);
+ WRITE_HDLCD_REG(HDLCD_REG_INT_MASK, irq_mask | HDLCD_INTERRUPT_VSYNC);
+
+ err = wait_for_completion_interruptible_timeout(&hdlcd->vsync_completion,
+ msecs_to_jiffies(100));
+
+ if (!err)
+ return -ETIMEDOUT;
+
+ return 0;
+}
+
+static int hdlcd_blank(int blank_mode, struct fb_info *info)
+{
+ struct hdlcd_device *hdlcd = to_hdlcd_device(info);
+
+ switch (blank_mode) {
+ case FB_BLANK_POWERDOWN:
+ clk_disable(hdlcd->clk);
+ case FB_BLANK_NORMAL:
+ hdlcd_disable(hdlcd);
+ break;
+ case FB_BLANK_UNBLANK:
+ clk_enable(hdlcd->clk);
+ hdlcd_enable(hdlcd);
+ break;
+ case FB_BLANK_VSYNC_SUSPEND:
+ case FB_BLANK_HSYNC_SUSPEND:
+ default:
+ return 1;
+ }
+
+ return 0;
+}
+
+static void hdlcd_mmap_open(struct vm_area_struct *vma)
+{
+}
+
+static void hdlcd_mmap_close(struct vm_area_struct *vma)
+{
+}
+
+static struct vm_operations_struct hdlcd_mmap_ops = {
+ .open = hdlcd_mmap_open,
+ .close = hdlcd_mmap_close,
+};
+
+static int hdlcd_mmap(struct fb_info *info, struct vm_area_struct *vma)
+{
+ struct hdlcd_device *hdlcd = to_hdlcd_device(info);
+ unsigned long off;
+ unsigned long start;
+ unsigned long len = hdlcd->fb.fix.smem_len;
+
+ if (vma->vm_end - vma->vm_start == 0)
+ return 0;
+ if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT))
+ return -EINVAL;
+
+ off = vma->vm_pgoff << PAGE_SHIFT;
+ if ((off >= len) || (vma->vm_end - vma->vm_start + off) > len)
+ return -EINVAL;
+
+ start = hdlcd->fb.fix.smem_start;
+ off += start;
+
+ vma->vm_pgoff = off >> PAGE_SHIFT;
+ vma->vm_flags |= VM_IO;
+ vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
+ vma->vm_ops = &hdlcd_mmap_ops;
+ if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot))
+ return -EAGAIN;
+
+ return 0;
+}
+
+static int hdlcd_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
+{
+ struct hdlcd_device *hdlcd = to_hdlcd_device(info);
+
+ hdlcd->fb.var.yoffset = var->yoffset;
+ WRITE_HDLCD_REG(HDLCD_REG_FB_BASE, hdlcd->fb.fix.smem_start +
+ (var->yoffset * hdlcd->fb.fix.line_length));
+
+ hdlcd_wait_for_vsync(info);
+
+ return 0;
+}
+
+static int hdlcd_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
+{
+ int err;
+
+ switch (cmd) {
+ case FBIO_WAITFORVSYNC:
+ err = hdlcd_wait_for_vsync(info);
+ break;
+ default:
+ err = -ENOIOCTLCMD;
+ break;
+ }
+
+ return err;
+}
+
+static struct fb_ops hdlcd_ops = {
+ .owner = THIS_MODULE,
+ .fb_check_var = hdlcd_check_var,
+ .fb_set_par = hdlcd_set_par,
+ .fb_setcolreg = hdlcd_setcolreg,
+ .fb_blank = hdlcd_blank,
+ .fb_fillrect = cfb_fillrect,
+ .fb_copyarea = cfb_copyarea,
+ .fb_imageblit = cfb_imageblit,
+ .fb_mmap = hdlcd_mmap,
+ .fb_pan_display = hdlcd_pan_display,
+ .fb_ioctl = hdlcd_ioctl,
+ .fb_compat_ioctl = hdlcd_ioctl
+};
+
+static int hdlcd_setup(struct hdlcd_device *hdlcd)
+{
+ u32 version;
+ int err = -EFAULT;
+
+ hdlcd->fb.device = hdlcd->dev;
+
+ hdlcd->clk = clk_get(hdlcd->dev, NULL);
+ if (IS_ERR(hdlcd->clk)) {
+ dev_err(hdlcd->dev, "HDLCD: unable to find clock data\n");
+ return PTR_ERR(hdlcd->clk);
+ }
+
+ hdlcd->base = ioremap_nocache(hdlcd->fb.fix.mmio_start, hdlcd->fb.fix.mmio_len);
+ if (!hdlcd->base) {
+ dev_err(hdlcd->dev, "HDLCD: unable to map registers\n");
+ goto remap_err;
+ }
+
+ hdlcd->fb.pseudo_palette = kmalloc(sizeof(u32) * 16, GFP_KERNEL);
+ if (!hdlcd->fb.pseudo_palette) {
+ dev_err(hdlcd->dev, "HDLCD: unable to allocate pseudo_palette memory\n");
+ err = -ENOMEM;
+ goto kmalloc_err;
+ }
+
+ version = readl(hdlcd->base + HDLCD_REG_VERSION);
+ if ((version & HDLCD_PRODUCT_MASK) != HDLCD_PRODUCT_ID) {
+ dev_err(hdlcd->dev, "HDLCD: unknown product id: 0x%x\n", version);
+ err = -EINVAL;
+ goto kmalloc_err;
+ }
+ dev_info(hdlcd->dev, "HDLCD: found ARM HDLCD version r%dp%d\n",
+ (version & HDLCD_VERSION_MAJOR_MASK) >> 8,
+ version & HDLCD_VERSION_MINOR_MASK);
+
+ strcpy(hdlcd->fb.fix.id, "hdlcd");
+ hdlcd->fb.fbops = &hdlcd_ops;
+ hdlcd->fb.flags = FBINFO_FLAG_DEFAULT/* | FBINFO_VIRTFB*/;
+
+ hdlcd->fb.fix.type = FB_TYPE_PACKED_PIXELS;
+ hdlcd->fb.fix.type_aux = 0;
+ hdlcd->fb.fix.xpanstep = 0;
+ hdlcd->fb.fix.ypanstep = 1;
+ hdlcd->fb.fix.ywrapstep = 0;
+ hdlcd->fb.fix.accel = FB_ACCEL_NONE;
+
+ hdlcd->fb.var.nonstd = 0;
+ hdlcd->fb.var.activate = FB_ACTIVATE_NOW;
+ hdlcd->fb.var.height = -1;
+ hdlcd->fb.var.width = -1;
+ hdlcd->fb.var.accel_flags = 0;
+
+ init_completion(&hdlcd->vsync_completion);
+
+ if (hdlcd->edid) {
+ /* build modedb from EDID */
+ fb_edid_to_monspecs(hdlcd->edid, &hdlcd->fb.monspecs);
+ fb_videomode_to_modelist(hdlcd->fb.monspecs.modedb,
+ hdlcd->fb.monspecs.modedb_len,
+ &hdlcd->fb.modelist);
+ fb_find_mode(&hdlcd->fb.var, &hdlcd->fb, fb_mode,
+ hdlcd->fb.monspecs.modedb,
+ hdlcd->fb.monspecs.modedb_len,
+ &hdlcd_default_mode, 32);
+ } else {
+ hdlcd->fb.monspecs.hfmin = 0;
+ hdlcd->fb.monspecs.hfmax = 100000;
+ hdlcd->fb.monspecs.vfmin = 0;
+ hdlcd->fb.monspecs.vfmax = 400;
+ hdlcd->fb.monspecs.dclkmin = 1000000;
+ hdlcd->fb.monspecs.dclkmax = 100000000;
+ fb_find_mode(&hdlcd->fb.var, &hdlcd->fb, fb_mode, NULL, 0, &hdlcd_default_mode, 32);
+ }
+
+ dev_info(hdlcd->dev, "using %dx%d-%d@%d mode\n", hdlcd->fb.var.xres,
+ hdlcd->fb.var.yres, hdlcd->fb.var.bits_per_pixel,
+ hdlcd->fb.mode ? hdlcd->fb.mode->refresh : 60);
+ hdlcd->fb.var.xres_virtual = hdlcd->fb.var.xres;
+#ifdef HDLCD_NO_VIRTUAL_SCREEN
+ hdlcd->fb.var.yres_virtual = hdlcd->fb.var.yres;
+#else
+ hdlcd->fb.var.yres_virtual = hdlcd->fb.var.yres * 2;
+#endif
+
+ /* initialise and set the palette */
+ if (fb_alloc_cmap(&hdlcd->fb.cmap, NR_PALETTE, 0)) {
+ dev_err(hdlcd->dev, "failed to allocate cmap memory\n");
+ err = -ENOMEM;
+ goto setup_err;
+ }
+ fb_set_cmap(&hdlcd->fb.cmap, &hdlcd->fb);
+
+ /* Allow max number of outstanding requests with the largest beat burst */
+ WRITE_HDLCD_REG(HDLCD_REG_BUS_OPTIONS, HDLCD_BUS_MAX_OUTSTAND | HDLCD_BUS_BURST_16);
+ /* Set the framebuffer base to start of allocated memory */
+ WRITE_HDLCD_REG(HDLCD_REG_FB_BASE, hdlcd->fb.fix.smem_start);
+#ifdef HDLCD_COUNT_BUFFERUNDERRUNS
+ /* turn on underrun interrupt for counting */
+ WRITE_HDLCD_REG(HDLCD_REG_INT_MASK, HDLCD_INTERRUPT_UNDERRUN);
+#else
+ /* Ensure interrupts are disabled */
+ WRITE_HDLCD_REG(HDLCD_REG_INT_MASK, 0);
+#endif
+ if (!register_framebuffer(&hdlcd->fb)) {
+ fb_set_var(&hdlcd->fb, &hdlcd->fb.var);
+ clk_enable(hdlcd->clk);
+ return 0;
+ }
+
+ dev_err(hdlcd->dev, "HDLCD: cannot register framebuffer\n");
+
+ fb_dealloc_cmap(&hdlcd->fb.cmap);
+setup_err:
+ iounmap(hdlcd->base);
+kmalloc_err:
+ kfree(hdlcd->fb.pseudo_palette);
+remap_err:
+ clk_put(hdlcd->clk);
+ return err;
+}
+
+static inline unsigned char atohex(u8 data)
+{
+ if (!isxdigit(data))
+ return 0;
+ /* truncate the upper nibble and add 9 to non-digit values */
+ return (data > 0x39) ? ((data & 0xf) + 9) : (data & 0xf);
+}
+
+/* EDID data is passed from devicetree in a literal string that can contain spaces and
+ the hexadecimal dump of the data */
+static int parse_edid_data(struct hdlcd_device *hdlcd, const u8 *edid_data, int data_len)
+{
+ int i, j;
+
+ if (!edid_data)
+ return -EINVAL;
+
+ hdlcd->edid = kzalloc(EDID_LENGTH, GFP_KERNEL);
+ if (!hdlcd->edid)
+ return -ENOMEM;
+
+ for (i = 0, j = 0; i < data_len; i++) {
+ if (isspace(edid_data[i]))
+ continue;
+ hdlcd->edid[j++] = atohex(edid_data[i]);
+ if (j >= EDID_LENGTH)
+ break;
+ }
+
+ if (j < EDID_LENGTH) {
+ kfree(hdlcd->edid);
+ hdlcd->edid = NULL;
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int __devinit hdlcd_probe(struct platform_device *pdev)
+{
+ int err = 0, i;
+ struct hdlcd_device *hdlcd;
+ struct resource *mem;
+#ifdef CONFIG_OF
+ struct device_node *of_node;
+#endif
+
+ memset(&cached_var_screeninfo, 0, sizeof(struct fb_var_screeninfo));
+
+ dev_dbg(&pdev->dev, "HDLCD: probing\n");
+
+ hdlcd = kzalloc(sizeof(*hdlcd), GFP_KERNEL);
+ if (!hdlcd)
+ return -ENOMEM;
+
+#ifdef CONFIG_OF
+ of_node = pdev->dev.of_node;
+ if (of_node) {
+ int len;
+ const u8 *edid;
+ const __be32 *prop = of_get_property(of_node, "mode", &len);
+ if (prop)
+ strncpy(fb_mode, (char *)prop, len);
+ prop = of_get_property(of_node, "framebuffer", &len);
+ if (prop) {
+ hdlcd->fb.fix.smem_start = of_read_ulong(prop,
+ of_n_addr_cells(of_node));
+ prop += of_n_addr_cells(of_node);
+ framebuffer_size = of_read_ulong(prop,
+ of_n_size_cells(of_node));
+ if (framebuffer_size > HDLCD_MAX_FRAMEBUFFER_SIZE)
+ framebuffer_size = HDLCD_MAX_FRAMEBUFFER_SIZE;
+ dev_dbg(&pdev->dev, "HDLCD: phys_addr = 0x%lx, size = 0x%lx\n",
+ hdlcd->fb.fix.smem_start, framebuffer_size);
+#ifdef CONFIG_CMA
+ } else {
+ /* allocate framebuffer memory using CMA */
+ dma_addr_t dma_addr;
+ void *virt_addr;
+
+ virt_addr = dma_alloc_writecombine(&pdev->dev,
+ framebuffer_size,
+ &dma_addr, GFP_KERNEL);
+ if (!virt_addr) {
+ dev_err(&pdev->dev, "HDLCD: failed to allocate"
+ " framebuffer memory!\n");
+ return -ENOMEM;
+ }
+ hdlcd->fb.fix.smem_start = dma_addr;
+ hdlcd->fb.screen_base = virt_addr;
+ dev_dbg(&pdev->dev, "HDLCD: phys_addr = 0x%lx, size = 0x%lx\n",
+ hdlcd->fb.fix.smem_start, framebuffer_size);
+#endif
+ }
+ edid = of_get_property(of_node, "edid", &len);
+ if (edid) {
+ err = parse_edid_data(hdlcd, edid, len);
+#ifdef CONFIG_SERIAL_AMBA_PCU_UART
+ } else {
+ /* ask the firmware to fetch the EDID */
+ dev_dbg(&pdev->dev, "HDLCD: Requesting EDID data\n");
+ hdlcd->edid = kzalloc(EDID_LENGTH, GFP_KERNEL);
+ if (!hdlcd->edid)
+ return -ENOMEM;
+ err = get_edid(hdlcd->edid);
+#endif /* CONFIG_SERIAL_AMBA_PCU_UART */
+ }
+ if (err)
+ dev_info(&pdev->dev, "HDLCD: Failed to parse EDID data\n");
+ }
+#endif /* CONFIG_OF */
+
+ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!mem) {
+ dev_err(&pdev->dev, "HDLCD: cannot get platform resources\n");
+ err = -EINVAL;
+ goto resource_err;
+ }
+
+ i = platform_get_irq(pdev, 0);
+ if (i < 0) {
+ dev_err(&pdev->dev, "HDLCD: no irq defined for vsync\n");
+ err = -ENOENT;
+ goto resource_err;
+ } else {
+ err = request_irq(i, hdlcd_irq, 0, dev_name(&pdev->dev), hdlcd);
+ if (err) {
+ dev_err(&pdev->dev, "HDLCD: unable to request irq\n");
+ goto resource_err;
+ }
+ hdlcd->irq = i;
+ }
+
+ if (!request_mem_region(mem->start, resource_size(mem), dev_name(&pdev->dev))) {
+ err = -ENXIO;
+ goto request_err;
+ }
+
+ if (!hdlcd->fb.fix.smem_start) {
+ dev_err(&pdev->dev, "platform did not allocate frame buffer memory\n");
+ err = -ENOMEM;
+ goto memalloc_err;
+ }
+
+ /* if we use CMA we might have already setup the screen_base */
+ if (!hdlcd->fb.screen_base) {
+ hdlcd->fb.screen_base = ioremap_wc(hdlcd->fb.fix.smem_start,
+ framebuffer_size);
+ if (!hdlcd->fb.screen_base) {
+ dev_err(&pdev->dev, "unable to ioremap framebuffer\n");
+ err = -ENOMEM;
+ goto probe_err;
+ }
+
+ /* Clear the framebuffer */
+ memset(hdlcd->fb.screen_base, 0, framebuffer_size);
+ }
+
+ hdlcd->fb.screen_size = framebuffer_size;
+ hdlcd->fb.fix.smem_len = framebuffer_size;
+ hdlcd->fb.fix.mmio_start = mem->start;
+ hdlcd->fb.fix.mmio_len = resource_size(mem);
+
+ hdlcd->dev = &pdev->dev;
+
+ dev_dbg(&pdev->dev, "HDLCD: framebuffer virt base %p, phys base 0x%lX\n",
+ hdlcd->fb.screen_base, (unsigned long)hdlcd->fb.fix.smem_start);
+
+ err = hdlcd_setup(hdlcd);
+
+ if (err)
+ goto probe_err;
+
+ platform_set_drvdata(pdev, hdlcd);
+ return 0;
+
+probe_err:
+#ifdef CONFIG_CMA
+ dma_free_writecombine(&pdev->dev, framebuffer_size,
+ hdlcd->fb.screen_base, hdlcd->fb.fix.smem_start);
+#else
+ iounmap(hdlcd->fb.screen_base);
+ memblock_free(hdlcd->fb.fix.smem_start, hdlcd->fb.fix.smem_start);
+#endif
+
+memalloc_err:
+ release_mem_region(mem->start, resource_size(mem));
+
+request_err:
+ free_irq(hdlcd->irq, hdlcd);
+
+resource_err:
+ kfree(hdlcd);
+
+ return err;
+}
+
+static int hdlcd_remove(struct platform_device *pdev)
+{
+ struct hdlcd_device *hdlcd = platform_get_drvdata(pdev);
+
+ clk_disable(hdlcd->clk);
+ clk_unprepare(hdlcd->clk);
+ clk_put(hdlcd->clk);
+
+ /* unmap memory */
+#ifdef CONFIG_CMA
+ dma_free_writecombine(&pdev->dev, framebuffer_size,
+ hdlcd->fb.screen_base, hdlcd->fb.fix.smem_start);
+#else
+ iounmap(hdlcd->fb.screen_base);
+ memblock_free(hdlcd->fb.fix.smem_start, hdlcd->fb.fix.smem_start);
+#endif
+ iounmap(hdlcd->base);
+
+ /* deallocate memory */
+ fb_dealloc_cmap(&hdlcd->fb.cmap);
+ kfree(hdlcd->fb.pseudo_palette);
+ release_mem_region(hdlcd->fb.fix.mmio_start, hdlcd->fb.fix.mmio_len);
+
+ free_irq(hdlcd->irq, NULL);
+ kfree(hdlcd);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int hdlcd_suspend(struct platform_device *pdev, pm_message_t state)
+{
+ /* not implemented yet */
+ return 0;
+}
+
+static int hdlcd_resume(struct platform_device *pdev)
+{
+ /* not implemented yet */
+ return 0;
+}
+#else
+#define hdlcd_suspend NULL
+#define hdlcd_resume NULL
+#endif
+
+static struct platform_driver hdlcd_driver = {
+ .probe = hdlcd_probe,
+ .remove = __devexit_p(hdlcd_remove),
+ .suspend = hdlcd_suspend,
+ .resume = hdlcd_resume,
+ .driver = {
+ .name = "hdlcd",
+ .owner = THIS_MODULE,
+ .of_match_table = hdlcd_of_matches,
+ },
+};
+
+static int __init hdlcd_init(void)
+{
+ int err = platform_driver_register(&hdlcd_driver);
+
+#ifdef HDLCD_COUNT_BUFFERUNDERRUNS
+ if (!err)
+ hdlcd_underrun_init();
+#endif
+
+ return err;
+}
+
+void __exit hdlcd_exit(void)
+{
+#ifdef HDLCD_COUNT_BUFFERUNDERRUNS
+ hdlcd_underrun_close();
+#endif
+ platform_driver_unregister(&hdlcd_driver);
+}
+
+module_init(hdlcd_init);
+module_exit(hdlcd_exit);
+
+MODULE_AUTHOR("Liviu Dudau");
+MODULE_DESCRIPTION("ARM HDLCD core driver");
+MODULE_LICENSE("GPL v2");
diff --git a/include/linux/arm-hdlcd.h b/include/linux/arm-hdlcd.h
new file mode 100644
index 0000000..8ab3d7f
--- /dev/null
+++ b/include/linux/arm-hdlcd.h
@@ -0,0 +1,128 @@
+/*
+ * include/linux/arm-hdlcd.h
+ *
+ * Copyright (C) 2012 ARM Limited
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file COPYING in the main directory of this archive
+ * for more details.
+ *
+ * ARM HDLCD Controller register definition
+ */
+
+#include <linux/fb.h>
+#include <linux/completion.h>
+
+/* register offsets */
+#define HDLCD_REG_VERSION 0x0000 /* ro */
+#define HDLCD_REG_INT_RAWSTAT 0x0010 /* rw */
+#define HDLCD_REG_INT_CLEAR 0x0014 /* wo */
+#define HDLCD_REG_INT_MASK 0x0018 /* rw */
+#define HDLCD_REG_INT_STATUS 0x001c /* ro */
+#define HDLCD_REG_USER_OUT 0x0020 /* rw */
+#define HDLCD_REG_FB_BASE 0x0100 /* rw */
+#define HDLCD_REG_FB_LINE_LENGTH 0x0104 /* rw */
+#define HDLCD_REG_FB_LINE_COUNT 0x0108 /* rw */
+#define HDLCD_REG_FB_LINE_PITCH 0x010c /* rw */
+#define HDLCD_REG_BUS_OPTIONS 0x0110 /* rw */
+#define HDLCD_REG_V_SYNC 0x0200 /* rw */
+#define HDLCD_REG_V_BACK_PORCH 0x0204 /* rw */
+#define HDLCD_REG_V_DATA 0x0208 /* rw */
+#define HDLCD_REG_V_FRONT_PORCH 0x020c /* rw */
+#define HDLCD_REG_H_SYNC 0x0210 /* rw */
+#define HDLCD_REG_H_BACK_PORCH 0x0214 /* rw */
+#define HDLCD_REG_H_DATA 0x0218 /* rw */
+#define HDLCD_REG_H_FRONT_PORCH 0x021c /* rw */
+#define HDLCD_REG_POLARITIES 0x0220 /* rw */
+#define HDLCD_REG_COMMAND 0x0230 /* rw */
+#define HDLCD_REG_PIXEL_FORMAT 0x0240 /* rw */
+#define HDLCD_REG_BLUE_SELECT 0x0244 /* rw */
+#define HDLCD_REG_GREEN_SELECT 0x0248 /* rw */
+#define HDLCD_REG_RED_SELECT 0x024c /* rw */
+
+/* version */
+#define HDLCD_PRODUCT_ID 0x1CDC0000
+#define HDLCD_PRODUCT_MASK 0xFFFF0000
+#define HDLCD_VERSION_MAJOR_MASK 0x0000FF00
+#define HDLCD_VERSION_MINOR_MASK 0x000000FF
+
+/* interrupts */
+#define HDLCD_INTERRUPT_DMA_END (1 << 0)
+#define HDLCD_INTERRUPT_BUS_ERROR (1 << 1)
+#define HDLCD_INTERRUPT_VSYNC (1 << 2)
+#define HDLCD_INTERRUPT_UNDERRUN (1 << 3)
+
+/* polarity */
+#define HDLCD_POLARITY_VSYNC (1 << 0)
+#define HDLCD_POLARITY_HSYNC (1 << 1)
+#define HDLCD_POLARITY_DATAEN (1 << 2)
+#define HDLCD_POLARITY_DATA (1 << 3)
+#define HDLCD_POLARITY_PIXELCLK (1 << 4)
+
+/* commands */
+#define HDLCD_COMMAND_DISABLE (0 << 0)
+#define HDLCD_COMMAND_ENABLE (1 << 0)
+
+/* pixel format */
+#define HDLCD_PIXEL_FMT_LITTLE_ENDIAN (0 << 31)
+#define HDLCD_PIXEL_FMT_BIG_ENDIAN (1 << 31)
+#define HDLCD_BYTES_PER_PIXEL_MASK (3 << 3)
+
+/* bus options */
+#define HDLCD_BUS_BURST_MASK 0x01f
+#define HDLCD_BUS_MAX_OUTSTAND 0xf00
+#define HDLCD_BUS_BURST_NONE (0 << 0)
+#define HDLCD_BUS_BURST_1 (1 << 0)
+#define HDLCD_BUS_BURST_2 (1 << 1)
+#define HDLCD_BUS_BURST_4 (1 << 2)
+#define HDLCD_BUS_BURST_8 (1 << 3)
+#define HDLCD_BUS_BURST_16 (1 << 4)
+
+/* Max resolution supported is 4096x4096, 8 bit per color component,
+ 8 bit alpha, but we are going to choose the usual hardware default
+ (2048x2048, 32 bpp) and enable double buffering */
+#define HDLCD_MAX_XRES 2048
+#define HDLCD_MAX_YRES 2048
+#define HDLCD_MAX_FRAMEBUFFER_SIZE (HDLCD_MAX_XRES * HDLCD_MAX_YRES << 2)
+
+#define HDLCD_MEM_BASE (CONFIG_PAGE_OFFSET - 0x1000000)
+
+#define NR_PALETTE 256
+
+/*
+ * Developers using HDLCD may wish to enable these settings if
+ * display disruption is apparent and you suspect HDLCD
+ * access to RAM may be starved.
+ */
+
+/*
+ * Turn HDLCD default color to red instead of default black so
+ * that it's easy to see pixel clock data underruns
+ * (compared to other visual disruption)
+ */
+#undef HDLCD_SHOW_UNDERRUN
+
+/*
+ * Add a counter in the IRQ handler to count buffer underruns
+ * and /proc/hdlcd_underrun to read the counter
+ */
+#undef HDLCD_COUNT_BUFFERUNDERRUNS
+
+/*
+ * Restrict height to 1x screen size
+ */
+#undef HDLCD_NO_VIRTUAL_SCREEN
+
+#ifdef CONFIG_ANDROID
+#define HDLCD_NO_VIRTUAL_SCREEN
+#endif
+
+struct hdlcd_device {
+ struct fb_info fb;
+ struct device *dev;
+ struct clk *clk;
+ void __iomem *base;
+ int irq;
+ struct completion vsync_completion;
+ unsigned char *edid;
+};
--
1.7.9.5
^ permalink raw reply related
* RFC: ARM HLCD: Add support for HDLCD device driver
From: Liviu Dudau @ 2012-12-06 15:48 UTC (permalink / raw)
To: linux-arm-kernel
Hello,
This is an initial attempt to add support for ARM's HDLCD device into
the mainline kernel. This code has been in use by Linaro for a while
and now it's time to push it into mainline as more people will have
access to the CoreTiles that support the device.
This patch is sent as an RFC as I am new to the whole submission
process in the kernel and would like to gather feedback first.
Thanks,
Liviu
^ permalink raw reply
* Re: [PATCHv15 2/7] video: add display_timing and videomode
From: Grant Likely @ 2012-12-06 10:07 UTC (permalink / raw)
To: Steffen Trumtrar, Tomi Valkeinen
Cc: linux-fbdev-u79uwXL29TY76Z2rM5mHXA, Florian Tobias Schandinat,
David Airlie, devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW, Laurent Pinchart,
kernel-bIcnvbaLZ9MEGnE8C9+IrQ, Guennady Liakhovetski,
linux-media-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20121126153958.GA30791-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
On Mon, 26 Nov 2012 16:39:58 +0100, Steffen Trumtrar <s.trumtrar@pengutronix.de> wrote:
> On Mon, Nov 26, 2012 at 02:37:26PM +0200, Tomi Valkeinen wrote:
> > On 2012-11-26 11:07, Steffen Trumtrar wrote:
> >
> > > +/*
> > > + * Subsystem independent description of a videomode.
> > > + * Can be generated from struct display_timing.
> > > + */
> > > +struct videomode {
> > > + u32 pixelclock; /* pixelclock in Hz */
> >
> > I don't know if this is of any importance, but the linux clock framework
> > manages clock rates with unsigned long. Would it be better to use the
> > same type here?
> >
>
> Hm, I don't know. Anyone? u32 should be large enough for a pixelclock.
4GHz is a pretty large pixel clock. I have no idea how conceivable it is
that hardware will get to that speed. However, if it will ever be
larger, then you'll need to account for that in the DT binding so that
the pixel clock can be specified using 2 cells.
g.
^ permalink raw reply
* RE: [PATCH] da8xx: Allow use by am33xx based devices
From: Manjunathappa, Prakash @ 2012-12-06 8:08 UTC (permalink / raw)
To: Valkeinen, Tomi
Cc: linux-fbdev@vger.kernel.org, linux-kernel@vger.kernel.org,
Koen Kooi, Porter, Matt, Dill, Russ, linux-omap@vger.kernel.org,
davinci-linux-open-source@linux.davincidsp.com,
FlorianSchandinat@gmx.de, Pantelis Antoniou
In-Reply-To: <1351698968-3965-1-git-send-email-panto@antoniou-consulting.com>
Hi Tomi,
On Wed, Oct 31, 2012 at 10:52:59, Manjunathappa, Prakash wrote:
> Hi,
>
> On Wed, Oct 31, 2012 at 21:26:08, Pantelis Antoniou wrote:
> > This driver can be used for AM33xx devices, like the popular beaglebone.
> >
> > Signed-off-by: Pantelis Antoniou <panto@antoniou-consulting.com>
> > ---
> > drivers/video/Kconfig | 2 +-
> > 1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
> > index 9791d10..e7868d8 100644
> > --- a/drivers/video/Kconfig
> > +++ b/drivers/video/Kconfig
> > @@ -2202,7 +2202,7 @@ config FB_SH7760
> >
> > config FB_DA8XX
> > tristate "DA8xx/OMAP-L1xx Framebuffer support"
> > - depends on FB && ARCH_DAVINCI_DA8XX
> > + depends on FB && (ARCH_DAVINCI_DA8XX || SOC_AM33XX)
>
> Agreed this is present on da8xx and am33xx, but moving forward for
> supporting DT, we should be avoiding these dependencies. So instead
> change this to remove machine dependencies.
>
I could be wrong here, having dependency on platform seems to be right.
Otherwise may lead to build errors for other platforms. Please ignore my
comments and accept this patch.
Thanks,
Prakash
^ permalink raw reply
* [PATCH V2 6/6] OMAPDSS: DSS: Add members fld_dispc_clk_switch and dss_fck_max
From: Chandrabhanu Mahapatra @ 2012-12-05 10:28 UTC (permalink / raw)
To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, Chandrabhanu Mahapatra
In-Reply-To: <cover.1354702077.git.cmahapatra@ti.com>
The members fld_dispc_clk_switch and dss_fck_max are added to struct
dss_features and are initialized in corresponding dss_feats structure as per DSS
version. The reg_fields, num_reg_fields and dss_params entries are removed from
struct omap_dss_features as they are no longer referenced.
Signed-off-by: Chandrabhanu Mahapatra <cmahapatra@ti.com>
---
drivers/video/omap2/dss/dss.c | 22 ++++++--
drivers/video/omap2/dss/dss_features.c | 96 --------------------------------
drivers/video/omap2/dss/dss_features.h | 12 ----
3 files changed, 16 insertions(+), 114 deletions(-)
diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c
index 6ca69d5..ef005e2 100644
--- a/drivers/video/omap2/dss/dss.c
+++ b/drivers/video/omap2/dss/dss.c
@@ -69,6 +69,8 @@ struct dss_features {
u8 dss_fck_multiplier;
const char *clk_name;
int (*dpi_select_source)(enum omap_channel channel);
+ struct omapdss_reg_field fld_dispc_clk_switch;
+ int dss_fck_max;
};
static struct {
@@ -308,7 +310,6 @@ static void dss_select_dispc_clk_source(enum omap_dss_clk_source clk_src)
{
struct platform_device *dsidev;
int b;
- u8 start, end;
switch (clk_src) {
case OMAP_DSS_CLK_SRC_FCK:
@@ -329,9 +330,8 @@ static void dss_select_dispc_clk_source(enum omap_dss_clk_source clk_src)
return;
}
- dss_feat_get_reg_field(FEAT_REG_DISPC_CLK_SWITCH, &start, &end);
-
- REG_FLD_MOD(DSS_CONTROL, b, start, end); /* DISPC_CLK_SWITCH */
+ REG_FLD_MOD(DSS_CONTROL, b, dss.feat->fld_dispc_clk_switch.start,
+ dss.feat->fld_dispc_clk_switch.end); /* DISPC_CLK_SWITCH */
dss.dispc_clk_source = clk_src;
}
@@ -497,7 +497,7 @@ static int dss_setup_default_clock(void)
if (dss.dpll4_m4_ck = NULL)
return 0;
- max_dss_fck = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK);
+ max_dss_fck = dss.feat->dss_fck_max;
prate = dss_get_dpll4_rate();
@@ -533,7 +533,7 @@ int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo,
prate = dss_get_dpll4_rate();
- max_dss_fck = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK);
+ max_dss_fck = dss.feat->dss_fck_max;
fck = clk_get_rate(dss.dss_clk);
if (req_pck = dss.cache_req_pck && prate = dss.cache_prate &&
@@ -822,6 +822,8 @@ static const struct dss_features omap24xx_dss_feats __initconst = {
.dss_fck_multiplier = 2,
.clk_name = NULL,
.dpi_select_source = &dss_dpi_select_source_omap2_omap3,
+ .fld_dispc_clk_switch = { 0, 0 },
+ .dss_fck_max = 173000000,
};
static const struct dss_features omap34xx_dss_feats __initconst = {
@@ -829,6 +831,8 @@ static const struct dss_features omap34xx_dss_feats __initconst = {
.dss_fck_multiplier = 2,
.clk_name = "dpll4_m4_ck",
.dpi_select_source = &dss_dpi_select_source_omap2_omap3,
+ .fld_dispc_clk_switch = { 0, 0 },
+ .dss_fck_max = 173000000,
};
static const struct dss_features omap3630_dss_feats __initconst = {
@@ -836,6 +840,8 @@ static const struct dss_features omap3630_dss_feats __initconst = {
.dss_fck_multiplier = 1,
.clk_name = "dpll4_m4_ck",
.dpi_select_source = &dss_dpi_select_source_omap2_omap3,
+ .fld_dispc_clk_switch = { 0, 0 },
+ .dss_fck_max = 173000000,
};
static const struct dss_features omap44xx_dss_feats __initconst = {
@@ -843,6 +849,8 @@ static const struct dss_features omap44xx_dss_feats __initconst = {
.dss_fck_multiplier = 1,
.clk_name = "dpll_per_m5x2_ck",
.dpi_select_source = &dss_dpi_select_source_omap4,
+ .fld_dispc_clk_switch = { 9, 8 },
+ .dss_fck_max = 186000000,
};
static const struct dss_features omap54xx_dss_feats __initconst = {
@@ -850,6 +858,8 @@ static const struct dss_features omap54xx_dss_feats __initconst = {
.dss_fck_multiplier = 1,
.clk_name = "dpll_per_h12x2_ck",
.dpi_select_source = &dss_dpi_select_source_omap5,
+ .fld_dispc_clk_switch = { 9, 7 },
+ .dss_fck_max = 200000000,
};
static int __init dss_init_features(struct platform_device *pdev)
diff --git a/drivers/video/omap2/dss/dss_features.c b/drivers/video/omap2/dss/dss_features.c
index 75dddb2..e7fca28 100644
--- a/drivers/video/omap2/dss/dss_features.c
+++ b/drivers/video/omap2/dss/dss_features.c
@@ -27,19 +27,7 @@
#include "dss.h"
#include "dss_features.h"
-/* Defines a generic omap register field */
-struct dss_reg_field {
- u8 start, end;
-};
-
-struct dss_param_range {
- int min, max;
-};
-
struct omap_dss_features {
- const struct dss_reg_field *reg_fields;
- const int num_reg_fields;
-
const enum dss_feat_id *features;
const int num_features;
@@ -51,7 +39,6 @@ struct omap_dss_features {
const enum omap_color_mode *supported_color_modes;
const enum omap_overlay_caps *overlay_caps;
const char * const *clksrc_names;
- const struct dss_param_range *dss_params;
const enum omap_dss_rotation_type supported_rotation_types;
};
@@ -59,22 +46,6 @@ struct omap_dss_features {
/* This struct is assigned to one of the below during initialization */
static const struct omap_dss_features *omap_current_dss_features;
-static const struct dss_reg_field omap2_dss_reg_fields[] = {
- [FEAT_REG_DISPC_CLK_SWITCH] = { 0, 0 },
-};
-
-static const struct dss_reg_field omap3_dss_reg_fields[] = {
- [FEAT_REG_DISPC_CLK_SWITCH] = { 0, 0 },
-};
-
-static const struct dss_reg_field omap4_dss_reg_fields[] = {
- [FEAT_REG_DISPC_CLK_SWITCH] = { 9, 8 },
-};
-
-static const struct dss_reg_field omap5_dss_reg_fields[] = {
- [FEAT_REG_DISPC_CLK_SWITCH] = { 9, 7 },
-};
-
static const enum omap_display_type omap2_dss_supported_displays[] = {
/* OMAP_DSS_CHANNEL_LCD */
OMAP_DISPLAY_TYPE_DPI | OMAP_DISPLAY_TYPE_DBI,
@@ -367,22 +338,6 @@ static const char * const omap5_dss_clk_source_names[] = {
[OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI] = "DPLL_DSI1_C_CLK2",
};
-static const struct dss_param_range omap2_dss_param_range[] = {
- [FEAT_PARAM_DSS_FCK] = { 0, 173000000 },
-};
-
-static const struct dss_param_range omap3_dss_param_range[] = {
- [FEAT_PARAM_DSS_FCK] = { 0, 173000000 },
-};
-
-static const struct dss_param_range omap4_dss_param_range[] = {
- [FEAT_PARAM_DSS_FCK] = { 0, 186000000 },
-};
-
-static const struct dss_param_range omap5_dss_param_range[] = {
- [FEAT_PARAM_DSS_FCK] = { 0, 200000000 },
-};
-
static const enum dss_feat_id omap2_dss_feat_list[] = {
FEAT_LCDENABLEPOL,
FEAT_LCDENABLESIGNAL,
@@ -527,9 +482,6 @@ static const enum dss_feat_id omap5_dss_feat_list[] = {
/* OMAP2 DSS Features */
static const struct omap_dss_features omap2_dss_features = {
- .reg_fields = omap2_dss_reg_fields,
- .num_reg_fields = ARRAY_SIZE(omap2_dss_reg_fields),
-
.features = omap2_dss_feat_list,
.num_features = ARRAY_SIZE(omap2_dss_feat_list),
@@ -540,15 +492,11 @@ static const struct omap_dss_features omap2_dss_features = {
.supported_color_modes = omap2_dss_supported_color_modes,
.overlay_caps = omap2_dss_overlay_caps,
.clksrc_names = omap2_dss_clk_source_names,
- .dss_params = omap2_dss_param_range,
.supported_rotation_types = OMAP_DSS_ROT_DMA | OMAP_DSS_ROT_VRFB,
};
/* OMAP3 DSS Features */
static const struct omap_dss_features omap3430_dss_features = {
- .reg_fields = omap3_dss_reg_fields,
- .num_reg_fields = ARRAY_SIZE(omap3_dss_reg_fields),
-
.features = omap3430_dss_feat_list,
.num_features = ARRAY_SIZE(omap3430_dss_feat_list),
@@ -559,7 +507,6 @@ static const struct omap_dss_features omap3430_dss_features = {
.supported_color_modes = omap3_dss_supported_color_modes,
.overlay_caps = omap3430_dss_overlay_caps,
.clksrc_names = omap3_dss_clk_source_names,
- .dss_params = omap3_dss_param_range,
.supported_rotation_types = OMAP_DSS_ROT_DMA | OMAP_DSS_ROT_VRFB,
};
@@ -568,9 +515,6 @@ static const struct omap_dss_features omap3430_dss_features = {
* vdds_dsi regulator.
*/
static const struct omap_dss_features am35xx_dss_features = {
- .reg_fields = omap3_dss_reg_fields,
- .num_reg_fields = ARRAY_SIZE(omap3_dss_reg_fields),
-
.features = am35xx_dss_feat_list,
.num_features = ARRAY_SIZE(am35xx_dss_feat_list),
@@ -581,14 +525,10 @@ static const struct omap_dss_features am35xx_dss_features = {
.supported_color_modes = omap3_dss_supported_color_modes,
.overlay_caps = omap3430_dss_overlay_caps,
.clksrc_names = omap3_dss_clk_source_names,
- .dss_params = omap3_dss_param_range,
.supported_rotation_types = OMAP_DSS_ROT_DMA | OMAP_DSS_ROT_VRFB,
};
static const struct omap_dss_features omap3630_dss_features = {
- .reg_fields = omap3_dss_reg_fields,
- .num_reg_fields = ARRAY_SIZE(omap3_dss_reg_fields),
-
.features = omap3630_dss_feat_list,
.num_features = ARRAY_SIZE(omap3630_dss_feat_list),
@@ -599,16 +539,12 @@ static const struct omap_dss_features omap3630_dss_features = {
.supported_color_modes = omap3_dss_supported_color_modes,
.overlay_caps = omap3630_dss_overlay_caps,
.clksrc_names = omap3_dss_clk_source_names,
- .dss_params = omap3_dss_param_range,
.supported_rotation_types = OMAP_DSS_ROT_DMA | OMAP_DSS_ROT_VRFB,
};
/* OMAP4 DSS Features */
/* For OMAP4430 ES 1.0 revision */
static const struct omap_dss_features omap4430_es1_0_dss_features = {
- .reg_fields = omap4_dss_reg_fields,
- .num_reg_fields = ARRAY_SIZE(omap4_dss_reg_fields),
-
.features = omap4430_es1_0_dss_feat_list,
.num_features = ARRAY_SIZE(omap4430_es1_0_dss_feat_list),
@@ -620,15 +556,11 @@ static const struct omap_dss_features omap4430_es1_0_dss_features = {
.supported_color_modes = omap4_dss_supported_color_modes,
.overlay_caps = omap4_dss_overlay_caps,
.clksrc_names = omap4_dss_clk_source_names,
- .dss_params = omap4_dss_param_range,
.supported_rotation_types = OMAP_DSS_ROT_DMA | OMAP_DSS_ROT_TILER,
};
/* For OMAP4430 ES 2.0, 2.1 and 2.2 revisions */
static const struct omap_dss_features omap4430_es2_0_1_2_dss_features = {
- .reg_fields = omap4_dss_reg_fields,
- .num_reg_fields = ARRAY_SIZE(omap4_dss_reg_fields),
-
.features = omap4430_es2_0_1_2_dss_feat_list,
.num_features = ARRAY_SIZE(omap4430_es2_0_1_2_dss_feat_list),
@@ -640,15 +572,11 @@ static const struct omap_dss_features omap4430_es2_0_1_2_dss_features = {
.supported_color_modes = omap4_dss_supported_color_modes,
.overlay_caps = omap4_dss_overlay_caps,
.clksrc_names = omap4_dss_clk_source_names,
- .dss_params = omap4_dss_param_range,
.supported_rotation_types = OMAP_DSS_ROT_DMA | OMAP_DSS_ROT_TILER,
};
/* For all the other OMAP4 versions */
static const struct omap_dss_features omap4_dss_features = {
- .reg_fields = omap4_dss_reg_fields,
- .num_reg_fields = ARRAY_SIZE(omap4_dss_reg_fields),
-
.features = omap4_dss_feat_list,
.num_features = ARRAY_SIZE(omap4_dss_feat_list),
@@ -660,15 +588,11 @@ static const struct omap_dss_features omap4_dss_features = {
.supported_color_modes = omap4_dss_supported_color_modes,
.overlay_caps = omap4_dss_overlay_caps,
.clksrc_names = omap4_dss_clk_source_names,
- .dss_params = omap4_dss_param_range,
.supported_rotation_types = OMAP_DSS_ROT_DMA | OMAP_DSS_ROT_TILER,
};
/* OMAP5 DSS Features */
static const struct omap_dss_features omap5_dss_features = {
- .reg_fields = omap5_dss_reg_fields,
- .num_reg_fields = ARRAY_SIZE(omap5_dss_reg_fields),
-
.features = omap5_dss_feat_list,
.num_features = ARRAY_SIZE(omap5_dss_feat_list),
@@ -679,7 +603,6 @@ static const struct omap_dss_features omap5_dss_features = {
.supported_color_modes = omap4_dss_supported_color_modes,
.overlay_caps = omap4_dss_overlay_caps,
.clksrc_names = omap5_dss_clk_source_names,
- .dss_params = omap5_dss_param_range,
.supported_rotation_types = OMAP_DSS_ROT_DMA | OMAP_DSS_ROT_TILER,
};
@@ -744,16 +667,6 @@ int dss_feat_get_num_wbs(void)
return omap_current_dss_features->num_wbs;
}
-unsigned long dss_feat_get_param_min(enum dss_range_param param)
-{
- return omap_current_dss_features->dss_params[param].min;
-}
-
-unsigned long dss_feat_get_param_max(enum dss_range_param param)
-{
- return omap_current_dss_features->dss_params[param].max;
-}
-
enum omap_display_type dss_feat_get_supported_displays(enum omap_channel channel)
{
return omap_current_dss_features->supported_displays[channel];
@@ -801,15 +714,6 @@ bool dss_has_feature(enum dss_feat_id id)
return false;
}
-void dss_feat_get_reg_field(enum dss_feat_reg_field id, u8 *start, u8 *end)
-{
- if (id >= omap_current_dss_features->num_reg_fields)
- BUG();
-
- *start = omap_current_dss_features->reg_fields[id].start;
- *end = omap_current_dss_features->reg_fields[id].end;
-}
-
bool dss_feat_rotation_type_supported(enum omap_dss_rotation_type rot_type)
{
return omap_current_dss_features->supported_rotation_types & rot_type;
diff --git a/drivers/video/omap2/dss/dss_features.h b/drivers/video/omap2/dss/dss_features.h
index d9f69c7..0b84484 100644
--- a/drivers/video/omap2/dss/dss_features.h
+++ b/drivers/video/omap2/dss/dss_features.h
@@ -70,21 +70,10 @@ enum dss_feat_id {
FEAT_DSI_PHY_DCC,
};
-/* DSS register field id */
-enum dss_feat_reg_field {
- FEAT_REG_DISPC_CLK_SWITCH,
-};
-
-enum dss_range_param {
- FEAT_PARAM_DSS_FCK,
-};
-
/* DSS Feature Functions */
int dss_feat_get_num_mgrs(void);
int dss_feat_get_num_ovls(void);
int dss_feat_get_num_wbs(void);
-unsigned long dss_feat_get_param_min(enum dss_range_param param);
-unsigned long dss_feat_get_param_max(enum dss_range_param param);
enum omap_display_type dss_feat_get_supported_displays(enum omap_channel channel);
enum omap_dss_output_id dss_feat_get_supported_outputs(enum omap_channel channel);
enum omap_color_mode dss_feat_get_supported_color_modes(enum omap_plane plane);
@@ -96,7 +85,6 @@ const char *dss_feat_get_clk_source_name(enum omap_dss_clk_source id);
bool dss_feat_rotation_type_supported(enum omap_dss_rotation_type rot_type);
bool dss_has_feature(enum dss_feat_id id);
-void dss_feat_get_reg_field(enum dss_feat_reg_field id, u8 *start, u8 *end);
void dss_features_init(enum omapdss_version version);
#if defined(CONFIG_OMAP4_DSS_HDMI)
void dss_init_hdmi_ip_ops(struct hdmi_ip_data *ip_data,
--
1.7.10
^ permalink raw reply related
* [PATCH V2 5/6] OMAPDSS: DSI: Move DSI specific dss_params to dsi_feats
From: Chandrabhanu Mahapatra @ 2012-12-05 10:28 UTC (permalink / raw)
To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, Chandrabhanu Mahapatra
In-Reply-To: <cover.1354702077.git.cmahapatra@ti.com>
The DSI specific dss_param_range are moved from struct omap_dss_features to
corresponding struct dsi_param_range, which is initialized in struct dsi_feats
thereby enabling local access.
Signed-off-by: Chandrabhanu Mahapatra <cmahapatra@ti.com>
---
drivers/video/omap2/dss/dsi.c | 80 +++++++++++++++++++++++++++-----
drivers/video/omap2/dss/dss_features.c | 27 -----------
drivers/video/omap2/dss/dss_features.h | 7 ---
3 files changed, 69 insertions(+), 45 deletions(-)
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index 472cdb4..a1ea5ac 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -351,8 +351,20 @@ struct dsi_reg_fields {
struct omapdss_reg_field regm_dsi;
};
+struct dsi_param_ranges {
+ struct omapdss_param_range regn;
+ struct omapdss_param_range regm;
+ struct omapdss_param_range regm_dispc;
+ struct omapdss_param_range regm_dsi;
+ struct omapdss_param_range fint;
+ struct omapdss_param_range lpdiv;
+ struct omapdss_param_range dsi_fck;
+ struct omapdss_param_range dss_fck;
+};
+
struct feats {
const struct dsi_reg_fields *reg_fields;
+ const struct dsi_param_ranges *params;
};
static const struct feats *dsi_feat;
@@ -1342,7 +1354,7 @@ int dsi_pll_calc_clock_div_pck(struct platform_device *dsidev,
dss_sys_clk = clk_get_rate(dsi->sys_clk);
- max_dss_fck = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK);
+ max_dss_fck = dsi_feat->params->dss_fck.max;
if (req_pck = dsi->cache_req_pck &&
dsi->cache_cinfo.clkin = dss_sys_clk) {
@@ -1518,7 +1530,7 @@ static void dsi_pll_calc_dsi_fck(struct platform_device *dsidev,
{
unsigned long max_dsi_fck;
- max_dsi_fck = dss_feat_get_param_max(FEAT_PARAM_DSI_FCK);
+ max_dsi_fck = dsi_feat->params->dsi_fck.max;
cinfo->regm_dsi = DIV_ROUND_UP(cinfo->clkin4ddr, max_dsi_fck);
cinfo->dsi_pll_hsdiv_dsi_clk = cinfo->clkin4ddr / cinfo->regm_dsi;
@@ -1536,7 +1548,7 @@ static int dsi_pll_calc_dispc_fck(struct platform_device *dsidev,
struct dispc_clock_info best_dispc;
bool match;
- max_dss_fck = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK);
+ max_dss_fck = dsi_feat->params->dss_fck.max;
min_fck_per_pck = CONFIG_OMAP2_DSS_MIN_FCK_PER_PCK;
@@ -5077,14 +5089,13 @@ static void dsi_calc_clock_param_ranges(struct platform_device *dsidev)
{
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
- dsi->regn_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_REGN);
- dsi->regm_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_REGM);
- dsi->regm_dispc_max - dss_feat_get_param_max(FEAT_PARAM_DSIPLL_REGM_DISPC);
- dsi->regm_dsi_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_REGM_DSI);
- dsi->fint_min = dss_feat_get_param_min(FEAT_PARAM_DSIPLL_FINT);
- dsi->fint_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_FINT);
- dsi->lpdiv_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_LPDIV);
+ dsi->regn_max = dsi_feat->params->regn.max;
+ dsi->regm_max = dsi_feat->params->regm.max;
+ dsi->regm_dispc_max = dsi_feat->params->regm_dispc.max;
+ dsi->regm_dsi_max = dsi_feat->params->regm_dsi.max;
+ dsi->fint_min = dsi_feat->params->fint.min;
+ dsi->fint_max = dsi_feat->params->fint.max;
+ dsi->lpdiv_max = dsi_feat->params->lpdiv.max;
}
static int dsi_get_clocks(struct platform_device *dsidev)
@@ -5237,20 +5248,67 @@ static struct dsi_reg_fields omap5_dsi_reg_fields = {
.regm_dsi = { 30, 26 },
};
+static struct dsi_param_ranges omap2_dsi_param_ranges = {
+ .regn = { 0, 0 },
+ .regm = { 0, 0 },
+ .regm_dispc = { 0, 0 },
+ .regm_dsi = { 0, 0 },
+ .fint = { 0, 0 },
+ .lpdiv = { 0, 0 },
+ .dss_fck = { 0, 173000000 },
+};
+
+static struct dsi_param_ranges omap3_dsi_param_ranges = {
+ .regn = { 0, (1 << 7) - 1 },
+ .regm = { 0, (1 << 11) - 1 },
+ .regm_dispc = { 0, (1 << 4) - 1 },
+ .regm_dsi = { 0, (1 << 4) - 1 },
+ .fint = { 750000, 2100000 },
+ .lpdiv = { 1, (1 << 13) - 1},
+ .dsi_fck = { 0, 173000000 },
+ .dss_fck = { 0, 173000000 },
+};
+
+static struct dsi_param_ranges omap4_dsi_param_ranges = {
+ .regn = { 0, (1 << 8) - 1 },
+ .regm = { 0, (1 << 12) - 1 },
+ .regm_dispc = { 0, (1 << 5) - 1 },
+ .regm_dsi = { 0, (1 << 5) - 1 },
+ .fint = { 500000, 2500000 },
+ .lpdiv = { 0, (1 << 13) - 1 },
+ .dsi_fck = { 0, 170000000 },
+ .dss_fck = { 0, 186000000 },
+};
+
+static struct dsi_param_ranges omap5_dsi_param_ranges = {
+ .regn = { 0, (1 << 8) - 1 },
+ .regm = { 0, (1 << 12) - 1 },
+ .regm_dispc = { 0, (1 << 5) - 1 },
+ .regm_dsi = { 0, (1 << 5) - 1 },
+ .fint = { 500000, 2500000 },
+ .lpdiv = { 0, (1 << 13) - 1 },
+ .dsi_fck = { 0, 170000000 },
+ .dss_fck = { 0, 200000000 },
+};
+
static const struct feats omap24xx_dsi_feats __initconst = {
.reg_fields = &omap2_dsi_reg_fields,
+ .params = &omap2_dsi_param_ranges,
};
static const struct feats omap34xx_dsi_feats __initconst = {
.reg_fields = &omap3_dsi_reg_fields,
+ .params = &omap3_dsi_param_ranges,
};
static const struct feats omap44xx_dsi_feats __initconst = {
.reg_fields = &omap4_dsi_reg_fields,
+ .params = &omap4_dsi_param_ranges,
};
static const struct feats omap54xx_dsi_feats __initconst = {
.reg_fields = &omap5_dsi_reg_fields,
+ .params = &omap5_dsi_param_ranges,
};
static int __init dsi_init_features(struct platform_device *dsidev)
diff --git a/drivers/video/omap2/dss/dss_features.c b/drivers/video/omap2/dss/dss_features.c
index 8e6defb..75dddb2 100644
--- a/drivers/video/omap2/dss/dss_features.c
+++ b/drivers/video/omap2/dss/dss_features.c
@@ -369,45 +369,18 @@ static const char * const omap5_dss_clk_source_names[] = {
static const struct dss_param_range omap2_dss_param_range[] = {
[FEAT_PARAM_DSS_FCK] = { 0, 173000000 },
- [FEAT_PARAM_DSIPLL_REGN] = { 0, 0 },
- [FEAT_PARAM_DSIPLL_REGM] = { 0, 0 },
- [FEAT_PARAM_DSIPLL_REGM_DISPC] = { 0, 0 },
- [FEAT_PARAM_DSIPLL_REGM_DSI] = { 0, 0 },
- [FEAT_PARAM_DSIPLL_FINT] = { 0, 0 },
- [FEAT_PARAM_DSIPLL_LPDIV] = { 0, 0 },
};
static const struct dss_param_range omap3_dss_param_range[] = {
[FEAT_PARAM_DSS_FCK] = { 0, 173000000 },
- [FEAT_PARAM_DSIPLL_REGN] = { 0, (1 << 7) - 1 },
- [FEAT_PARAM_DSIPLL_REGM] = { 0, (1 << 11) - 1 },
- [FEAT_PARAM_DSIPLL_REGM_DISPC] = { 0, (1 << 4) - 1 },
- [FEAT_PARAM_DSIPLL_REGM_DSI] = { 0, (1 << 4) - 1 },
- [FEAT_PARAM_DSIPLL_FINT] = { 750000, 2100000 },
- [FEAT_PARAM_DSIPLL_LPDIV] = { 1, (1 << 13) - 1},
- [FEAT_PARAM_DSI_FCK] = { 0, 173000000 },
};
static const struct dss_param_range omap4_dss_param_range[] = {
[FEAT_PARAM_DSS_FCK] = { 0, 186000000 },
- [FEAT_PARAM_DSIPLL_REGN] = { 0, (1 << 8) - 1 },
- [FEAT_PARAM_DSIPLL_REGM] = { 0, (1 << 12) - 1 },
- [FEAT_PARAM_DSIPLL_REGM_DISPC] = { 0, (1 << 5) - 1 },
- [FEAT_PARAM_DSIPLL_REGM_DSI] = { 0, (1 << 5) - 1 },
- [FEAT_PARAM_DSIPLL_FINT] = { 500000, 2500000 },
- [FEAT_PARAM_DSIPLL_LPDIV] = { 0, (1 << 13) - 1 },
- [FEAT_PARAM_DSI_FCK] = { 0, 170000000 },
};
static const struct dss_param_range omap5_dss_param_range[] = {
[FEAT_PARAM_DSS_FCK] = { 0, 200000000 },
- [FEAT_PARAM_DSIPLL_REGN] = { 0, (1 << 8) - 1 },
- [FEAT_PARAM_DSIPLL_REGM] = { 0, (1 << 12) - 1 },
- [FEAT_PARAM_DSIPLL_REGM_DISPC] = { 0, (1 << 5) - 1 },
- [FEAT_PARAM_DSIPLL_REGM_DSI] = { 0, (1 << 5) - 1 },
- [FEAT_PARAM_DSIPLL_FINT] = { 500000, 2500000 },
- [FEAT_PARAM_DSIPLL_LPDIV] = { 0, (1 << 13) - 1 },
- [FEAT_PARAM_DSI_FCK] = { 0, 170000000 },
};
static const enum dss_feat_id omap2_dss_feat_list[] = {
diff --git a/drivers/video/omap2/dss/dss_features.h b/drivers/video/omap2/dss/dss_features.h
index 3e82404..d9f69c7 100644
--- a/drivers/video/omap2/dss/dss_features.h
+++ b/drivers/video/omap2/dss/dss_features.h
@@ -77,13 +77,6 @@ enum dss_feat_reg_field {
enum dss_range_param {
FEAT_PARAM_DSS_FCK,
- FEAT_PARAM_DSIPLL_REGN,
- FEAT_PARAM_DSIPLL_REGM,
- FEAT_PARAM_DSIPLL_REGM_DISPC,
- FEAT_PARAM_DSIPLL_REGM_DSI,
- FEAT_PARAM_DSIPLL_FINT,
- FEAT_PARAM_DSIPLL_LPDIV,
- FEAT_PARAM_DSI_FCK,
};
/* DSS Feature Functions */
--
1.7.10
^ permalink raw reply related
* [PATCH V2 4/6] OMAPDSS: DSI: Move DSI specific reg_fields to dsi_feats
From: Chandrabhanu Mahapatra @ 2012-12-05 10:28 UTC (permalink / raw)
To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, Chandrabhanu Mahapatra
In-Reply-To: <cover.1354702077.git.cmahapatra@ti.com>
The DSI specific dss_reg_fields are moved to corresponding dsi_reg_fields
initialized in dsi_feats. The dsi_feats structure is initialized as per
corresponding DSS version in dsi_init_features().
Signed-off-by: Chandrabhanu Mahapatra <cmahapatra@ti.com>
---
drivers/video/omap2/dss/dsi.c | 126 +++++++++++++++++++++++++++++---
drivers/video/omap2/dss/dss_features.c | 16 ----
drivers/video/omap2/dss/dss_features.h | 4 -
3 files changed, 114 insertions(+), 32 deletions(-)
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index cf32dc7..472cdb4 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -344,6 +344,19 @@ struct dsi_packet_sent_handler_data {
struct completion *completion;
};
+struct dsi_reg_fields {
+ struct omapdss_reg_field regn;
+ struct omapdss_reg_field regm;
+ struct omapdss_reg_field regm_dispc;
+ struct omapdss_reg_field regm_dsi;
+};
+
+struct feats {
+ const struct dsi_reg_fields *reg_fields;
+};
+
+static const struct feats *dsi_feat;
+
#ifdef DEBUG
static bool dsi_perf;
module_param(dsi_perf, bool, 0644);
@@ -1602,8 +1615,8 @@ int dsi_pll_set_clock_div(struct platform_device *dsidev,
int r = 0;
u32 l;
int f = 0;
- u8 regn_start, regn_end, regm_start, regm_end;
- u8 regm_dispc_start, regm_dispc_end, regm_dsi_start, regm_dsi_end;
+ const struct omapdss_reg_field *regn_field, *regm_field;
+ const struct omapdss_reg_field *regm_dispc_field, *regm_dsi_field;
DSSDBG("DSI PLL clock config starts");
@@ -1645,12 +1658,10 @@ int dsi_pll_set_clock_div(struct platform_device *dsidev,
dss_feat_get_clk_source_name(OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI),
cinfo->dsi_pll_hsdiv_dsi_clk);
- dss_feat_get_reg_field(FEAT_REG_DSIPLL_REGN, ®n_start, ®n_end);
- dss_feat_get_reg_field(FEAT_REG_DSIPLL_REGM, ®m_start, ®m_end);
- dss_feat_get_reg_field(FEAT_REG_DSIPLL_REGM_DISPC, ®m_dispc_start,
- ®m_dispc_end);
- dss_feat_get_reg_field(FEAT_REG_DSIPLL_REGM_DSI, ®m_dsi_start,
- ®m_dsi_end);
+ regn_field = &dsi_feat->reg_fields->regn;
+ regm_field = &dsi_feat->reg_fields->regm;
+ regm_dispc_field = &dsi_feat->reg_fields->regm_dispc;
+ regm_dsi_field = &dsi_feat->reg_fields->regm_dsi;
/* DSI_PLL_AUTOMODE = manual */
REG_FLD_MOD(dsidev, DSI_PLL_CONTROL, 0, 0, 0);
@@ -1658,15 +1669,15 @@ int dsi_pll_set_clock_div(struct platform_device *dsidev,
l = dsi_read_reg(dsidev, DSI_PLL_CONFIGURATION1);
l = FLD_MOD(l, 1, 0, 0); /* DSI_PLL_STOPMODE */
/* DSI_PLL_REGN */
- l = FLD_MOD(l, cinfo->regn - 1, regn_start, regn_end);
+ l = FLD_MOD(l, cinfo->regn - 1, regn_field->start, regn_field->end);
/* DSI_PLL_REGM */
- l = FLD_MOD(l, cinfo->regm, regm_start, regm_end);
+ l = FLD_MOD(l, cinfo->regm, regm_field->start, regm_field->end);
/* DSI_CLOCK_DIV */
l = FLD_MOD(l, cinfo->regm_dispc > 0 ? cinfo->regm_dispc - 1 : 0,
- regm_dispc_start, regm_dispc_end);
+ regm_dispc_field->start, regm_dispc_field->end);
/* DSIPROTO_CLOCK_DIV */
l = FLD_MOD(l, cinfo->regm_dsi > 0 ? cinfo->regm_dsi - 1 : 0,
- regm_dsi_start, regm_dsi_end);
+ regm_dsi_field->start, regm_dsi_field->end);
dsi_write_reg(dsidev, DSI_PLL_CONFIGURATION1, l);
BUG_ON(cinfo->fint < dsi->fint_min || cinfo->fint > dsi->fint_max);
@@ -5198,6 +5209,93 @@ static void __exit dsi_uninit_output(struct platform_device *dsidev)
dss_unregister_output(out);
}
+static struct dsi_reg_fields omap2_dsi_reg_fields = {
+ .regn = { 0, 0 },
+ .regm = { 0, 0 },
+ .regm_dispc = { 0, 0 },
+ .regm_dsi = { 0, 0 },
+};
+
+static struct dsi_reg_fields omap3_dsi_reg_fields = {
+ .regn = { 7, 1 },
+ .regm = { 18, 8 },
+ .regm_dispc = { 22, 19 },
+ .regm_dsi = { 26, 23 },
+};
+
+static struct dsi_reg_fields omap4_dsi_reg_fields = {
+ .regn = { 8, 1 },
+ .regm = { 20, 9 },
+ .regm_dispc = { 25, 21 },
+ .regm_dsi = { 30, 26 },
+};
+
+static struct dsi_reg_fields omap5_dsi_reg_fields = {
+ .regn = { 8, 1 },
+ .regm = { 20, 9 },
+ .regm_dispc = { 25, 21 },
+ .regm_dsi = { 30, 26 },
+};
+
+static const struct feats omap24xx_dsi_feats __initconst = {
+ .reg_fields = &omap2_dsi_reg_fields,
+};
+
+static const struct feats omap34xx_dsi_feats __initconst = {
+ .reg_fields = &omap3_dsi_reg_fields,
+};
+
+static const struct feats omap44xx_dsi_feats __initconst = {
+ .reg_fields = &omap4_dsi_reg_fields,
+};
+
+static const struct feats omap54xx_dsi_feats __initconst = {
+ .reg_fields = &omap5_dsi_reg_fields,
+};
+
+static int __init dsi_init_features(struct platform_device *dsidev)
+{
+ const struct feats *src;
+ struct feats *dst;
+
+ dst = devm_kzalloc(&dsidev->dev, sizeof(*dst), GFP_KERNEL);
+ if (!dst) {
+ dev_err(&dsidev->dev, "Failed to allocate DISPC Features\n");
+ return -ENOMEM;
+ }
+
+ switch (omapdss_get_version()) {
+ case OMAPDSS_VER_OMAP24xx:
+ src = &omap24xx_dsi_feats;
+ break;
+
+ case OMAPDSS_VER_OMAP34xx_ES1:
+ case OMAPDSS_VER_OMAP34xx_ES3:
+ case OMAPDSS_VER_OMAP3630:
+ case OMAPDSS_VER_AM35xx:
+ src = &omap34xx_dsi_feats;
+ break;
+
+ case OMAPDSS_VER_OMAP4430_ES1:
+ case OMAPDSS_VER_OMAP4430_ES2:
+ case OMAPDSS_VER_OMAP4:
+ src = &omap44xx_dsi_feats;
+ break;
+
+ case OMAPDSS_VER_OMAP5:
+ src = &omap54xx_dsi_feats;
+ break;
+
+ default:
+ return -ENODEV;
+ }
+
+ memcpy(dst, src, sizeof(*dst));
+ dsi_feat = dst;
+
+ return 0;
+}
+
/* DSI1 HW IP initialisation */
static int __init omap_dsihw_probe(struct platform_device *dsidev)
{
@@ -5206,6 +5304,10 @@ static int __init omap_dsihw_probe(struct platform_device *dsidev)
struct resource *dsi_mem;
struct dsi_data *dsi;
+ r = dsi_init_features(dsidev);
+ if (r)
+ return r;
+
dsi = devm_kzalloc(&dsidev->dev, sizeof(*dsi), GFP_KERNEL);
if (!dsi)
return -ENOMEM;
diff --git a/drivers/video/omap2/dss/dss_features.c b/drivers/video/omap2/dss/dss_features.c
index 3a9d1df..8e6defb 100644
--- a/drivers/video/omap2/dss/dss_features.c
+++ b/drivers/video/omap2/dss/dss_features.c
@@ -61,34 +61,18 @@ static const struct omap_dss_features *omap_current_dss_features;
static const struct dss_reg_field omap2_dss_reg_fields[] = {
[FEAT_REG_DISPC_CLK_SWITCH] = { 0, 0 },
- [FEAT_REG_DSIPLL_REGN] = { 0, 0 },
- [FEAT_REG_DSIPLL_REGM] = { 0, 0 },
- [FEAT_REG_DSIPLL_REGM_DISPC] = { 0, 0 },
- [FEAT_REG_DSIPLL_REGM_DSI] = { 0, 0 },
};
static const struct dss_reg_field omap3_dss_reg_fields[] = {
[FEAT_REG_DISPC_CLK_SWITCH] = { 0, 0 },
- [FEAT_REG_DSIPLL_REGN] = { 7, 1 },
- [FEAT_REG_DSIPLL_REGM] = { 18, 8 },
- [FEAT_REG_DSIPLL_REGM_DISPC] = { 22, 19 },
- [FEAT_REG_DSIPLL_REGM_DSI] = { 26, 23 },
};
static const struct dss_reg_field omap4_dss_reg_fields[] = {
[FEAT_REG_DISPC_CLK_SWITCH] = { 9, 8 },
- [FEAT_REG_DSIPLL_REGN] = { 8, 1 },
- [FEAT_REG_DSIPLL_REGM] = { 20, 9 },
- [FEAT_REG_DSIPLL_REGM_DISPC] = { 25, 21 },
- [FEAT_REG_DSIPLL_REGM_DSI] = { 30, 26 },
};
static const struct dss_reg_field omap5_dss_reg_fields[] = {
[FEAT_REG_DISPC_CLK_SWITCH] = { 9, 7 },
- [FEAT_REG_DSIPLL_REGN] = { 8, 1 },
- [FEAT_REG_DSIPLL_REGM] = { 20, 9 },
- [FEAT_REG_DSIPLL_REGM_DISPC] = { 25, 21 },
- [FEAT_REG_DSIPLL_REGM_DSI] = { 30, 26 },
};
static const enum omap_display_type omap2_dss_supported_displays[] = {
diff --git a/drivers/video/omap2/dss/dss_features.h b/drivers/video/omap2/dss/dss_features.h
index 40b98ff..3e82404 100644
--- a/drivers/video/omap2/dss/dss_features.h
+++ b/drivers/video/omap2/dss/dss_features.h
@@ -73,10 +73,6 @@ enum dss_feat_id {
/* DSS register field id */
enum dss_feat_reg_field {
FEAT_REG_DISPC_CLK_SWITCH,
- FEAT_REG_DSIPLL_REGN,
- FEAT_REG_DSIPLL_REGM,
- FEAT_REG_DSIPLL_REGM_DISPC,
- FEAT_REG_DSIPLL_REGM_DSI,
};
enum dss_range_param {
--
1.7.10
^ permalink raw reply related
* [PATCH V2 3/6] OMAPDSS: DISPC: Move DISPC specific dss_params to dispc_features
From: Chandrabhanu Mahapatra @ 2012-12-05 10:28 UTC (permalink / raw)
To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, Chandrabhanu Mahapatra
In-Reply-To: <cover.1354702077.git.cmahapatra@ti.com>
The DISPC specific dss_param_range are moved from struct omap_dss_features to
corresponding DSS version specific dispc_param_range struct, initialized in
dispc_features thereby enabling local access. The mgr_width_max and
mgr_height_max, members of dispc_features, are also moved to dispc_param_range.
Signed-off-by: Chandrabhanu Mahapatra <cmahapatra@ti.com>
---
drivers/video/omap2/dss/dispc.c | 83 +++++++++++++++++++++++---------
drivers/video/omap2/dss/dss.h | 4 ++
drivers/video/omap2/dss/dss_features.c | 16 ------
drivers/video/omap2/dss/dss_features.h | 3 --
4 files changed, 63 insertions(+), 43 deletions(-)
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index ee4b152..6a449a5 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -90,6 +90,14 @@ struct dispc_reg_fields {
struct omapdss_reg_field vert_accu;
};
+struct dispc_param_ranges {
+ struct omapdss_param_range pcd;
+ struct omapdss_param_range downscale;
+ struct omapdss_param_range linewidth;
+ struct omapdss_param_range mgr_width;
+ struct omapdss_param_range mgr_height;
+};
+
struct dispc_features {
u8 sw_start;
u8 fp_start;
@@ -99,8 +107,6 @@ struct dispc_features {
u16 hp_max;
u8 mgr_width_start;
u8 mgr_height_start;
- u16 mgr_width_max;
- u16 mgr_height_max;
int (*calc_scaling) (unsigned long pclk, unsigned long lclk,
const struct omap_video_timings *mgr_timings,
u16 width, u16 height, u16 out_width, u16 out_height,
@@ -122,6 +128,7 @@ struct dispc_features {
u32 burst_size_unit; /* in bytes */
struct dispc_reg_fields *reg_fields;
+ struct dispc_param_ranges *params;
};
#define DISPC_MAX_NR_FIFOS 5
@@ -2159,8 +2166,7 @@ static int dispc_ovl_calc_scaling_24xx(unsigned long pclk, unsigned long lclk,
int error;
u16 in_width, in_height;
int min_factor = min(*decim_x, *decim_y);
- const int maxsinglelinewidth - dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH);
+ const int maxsinglelinewidth = dispc.feat->params->linewidth.max;
*five_taps = false;
@@ -2200,8 +2206,7 @@ static int dispc_ovl_calc_scaling_34xx(unsigned long pclk, unsigned long lclk,
int error;
u16 in_width, in_height;
int min_factor = min(*decim_x, *decim_y);
- const int maxsinglelinewidth - dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH);
+ const int maxsinglelinewidth = dispc.feat->params->linewidth.max;
do {
in_height = DIV_ROUND_UP(height, *decim_y);
@@ -2266,9 +2271,8 @@ static int dispc_ovl_calc_scaling_44xx(unsigned long pclk, unsigned long lclk,
u16 in_width, in_width_max;
int decim_x_min = *decim_x;
u16 in_height = DIV_ROUND_UP(height, *decim_y);
- const int maxsinglelinewidth - dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH);
- const int maxdownscale = dss_feat_get_param_max(FEAT_PARAM_DOWNSCALE);
+ const int maxsinglelinewidth = dispc.feat->params->linewidth.max;
+ const int maxdownscale = dispc.feat->params->downscale.max;
if (mem_to_mem) {
in_width_max = out_width * maxdownscale;
@@ -2306,7 +2310,7 @@ static int dispc_ovl_calc_scaling(unsigned long pclk, unsigned long lclk,
int *x_predecim, int *y_predecim, u16 pos_x,
enum omap_dss_rotation_type rotation_type, bool mem_to_mem)
{
- const int maxdownscale = dss_feat_get_param_max(FEAT_PARAM_DOWNSCALE);
+ const int maxdownscale = dispc.feat->params->downscale.max;
const int max_decim_limit = 16;
unsigned long core_clk = 0;
int decim_x, decim_y, ret;
@@ -2974,8 +2978,8 @@ void dispc_mgr_set_lcd_config(enum omap_channel channel,
static bool _dispc_mgr_size_ok(u16 width, u16 height)
{
- return width <= dispc.feat->mgr_width_max &&
- height <= dispc.feat->mgr_height_max;
+ return width <= dispc.feat->params->mgr_width.max &&
+ height <= dispc.feat->params->mgr_height.max;
}
static bool _dispc_lcd_timings_ok(int hsw, int hfp, int hbp,
@@ -3547,8 +3551,8 @@ void dispc_find_clk_divs(unsigned long req_pck, unsigned long fck,
u16 best_ld, cur_ld;
u16 best_pd, cur_pd;
- pcd_min = dss_feat_get_param_min(FEAT_PARAM_DSS_PCD);
- pcd_max = dss_feat_get_param_max(FEAT_PARAM_DSS_PCD);
+ pcd_min = dispc.feat->params->pcd.min;
+ pcd_max = dispc.feat->params->pcd.max;
best_pck = 0;
best_ld = 0;
@@ -4099,6 +4103,42 @@ static struct dispc_reg_fields omap5_dispc_reg_fields = {
.vert_accu = { 26, 16 },
};
+static struct dispc_param_ranges omap2_dispc_param_ranges = {
+ .pcd = { 2, 255 },
+ .downscale = { 1, 2 },
+ /*
+ * Assuming the line width buffer to be 768 pixels as OMAP2 DISPC
+ * scaler cannot scale a image with width more than 768.
+ */
+ .linewidth = { 1, 768 },
+ .mgr_width = { 1, 2048 },
+ .mgr_height = { 1, 2048 },
+};
+
+static struct dispc_param_ranges omap3_dispc_param_ranges = {
+ .pcd = { 1, 255 },
+ .downscale = { 1, 4 },
+ .linewidth = { 1, 1024 },
+ .mgr_width = { 1, 2048 },
+ .mgr_height = { 1, 2048 },
+};
+
+static struct dispc_param_ranges omap4_dispc_param_ranges = {
+ .pcd = { 1, 255 },
+ .downscale = { 1, 4 },
+ .linewidth = { 1, 2048 },
+ .mgr_width = { 1, 2048 },
+ .mgr_height = { 1, 2048 },
+};
+
+static struct dispc_param_ranges omap5_dispc_param_ranges = {
+ .pcd = { 1, 255 },
+ .downscale = { 1, 4 },
+ .linewidth = { 1, 2048 },
+ .mgr_width = { 1, 2048 },
+ .mgr_height = { 1, 2048 },
+};
+
static const struct dispc_features omap24xx_dispc_feats __initconst = {
.sw_start = 5,
.fp_start = 15,
@@ -4108,8 +4148,6 @@ static const struct dispc_features omap24xx_dispc_feats __initconst = {
.hp_max = 256,
.mgr_width_start = 10,
.mgr_height_start = 26,
- .mgr_width_max = 2048,
- .mgr_height_max = 2048,
.calc_scaling = dispc_ovl_calc_scaling_24xx,
.calc_core_clk = calc_core_clk_24xx,
.num_fifos = 3,
@@ -4117,6 +4155,7 @@ static const struct dispc_features omap24xx_dispc_feats __initconst = {
.buffer_size_unit = 1,
.burst_size_unit = 8,
.reg_fields = &omap2_dispc_reg_fields,
+ .params = &omap2_dispc_param_ranges,
};
static const struct dispc_features omap34xx_rev1_0_dispc_feats __initconst = {
@@ -4128,8 +4167,6 @@ static const struct dispc_features omap34xx_rev1_0_dispc_feats __initconst = {
.hp_max = 256,
.mgr_width_start = 10,
.mgr_height_start = 26,
- .mgr_width_max = 2048,
- .mgr_height_max = 2048,
.calc_scaling = dispc_ovl_calc_scaling_34xx,
.calc_core_clk = calc_core_clk_34xx,
.num_fifos = 3,
@@ -4137,6 +4174,7 @@ static const struct dispc_features omap34xx_rev1_0_dispc_feats __initconst = {
.buffer_size_unit = 1,
.burst_size_unit = 8,
.reg_fields = &omap3_dispc_reg_fields,
+ .params = &omap3_dispc_param_ranges,
};
static const struct dispc_features omap34xx_rev3_0_dispc_feats __initconst = {
@@ -4148,8 +4186,6 @@ static const struct dispc_features omap34xx_rev3_0_dispc_feats __initconst = {
.hp_max = 4096,
.mgr_width_start = 10,
.mgr_height_start = 26,
- .mgr_width_max = 2048,
- .mgr_height_max = 2048,
.calc_scaling = dispc_ovl_calc_scaling_34xx,
.calc_core_clk = calc_core_clk_34xx,
.num_fifos = 3,
@@ -4157,6 +4193,7 @@ static const struct dispc_features omap34xx_rev3_0_dispc_feats __initconst = {
.buffer_size_unit = 1,
.burst_size_unit = 8,
.reg_fields = &omap3_dispc_reg_fields,
+ .params = &omap3_dispc_param_ranges,
};
static const struct dispc_features omap44xx_dispc_feats __initconst = {
@@ -4168,8 +4205,6 @@ static const struct dispc_features omap44xx_dispc_feats __initconst = {
.hp_max = 4096,
.mgr_width_start = 10,
.mgr_height_start = 26,
- .mgr_width_max = 2048,
- .mgr_height_max = 2048,
.calc_scaling = dispc_ovl_calc_scaling_44xx,
.calc_core_clk = calc_core_clk_44xx,
.num_fifos = 5,
@@ -4177,6 +4212,7 @@ static const struct dispc_features omap44xx_dispc_feats __initconst = {
.buffer_size_unit = 16,
.burst_size_unit = 16,
.reg_fields = &omap4_dispc_reg_fields,
+ .params = &omap4_dispc_param_ranges,
};
static const struct dispc_features omap54xx_dispc_feats __initconst = {
@@ -4188,8 +4224,6 @@ static const struct dispc_features omap54xx_dispc_feats __initconst = {
.hp_max = 4096,
.mgr_width_start = 11,
.mgr_height_start = 27,
- .mgr_width_max = 4096,
- .mgr_height_max = 4096,
.calc_scaling = dispc_ovl_calc_scaling_44xx,
.calc_core_clk = calc_core_clk_44xx,
.num_fifos = 5,
@@ -4197,6 +4231,7 @@ static const struct dispc_features omap54xx_dispc_feats __initconst = {
.buffer_size_unit = 16,
.burst_size_unit = 16,
.reg_fields = &omap5_dispc_reg_fields,
+ .params = &omap5_dispc_param_ranges,
};
static int __init dispc_init_features(struct platform_device *pdev)
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 18842e2..0b68001 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -147,6 +147,10 @@ struct omapdss_reg_field {
u8 start, end;
};
+struct omapdss_param_range {
+ int min, max;
+};
+
struct dss_lcd_mgr_config {
enum dss_io_pad_mode io_pad_mode;
diff --git a/drivers/video/omap2/dss/dss_features.c b/drivers/video/omap2/dss/dss_features.c
index defdfc0..3a9d1df 100644
--- a/drivers/video/omap2/dss/dss_features.c
+++ b/drivers/video/omap2/dss/dss_features.c
@@ -385,24 +385,16 @@ static const char * const omap5_dss_clk_source_names[] = {
static const struct dss_param_range omap2_dss_param_range[] = {
[FEAT_PARAM_DSS_FCK] = { 0, 173000000 },
- [FEAT_PARAM_DSS_PCD] = { 2, 255 },
[FEAT_PARAM_DSIPLL_REGN] = { 0, 0 },
[FEAT_PARAM_DSIPLL_REGM] = { 0, 0 },
[FEAT_PARAM_DSIPLL_REGM_DISPC] = { 0, 0 },
[FEAT_PARAM_DSIPLL_REGM_DSI] = { 0, 0 },
[FEAT_PARAM_DSIPLL_FINT] = { 0, 0 },
[FEAT_PARAM_DSIPLL_LPDIV] = { 0, 0 },
- [FEAT_PARAM_DOWNSCALE] = { 1, 2 },
- /*
- * Assuming the line width buffer to be 768 pixels as OMAP2 DISPC
- * scaler cannot scale a image with width more than 768.
- */
- [FEAT_PARAM_LINEWIDTH] = { 1, 768 },
};
static const struct dss_param_range omap3_dss_param_range[] = {
[FEAT_PARAM_DSS_FCK] = { 0, 173000000 },
- [FEAT_PARAM_DSS_PCD] = { 1, 255 },
[FEAT_PARAM_DSIPLL_REGN] = { 0, (1 << 7) - 1 },
[FEAT_PARAM_DSIPLL_REGM] = { 0, (1 << 11) - 1 },
[FEAT_PARAM_DSIPLL_REGM_DISPC] = { 0, (1 << 4) - 1 },
@@ -410,13 +402,10 @@ static const struct dss_param_range omap3_dss_param_range[] = {
[FEAT_PARAM_DSIPLL_FINT] = { 750000, 2100000 },
[FEAT_PARAM_DSIPLL_LPDIV] = { 1, (1 << 13) - 1},
[FEAT_PARAM_DSI_FCK] = { 0, 173000000 },
- [FEAT_PARAM_DOWNSCALE] = { 1, 4 },
- [FEAT_PARAM_LINEWIDTH] = { 1, 1024 },
};
static const struct dss_param_range omap4_dss_param_range[] = {
[FEAT_PARAM_DSS_FCK] = { 0, 186000000 },
- [FEAT_PARAM_DSS_PCD] = { 1, 255 },
[FEAT_PARAM_DSIPLL_REGN] = { 0, (1 << 8) - 1 },
[FEAT_PARAM_DSIPLL_REGM] = { 0, (1 << 12) - 1 },
[FEAT_PARAM_DSIPLL_REGM_DISPC] = { 0, (1 << 5) - 1 },
@@ -424,13 +413,10 @@ static const struct dss_param_range omap4_dss_param_range[] = {
[FEAT_PARAM_DSIPLL_FINT] = { 500000, 2500000 },
[FEAT_PARAM_DSIPLL_LPDIV] = { 0, (1 << 13) - 1 },
[FEAT_PARAM_DSI_FCK] = { 0, 170000000 },
- [FEAT_PARAM_DOWNSCALE] = { 1, 4 },
- [FEAT_PARAM_LINEWIDTH] = { 1, 2048 },
};
static const struct dss_param_range omap5_dss_param_range[] = {
[FEAT_PARAM_DSS_FCK] = { 0, 200000000 },
- [FEAT_PARAM_DSS_PCD] = { 1, 255 },
[FEAT_PARAM_DSIPLL_REGN] = { 0, (1 << 8) - 1 },
[FEAT_PARAM_DSIPLL_REGM] = { 0, (1 << 12) - 1 },
[FEAT_PARAM_DSIPLL_REGM_DISPC] = { 0, (1 << 5) - 1 },
@@ -438,8 +424,6 @@ static const struct dss_param_range omap5_dss_param_range[] = {
[FEAT_PARAM_DSIPLL_FINT] = { 500000, 2500000 },
[FEAT_PARAM_DSIPLL_LPDIV] = { 0, (1 << 13) - 1 },
[FEAT_PARAM_DSI_FCK] = { 0, 170000000 },
- [FEAT_PARAM_DOWNSCALE] = { 1, 4 },
- [FEAT_PARAM_LINEWIDTH] = { 1, 2048 },
};
static const enum dss_feat_id omap2_dss_feat_list[] = {
diff --git a/drivers/video/omap2/dss/dss_features.h b/drivers/video/omap2/dss/dss_features.h
index 42a1bd1..40b98ff 100644
--- a/drivers/video/omap2/dss/dss_features.h
+++ b/drivers/video/omap2/dss/dss_features.h
@@ -81,7 +81,6 @@ enum dss_feat_reg_field {
enum dss_range_param {
FEAT_PARAM_DSS_FCK,
- FEAT_PARAM_DSS_PCD,
FEAT_PARAM_DSIPLL_REGN,
FEAT_PARAM_DSIPLL_REGM,
FEAT_PARAM_DSIPLL_REGM_DISPC,
@@ -89,8 +88,6 @@ enum dss_range_param {
FEAT_PARAM_DSIPLL_FINT,
FEAT_PARAM_DSIPLL_LPDIV,
FEAT_PARAM_DSI_FCK,
- FEAT_PARAM_DOWNSCALE,
- FEAT_PARAM_LINEWIDTH,
};
/* DSS Feature Functions */
--
1.7.10
^ permalink raw reply related
* [PATCH V2 2/6] OMAPDSS: DISPC: Move DISPC specific dss_reg_fields to dispc_features
From: Chandrabhanu Mahapatra @ 2012-12-05 10:28 UTC (permalink / raw)
To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, Chandrabhanu Mahapatra
In-Reply-To: <cover.1354702077.git.cmahapatra@ti.com>
The register fields in dss_reg_fields specific to DISPC are moved from struct
omap_dss_features to corresponding dispc_reg_fields, initialized in struct
dispc_features, thereby enabling local access.
Signed-off-by: Chandrabhanu Mahapatra <cmahapatra@ti.com>
---
drivers/video/omap2/dss/dispc.c | 114 ++++++++++++++++++++++++--------
drivers/video/omap2/dss/dss.h | 4 ++
drivers/video/omap2/dss/dss_features.c | 28 --------
drivers/video/omap2/dss/dss_features.h | 7 --
4 files changed, 89 insertions(+), 64 deletions(-)
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index bbba83f..ee4b152 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -80,6 +80,16 @@ struct dispc_irq_stats {
unsigned irqs[32];
};
+struct dispc_reg_fields {
+ struct omapdss_reg_field firhinc;
+ struct omapdss_reg_field firvinc;
+ struct omapdss_reg_field fifo_low_thresh;
+ struct omapdss_reg_field fifo_high_thresh;
+ struct omapdss_reg_field fifosize;
+ struct omapdss_reg_field hori_accu;
+ struct omapdss_reg_field vert_accu;
+};
+
struct dispc_features {
u8 sw_start;
u8 fp_start;
@@ -110,6 +120,8 @@ struct dispc_features {
u32 buffer_size_unit; /* in bytes */
u32 burst_size_unit; /* in bytes */
+
+ struct dispc_reg_fields *reg_fields;
};
#define DISPC_MAX_NR_FIFOS 5
@@ -1137,17 +1149,17 @@ static void dispc_mgr_set_size(enum omap_channel channel, u16 width,
static void dispc_init_fifos(void)
{
- u32 size;
+ u32 size, unit;
int fifo;
- u8 start, end;
- u32 unit;
+ const struct omapdss_reg_field *fifo_field;
unit = dispc.feat->buffer_size_unit;
- dss_feat_get_reg_field(FEAT_REG_FIFOSIZE, &start, &end);
+ fifo_field = &dispc.feat->reg_fields->fifosize;
for (fifo = 0; fifo < dispc.feat->num_fifos; ++fifo) {
- size = REG_GET(DISPC_OVL_FIFO_SIZE_STATUS(fifo), start, end);
+ size = REG_GET(DISPC_OVL_FIFO_SIZE_STATUS(fifo),
+ fifo_field->start, fifo_field->end);
size *= unit;
dispc.fifo_size[fifo] = size;
@@ -1197,8 +1209,8 @@ static u32 dispc_ovl_get_fifo_size(enum omap_plane plane)
void dispc_ovl_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high)
{
- u8 hi_start, hi_end, lo_start, lo_end;
u32 unit;
+ const struct omapdss_reg_field *hi_field, *lo_field;
unit = dispc.feat->buffer_size_unit;
@@ -1208,20 +1220,20 @@ void dispc_ovl_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high)
low /= unit;
high /= unit;
- dss_feat_get_reg_field(FEAT_REG_FIFOHIGHTHRESHOLD, &hi_start, &hi_end);
- dss_feat_get_reg_field(FEAT_REG_FIFOLOWTHRESHOLD, &lo_start, &lo_end);
+ hi_field = &dispc.feat->reg_fields->fifo_high_thresh;
+ lo_field = &dispc.feat->reg_fields->fifo_low_thresh;
DSSDBG("fifo(%d) threshold (bytes), old %u/%u, new %u/%u\n",
plane,
REG_GET(DISPC_OVL_FIFO_THRESHOLD(plane),
- lo_start, lo_end) * unit,
+ lo_field->start, lo_field->end) * unit,
REG_GET(DISPC_OVL_FIFO_THRESHOLD(plane),
- hi_start, hi_end) * unit,
+ hi_field->start, hi_field->end) * unit,
low * unit, high * unit);
dispc_write_reg(DISPC_OVL_FIFO_THRESHOLD(plane),
- FLD_VAL(high, hi_start, hi_end) |
- FLD_VAL(low, lo_start, lo_end));
+ FLD_VAL(high, hi_field->start, hi_field->end) |
+ FLD_VAL(low, lo_field->start, lo_field->end));
}
void dispc_enable_fifomerge(bool enable)
@@ -1289,14 +1301,13 @@ static void dispc_ovl_set_fir(enum omap_plane plane,
u32 val;
if (color_comp = DISPC_COLOR_COMPONENT_RGB_Y) {
- u8 hinc_start, hinc_end, vinc_start, vinc_end;
+ const struct omapdss_reg_field *hinc_field, *vinc_field;
- dss_feat_get_reg_field(FEAT_REG_FIRHINC,
- &hinc_start, &hinc_end);
- dss_feat_get_reg_field(FEAT_REG_FIRVINC,
- &vinc_start, &vinc_end);
- val = FLD_VAL(vinc, vinc_start, vinc_end) |
- FLD_VAL(hinc, hinc_start, hinc_end);
+ hinc_field = &dispc.feat->reg_fields->firhinc;
+ vinc_field = &dispc.feat->reg_fields->firvinc;
+
+ val = FLD_VAL(vinc, vinc_field->start, vinc_field->end) |
+ FLD_VAL(hinc, hinc_field->start, hinc_field->end);
dispc_write_reg(DISPC_OVL_FIR(plane), val);
} else {
@@ -1308,13 +1319,13 @@ static void dispc_ovl_set_fir(enum omap_plane plane,
static void dispc_ovl_set_vid_accu0(enum omap_plane plane, int haccu, int vaccu)
{
u32 val;
- u8 hor_start, hor_end, vert_start, vert_end;
+ const struct omapdss_reg_field *haccu_field, *vaccu_field;
- dss_feat_get_reg_field(FEAT_REG_HORIZONTALACCU, &hor_start, &hor_end);
- dss_feat_get_reg_field(FEAT_REG_VERTICALACCU, &vert_start, &vert_end);
+ haccu_field = &dispc.feat->reg_fields->hori_accu;
+ vaccu_field = &dispc.feat->reg_fields->vert_accu;
- val = FLD_VAL(vaccu, vert_start, vert_end) |
- FLD_VAL(haccu, hor_start, hor_end);
+ val = FLD_VAL(vaccu, vaccu_field->start, vaccu_field->end) |
+ FLD_VAL(haccu, haccu_field->start, haccu_field->end);
dispc_write_reg(DISPC_OVL_ACCU0(plane), val);
}
@@ -1322,13 +1333,13 @@ static void dispc_ovl_set_vid_accu0(enum omap_plane plane, int haccu, int vaccu)
static void dispc_ovl_set_vid_accu1(enum omap_plane plane, int haccu, int vaccu)
{
u32 val;
- u8 hor_start, hor_end, vert_start, vert_end;
+ const struct omapdss_reg_field *haccu_field, *vaccu_field;
- dss_feat_get_reg_field(FEAT_REG_HORIZONTALACCU, &hor_start, &hor_end);
- dss_feat_get_reg_field(FEAT_REG_VERTICALACCU, &vert_start, &vert_end);
+ haccu_field = &dispc.feat->reg_fields->hori_accu;
+ vaccu_field = &dispc.feat->reg_fields->vert_accu;
- val = FLD_VAL(vaccu, vert_start, vert_end) |
- FLD_VAL(haccu, hor_start, hor_end);
+ val = FLD_VAL(vaccu, vaccu_field->start, vaccu_field->end) |
+ FLD_VAL(haccu, haccu_field->start, haccu_field->end);
dispc_write_reg(DISPC_OVL_ACCU1(plane), val);
}
@@ -4048,6 +4059,46 @@ static void _omap_dispc_initial_config(void)
dispc_ovl_enable_zorder_planes();
}
+static struct dispc_reg_fields omap2_dispc_reg_fields = {
+ .firhinc = { 11, 0 },
+ .firvinc = { 27, 16 },
+ .fifo_low_thresh = { 8, 0 },
+ .fifo_high_thresh = { 24, 16 },
+ .fifosize = { 8, 0 },
+ .hori_accu = { 9, 0 },
+ .vert_accu = { 25, 16 },
+};
+
+static struct dispc_reg_fields omap3_dispc_reg_fields = {
+ .firhinc = { 12, 0 },
+ .firvinc = { 28, 16 },
+ .fifo_low_thresh = { 11, 0 },
+ .fifo_high_thresh = { 27, 16 },
+ .fifosize = { 10, 0 },
+ .hori_accu = { 9, 0 },
+ .vert_accu = { 25, 16 },
+};
+
+static struct dispc_reg_fields omap4_dispc_reg_fields = {
+ .firhinc = { 12, 0 },
+ .firvinc = { 28, 16 },
+ .fifo_low_thresh = { 15, 0 },
+ .fifo_high_thresh = { 31, 16 },
+ .fifosize = { 15, 0 },
+ .hori_accu = { 10, 0 },
+ .vert_accu = { 26, 16 },
+};
+
+static struct dispc_reg_fields omap5_dispc_reg_fields = {
+ .firhinc = { 12, 0 },
+ .firvinc = { 28, 16 },
+ .fifo_low_thresh = { 15, 0 },
+ .fifo_high_thresh = { 31, 16 },
+ .fifosize = { 15, 0 },
+ .hori_accu = { 10, 0 },
+ .vert_accu = { 26, 16 },
+};
+
static const struct dispc_features omap24xx_dispc_feats __initconst = {
.sw_start = 5,
.fp_start = 15,
@@ -4065,6 +4116,7 @@ static const struct dispc_features omap24xx_dispc_feats __initconst = {
.no_framedone_tv = true,
.buffer_size_unit = 1,
.burst_size_unit = 8,
+ .reg_fields = &omap2_dispc_reg_fields,
};
static const struct dispc_features omap34xx_rev1_0_dispc_feats __initconst = {
@@ -4084,6 +4136,7 @@ static const struct dispc_features omap34xx_rev1_0_dispc_feats __initconst = {
.no_framedone_tv = true,
.buffer_size_unit = 1,
.burst_size_unit = 8,
+ .reg_fields = &omap3_dispc_reg_fields,
};
static const struct dispc_features omap34xx_rev3_0_dispc_feats __initconst = {
@@ -4103,6 +4156,7 @@ static const struct dispc_features omap34xx_rev3_0_dispc_feats __initconst = {
.no_framedone_tv = true,
.buffer_size_unit = 1,
.burst_size_unit = 8,
+ .reg_fields = &omap3_dispc_reg_fields,
};
static const struct dispc_features omap44xx_dispc_feats __initconst = {
@@ -4122,6 +4176,7 @@ static const struct dispc_features omap44xx_dispc_feats __initconst = {
.gfx_fifo_workaround = true,
.buffer_size_unit = 16,
.burst_size_unit = 16,
+ .reg_fields = &omap4_dispc_reg_fields,
};
static const struct dispc_features omap54xx_dispc_feats __initconst = {
@@ -4141,6 +4196,7 @@ static const struct dispc_features omap54xx_dispc_feats __initconst = {
.gfx_fifo_workaround = true,
.buffer_size_unit = 16,
.burst_size_unit = 16,
+ .reg_fields = &omap5_dispc_reg_fields,
};
static int __init dispc_init_features(struct platform_device *pdev)
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 9ee3c88..18842e2 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -143,6 +143,10 @@ struct reg_field {
u8 low;
};
+struct omapdss_reg_field {
+ u8 start, end;
+};
+
struct dss_lcd_mgr_config {
enum dss_io_pad_mode io_pad_mode;
diff --git a/drivers/video/omap2/dss/dss_features.c b/drivers/video/omap2/dss/dss_features.c
index 092e21b..defdfc0 100644
--- a/drivers/video/omap2/dss/dss_features.c
+++ b/drivers/video/omap2/dss/dss_features.c
@@ -60,13 +60,6 @@ struct omap_dss_features {
static const struct omap_dss_features *omap_current_dss_features;
static const struct dss_reg_field omap2_dss_reg_fields[] = {
- [FEAT_REG_FIRHINC] = { 11, 0 },
- [FEAT_REG_FIRVINC] = { 27, 16 },
- [FEAT_REG_FIFOLOWTHRESHOLD] = { 8, 0 },
- [FEAT_REG_FIFOHIGHTHRESHOLD] = { 24, 16 },
- [FEAT_REG_FIFOSIZE] = { 8, 0 },
- [FEAT_REG_HORIZONTALACCU] = { 9, 0 },
- [FEAT_REG_VERTICALACCU] = { 25, 16 },
[FEAT_REG_DISPC_CLK_SWITCH] = { 0, 0 },
[FEAT_REG_DSIPLL_REGN] = { 0, 0 },
[FEAT_REG_DSIPLL_REGM] = { 0, 0 },
@@ -75,13 +68,6 @@ static const struct dss_reg_field omap2_dss_reg_fields[] = {
};
static const struct dss_reg_field omap3_dss_reg_fields[] = {
- [FEAT_REG_FIRHINC] = { 12, 0 },
- [FEAT_REG_FIRVINC] = { 28, 16 },
- [FEAT_REG_FIFOLOWTHRESHOLD] = { 11, 0 },
- [FEAT_REG_FIFOHIGHTHRESHOLD] = { 27, 16 },
- [FEAT_REG_FIFOSIZE] = { 10, 0 },
- [FEAT_REG_HORIZONTALACCU] = { 9, 0 },
- [FEAT_REG_VERTICALACCU] = { 25, 16 },
[FEAT_REG_DISPC_CLK_SWITCH] = { 0, 0 },
[FEAT_REG_DSIPLL_REGN] = { 7, 1 },
[FEAT_REG_DSIPLL_REGM] = { 18, 8 },
@@ -90,13 +76,6 @@ static const struct dss_reg_field omap3_dss_reg_fields[] = {
};
static const struct dss_reg_field omap4_dss_reg_fields[] = {
- [FEAT_REG_FIRHINC] = { 12, 0 },
- [FEAT_REG_FIRVINC] = { 28, 16 },
- [FEAT_REG_FIFOLOWTHRESHOLD] = { 15, 0 },
- [FEAT_REG_FIFOHIGHTHRESHOLD] = { 31, 16 },
- [FEAT_REG_FIFOSIZE] = { 15, 0 },
- [FEAT_REG_HORIZONTALACCU] = { 10, 0 },
- [FEAT_REG_VERTICALACCU] = { 26, 16 },
[FEAT_REG_DISPC_CLK_SWITCH] = { 9, 8 },
[FEAT_REG_DSIPLL_REGN] = { 8, 1 },
[FEAT_REG_DSIPLL_REGM] = { 20, 9 },
@@ -105,13 +84,6 @@ static const struct dss_reg_field omap4_dss_reg_fields[] = {
};
static const struct dss_reg_field omap5_dss_reg_fields[] = {
- [FEAT_REG_FIRHINC] = { 12, 0 },
- [FEAT_REG_FIRVINC] = { 28, 16 },
- [FEAT_REG_FIFOLOWTHRESHOLD] = { 15, 0 },
- [FEAT_REG_FIFOHIGHTHRESHOLD] = { 31, 16 },
- [FEAT_REG_FIFOSIZE] = { 15, 0 },
- [FEAT_REG_HORIZONTALACCU] = { 10, 0 },
- [FEAT_REG_VERTICALACCU] = { 26, 16 },
[FEAT_REG_DISPC_CLK_SWITCH] = { 9, 7 },
[FEAT_REG_DSIPLL_REGN] = { 8, 1 },
[FEAT_REG_DSIPLL_REGM] = { 20, 9 },
diff --git a/drivers/video/omap2/dss/dss_features.h b/drivers/video/omap2/dss/dss_features.h
index 16658e1..42a1bd1 100644
--- a/drivers/video/omap2/dss/dss_features.h
+++ b/drivers/video/omap2/dss/dss_features.h
@@ -72,13 +72,6 @@ enum dss_feat_id {
/* DSS register field id */
enum dss_feat_reg_field {
- FEAT_REG_FIRHINC,
- FEAT_REG_FIRVINC,
- FEAT_REG_FIFOHIGHTHRESHOLD,
- FEAT_REG_FIFOLOWTHRESHOLD,
- FEAT_REG_FIFOSIZE,
- FEAT_REG_HORIZONTALACCU,
- FEAT_REG_VERTICALACCU,
FEAT_REG_DISPC_CLK_SWITCH,
FEAT_REG_DSIPLL_REGN,
FEAT_REG_DSIPLL_REGM,
--
1.7.10
^ permalink raw reply related
* [PATCH V2 1/6] OMAPDSS: DISPC: Move burst_size and buffer_size to dispc_features
From: Chandrabhanu Mahapatra @ 2012-12-05 10:28 UTC (permalink / raw)
To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, Chandrabhanu Mahapatra
In-Reply-To: <cover.1354702077.git.cmahapatra@ti.com>
The burst_size and buffer_size being local data to DISPC are moved to
dispc_features and so removed from struct omap_dss_features. The functions
referring to burst and buffer size are also removed from dss_features.c as they
are now accessed locally in dispc.c.
Signed-off-by: Chandrabhanu Mahapatra <cmahapatra@ti.com>
---
drivers/video/omap2/dss/dispc.c | 21 +++++++++++++++++----
drivers/video/omap2/dss/dss_features.c | 29 -----------------------------
drivers/video/omap2/dss/dss_features.h | 3 ---
3 files changed, 17 insertions(+), 36 deletions(-)
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index ce594a1..bbba83f 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -107,6 +107,9 @@ struct dispc_features {
/* no DISPC_IRQ_FRAMEDONETV on this SoC */
bool no_framedone_tv:1;
+
+ u32 buffer_size_unit; /* in bytes */
+ u32 burst_size_unit; /* in bytes */
};
#define DISPC_MAX_NR_FIFOS 5
@@ -1050,7 +1053,7 @@ static void dispc_configure_burst_sizes(void)
static u32 dispc_ovl_get_burst_size(enum omap_plane plane)
{
- unsigned unit = dss_feat_get_burst_size_unit();
+ unsigned unit = dispc.feat->burst_size_unit;
/* burst multiplier is always x8 (see dispc_configure_burst_sizes()) */
return unit * 8;
}
@@ -1139,7 +1142,7 @@ static void dispc_init_fifos(void)
u8 start, end;
u32 unit;
- unit = dss_feat_get_buffer_size_unit();
+ unit = dispc.feat->buffer_size_unit;
dss_feat_get_reg_field(FEAT_REG_FIFOSIZE, &start, &end);
@@ -1197,7 +1200,7 @@ void dispc_ovl_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high)
u8 hi_start, hi_end, lo_start, lo_end;
u32 unit;
- unit = dss_feat_get_buffer_size_unit();
+ unit = dispc.feat->buffer_size_unit;
WARN_ON(low % unit != 0);
WARN_ON(high % unit != 0);
@@ -1241,7 +1244,7 @@ void dispc_ovl_compute_fifo_thresholds(enum omap_plane plane,
* buffer_units, and the fifo thresholds must be buffer_unit aligned.
*/
- unsigned buf_unit = dss_feat_get_buffer_size_unit();
+ unsigned buf_unit = dispc.feat->buffer_size_unit;
unsigned ovl_fifo_size, total_fifo_size, burst_size;
int i;
@@ -4060,6 +4063,8 @@ static const struct dispc_features omap24xx_dispc_feats __initconst = {
.calc_core_clk = calc_core_clk_24xx,
.num_fifos = 3,
.no_framedone_tv = true,
+ .buffer_size_unit = 1,
+ .burst_size_unit = 8,
};
static const struct dispc_features omap34xx_rev1_0_dispc_feats __initconst = {
@@ -4077,6 +4082,8 @@ static const struct dispc_features omap34xx_rev1_0_dispc_feats __initconst = {
.calc_core_clk = calc_core_clk_34xx,
.num_fifos = 3,
.no_framedone_tv = true,
+ .buffer_size_unit = 1,
+ .burst_size_unit = 8,
};
static const struct dispc_features omap34xx_rev3_0_dispc_feats __initconst = {
@@ -4094,6 +4101,8 @@ static const struct dispc_features omap34xx_rev3_0_dispc_feats __initconst = {
.calc_core_clk = calc_core_clk_34xx,
.num_fifos = 3,
.no_framedone_tv = true,
+ .buffer_size_unit = 1,
+ .burst_size_unit = 8,
};
static const struct dispc_features omap44xx_dispc_feats __initconst = {
@@ -4111,6 +4120,8 @@ static const struct dispc_features omap44xx_dispc_feats __initconst = {
.calc_core_clk = calc_core_clk_44xx,
.num_fifos = 5,
.gfx_fifo_workaround = true,
+ .buffer_size_unit = 16,
+ .burst_size_unit = 16,
};
static const struct dispc_features omap54xx_dispc_feats __initconst = {
@@ -4128,6 +4139,8 @@ static const struct dispc_features omap54xx_dispc_feats __initconst = {
.calc_core_clk = calc_core_clk_44xx,
.num_fifos = 5,
.gfx_fifo_workaround = true,
+ .buffer_size_unit = 16,
+ .burst_size_unit = 16,
};
static int __init dispc_init_features(struct platform_device *pdev)
diff --git a/drivers/video/omap2/dss/dss_features.c b/drivers/video/omap2/dss/dss_features.c
index 1d125c6..092e21b 100644
--- a/drivers/video/omap2/dss/dss_features.c
+++ b/drivers/video/omap2/dss/dss_features.c
@@ -54,9 +54,6 @@ struct omap_dss_features {
const struct dss_param_range *dss_params;
const enum omap_dss_rotation_type supported_rotation_types;
-
- const u32 buffer_size_unit;
- const u32 burst_size_unit;
};
/* This struct is assigned to one of the below during initialization */
@@ -632,8 +629,6 @@ static const struct omap_dss_features omap2_dss_features = {
.clksrc_names = omap2_dss_clk_source_names,
.dss_params = omap2_dss_param_range,
.supported_rotation_types = OMAP_DSS_ROT_DMA | OMAP_DSS_ROT_VRFB,
- .buffer_size_unit = 1,
- .burst_size_unit = 8,
};
/* OMAP3 DSS Features */
@@ -653,8 +648,6 @@ static const struct omap_dss_features omap3430_dss_features = {
.clksrc_names = omap3_dss_clk_source_names,
.dss_params = omap3_dss_param_range,
.supported_rotation_types = OMAP_DSS_ROT_DMA | OMAP_DSS_ROT_VRFB,
- .buffer_size_unit = 1,
- .burst_size_unit = 8,
};
/*
@@ -677,8 +670,6 @@ static const struct omap_dss_features am35xx_dss_features = {
.clksrc_names = omap3_dss_clk_source_names,
.dss_params = omap3_dss_param_range,
.supported_rotation_types = OMAP_DSS_ROT_DMA | OMAP_DSS_ROT_VRFB,
- .buffer_size_unit = 1,
- .burst_size_unit = 8,
};
static const struct omap_dss_features omap3630_dss_features = {
@@ -697,8 +688,6 @@ static const struct omap_dss_features omap3630_dss_features = {
.clksrc_names = omap3_dss_clk_source_names,
.dss_params = omap3_dss_param_range,
.supported_rotation_types = OMAP_DSS_ROT_DMA | OMAP_DSS_ROT_VRFB,
- .buffer_size_unit = 1,
- .burst_size_unit = 8,
};
/* OMAP4 DSS Features */
@@ -720,8 +709,6 @@ static const struct omap_dss_features omap4430_es1_0_dss_features = {
.clksrc_names = omap4_dss_clk_source_names,
.dss_params = omap4_dss_param_range,
.supported_rotation_types = OMAP_DSS_ROT_DMA | OMAP_DSS_ROT_TILER,
- .buffer_size_unit = 16,
- .burst_size_unit = 16,
};
/* For OMAP4430 ES 2.0, 2.1 and 2.2 revisions */
@@ -742,8 +729,6 @@ static const struct omap_dss_features omap4430_es2_0_1_2_dss_features = {
.clksrc_names = omap4_dss_clk_source_names,
.dss_params = omap4_dss_param_range,
.supported_rotation_types = OMAP_DSS_ROT_DMA | OMAP_DSS_ROT_TILER,
- .buffer_size_unit = 16,
- .burst_size_unit = 16,
};
/* For all the other OMAP4 versions */
@@ -764,8 +749,6 @@ static const struct omap_dss_features omap4_dss_features = {
.clksrc_names = omap4_dss_clk_source_names,
.dss_params = omap4_dss_param_range,
.supported_rotation_types = OMAP_DSS_ROT_DMA | OMAP_DSS_ROT_TILER,
- .buffer_size_unit = 16,
- .burst_size_unit = 16,
};
/* OMAP5 DSS Features */
@@ -785,8 +768,6 @@ static const struct omap_dss_features omap5_dss_features = {
.clksrc_names = omap5_dss_clk_source_names,
.dss_params = omap5_dss_param_range,
.supported_rotation_types = OMAP_DSS_ROT_DMA | OMAP_DSS_ROT_TILER,
- .buffer_size_unit = 16,
- .burst_size_unit = 16,
};
#if defined(CONFIG_OMAP4_DSS_HDMI)
@@ -892,16 +873,6 @@ const char *dss_feat_get_clk_source_name(enum omap_dss_clk_source id)
return omap_current_dss_features->clksrc_names[id];
}
-u32 dss_feat_get_buffer_size_unit(void)
-{
- return omap_current_dss_features->buffer_size_unit;
-}
-
-u32 dss_feat_get_burst_size_unit(void)
-{
- return omap_current_dss_features->burst_size_unit;
-}
-
/* DSS has_feature check */
bool dss_has_feature(enum dss_feat_id id)
{
diff --git a/drivers/video/omap2/dss/dss_features.h b/drivers/video/omap2/dss/dss_features.h
index 385b0af..16658e1 100644
--- a/drivers/video/omap2/dss/dss_features.h
+++ b/drivers/video/omap2/dss/dss_features.h
@@ -114,9 +114,6 @@ bool dss_feat_color_mode_supported(enum omap_plane plane,
enum omap_color_mode color_mode);
const char *dss_feat_get_clk_source_name(enum omap_dss_clk_source id);
-u32 dss_feat_get_buffer_size_unit(void); /* in bytes */
-u32 dss_feat_get_burst_size_unit(void); /* in bytes */
-
bool dss_feat_rotation_type_supported(enum omap_dss_rotation_type rot_type);
bool dss_has_feature(enum dss_feat_id id);
--
1.7.10
^ permalink raw reply related
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