Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 225609
b: refs/heads/master
c: c36940e
h: refs/heads/master
i:
  225607: 27cd37b
v: v3
  • Loading branch information
Guennadi Liakhovetski authored and Paul Mundt committed Nov 10, 2010
1 parent 8b4ff41 commit b5348d2
Show file tree
Hide file tree
Showing 17 changed files with 111 additions and 1,413 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: dc7c0b6a6d28b0de231728de963ed53a9cee85cf
refs/heads/master: c36940e678fc30779c99246c034deca1fed61ae4
26 changes: 0 additions & 26 deletions trunk/drivers/video/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -186,14 +186,6 @@ config FB_SYS_FOPS
depends on FB
default n

config FB_WMT_GE_ROPS
tristate
depends on FB
default n
---help---
Include functions for accelerated rectangle filling and area
copying using WonderMedia Graphics Engine operations.

config FB_DEFERRED_IO
bool
depends on FB
Expand Down Expand Up @@ -1730,24 +1722,6 @@ config FB_AU1200
various panels and CRTs by passing in kernel cmd line option
au1200fb:panel=<name>.

config FB_VT8500
bool "VT8500 LCD Driver"
depends on (FB = y) && ARM && ARCH_VT8500 && VTWM_VERSION_VT8500
select FB_WMT_GE_ROPS
select FB_SYS_IMAGEBLIT
help
This is the framebuffer driver for VIA VT8500 integrated LCD
controller.

config FB_WM8505
bool "WM8505 frame buffer support"
depends on (FB = y) && ARM && ARCH_VT8500 && VTWM_VERSION_WM8505
select FB_WMT_GE_ROPS
select FB_SYS_IMAGEBLIT
help
This is the framebuffer driver for WonderMedia WM8505
integrated LCD controller.

source "drivers/video/geode/Kconfig"

config FB_HIT
Expand Down
3 changes: 0 additions & 3 deletions trunk/drivers/video/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ obj-$(CONFIG_FB_SVGALIB) += svgalib.o
obj-$(CONFIG_FB_MACMODES) += macmodes.o
obj-$(CONFIG_FB_DDC) += fb_ddc.o
obj-$(CONFIG_FB_DEFERRED_IO) += fb_defio.o
obj-$(CONFIG_FB_WMT_GE_ROPS) += wmt_ge_rops.o

# Hardware specific drivers go first
obj-$(CONFIG_FB_AMIGA) += amifb.o c2p_planar.o
Expand Down Expand Up @@ -105,8 +104,6 @@ obj-$(CONFIG_FB_W100) += w100fb.o
obj-$(CONFIG_FB_TMIO) += tmiofb.o
obj-$(CONFIG_FB_AU1100) += au1100fb.o
obj-$(CONFIG_FB_AU1200) += au1200fb.o
obj-$(CONFIG_FB_VT8500) += vt8500lcdfb.o
obj-$(CONFIG_FB_WM8505) += wm8505fb.o
obj-$(CONFIG_FB_PMAG_AA) += pmag-aa-fb.o
obj-$(CONFIG_FB_PMAG_BA) += pmag-ba-fb.o
obj-$(CONFIG_FB_PMAGB_B) += pmagb-b-fb.o
Expand Down
117 changes: 72 additions & 45 deletions trunk/drivers/video/sh_mobile_hdmi.c
Original file line number Diff line number Diff line change
Expand Up @@ -685,26 +685,37 @@ static void sh_hdmi_configure(struct sh_hdmi *hdmi)
}

static unsigned long sh_hdmi_rate_error(struct sh_hdmi *hdmi,
const struct fb_videomode *mode)
const struct fb_videomode *mode,
unsigned long *hdmi_rate, unsigned long *parent_rate)
{
long target = PICOS2KHZ(mode->pixclock) * 1000,
rate = clk_round_rate(hdmi->hdmi_clk, target);
unsigned long rate_error = rate > 0 ? abs(rate - target) : ULONG_MAX;
unsigned long target = PICOS2KHZ(mode->pixclock) * 1000, rate_error;
struct sh_mobile_hdmi_info *pdata = hdmi->dev->platform_data;

*hdmi_rate = clk_round_rate(hdmi->hdmi_clk, target);
if ((long)*hdmi_rate < 0)
*hdmi_rate = clk_get_rate(hdmi->hdmi_clk);

rate_error = (long)*hdmi_rate > 0 ? abs(*hdmi_rate - target) : ULONG_MAX;
if (rate_error && pdata->clk_optimize_parent)
rate_error = pdata->clk_optimize_parent(target, hdmi_rate, parent_rate);
else if (clk_get_parent(hdmi->hdmi_clk))
*parent_rate = clk_get_rate(clk_get_parent(hdmi->hdmi_clk));

dev_dbg(hdmi->dev, "%u-%u-%u-%u x %u-%u-%u-%u\n",
mode->left_margin, mode->xres,
mode->right_margin, mode->hsync_len,
mode->upper_margin, mode->yres,
mode->lower_margin, mode->vsync_len);

dev_dbg(hdmi->dev, "\t@%lu(+/-%lu)Hz, e=%lu / 1000, r=%uHz\n", target,
rate_error, rate_error ? 10000 / (10 * target / rate_error) : 0,
mode->refresh);
dev_dbg(hdmi->dev, "\t@%lu(+/-%lu)Hz, e=%lu / 1000, r=%uHz, p=%luHz\n", target,
rate_error, rate_error ? 10000 / (10 * target / rate_error) : 0,
mode->refresh, *parent_rate);

return rate_error;
}

static int sh_hdmi_read_edid(struct sh_hdmi *hdmi)
static int sh_hdmi_read_edid(struct sh_hdmi *hdmi, unsigned long *hdmi_rate,
unsigned long *parent_rate)
{
struct fb_var_screeninfo tmpvar;
struct fb_var_screeninfo *var = &tmpvar;
Expand Down Expand Up @@ -754,11 +765,14 @@ static int sh_hdmi_read_edid(struct sh_hdmi *hdmi)
for (i = 0, mode = hdmi->monspec.modedb;
f_width && f_height && i < hdmi->monspec.modedb_len && !exact_match;
i++, mode++) {
unsigned long rate_error = sh_hdmi_rate_error(hdmi, mode);
unsigned long rate_error;

/* No interest in unmatching modes */
if (f_width != mode->xres || f_height != mode->yres)
continue;

rate_error = sh_hdmi_rate_error(hdmi, mode, hdmi_rate, parent_rate);

if (f_refresh == mode->refresh || (!f_refresh && !rate_error))
/*
* Exact match if either the refresh rate matches or it
Expand Down Expand Up @@ -802,25 +816,26 @@ static int sh_hdmi_read_edid(struct sh_hdmi *hdmi)

if (modelist) {
found = &modelist->mode;
found_rate_error = sh_hdmi_rate_error(hdmi, found);
found_rate_error = sh_hdmi_rate_error(hdmi, found, hdmi_rate, parent_rate);
}
}

/* No cookie today */
if (!found)
return -ENXIO;

dev_info(hdmi->dev, "Using %s mode %ux%u@%uHz (%luHz), clock error %luHz\n",
modelist ? "default" : "EDID", found->xres, found->yres,
found->refresh, PICOS2KHZ(found->pixclock) * 1000, found_rate_error);

if ((found->xres == 720 && found->yres == 480) ||
(found->xres == 1280 && found->yres == 720) ||
(found->xres == 1920 && found->yres == 1080))
hdmi->preprogrammed_mode = true;
else
hdmi->preprogrammed_mode = false;

dev_dbg(hdmi->dev, "Using %s %s mode %ux%u@%uHz (%luHz), clock error %luHz\n",
modelist ? "default" : "EDID", hdmi->preprogrammed_mode ? "VIC" : "external",
found->xres, found->yres, found->refresh,
PICOS2KHZ(found->pixclock) * 1000, found_rate_error);

fb_videomode_to_var(&hdmi->var, found);
sh_hdmi_external_video_param(hdmi);

Expand Down Expand Up @@ -972,39 +987,38 @@ static bool sh_hdmi_must_reconfigure(struct sh_hdmi *hdmi)

/**
* sh_hdmi_clk_configure() - set HDMI clock frequency and enable the clock
* @hdmi: driver context
* @pixclock: pixel clock period in picoseconds
* return: configured positive rate if successful
* 0 if couldn't set the rate, but managed to enable the clock
* negative error, if couldn't enable the clock
* @hdmi: driver context
* @hdmi_rate: HDMI clock frequency in Hz
* @parent_rate: if != 0 - set parent clock rate for optimal precision
* return: configured positive rate if successful
* 0 if couldn't set the rate, but managed to enable the
* clock, negative error, if couldn't enable the clock
*/
static long sh_hdmi_clk_configure(struct sh_hdmi *hdmi, unsigned long pixclock)
static long sh_hdmi_clk_configure(struct sh_hdmi *hdmi, unsigned long hdmi_rate,
unsigned long parent_rate)
{
long rate;
struct sh_mobile_hdmi_info *pdata = hdmi->dev->platform_data;
int ret;

rate = PICOS2KHZ(pixclock) * 1000;
rate = clk_round_rate(hdmi->hdmi_clk, rate);
if (rate > 0) {
ret = clk_set_rate(hdmi->hdmi_clk, rate);
if (parent_rate && clk_get_parent(hdmi->hdmi_clk)) {
ret = clk_set_rate(clk_get_parent(hdmi->hdmi_clk), parent_rate);
if (ret < 0) {
dev_warn(hdmi->dev, "Cannot set rate %ld: %d\n", rate, ret);
rate = 0;
dev_warn(hdmi->dev, "Cannot set parent rate %ld: %d\n", parent_rate, ret);
hdmi_rate = clk_round_rate(hdmi->hdmi_clk, hdmi_rate);
} else {
dev_dbg(hdmi->dev, "HDMI set frequency %lu\n", rate);
dev_dbg(hdmi->dev, "HDMI set parent frequency %lu\n", parent_rate);
}
} else {
rate = 0;
dev_warn(hdmi->dev, "Cannot get suitable rate: %ld\n", rate);
}

ret = clk_enable(hdmi->hdmi_clk);
ret = clk_set_rate(hdmi->hdmi_clk, hdmi_rate);
if (ret < 0) {
dev_err(hdmi->dev, "Cannot enable clock: %d\n", ret);
return ret;
dev_warn(hdmi->dev, "Cannot set rate %ld: %d\n", hdmi_rate, ret);
hdmi_rate = 0;
} else {
dev_dbg(hdmi->dev, "HDMI set frequency %lu\n", hdmi_rate);
}

return rate;
return hdmi_rate;
}

/* Hotplug interrupt occurred, read EDID */
Expand All @@ -1024,16 +1038,17 @@ static void sh_hdmi_edid_work_fn(struct work_struct *work)
mutex_lock(&hdmi->mutex);

if (hdmi->hp_state == HDMI_HOTPLUG_EDID_DONE) {
unsigned long parent_rate = 0, hdmi_rate;

/* A device has been plugged in */
pm_runtime_get_sync(hdmi->dev);

ret = sh_hdmi_read_edid(hdmi);
ret = sh_hdmi_read_edid(hdmi, &hdmi_rate, &parent_rate);
if (ret < 0)
goto out;

/* Reconfigure the clock */
clk_disable(hdmi->hdmi_clk);
ret = sh_hdmi_clk_configure(hdmi, hdmi->var.pixclock);
ret = sh_hdmi_clk_configure(hdmi, hdmi_rate, parent_rate);
if (ret < 0)
goto out;

Expand Down Expand Up @@ -1071,14 +1086,17 @@ static void sh_hdmi_edid_work_fn(struct work_struct *work)
if (!hdmi->info)
goto out;

hdmi->monspec.modedb_len = 0;
fb_destroy_modedb(hdmi->monspec.modedb);
hdmi->monspec.modedb = NULL;

acquire_console_sem();

/* HDMI disconnect */
fb_set_suspend(hdmi->info, 1);

release_console_sem();
pm_runtime_put(hdmi->dev);
fb_destroy_modedb(hdmi->monspec.modedb);
}

out:
Expand Down Expand Up @@ -1163,13 +1181,22 @@ static int __init sh_hdmi_probe(struct platform_device *pdev)
goto egetclk;
}

/* Some arbitrary relaxed pixclock just to get things started */
rate = sh_hdmi_clk_configure(hdmi, 37037);
/* An arbitrary relaxed pixclock just to get things started: from standard 480p */
rate = clk_round_rate(hdmi->hdmi_clk, PICOS2KHZ(37037));
if (rate > 0)
rate = sh_hdmi_clk_configure(hdmi, rate, 0);

if (rate < 0) {
ret = rate;
goto erate;
}

ret = clk_enable(hdmi->hdmi_clk);
if (ret < 0) {
dev_err(hdmi->dev, "Cannot enable clock: %d\n", ret);
goto erate;
}

dev_dbg(&pdev->dev, "Enabled HDMI clock at %luHz\n", rate);

if (!request_mem_region(res->start, resource_size(res), dev_name(&pdev->dev))) {
Expand All @@ -1187,10 +1214,6 @@ static int __init sh_hdmi_probe(struct platform_device *pdev)

platform_set_drvdata(pdev, hdmi);

/* Product and revision IDs are 0 in sh-mobile version */
dev_info(&pdev->dev, "Detected HDMI controller 0x%x:0x%x\n",
hdmi_read(hdmi, HDMI_PRODUCT_ID), hdmi_read(hdmi, HDMI_REVISION_ID));

/* Set up LCDC callbacks */
board_cfg = &pdata->lcd_chan->board_cfg;
board_cfg->owner = THIS_MODULE;
Expand All @@ -1203,6 +1226,10 @@ static int __init sh_hdmi_probe(struct platform_device *pdev)
pm_runtime_enable(&pdev->dev);
pm_runtime_resume(&pdev->dev);

/* Product and revision IDs are 0 in sh-mobile version */
dev_info(&pdev->dev, "Detected HDMI controller 0x%x:0x%x\n",
hdmi_read(hdmi, HDMI_PRODUCT_ID), hdmi_read(hdmi, HDMI_REVISION_ID));

ret = request_irq(irq, sh_hdmi_hotplug, 0,
dev_name(&pdev->dev), hdmi);
if (ret < 0) {
Expand Down
21 changes: 12 additions & 9 deletions trunk/drivers/video/sh_mobile_lcdcfb.c
Original file line number Diff line number Diff line change
Expand Up @@ -115,15 +115,16 @@ static const struct fb_videomode default_720p = {
.xres = 1280,
.yres = 720,

.left_margin = 200,
.right_margin = 88,
.hsync_len = 48,
.left_margin = 220,
.right_margin = 110,
.hsync_len = 40,

.upper_margin = 20,
.lower_margin = 5,
.vsync_len = 5,

.pixclock = 13468,
.refresh = 60,
.sync = FB_SYNC_VERT_HIGH_ACT | FB_SYNC_HOR_HIGH_ACT,
};

Expand Down Expand Up @@ -1197,6 +1198,7 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev)
const struct fb_videomode *mode = cfg->lcd_cfg;
unsigned long max_size = 0;
int k;
int num_cfg;

ch->info = framebuffer_alloc(0, &pdev->dev);
if (!ch->info) {
Expand Down Expand Up @@ -1232,8 +1234,14 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev)
info->fix = sh_mobile_lcdc_fix;
info->fix.smem_len = max_size * (cfg->bpp / 8) * 2;

if (!mode)
if (!mode) {
mode = &default_720p;
num_cfg = 1;
} else {
num_cfg = ch->cfg.num_cfg;
}

fb_videomode_to_modelist(mode, num_cfg, &info->modelist);

fb_videomode_to_var(var, mode);
/* Default Y virtual resolution is 2x panel size */
Expand Down Expand Up @@ -1281,10 +1289,6 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev)

for (i = 0; i < j; i++) {
struct sh_mobile_lcdc_chan *ch = priv->ch + i;
const struct fb_videomode *mode = ch->cfg.lcd_cfg;

if (!mode)
mode = &default_720p;

info = ch->info;

Expand All @@ -1297,7 +1301,6 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev)
}
}

fb_videomode_to_modelist(mode, ch->cfg.num_cfg, &info->modelist);
error = register_framebuffer(info);
if (error < 0)
goto err1;
Expand Down
Loading

0 comments on commit b5348d2

Please sign in to comment.