* Re: msync on fbdev
From: Tomi Valkeinen @ 2014-12-19 11:59 UTC (permalink / raw)
To: linux-fbdev
In-Reply-To: <CABMKUD9mtus77hdfPA5mAtwc8MCpyJQ-kvvvyVmKQuw2Tuo9mA@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 2389 bytes --]
On 18/12/14 15:55, Martin Jackson wrote:
> Dear fbdev developers,
>
> This relates to the core implementation of fbdev with the
> CONFIG_FB_DEFERRED_IO option enabled.
>
> I believe I have found a bug when doing msync(2) on a framebuffer
> device. We are using an old (2.6.37) kernel on an embedded plaform,
> but if I look at the current torvalds kernel (fbdev kernel looks
> rather old!?), the bug seems to still be there.
>
> When looking at the msync(2) man page, msync is meant to return 0 on
> success and -1 on failure, however we are seeing it return 1, which is
> undocumented and in my opinion wrong.
>
> This is because the fb_deferred_io_fsync method returns the code from
> 'schedule_delayed_work', which is either 0 or 1 depending on whether
> the work was already scheduled, leading to the possibility that msync
> returns the value 1 to userland.
Indeed, looks broken. schedule_delayed_work() never returns an error, it
just returns a bool telling if the work was already scheduled.
I guess no one really uses deferred io much =).
Here's a patch:
From 9cc80b3cf9d6023ede084d024ed8b5c0cb247bc2 Mon Sep 17 00:00:00 2001
From: Tomi Valkeinen <tomi.valkeinen@ti.com>
Date: Fri, 19 Dec 2014 13:55:41 +0200
Subject: [PATCH] video/fbdev: fix defio's fsync
fb_deferred_io_fsync() returns the value of schedule_delayed_work() as
an error code, but schedule_delayed_work() does not return an error. It
returns true/false depending on whether the work was already queued.
Fix this by ignoring the return value of schedule_delayed_work().
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/fbdev/core/fb_defio.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/video/fbdev/core/fb_defio.c
b/drivers/video/fbdev/core/fb_defio.c
index 900aa4ecd617..d6cab1fd9a47 100644
--- a/drivers/video/fbdev/core/fb_defio.c
+++ b/drivers/video/fbdev/core/fb_defio.c
@@ -83,9 +83,10 @@ int fb_deferred_io_fsync(struct file *file, loff_t
start, loff_t end, int datasy
cancel_delayed_work_sync(&info->deferred_work);
/* Run it immediately */
- err = schedule_delayed_work(&info->deferred_work, 0);
+ schedule_delayed_work(&info->deferred_work, 0);
mutex_unlock(&inode->i_mutex);
- return err;
+
+ return 0;
}
EXPORT_SYMBOL_GPL(fb_deferred_io_fsync);
--
2.2.0
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]
^ permalink raw reply related
* Re: [PATCH v2 3/7] drm_modes: add videomode_from_drm_display_mode
From: Emil Velikov @ 2014-12-19 19:03 UTC (permalink / raw)
To: Philipp Zabel, Steve Longerbeam
Cc: Fabio Estevam, linux-fbdev, Steve Longerbeam, emil.l.velikov,
linux-kernel, dri-devel, Denis Carikli, Tomi Valkeinen,
Russell King, Jean-Christophe Plagniol-Villard
In-Reply-To: <1418986984.3165.64.camel@pengutronix.de>
On 19/12/14 11:03, Philipp Zabel wrote:
> Am Donnerstag, den 18.12.2014, 18:00 -0800 schrieb Steve Longerbeam:
>> Add conversion from drm_display_mode to videomode.
>>
>> Signed-off-by: Steve Longerbeam <steve_longerbeam@mentor.com>
>> ---
>> drivers/gpu/drm/drm_modes.c | 40 ++++++++++++++++++++++++++++++++++++++++
>> include/drm/drm_modes.h | 2 ++
>> 2 files changed, 42 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c
>> index 6d8b941..583a391 100644
>> --- a/drivers/gpu/drm/drm_modes.c
>> +++ b/drivers/gpu/drm/drm_modes.c
>> @@ -615,6 +615,46 @@ void drm_display_mode_from_videomode(const struct videomode *vm,
>> }
>> EXPORT_SYMBOL_GPL(drm_display_mode_from_videomode);
>>
>> +/**
>> + * videomode_from_drm_display_mode - fill in @vm using @dmode,
>> + * @dmode: drm_display_mode structure to use as source
>> + * @vm: videomode structure to use as destination
>> + *
>> + * Fills out @vm using the display mode specified in @dmode.
>> + */
>> +void videomode_from_drm_display_mode(const struct drm_display_mode *dmode,
>> + struct videomode *vm)
>> +{
>> + vm->hactive = dmode->hdisplay;
>> + vm->hfront_porch = dmode->hsync_start - dmode->hdisplay;
>> + vm->hsync_len = dmode->hsync_end - dmode->hsync_start;
>> + vm->hback_porch = dmode->htotal - dmode->hsync_end;
>> +
>> + vm->vactive = dmode->vdisplay;
>> + vm->vfront_porch = dmode->vsync_start - dmode->vdisplay;
>> + vm->vsync_len = dmode->vsync_end - dmode->vsync_start;
>> + vm->vback_porch = dmode->vtotal - dmode->vsync_end;
>> +
>> + vm->pixelclock = dmode->clock * 1000;
>> +
>> + vm->flags = 0;
>> + if (dmode->flags & DRM_MODE_FLAG_PHSYNC)
>> + vm->flags |= DISPLAY_FLAGS_HSYNC_HIGH;
>> + else if (dmode->flags & DRM_MODE_FLAG_NHSYNC)
>> + vm->flags |= DISPLAY_FLAGS_HSYNC_LOW;
>> + if (dmode->flags & DRM_MODE_FLAG_PVSYNC)
>> + vm->flags |= DISPLAY_FLAGS_VSYNC_HIGH;
>> + else if (dmode->flags & DRM_MODE_FLAG_NVSYNC)
>> + vm->flags |= DISPLAY_FLAGS_VSYNC_LOW;
>> + if (dmode->flags & DRM_MODE_FLAG_INTERLACE)
>> + vm->flags |= DISPLAY_FLAGS_INTERLACED;
>> + if (dmode->flags & DRM_MODE_FLAG_DBLSCAN)
>> + vm->flags |= DISPLAY_FLAGS_DOUBLESCAN;
>> + if (dmode->flags & DRM_MODE_FLAG_DBLCLK)
>> + vm->flags |= DISPLAY_FLAGS_DOUBLECLK;
>> +}
>> +EXPORT_SYMBOL_GPL(videomode_from_drm_display_mode);
>
> Is it ok for drm_modes to export a function that doesn't start with
> drm_ ? We could just rename this to drm_display_mode_to_videomode if
> necessary. I can fix it up as I apply it, but I'd like to know which is
> preferred.
>
Non-native English speaker here, and drm_display_mode_to_videomode
sounds better. Plus I think that *to* functions are more common than
*from* ones.
I'm not a drm dev, so just my 2c :)
Cheers,
Emil
^ permalink raw reply
* Re: [PATCH v2 3/7] drm_modes: add videomode_from_drm_display_mode
From: Steve Longerbeam @ 2014-12-19 19:10 UTC (permalink / raw)
To: Philipp Zabel
Cc: dri-devel, linux-kernel, linux-fbdev, David Airlie,
Jean-Christophe Plagniol-Villard, Tomi Valkeinen, Russell King,
Fabio Estevam, Shawn Guo, Denis Carikli, Jiada Wang,
Steve Longerbeam
In-Reply-To: <1418986984.3165.64.camel@pengutronix.de>
On 12/19/2014 03:03 AM, Philipp Zabel wrote:
>
> +EXPORT_SYMBOL_GPL(videomode_from_drm_display_mode);
> Is it ok for drm_modes to export a function that doesn't start with
> drm_ ? We could just rename this to drm_display_mode_to_videomode if
> necessary. I can fix it up as I apply it, but I'd like to know which is
> preferred.
Yeah, drm_display_mode_to_videomode() is probably better,
makes it more clear it's part of the DRM kernel interfaces.
Steve
^ permalink raw reply
* Re: [PATCH v2 4/7] imx-drm: ipuv3-crtc: Implement mode_fixup
From: Russell King - ARM Linux @ 2014-12-20 15:52 UTC (permalink / raw)
To: Steve Longerbeam
Cc: Fabio Estevam, linux-fbdev, Steve Longerbeam, linux-kernel,
dri-devel, Denis Carikli, Tomi Valkeinen,
Jean-Christophe Plagniol-Villard
In-Reply-To: <1418954426-21909-5-git-send-email-steve_longerbeam@mentor.com>
On Thu, Dec 18, 2014 at 06:00:23PM -0800, Steve Longerbeam wrote:
> Ask the IPU display interface, via ipu_di_adjust_videomode(), to
> adjust a video mode to meet any DI restrictions. The function takes
> a subsystem independent videomode, so the drm_display_mode must be
> converted to videomode first, and then the adjusted mode converted
> back to a drm_display_mode.
What is the reason to use videomode (apart from it being subsystem
independent)? Do we forsee implementation of other output subsystems
for the IPU?
--
FTTC broadband for 0.8mile line: currently at 9.5Mbps down 400kbps up
according to speedtest.net.
^ permalink raw reply
* Re: [GIT PULL] fbdev fixes for 3.19
From: Pavel Machek @ 2014-12-20 21:01 UTC (permalink / raw)
To: Tomi Valkeinen
Cc: Linus Torvalds, LKML, Linux Fbdev development list, Mark Brown
In-Reply-To: <54899F0E.4090309@ti.com>
Hi!
> Please pull fbdev changes for 3.19.
>
> Tomi
v3.19-rc0 breaks video on my n900.
> Archit Taneja (7):
> OMAPDSS: DPI: Use DPI driver data
> OMAPDSS: DPI: Allocate driver data
> OMAPDSS: DPI: Store dpi_data pointer in the DT port's data
> OMAPDSS: DSS: init dss ports cleanly
> OMAPDSS: DT: Get source endpoint by matching reg-id
> OMAPDSS: DPI: Add support for multiple instances
> OMAPDSS: DSS: add a param to dpi_select_source which specifies
> it's port number
And I have these in my tree, so I should have latest fixes. Any ideas
what I should try?
Pavel
--
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
^ permalink raw reply
* Re: [GIT PULL] fbdev fixes for 3.19
From: Pavel Machek @ 2014-12-20 21:20 UTC (permalink / raw)
To: Tomi Valkeinen
Cc: Linus Torvalds, LKML, Linux Fbdev development list, Mark Brown
In-Reply-To: <20141220210125.GB16705@amd>
On Sat 2014-12-20 22:01:25, Pavel Machek wrote:
> Hi!
>
> > Please pull fbdev changes for 3.19.
> >
> > Tomi
>
> v3.19-rc0 breaks video on my n900.
>
> > Archit Taneja (7):
> > OMAPDSS: DPI: Use DPI driver data
> > OMAPDSS: DPI: Allocate driver data
> > OMAPDSS: DPI: Store dpi_data pointer in the DT port's data
> > OMAPDSS: DSS: init dss ports cleanly
> > OMAPDSS: DT: Get source endpoint by matching reg-id
> > OMAPDSS: DPI: Add support for multiple instances
> > OMAPDSS: DSS: add a param to dpi_select_source which specifies
> > it's port number
>
> And I have these in my tree, so I should have latest fixes. Any ideas
> what I should try?
I test-merged 3315764efceaccfb02c7d4c99ef8eed6716cd861, and boom,
video is gone.
Pavel
--
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
^ permalink raw reply
* Re: [GIT PULL] fbdev fixes for 3.19
From: Pavel Machek @ 2014-12-20 21:57 UTC (permalink / raw)
To: Tomi Valkeinen
Cc: Linus Torvalds, LKML, Linux Fbdev development list, Mark Brown
In-Reply-To: <20141220212027.GC16705@amd>
On Sat 2014-12-20 22:20:27, Pavel Machek wrote:
> On Sat 2014-12-20 22:01:25, Pavel Machek wrote:
> > Hi!
> >
> > > Please pull fbdev changes for 3.19.
> > >
> > > Tomi
> >
> > v3.19-rc0 breaks video on my n900.
> >
> > > Archit Taneja (7):
> > > OMAPDSS: DPI: Use DPI driver data
> > > OMAPDSS: DPI: Allocate driver data
> > > OMAPDSS: DPI: Store dpi_data pointer in the DT port's data
> > > OMAPDSS: DSS: init dss ports cleanly
> > > OMAPDSS: DT: Get source endpoint by matching reg-id
> > > OMAPDSS: DPI: Add support for multiple instances
> > > OMAPDSS: DSS: add a param to dpi_select_source which specifies
> > > it's port number
> >
> > And I have these in my tree, so I should have latest fixes. Any ideas
> > what I should try?
>
> I test-merged 3315764efceaccfb02c7d4c99ef8eed6716cd861, and boom,
> video is gone.
I reverted
4b4123f0c7b02f7cf1a3189f967f079197578c3a..9051909e451a0368c95ccf74562adb53fd2719f8
in 3.19, and voila, video is back.
Pavel
--
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
^ permalink raw reply
* [PATCH] video: fbdev: omap2: dss: rfbi.c: Remove some unused functions
From: Rickard Strandqvist @ 2014-12-21 16:59 UTC (permalink / raw)
To: Tomi Valkeinen, Jean-Christophe Plagniol-Villard
Cc: Rickard Strandqvist, Jingoo Han, Laurent Pinchart, Rob Clark,
linux-omap, linux-fbdev, linux-kernel
Removes some functions that are not used anywhere:
rfbi_init_display() rfbi_display_disable() rfbi_display_enable()
rfbi_set_interface_timings() rfbi_set_data_lines() rfbi_set_pixel_size()
rfbi_set_size() rfbi_update() rfbi_configure() rfbi_enable_te()
rfbi_setup_te() rfbi_write_pixels() rfbi_write_data() rfbi_read_data()
rfbi_write_command() rfbi_bus_unlock() rfbi_bus_lock()
This was partially found by using a static code analysis program called cppcheck.
Signed-off-by: Rickard Strandqvist <rickard_strandqvist@spectrumdigital.se>
---
drivers/video/fbdev/omap2/dss/rfbi.c | 297 ----------------------------------
1 file changed, 297 deletions(-)
diff --git a/drivers/video/fbdev/omap2/dss/rfbi.c b/drivers/video/fbdev/omap2/dss/rfbi.c
index 878273f..3e25028 100644
--- a/drivers/video/fbdev/omap2/dss/rfbi.c
+++ b/drivers/video/fbdev/omap2/dss/rfbi.c
@@ -151,156 +151,6 @@ static void rfbi_runtime_put(void)
WARN_ON(r < 0 && r != -ENOSYS);
}
-static void rfbi_bus_lock(void)
-{
- down(&rfbi.bus_lock);
-}
-
-static void rfbi_bus_unlock(void)
-{
- up(&rfbi.bus_lock);
-}
-
-static void rfbi_write_command(const void *buf, u32 len)
-{
- switch (rfbi.parallelmode) {
- case OMAP_DSS_RFBI_PARALLELMODE_8:
- {
- const u8 *b = buf;
- for (; len; len--)
- rfbi_write_reg(RFBI_CMD, *b++);
- break;
- }
-
- case OMAP_DSS_RFBI_PARALLELMODE_16:
- {
- const u16 *w = buf;
- BUG_ON(len & 1);
- for (; len; len -= 2)
- rfbi_write_reg(RFBI_CMD, *w++);
- break;
- }
-
- case OMAP_DSS_RFBI_PARALLELMODE_9:
- case OMAP_DSS_RFBI_PARALLELMODE_12:
- default:
- BUG();
- }
-}
-
-static void rfbi_read_data(void *buf, u32 len)
-{
- switch (rfbi.parallelmode) {
- case OMAP_DSS_RFBI_PARALLELMODE_8:
- {
- u8 *b = buf;
- for (; len; len--) {
- rfbi_write_reg(RFBI_READ, 0);
- *b++ = rfbi_read_reg(RFBI_READ);
- }
- break;
- }
-
- case OMAP_DSS_RFBI_PARALLELMODE_16:
- {
- u16 *w = buf;
- BUG_ON(len & ~1);
- for (; len; len -= 2) {
- rfbi_write_reg(RFBI_READ, 0);
- *w++ = rfbi_read_reg(RFBI_READ);
- }
- break;
- }
-
- case OMAP_DSS_RFBI_PARALLELMODE_9:
- case OMAP_DSS_RFBI_PARALLELMODE_12:
- default:
- BUG();
- }
-}
-
-static void rfbi_write_data(const void *buf, u32 len)
-{
- switch (rfbi.parallelmode) {
- case OMAP_DSS_RFBI_PARALLELMODE_8:
- {
- const u8 *b = buf;
- for (; len; len--)
- rfbi_write_reg(RFBI_PARAM, *b++);
- break;
- }
-
- case OMAP_DSS_RFBI_PARALLELMODE_16:
- {
- const u16 *w = buf;
- BUG_ON(len & 1);
- for (; len; len -= 2)
- rfbi_write_reg(RFBI_PARAM, *w++);
- break;
- }
-
- case OMAP_DSS_RFBI_PARALLELMODE_9:
- case OMAP_DSS_RFBI_PARALLELMODE_12:
- default:
- BUG();
-
- }
-}
-
-static void rfbi_write_pixels(const void __iomem *buf, int scr_width,
- u16 x, u16 y,
- u16 w, u16 h)
-{
- int start_offset = scr_width * y + x;
- int horiz_offset = scr_width - w;
- int i;
-
- if (rfbi.datatype = OMAP_DSS_RFBI_DATATYPE_16 &&
- rfbi.parallelmode = OMAP_DSS_RFBI_PARALLELMODE_8) {
- const u16 __iomem *pd = buf;
- pd += start_offset;
-
- for (; h; --h) {
- for (i = 0; i < w; ++i) {
- const u8 __iomem *b = (const u8 __iomem *)pd;
- rfbi_write_reg(RFBI_PARAM, __raw_readb(b+1));
- rfbi_write_reg(RFBI_PARAM, __raw_readb(b+0));
- ++pd;
- }
- pd += horiz_offset;
- }
- } else if (rfbi.datatype = OMAP_DSS_RFBI_DATATYPE_24 &&
- rfbi.parallelmode = OMAP_DSS_RFBI_PARALLELMODE_8) {
- const u32 __iomem *pd = buf;
- pd += start_offset;
-
- for (; h; --h) {
- for (i = 0; i < w; ++i) {
- const u8 __iomem *b = (const u8 __iomem *)pd;
- rfbi_write_reg(RFBI_PARAM, __raw_readb(b+2));
- rfbi_write_reg(RFBI_PARAM, __raw_readb(b+1));
- rfbi_write_reg(RFBI_PARAM, __raw_readb(b+0));
- ++pd;
- }
- pd += horiz_offset;
- }
- } else if (rfbi.datatype = OMAP_DSS_RFBI_DATATYPE_16 &&
- rfbi.parallelmode = OMAP_DSS_RFBI_PARALLELMODE_16) {
- const u16 __iomem *pd = buf;
- pd += start_offset;
-
- for (; h; --h) {
- for (i = 0; i < w; ++i) {
- rfbi_write_reg(RFBI_PARAM, __raw_readw(pd));
- ++pd;
- }
- pd += horiz_offset;
- }
- } else {
- BUG();
- }
-}
-
static int rfbi_transfer_area(struct omap_dss_device *dssdev,
void (*callback)(void *data), void *data)
{
@@ -567,69 +417,6 @@ static int rfbi_convert_timings(struct rfbi_timings *t)
return 0;
}
-/* xxx FIX module selection missing */
-static int rfbi_setup_te(enum omap_rfbi_te_mode mode,
- unsigned hs_pulse_time, unsigned vs_pulse_time,
- int hs_pol_inv, int vs_pol_inv, int extif_div)
-{
- int hs, vs;
- int min;
- u32 l;
-
- hs = ps_to_rfbi_ticks(hs_pulse_time, 1);
- vs = ps_to_rfbi_ticks(vs_pulse_time, 1);
- if (hs < 2)
- return -EDOM;
- if (mode = OMAP_DSS_RFBI_TE_MODE_2)
- min = 2;
- else /* OMAP_DSS_RFBI_TE_MODE_1 */
- min = 4;
- if (vs < min)
- return -EDOM;
- if (vs = hs)
- return -EINVAL;
- rfbi.te_mode = mode;
- DSSDBG("setup_te: mode %d hs %d vs %d hs_inv %d vs_inv %d\n",
- mode, hs, vs, hs_pol_inv, vs_pol_inv);
-
- rfbi_write_reg(RFBI_HSYNC_WIDTH, hs);
- rfbi_write_reg(RFBI_VSYNC_WIDTH, vs);
-
- l = rfbi_read_reg(RFBI_CONFIG(0));
- if (hs_pol_inv)
- l &= ~(1 << 21);
- else
- l |= 1 << 21;
- if (vs_pol_inv)
- l &= ~(1 << 20);
- else
- l |= 1 << 20;
-
- return 0;
-}
-
-/* xxx FIX module selection missing */
-static int rfbi_enable_te(bool enable, unsigned line)
-{
- u32 l;
-
- DSSDBG("te %d line %d mode %d\n", enable, line, rfbi.te_mode);
- if (line > (1 << 11) - 1)
- return -EINVAL;
-
- l = rfbi_read_reg(RFBI_CONFIG(0));
- l &= ~(0x3 << 2);
- if (enable) {
- rfbi.te_enabled = 1;
- l |= rfbi.te_mode << 2;
- } else
- rfbi.te_enabled = 0;
- rfbi_write_reg(RFBI_CONFIG(0), l);
- rfbi_write_reg(RFBI_LINE_NUMBER, line);
-
- return 0;
-}
-
static int rfbi_configure_bus(int rfbi_module, int bpp, int lines)
{
u32 l;
@@ -762,40 +549,6 @@ static int rfbi_configure_bus(int rfbi_module, int bpp, int lines)
return 0;
}
-static int rfbi_configure(struct omap_dss_device *dssdev)
-{
- return rfbi_configure_bus(dssdev->phy.rfbi.channel, rfbi.pixel_size,
- rfbi.data_lines);
-}
-
-static int rfbi_update(struct omap_dss_device *dssdev, void (*callback)(void *),
- void *data)
-{
- return rfbi_transfer_area(dssdev, callback, data);
-}
-
-static void rfbi_set_size(struct omap_dss_device *dssdev, u16 w, u16 h)
-{
- rfbi.timings.x_res = w;
- rfbi.timings.y_res = h;
-}
-
-static void rfbi_set_pixel_size(struct omap_dss_device *dssdev, int pixel_size)
-{
- rfbi.pixel_size = pixel_size;
-}
-
-static void rfbi_set_data_lines(struct omap_dss_device *dssdev, int data_lines)
-{
- rfbi.data_lines = data_lines;
-}
-
-static void rfbi_set_interface_timings(struct omap_dss_device *dssdev,
- struct rfbi_timings *timings)
-{
- rfbi.intf_timings = *timings;
-}
-
static void rfbi_dump_regs(struct seq_file *s)
{
#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, rfbi_read_reg(r))
@@ -874,56 +627,6 @@ static void rfbi_config_lcd_manager(struct omap_dss_device *dssdev)
dss_mgr_set_timings(mgr, &rfbi.timings);
}
-static int rfbi_display_enable(struct omap_dss_device *dssdev)
-{
- struct omap_dss_device *out = &rfbi.output;
- int r;
-
- if (out = NULL || out->manager = NULL) {
- DSSERR("failed to enable display: no output/manager\n");
- return -ENODEV;
- }
-
- r = rfbi_runtime_get();
- if (r)
- return r;
-
- r = dss_mgr_register_framedone_handler(out->manager,
- framedone_callback, NULL);
- if (r) {
- DSSERR("can't get FRAMEDONE irq\n");
- goto err1;
- }
-
- rfbi_config_lcd_manager(dssdev);
-
- rfbi_configure_bus(dssdev->phy.rfbi.channel, rfbi.pixel_size,
- rfbi.data_lines);
-
- rfbi_set_timings(dssdev->phy.rfbi.channel, &rfbi.intf_timings);
-
- return 0;
-err1:
- rfbi_runtime_put();
- return r;
-}
-
-static void rfbi_display_disable(struct omap_dss_device *dssdev)
-{
- struct omap_dss_device *out = &rfbi.output;
-
- dss_mgr_unregister_framedone_handler(out->manager,
- framedone_callback, NULL);
-
- rfbi_runtime_put();
-}
-
-static int rfbi_init_display(struct omap_dss_device *dssdev)
-{
- rfbi.dssdev[dssdev->phy.rfbi.channel] = dssdev;
- return 0;
-}
-
static void rfbi_init_output(struct platform_device *pdev)
{
struct omap_dss_device *out = &rfbi.output;
--
1.7.10.4
^ permalink raw reply related
* Re: [PATCH v2 4/7] imx-drm: ipuv3-crtc: Implement mode_fixup
From: Philipp Zabel @ 2014-12-22 15:53 UTC (permalink / raw)
To: Russell King - ARM Linux
Cc: Steve Longerbeam, dri-devel, linux-kernel, linux-fbdev,
David Airlie, Philipp Zabel, Jean-Christophe Plagniol-Villard,
Tomi Valkeinen, Fabio Estevam, Shawn Guo, Denis Carikli,
Jiada Wang, Steve Longerbeam
In-Reply-To: <20141220155254.GJ11285@n2100.arm.linux.org.uk>
Hi Russell,
On Sat, Dec 20, 2014 at 03:52:54PM +0000, Russell King - ARM Linux wrote:
> On Thu, Dec 18, 2014 at 06:00:23PM -0800, Steve Longerbeam wrote:
> > Ask the IPU display interface, via ipu_di_adjust_videomode(), to
> > adjust a video mode to meet any DI restrictions. The function takes
> > a subsystem independent videomode, so the drm_display_mode must be
> > converted to videomode first, and then the adjusted mode converted
> > back to a drm_display_mode.
>
> What is the reason to use videomode (apart from it being subsystem
> independent)? Do we forsee implementation of other output subsystems
> for the IPU?
There might be the issue of possible CSI -> IC -> DC -> DI passthrough,
where the DI timing must be synchronized to the CSI input signal.
I haven't really thought about how that should be integrated with the
DRM driver mostly because of the 1024 pixel output width maximum in the
IC, which limits the usefulness somewhat.
I like the use of struct videomode here for the symmetry with patch 6.
But currently, we could make ipu_di_adjust_videomode take a drm_display_mode
just as well.
regards
Philipp
^ permalink raw reply
* [PATCH 3/3] video: fbdev: Validate mode timing against monspec
From: David Ung @ 2014-12-23 0:27 UTC (permalink / raw)
To: linux-fbdev
In-Reply-To: <1417643369-20603-3-git-send-email-davidu@nvidia.com>
fbmon may generate mode timings that are out of spec of the monitor.
eg DELL U2410 has a max clock 170mhz but advertises a resolutions of
1920x1200@60 in its Standard Timings using 2byte code of D1 00.
When this is looked up in the DMT table it gives it a 193mhz clock.
Although the DELL monitor supports 1920x1200@60, it can only run with
reduced timings at 154mhz or DMT id 0x44 which has no STD 2byte code.
This patch checks to see if the mode can be supported by the monitor
by comparing against monspecs.dclkmax.
Signed-off-by: David Ung <davidu@nvidia.com>
---
drivers/video/fbdev/core/fbmon.c | 27 ++++++++++++++++++---------
1 file changed, 18 insertions(+), 9 deletions(-)
diff --git a/drivers/video/fbdev/core/fbmon.c b/drivers/video/fbdev/core/fbmon.c
index aa1110a..cc3ea6c8 100644
--- a/drivers/video/fbdev/core/fbmon.c
+++ b/drivers/video/fbdev/core/fbmon.c
@@ -496,7 +496,7 @@ static int get_est_timing(unsigned char *block, struct fb_videomode *mode)
}
static int get_std_timing(unsigned char *block, struct fb_videomode *mode,
- int ver, int rev)
+ int ver, int rev, struct fb_monspecs *specs)
{
int xres, yres = 0, refresh, ratio, i;
@@ -542,16 +542,23 @@ static int get_std_timing(unsigned char *block, struct fb_videomode *mode,
if (i = DMT_SIZE || !dmt_modes[i].mode)
calc_mode_timings(xres, yres, refresh, mode);
+ /* Check the mode we got is within valid spec of the monitor */
+ if (specs && specs->dclkmax
+ && PICOS2KHZ(mode->pixclock) * 1000 > specs->dclkmax) {
+ DPRINTK(" mode exceed max DCLK\n");
+ return 0;
+ }
+
return 1;
}
-static int get_dst_timing(unsigned char *block,
- struct fb_videomode *mode, int ver, int rev)
+static int get_dst_timing(unsigned char *block, struct fb_videomode *mode,
+ int ver, int rev, struct fb_monspecs *specs)
{
int j, num = 0;
for (j = 0; j < 6; j++, block += STD_TIMING_DESCRIPTION_SIZE)
- num += get_std_timing(block, &mode[num], ver, rev);
+ num += get_std_timing(block, &mode[num], ver, rev, specs);
return num;
}
@@ -607,7 +614,8 @@ static void get_detailed_timing(unsigned char *block,
* This function builds a mode database using the contents of the EDID
* data
*/
-static struct fb_videomode *fb_create_modedb(unsigned char *edid, int *dbsize)
+static struct fb_videomode *fb_create_modedb(unsigned char *edid, int *dbsize,
+ struct fb_monspecs *specs)
{
struct fb_videomode *mode, *m;
unsigned char *block;
@@ -649,12 +657,13 @@ static struct fb_videomode *fb_create_modedb(unsigned char *edid, int *dbsize)
DPRINTK(" Standard Timings\n");
block = edid + STD_TIMING_DESCRIPTIONS_START;
for (i = 0; i < STD_TIMING; i++, block += STD_TIMING_DESCRIPTION_SIZE)
- num += get_std_timing(block, &mode[num], ver, rev);
+ num += get_std_timing(block, &mode[num], ver, rev, specs);
block = edid + DETAILED_TIMING_DESCRIPTIONS_START;
for (i = 0; i < 4; i++, block+= DETAILED_TIMING_DESCRIPTION_SIZE) {
if (block[0] = 0x00 && block[1] = 0x00 && block[3] = 0xfa)
- num += get_dst_timing(block + 5, &mode[num], ver, rev);
+ num += get_dst_timing(block + 5, &mode[num],
+ ver, rev, specs);
}
/* Yikes, EDID data is totally useless */
@@ -713,7 +722,7 @@ static int fb_get_monitor_limits(unsigned char *edid, struct fb_monspecs *specs)
int num_modes, hz, hscan, pixclock;
int vtotal, htotal;
- modes = fb_create_modedb(edid, &num_modes);
+ modes = fb_create_modedb(edid, &num_modes, specs);
if (!modes) {
DPRINTK("None Available\n");
return 1;
@@ -970,7 +979,7 @@ void fb_edid_to_monspecs(unsigned char *edid, struct fb_monspecs *specs)
DPRINTK(" Display Characteristics:\n");
get_monspecs(edid, specs);
- specs->modedb = fb_create_modedb(edid, &specs->modedb_len);
+ specs->modedb = fb_create_modedb(edid, &specs->modedb_len, specs);
/*
* Workaround for buggy EDIDs that sets that the first
--
1.8.1.5
-----------------------------------------------------------------------------------
This email message is for the sole use of the intended recipient(s) and may contain
confidential information. Any unauthorized review, use, disclosure or distribution
is prohibited. If you are not the intended recipient, please contact the sender by
reply email and destroy all copies of the original message.
-----------------------------------------------------------------------------------
^ permalink raw reply related
* Re: [GIT PULL] fbdev fixes for 3.19
From: Pavel Machek @ 2014-12-23 11:12 UTC (permalink / raw)
To: Tomi Valkeinen
Cc: Linus Torvalds, LKML, Linux Fbdev development list, Mark Brown
In-Reply-To: <20141220215718.GA25101@amd>
On Sat 2014-12-20 22:57:18, Pavel Machek wrote:
> On Sat 2014-12-20 22:20:27, Pavel Machek wrote:
> > On Sat 2014-12-20 22:01:25, Pavel Machek wrote:
> > > Hi!
> > >
> > > > Please pull fbdev changes for 3.19.
> > > >
> > > > Tomi
> > >
> > > v3.19-rc0 breaks video on my n900.
> > >
> > > > Archit Taneja (7):
> > > > OMAPDSS: DPI: Use DPI driver data
> > > > OMAPDSS: DPI: Allocate driver data
> > > > OMAPDSS: DPI: Store dpi_data pointer in the DT port's data
> > > > OMAPDSS: DSS: init dss ports cleanly
> > > > OMAPDSS: DT: Get source endpoint by matching reg-id
> > > > OMAPDSS: DPI: Add support for multiple instances
> > > > OMAPDSS: DSS: add a param to dpi_select_source which specifies
> > > > it's port number
> > >
> > > And I have these in my tree, so I should have latest fixes. Any ideas
> > > what I should try?
> >
> > I test-merged 3315764efceaccfb02c7d4c99ef8eed6716cd861, and boom,
> > video is gone.
>
> I reverted
> 4b4123f0c7b02f7cf1a3189f967f079197578c3a..9051909e451a0368c95ccf74562adb53fd2719f8
> in 3.19, and voila, video is back.
Tomi?
Your merge causes regression on my hardware. I'd expect some
communication from you. If you don't have time right now, can we
revert the merge until its fixed?
Pavel
--
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
^ permalink raw reply
* [patch] fbdev: off by one test (harmless)
From: Dan Carpenter @ 2014-12-26 17:26 UTC (permalink / raw)
To: linux-fbdev
ARRAY_SIZE(cea_modes) is 64 so the "idx > 63" test earlier means this
test is really a no-op. But it's still off by one and upsets the static
checkers so we may as well correct it.
Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
diff --git a/drivers/video/fbdev/core/fbmon.c b/drivers/video/fbdev/core/fbmon.c
index 5b0e313..3030269 100644
--- a/drivers/video/fbdev/core/fbmon.c
+++ b/drivers/video/fbdev/core/fbmon.c
@@ -1061,7 +1061,7 @@ void fb_edid_add_monspecs(unsigned char *edid, struct fb_monspecs *specs)
int idx = svd[i - specs->modedb_len - num];
if (!idx || idx > 63) {
pr_warning("Reserved SVD code %d\n", idx);
- } else if (idx > ARRAY_SIZE(cea_modes) || !cea_modes[idx].xres) {
+ } else if (idx >= ARRAY_SIZE(cea_modes) || !cea_modes[idx].xres) {
pr_warning("Unimplemented SVD code %d\n", idx);
} else {
memcpy(&m[i], cea_modes + idx, sizeof(m[i]));
^ permalink raw reply related
* Re: [patch] fbdev: off by one test (harmless)
From: Jingoo Han @ 2014-12-27 1:29 UTC (permalink / raw)
To: linux-fbdev
In-Reply-To: <20141226172657.GA14762@mwanda>
On Saturday, December 27, 2014 2:27 AM, Dan Carpenter wrote:
>
> ARRAY_SIZE(cea_modes) is 64 so the "idx > 63" test earlier means this
Good.
'cea_modes' is defined as below. So, ARRAY_SIZE(cea_modes) is 64.
extern const struct fb_videomode cea_modes[64];
> test is really a no-op. But it's still off by one and upsets the static
> checkers so we may as well correct it.
'idx' should be 0~63, because cea_modes array is defined as 'cea_modes[64]'.
>
> Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
Reviewed-by: Jingoo Han <jg1.han@samsung.com>
Best regards,
Jingoo Han
>
> diff --git a/drivers/video/fbdev/core/fbmon.c b/drivers/video/fbdev/core/fbmon.c
> index 5b0e313..3030269 100644
> --- a/drivers/video/fbdev/core/fbmon.c
> +++ b/drivers/video/fbdev/core/fbmon.c
> @@ -1061,7 +1061,7 @@ void fb_edid_add_monspecs(unsigned char *edid, struct fb_monspecs *specs)
> int idx = svd[i - specs->modedb_len - num];
> if (!idx || idx > 63) {
> pr_warning("Reserved SVD code %d\n", idx);
> - } else if (idx > ARRAY_SIZE(cea_modes) || !cea_modes[idx].xres) {
> + } else if (idx >= ARRAY_SIZE(cea_modes) || !cea_modes[idx].xres) {
> pr_warning("Unimplemented SVD code %d\n", idx);
> } else {
> memcpy(&m[i], cea_modes + idx, sizeof(m[i]));
^ permalink raw reply
* Re: [GIT PULL] fbdev fixes for 3.19
From: Tomi Valkeinen @ 2014-12-29 8:13 UTC (permalink / raw)
To: Pavel Machek
Cc: Linus Torvalds, LKML, Linux Fbdev development list, Mark Brown
In-Reply-To: <20141223111250.GA30284@amd>
[-- Attachment #1: Type: text/plain, Size: 539 bytes --]
Hi,
On 23/12/14 13:12, Pavel Machek wrote:
>>> I test-merged 3315764efceaccfb02c7d4c99ef8eed6716cd861, and boom,
>>> video is gone.
>>
>> I reverted
>> 4b4123f0c7b02f7cf1a3189f967f079197578c3a..9051909e451a0368c95ccf74562adb53fd2719f8
>> in 3.19, and voila, video is back.
>
> Tomi?
>
> Your merge causes regression on my hardware. I'd expect some
> communication from you. If you don't have time right now, can we
> revert the merge until its fixed?
I've posted a fix on the "n900 regressions" thread.
Tomi
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]
^ permalink raw reply
* RE: [patch] fbdev: off by one test (harmless)
From: David Ung @ 2014-12-29 21:51 UTC (permalink / raw)
To: linux-fbdev
In-Reply-To: <20141226172657.GA14762@mwanda>
> > test is really a no-op. But it's still off by one and upsets the
> > static checkers so we may as well correct it.
>
> 'idx' should be 0~63, because cea_modes array is defined as
> 'cea_modes[64]'.
According to CEA/EIA-861E, there are 64 defined modes, but idx is valid for 1-64, 0 is reserved hence the check for
If (!idx || idx > 63) {
Think idx check really should be !idx || idx > 64 if following CEA/EIA-861E
CEA/EIA-861F add additional entries and idx is valid from 1-107
David
-----------------------------------------------------------------------------------
This email message is for the sole use of the intended recipient(s) and may contain
confidential information. Any unauthorized review, use, disclosure or distribution
is prohibited. If you are not the intended recipient, please contact the sender by
reply email and destroy all copies of the original message.
-----------------------------------------------------------------------------------
^ permalink raw reply
* [GIT PULL] fbdev fixes for 3.19
From: Tomi Valkeinen @ 2014-12-30 11:44 UTC (permalink / raw)
To: Linus Torvalds; +Cc: Linux Fbdev development list, LKML
In-Reply-To: <54899F0E.4090309@ti.com>
[-- Attachment #1: Type: text/plain, Size: 1342 bytes --]
Hi Linus,
The following changes since commit b7392d2247cfe6771f95d256374f1a8e6a6f48d6:
Linux 3.19-rc2 (2014-12-28 16:49:37 -0800)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/tomba/linux.git tags/fbdev-fixes-3.19
for you to fetch changes up to a32442d4f8b712b701ea577c841d6a0a7c5993c1:
OMAPDSS: SDI: fix output port_num (2014-12-30 11:18:30 +0200)
----------------------------------------------------------------
fbdev fixes for 3.19
* Fix regression with Nokia N900 display
* Fix crash on fbdev using freed __initdata logos
* Fix fb_deferred_io_fsync() return value.
----------------------------------------------------------------
Dan Carpenter (1):
OMAPDSS: pll: NULL dereference in error handling
Tomi Valkeinen (4):
OMAPDSS: HDMI: remove double initializer entries
video/logo: prevent use of logos after they have been freed
video/fbdev: fix defio's fsync
OMAPDSS: SDI: fix output port_num
drivers/video/fbdev/core/fb_defio.c | 5 +++--
drivers/video/fbdev/omap2/dss/hdmi_pll.c | 2 --
drivers/video/fbdev/omap2/dss/pll.c | 3 ++-
drivers/video/fbdev/omap2/dss/sdi.c | 2 ++
drivers/video/logo/logo.c | 17 ++++++++++++++++-
5 files changed, 23 insertions(+), 6 deletions(-)
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]
^ permalink raw reply
* [PATCH] fbdev: geocode: remove unneeded NULL check
From: Sudip Mukherjee @ 2014-12-31 6:55 UTC (permalink / raw)
To: Jean-Christophe Plagniol-Villard, Tomi Valkeinen
Cc: Sudip Mukherjee, linux-geode, linux-fbdev, linux-kernel
the check for info is not required as we are checking it immediately
after gx1fb_init_fbinfo() and returnig -ENOMEM if it is NULL.
Signed-off-by: Sudip Mukherjee <sudip@vectorindia.org>
---
drivers/video/fbdev/geode/gx1fb_core.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/drivers/video/fbdev/geode/gx1fb_core.c b/drivers/video/fbdev/geode/gx1fb_core.c
index 2794ba1..9bee874 100644
--- a/drivers/video/fbdev/geode/gx1fb_core.c
+++ b/drivers/video/fbdev/geode/gx1fb_core.c
@@ -374,10 +374,8 @@ static int gx1fb_probe(struct pci_dev *pdev, const struct pci_device_id *id)
release_mem_region(gx1_gx_base() + 0x8300, 0x100);
}
- if (info) {
- fb_dealloc_cmap(&info->cmap);
- framebuffer_release(info);
- }
+ fb_dealloc_cmap(&info->cmap);
+ framebuffer_release(info);
return ret;
}
--
1.8.1.2
^ permalink raw reply related
* [PATCH 1/3] Revert "staging: sm7xxfb: remove driver"
From: Sudip Mukherjee @ 2014-12-31 12:38 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: Sudip Mukherjee, Teddy Wang, Sudip Mukherjee, linux-kernel, devel,
linux-fbdev
This reverts commit "dc93c85235efa5201e9a3c116bc3fbd1afc1a182"
Signed-off-by: Sudip Mukherjee <sudip@vectorindia.org>
---
Hi Greg K-H
With reference to our discussion at https://lkml.org/lkml/2014/11/22/54 ,
now I have the hardware and I will be working on the code along with
Teddy Wang.
drivers/staging/Kconfig | 2 +
drivers/staging/Makefile | 1 +
drivers/staging/sm7xxfb/Kconfig | 13 +
drivers/staging/sm7xxfb/Makefile | 1 +
drivers/staging/sm7xxfb/TODO | 9 +
drivers/staging/sm7xxfb/sm7xx.h | 779 ++++++++++++++++++++++++++++
drivers/staging/sm7xxfb/sm7xxfb.c | 1026 +++++++++++++++++++++++++++++++++++++
7 files changed, 1831 insertions(+)
create mode 100644 drivers/staging/sm7xxfb/Kconfig
create mode 100644 drivers/staging/sm7xxfb/Makefile
create mode 100644 drivers/staging/sm7xxfb/TODO
create mode 100644 drivers/staging/sm7xxfb/sm7xx.h
create mode 100644 drivers/staging/sm7xxfb/sm7xxfb.c
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
index 815de37..ff633da 100644
--- a/drivers/staging/Kconfig
+++ b/drivers/staging/Kconfig
@@ -58,6 +58,8 @@ source "drivers/staging/vt6656/Kconfig"
source "drivers/staging/iio/Kconfig"
+source "drivers/staging/sm7xxfb/Kconfig"
+
source "drivers/staging/xgifb/Kconfig"
source "drivers/staging/emxx_udc/Kconfig"
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
index 33c640b..43dc444 100644
--- a/drivers/staging/Makefile
+++ b/drivers/staging/Makefile
@@ -23,6 +23,7 @@ obj-$(CONFIG_VT6655) += vt6655/
obj-$(CONFIG_VT6656) += vt6656/
obj-$(CONFIG_VME_BUS) += vme/
obj-$(CONFIG_IIO) += iio/
+obj-$(CONFIG_FB_SM7XX) += sm7xxfb/
obj-$(CONFIG_FB_XGI) += xgifb/
obj-$(CONFIG_USB_EMXX) += emxx_udc/
obj-$(CONFIG_FT1000) += ft1000/
diff --git a/drivers/staging/sm7xxfb/Kconfig b/drivers/staging/sm7xxfb/Kconfig
new file mode 100644
index 0000000..e2922ae
--- /dev/null
+++ b/drivers/staging/sm7xxfb/Kconfig
@@ -0,0 +1,13 @@
+config FB_SM7XX
+ tristate "Silicon Motion SM7XX framebuffer support"
+ depends on FB && PCI
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ Frame buffer driver for the Silicon Motion SM710, SM712, SM721
+ and SM722 chips.
+
+ This driver is also available as a module. The module will be
+ called sm7xxfb. If you want to compile it as a module, say M
+ here and read <file:Documentation/kbuild/modules.txt>.
diff --git a/drivers/staging/sm7xxfb/Makefile b/drivers/staging/sm7xxfb/Makefile
new file mode 100644
index 0000000..48f471c
--- /dev/null
+++ b/drivers/staging/sm7xxfb/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_FB_SM7XX) += sm7xxfb.o
diff --git a/drivers/staging/sm7xxfb/TODO b/drivers/staging/sm7xxfb/TODO
new file mode 100644
index 0000000..1fcead5
--- /dev/null
+++ b/drivers/staging/sm7xxfb/TODO
@@ -0,0 +1,9 @@
+TODO:
+- Dual head support
+- 2D acceleration support
+- use kernel coding style
+- refine the code and remove unused code
+- move it to drivers/video/sm7xxfb.c
+
+Please send any patches to Greg Kroah-Hartman <greg@kroah.com> and
+Teddy Wang <teddy.wang@siliconmotion.com.cn>.
diff --git a/drivers/staging/sm7xxfb/sm7xx.h b/drivers/staging/sm7xxfb/sm7xx.h
new file mode 100644
index 0000000..8599861
--- /dev/null
+++ b/drivers/staging/sm7xxfb/sm7xx.h
@@ -0,0 +1,779 @@
+/*
+ * Silicon Motion SM712 frame buffer device
+ *
+ * Copyright (C) 2006 Silicon Motion Technology Corp.
+ * Authors: Ge Wang, gewang@siliconmotion.com
+ * Boyod boyod.yang@siliconmotion.com.cn
+ *
+ * Copyright (C) 2009 Lemote, Inc.
+ * Author: Wu Zhangjin, wuzhangjin@gmail.com
+ *
+ * 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.
+ */
+
+#define NR_PALETTE 256
+
+#define FB_ACCEL_SMI_LYNX 88
+
+#define SCREEN_X_RES 1024
+#define SCREEN_Y_RES 600
+#define SCREEN_BPP 16
+
+/*Assume SM712 graphics chip has 4MB VRAM */
+#define SM712_VIDEOMEMORYSIZE 0x00400000
+/*Assume SM722 graphics chip has 8MB VRAM */
+#define SM722_VIDEOMEMORYSIZE 0x00800000
+
+#define dac_reg (0x3c8)
+#define dac_val (0x3c9)
+
+extern void __iomem *smtc_RegBaseAddress;
+#define smtc_mmiowb(dat, reg) writeb(dat, smtc_RegBaseAddress + reg)
+#define smtc_mmioww(dat, reg) writew(dat, smtc_RegBaseAddress + reg)
+#define smtc_mmiowl(dat, reg) writel(dat, smtc_RegBaseAddress + reg)
+
+#define smtc_mmiorb(reg) readb(smtc_RegBaseAddress + reg)
+#define smtc_mmiorw(reg) readw(smtc_RegBaseAddress + reg)
+#define smtc_mmiorl(reg) readl(smtc_RegBaseAddress + reg)
+
+#define SIZE_SR00_SR04 (0x04 - 0x00 + 1)
+#define SIZE_SR10_SR24 (0x24 - 0x10 + 1)
+#define SIZE_SR30_SR75 (0x75 - 0x30 + 1)
+#define SIZE_SR80_SR93 (0x93 - 0x80 + 1)
+#define SIZE_SRA0_SRAF (0xAF - 0xA0 + 1)
+#define SIZE_GR00_GR08 (0x08 - 0x00 + 1)
+#define SIZE_AR00_AR14 (0x14 - 0x00 + 1)
+#define SIZE_CR00_CR18 (0x18 - 0x00 + 1)
+#define SIZE_CR30_CR4D (0x4D - 0x30 + 1)
+#define SIZE_CR90_CRA7 (0xA7 - 0x90 + 1)
+#define SIZE_VPR (0x6C + 1)
+#define SIZE_DPR (0x44 + 1)
+
+static inline void smtc_crtcw(int reg, int val)
+{
+ smtc_mmiowb(reg, 0x3d4);
+ smtc_mmiowb(val, 0x3d5);
+}
+
+static inline unsigned int smtc_crtcr(int reg)
+{
+ smtc_mmiowb(reg, 0x3d4);
+ return smtc_mmiorb(0x3d5);
+}
+
+static inline void smtc_grphw(int reg, int val)
+{
+ smtc_mmiowb(reg, 0x3ce);
+ smtc_mmiowb(val, 0x3cf);
+}
+
+static inline unsigned int smtc_grphr(int reg)
+{
+ smtc_mmiowb(reg, 0x3ce);
+ return smtc_mmiorb(0x3cf);
+}
+
+static inline void smtc_attrw(int reg, int val)
+{
+ smtc_mmiorb(0x3da);
+ smtc_mmiowb(reg, 0x3c0);
+ smtc_mmiorb(0x3c1);
+ smtc_mmiowb(val, 0x3c0);
+}
+
+static inline void smtc_seqw(int reg, int val)
+{
+ smtc_mmiowb(reg, 0x3c4);
+ smtc_mmiowb(val, 0x3c5);
+}
+
+static inline unsigned int smtc_seqr(int reg)
+{
+ smtc_mmiowb(reg, 0x3c4);
+ return smtc_mmiorb(0x3c5);
+}
+
+/* The next structure holds all information relevant for a specific video mode.
+ */
+
+struct ModeInit {
+ int mmSizeX;
+ int mmSizeY;
+ int bpp;
+ int hz;
+ unsigned char Init_MISC;
+ unsigned char Init_SR00_SR04[SIZE_SR00_SR04];
+ unsigned char Init_SR10_SR24[SIZE_SR10_SR24];
+ unsigned char Init_SR30_SR75[SIZE_SR30_SR75];
+ unsigned char Init_SR80_SR93[SIZE_SR80_SR93];
+ unsigned char Init_SRA0_SRAF[SIZE_SRA0_SRAF];
+ unsigned char Init_GR00_GR08[SIZE_GR00_GR08];
+ unsigned char Init_AR00_AR14[SIZE_AR00_AR14];
+ unsigned char Init_CR00_CR18[SIZE_CR00_CR18];
+ unsigned char Init_CR30_CR4D[SIZE_CR30_CR4D];
+ unsigned char Init_CR90_CRA7[SIZE_CR90_CRA7];
+};
+
+/**********************************************************************
+ SM712 Mode table.
+ **********************************************************************/
+struct ModeInit VGAMode[] = {
+ {
+ /* mode#0: 640 x 480 16Bpp 60Hz */
+ 640, 480, 16, 60,
+ /* Init_MISC */
+ 0xE3,
+ { /* Init_SR0_SR4 */
+ 0x03, 0x01, 0x0F, 0x00, 0x0E,
+ },
+ { /* Init_SR10_SR24 */
+ 0xFF, 0xBE, 0xEF, 0xFF, 0x00, 0x0E, 0x17, 0x2C,
+ 0x99, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xC4, 0x30, 0x02, 0x01, 0x01,
+ },
+ { /* Init_SR30_SR75 */
+ 0x32, 0x03, 0xA0, 0x09, 0xC0, 0x32, 0x32, 0x32,
+ 0x32, 0x32, 0x32, 0x32, 0x00, 0x00, 0x03, 0xFF,
+ 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC,
+ 0x20, 0x0C, 0x44, 0x20, 0x00, 0x32, 0x32, 0x32,
+ 0x04, 0x24, 0x63, 0x4F, 0x52, 0x0B, 0xDF, 0xEA,
+ 0x04, 0x50, 0x19, 0x32, 0x32, 0x00, 0x00, 0x32,
+ 0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00,
+ 0x50, 0x03, 0x74, 0x14, 0x07, 0x82, 0x07, 0x04,
+ 0x00, 0x45, 0x30, 0x30, 0x40, 0x30,
+ },
+ { /* Init_SR80_SR93 */
+ 0xFF, 0x07, 0x00, 0x6F, 0x7F, 0x7F, 0xFF, 0x32,
+ 0xF7, 0x00, 0x00, 0x00, 0xEF, 0xFF, 0x32, 0x32,
+ 0x00, 0x00, 0x00, 0x00,
+ },
+ { /* Init_SRA0_SRAF */
+ 0x00, 0xFF, 0xBF, 0xFF, 0xFF, 0xED, 0xED, 0xED,
+ 0x7B, 0xFF, 0xFF, 0xFF, 0xBF, 0xEF, 0xFF, 0xDF,
+ },
+ { /* Init_GR00_GR08 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,
+ 0xFF,
+ },
+ { /* Init_AR00_AR14 */
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+ 0x41, 0x00, 0x0F, 0x00, 0x00,
+ },
+ { /* Init_CR00_CR18 */
+ 0x5F, 0x4F, 0x4F, 0x00, 0x53, 0x1F, 0x0B, 0x3E,
+ 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xEA, 0x0C, 0xDF, 0x50, 0x40, 0xDF, 0x00, 0xE3,
+ 0xFF,
+ },
+ { /* Init_CR30_CR4D */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x03, 0x20,
+ 0x00, 0x00, 0x00, 0x40, 0x00, 0xE7, 0xFF, 0xFD,
+ 0x5F, 0x4F, 0x00, 0x54, 0x00, 0x0B, 0xDF, 0x00,
+ 0xEA, 0x0C, 0x2E, 0x00, 0x4F, 0xDF,
+ },
+ { /* Init_CR90_CRA7 */
+ 0x56, 0xDD, 0x5E, 0xEA, 0x87, 0x44, 0x8F, 0x55,
+ 0x0A, 0x8F, 0x55, 0x0A, 0x00, 0x00, 0x18, 0x00,
+ 0x11, 0x10, 0x0B, 0x0A, 0x0A, 0x0A, 0x0A, 0x00,
+ },
+ },
+ {
+ /* mode#1: 640 x 480 24Bpp 60Hz */
+ 640, 480, 24, 60,
+ /* Init_MISC */
+ 0xE3,
+ { /* Init_SR0_SR4 */
+ 0x03, 0x01, 0x0F, 0x00, 0x0E,
+ },
+ { /* Init_SR10_SR24 */
+ 0xFF, 0xBE, 0xEF, 0xFF, 0x00, 0x0E, 0x17, 0x2C,
+ 0x99, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xC4, 0x30, 0x02, 0x01, 0x01,
+ },
+ { /* Init_SR30_SR75 */
+ 0x32, 0x03, 0xA0, 0x09, 0xC0, 0x32, 0x32, 0x32,
+ 0x32, 0x32, 0x32, 0x32, 0x00, 0x00, 0x03, 0xFF,
+ 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC,
+ 0x20, 0x0C, 0x44, 0x20, 0x00, 0x32, 0x32, 0x32,
+ 0x04, 0x24, 0x63, 0x4F, 0x52, 0x0B, 0xDF, 0xEA,
+ 0x04, 0x50, 0x19, 0x32, 0x32, 0x00, 0x00, 0x32,
+ 0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00,
+ 0x50, 0x03, 0x74, 0x14, 0x07, 0x82, 0x07, 0x04,
+ 0x00, 0x45, 0x30, 0x30, 0x40, 0x30,
+ },
+ { /* Init_SR80_SR93 */
+ 0xFF, 0x07, 0x00, 0x6F, 0x7F, 0x7F, 0xFF, 0x32,
+ 0xF7, 0x00, 0x00, 0x00, 0xEF, 0xFF, 0x32, 0x32,
+ 0x00, 0x00, 0x00, 0x00,
+ },
+ { /* Init_SRA0_SRAF */
+ 0x00, 0xFF, 0xBF, 0xFF, 0xFF, 0xED, 0xED, 0xED,
+ 0x7B, 0xFF, 0xFF, 0xFF, 0xBF, 0xEF, 0xFF, 0xDF,
+ },
+ { /* Init_GR00_GR08 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,
+ 0xFF,
+ },
+ { /* Init_AR00_AR14 */
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+ 0x41, 0x00, 0x0F, 0x00, 0x00,
+ },
+ { /* Init_CR00_CR18 */
+ 0x5F, 0x4F, 0x4F, 0x00, 0x53, 0x1F, 0x0B, 0x3E,
+ 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xEA, 0x0C, 0xDF, 0x50, 0x40, 0xDF, 0x00, 0xE3,
+ 0xFF,
+ },
+ { /* Init_CR30_CR4D */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x03, 0x20,
+ 0x00, 0x00, 0x00, 0x40, 0x00, 0xE7, 0xFF, 0xFD,
+ 0x5F, 0x4F, 0x00, 0x54, 0x00, 0x0B, 0xDF, 0x00,
+ 0xEA, 0x0C, 0x2E, 0x00, 0x4F, 0xDF,
+ },
+ { /* Init_CR90_CRA7 */
+ 0x56, 0xDD, 0x5E, 0xEA, 0x87, 0x44, 0x8F, 0x55,
+ 0x0A, 0x8F, 0x55, 0x0A, 0x00, 0x00, 0x18, 0x00,
+ 0x11, 0x10, 0x0B, 0x0A, 0x0A, 0x0A, 0x0A, 0x00,
+ },
+ },
+ {
+ /* mode#0: 640 x 480 32Bpp 60Hz */
+ 640, 480, 32, 60,
+ /* Init_MISC */
+ 0xE3,
+ { /* Init_SR0_SR4 */
+ 0x03, 0x01, 0x0F, 0x00, 0x0E,
+ },
+ { /* Init_SR10_SR24 */
+ 0xFF, 0xBE, 0xEF, 0xFF, 0x00, 0x0E, 0x17, 0x2C,
+ 0x99, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xC4, 0x30, 0x02, 0x01, 0x01,
+ },
+ { /* Init_SR30_SR75 */
+ 0x32, 0x03, 0xA0, 0x09, 0xC0, 0x32, 0x32, 0x32,
+ 0x32, 0x32, 0x32, 0x32, 0x00, 0x00, 0x03, 0xFF,
+ 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC,
+ 0x20, 0x0C, 0x44, 0x20, 0x00, 0x32, 0x32, 0x32,
+ 0x04, 0x24, 0x63, 0x4F, 0x52, 0x0B, 0xDF, 0xEA,
+ 0x04, 0x50, 0x19, 0x32, 0x32, 0x00, 0x00, 0x32,
+ 0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00,
+ 0x50, 0x03, 0x74, 0x14, 0x07, 0x82, 0x07, 0x04,
+ 0x00, 0x45, 0x30, 0x30, 0x40, 0x30,
+ },
+ { /* Init_SR80_SR93 */
+ 0xFF, 0x07, 0x00, 0x6F, 0x7F, 0x7F, 0xFF, 0x32,
+ 0xF7, 0x00, 0x00, 0x00, 0xEF, 0xFF, 0x32, 0x32,
+ 0x00, 0x00, 0x00, 0x00,
+ },
+ { /* Init_SRA0_SRAF */
+ 0x00, 0xFF, 0xBF, 0xFF, 0xFF, 0xED, 0xED, 0xED,
+ 0x7B, 0xFF, 0xFF, 0xFF, 0xBF, 0xEF, 0xFF, 0xDF,
+ },
+ { /* Init_GR00_GR08 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,
+ 0xFF,
+ },
+ { /* Init_AR00_AR14 */
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+ 0x41, 0x00, 0x0F, 0x00, 0x00,
+ },
+ { /* Init_CR00_CR18 */
+ 0x5F, 0x4F, 0x4F, 0x00, 0x53, 0x1F, 0x0B, 0x3E,
+ 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xEA, 0x0C, 0xDF, 0x50, 0x40, 0xDF, 0x00, 0xE3,
+ 0xFF,
+ },
+ { /* Init_CR30_CR4D */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x03, 0x20,
+ 0x00, 0x00, 0x00, 0x40, 0x00, 0xE7, 0xFF, 0xFD,
+ 0x5F, 0x4F, 0x00, 0x54, 0x00, 0x0B, 0xDF, 0x00,
+ 0xEA, 0x0C, 0x2E, 0x00, 0x4F, 0xDF,
+ },
+ { /* Init_CR90_CRA7 */
+ 0x56, 0xDD, 0x5E, 0xEA, 0x87, 0x44, 0x8F, 0x55,
+ 0x0A, 0x8F, 0x55, 0x0A, 0x00, 0x00, 0x18, 0x00,
+ 0x11, 0x10, 0x0B, 0x0A, 0x0A, 0x0A, 0x0A, 0x00,
+ },
+ },
+
+ { /* mode#2: 800 x 600 16Bpp 60Hz */
+ 800, 600, 16, 60,
+ /* Init_MISC */
+ 0x2B,
+ { /* Init_SR0_SR4 */
+ 0x03, 0x01, 0x0F, 0x03, 0x0E,
+ },
+ { /* Init_SR10_SR24 */
+ 0xFF, 0xBE, 0xEE, 0xFF, 0x00, 0x0E, 0x17, 0x2C,
+ 0x99, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xC4, 0x30, 0x02, 0x01, 0x01,
+ },
+ { /* Init_SR30_SR75 */
+ 0x34, 0x03, 0x20, 0x09, 0xC0, 0x24, 0x24, 0x24,
+ 0x24, 0x24, 0x24, 0x24, 0x00, 0x00, 0x03, 0xFF,
+ 0x00, 0xFC, 0x00, 0x00, 0x20, 0x38, 0x00, 0xFC,
+ 0x20, 0x0C, 0x44, 0x20, 0x00, 0x24, 0x24, 0x24,
+ 0x04, 0x48, 0x83, 0x63, 0x68, 0x72, 0x57, 0x58,
+ 0x04, 0x55, 0x59, 0x24, 0x24, 0x00, 0x00, 0x24,
+ 0x01, 0x80, 0x7A, 0x1A, 0x1A, 0x00, 0x00, 0x00,
+ 0x50, 0x03, 0x74, 0x14, 0x1C, 0x85, 0x35, 0x13,
+ 0x02, 0x45, 0x30, 0x35, 0x40, 0x20,
+ },
+ { /* Init_SR80_SR93 */
+ 0x00, 0x00, 0x00, 0x6F, 0x7F, 0x7F, 0xFF, 0x24,
+ 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x24, 0x24,
+ 0x00, 0x00, 0x00, 0x00,
+ },
+ { /* Init_SRA0_SRAF */
+ 0x00, 0xFF, 0xBF, 0xFF, 0xFF, 0xED, 0xED, 0xED,
+ 0x7B, 0xFF, 0xFF, 0xFF, 0xBF, 0xEF, 0xBF, 0xDF,
+ },
+ { /* Init_GR00_GR08 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,
+ 0xFF,
+ },
+ { /* Init_AR00_AR14 */
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+ 0x41, 0x00, 0x0F, 0x00, 0x00,
+ },
+ { /* Init_CR00_CR18 */
+ 0x7F, 0x63, 0x63, 0x00, 0x68, 0x18, 0x72, 0xF0,
+ 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x58, 0x0C, 0x57, 0x64, 0x40, 0x57, 0x00, 0xE3,
+ 0xFF,
+ },
+ { /* Init_CR30_CR4D */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x03, 0x20,
+ 0x00, 0x00, 0x00, 0x40, 0x00, 0xE7, 0xBF, 0xFD,
+ 0x7F, 0x63, 0x00, 0x69, 0x18, 0x72, 0x57, 0x00,
+ 0x58, 0x0C, 0xE0, 0x20, 0x63, 0x57,
+ },
+ { /* Init_CR90_CRA7 */
+ 0x56, 0x4B, 0x5E, 0x55, 0x86, 0x9D, 0x8E, 0xAA,
+ 0xDB, 0x2A, 0xDF, 0x33, 0x00, 0x00, 0x18, 0x00,
+ 0x20, 0x1F, 0x1A, 0x19, 0x0F, 0x0F, 0x0F, 0x00,
+ },
+ },
+ { /* mode#3: 800 x 600 24Bpp 60Hz */
+ 800, 600, 24, 60,
+ 0x2B,
+ { /* Init_SR0_SR4 */
+ 0x03, 0x01, 0x0F, 0x03, 0x0E,
+ },
+ { /* Init_SR10_SR24 */
+ 0xFF, 0xBE, 0xEE, 0xFF, 0x00, 0x0E, 0x17, 0x2C,
+ 0x99, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xC4, 0x30, 0x02, 0x01, 0x01,
+ },
+ { /* Init_SR30_SR75 */
+ 0x36, 0x03, 0x20, 0x09, 0xC0, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x03, 0xFF,
+ 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC,
+ 0x20, 0x0C, 0x44, 0x20, 0x00, 0x36, 0x36, 0x36,
+ 0x04, 0x48, 0x83, 0x63, 0x68, 0x72, 0x57, 0x58,
+ 0x04, 0x55, 0x59, 0x36, 0x36, 0x00, 0x00, 0x36,
+ 0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00,
+ 0x50, 0x03, 0x74, 0x14, 0x1C, 0x85, 0x35, 0x13,
+ 0x02, 0x45, 0x30, 0x30, 0x40, 0x20,
+ },
+ { /* Init_SR80_SR93 */
+ 0xFF, 0x07, 0x00, 0x6F, 0x7F, 0x7F, 0xFF, 0x36,
+ 0xF7, 0x00, 0x00, 0x00, 0xEF, 0xFF, 0x36, 0x36,
+ 0x00, 0x00, 0x00, 0x00,
+ },
+ { /* Init_SRA0_SRAF */
+ 0x00, 0xFF, 0xBF, 0xFF, 0xFF, 0xED, 0xED, 0xED,
+ 0x7B, 0xFF, 0xFF, 0xFF, 0xBF, 0xEF, 0xBF, 0xDF,
+ },
+ { /* Init_GR00_GR08 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,
+ 0xFF,
+ },
+ { /* Init_AR00_AR14 */
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+ 0x41, 0x00, 0x0F, 0x00, 0x00,
+ },
+ { /* Init_CR00_CR18 */
+ 0x7F, 0x63, 0x63, 0x00, 0x68, 0x18, 0x72, 0xF0,
+ 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x58, 0x0C, 0x57, 0x64, 0x40, 0x57, 0x00, 0xE3,
+ 0xFF,
+ },
+ { /* Init_CR30_CR4D */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x03, 0x20,
+ 0x00, 0x00, 0x00, 0x40, 0x00, 0xE7, 0xBF, 0xFD,
+ 0x7F, 0x63, 0x00, 0x69, 0x18, 0x72, 0x57, 0x00,
+ 0x58, 0x0C, 0xE0, 0x20, 0x63, 0x57,
+ },
+ { /* Init_CR90_CRA7 */
+ 0x56, 0x4B, 0x5E, 0x55, 0x86, 0x9D, 0x8E, 0xAA,
+ 0xDB, 0x2A, 0xDF, 0x33, 0x00, 0x00, 0x18, 0x00,
+ 0x20, 0x1F, 0x1A, 0x19, 0x0F, 0x0F, 0x0F, 0x00,
+ },
+ },
+ { /* mode#7: 800 x 600 32Bpp 60Hz */
+ 800, 600, 32, 60,
+ /* Init_MISC */
+ 0x2B,
+ { /* Init_SR0_SR4 */
+ 0x03, 0x01, 0x0F, 0x03, 0x0E,
+ },
+ { /* Init_SR10_SR24 */
+ 0xFF, 0xBE, 0xEE, 0xFF, 0x00, 0x0E, 0x17, 0x2C,
+ 0x99, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xC4, 0x30, 0x02, 0x01, 0x01,
+ },
+ { /* Init_SR30_SR75 */
+ 0x34, 0x03, 0x20, 0x09, 0xC0, 0x24, 0x24, 0x24,
+ 0x24, 0x24, 0x24, 0x24, 0x00, 0x00, 0x03, 0xFF,
+ 0x00, 0xFC, 0x00, 0x00, 0x20, 0x38, 0x00, 0xFC,
+ 0x20, 0x0C, 0x44, 0x20, 0x00, 0x24, 0x24, 0x24,
+ 0x04, 0x48, 0x83, 0x63, 0x68, 0x72, 0x57, 0x58,
+ 0x04, 0x55, 0x59, 0x24, 0x24, 0x00, 0x00, 0x24,
+ 0x01, 0x80, 0x7A, 0x1A, 0x1A, 0x00, 0x00, 0x00,
+ 0x50, 0x03, 0x74, 0x14, 0x1C, 0x85, 0x35, 0x13,
+ 0x02, 0x45, 0x30, 0x35, 0x40, 0x20,
+ },
+ { /* Init_SR80_SR93 */
+ 0x00, 0x00, 0x00, 0x6F, 0x7F, 0x7F, 0xFF, 0x24,
+ 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x24, 0x24,
+ 0x00, 0x00, 0x00, 0x00,
+ },
+ { /* Init_SRA0_SRAF */
+ 0x00, 0xFF, 0xBF, 0xFF, 0xFF, 0xED, 0xED, 0xED,
+ 0x7B, 0xFF, 0xFF, 0xFF, 0xBF, 0xEF, 0xBF, 0xDF,
+ },
+ { /* Init_GR00_GR08 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,
+ 0xFF,
+ },
+ { /* Init_AR00_AR14 */
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+ 0x41, 0x00, 0x0F, 0x00, 0x00,
+ },
+ { /* Init_CR00_CR18 */
+ 0x7F, 0x63, 0x63, 0x00, 0x68, 0x18, 0x72, 0xF0,
+ 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x58, 0x0C, 0x57, 0x64, 0x40, 0x57, 0x00, 0xE3,
+ 0xFF,
+ },
+ { /* Init_CR30_CR4D */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x03, 0x20,
+ 0x00, 0x00, 0x00, 0x40, 0x00, 0xE7, 0xBF, 0xFD,
+ 0x7F, 0x63, 0x00, 0x69, 0x18, 0x72, 0x57, 0x00,
+ 0x58, 0x0C, 0xE0, 0x20, 0x63, 0x57,
+ },
+ { /* Init_CR90_CRA7 */
+ 0x56, 0x4B, 0x5E, 0x55, 0x86, 0x9D, 0x8E, 0xAA,
+ 0xDB, 0x2A, 0xDF, 0x33, 0x00, 0x00, 0x18, 0x00,
+ 0x20, 0x1F, 0x1A, 0x19, 0x0F, 0x0F, 0x0F, 0x00,
+ },
+ },
+ /* We use 1024x768 table to light 1024x600 panel for lemote */
+ { /* mode#4: 1024 x 600 16Bpp 60Hz */
+ 1024, 600, 16, 60,
+ /* Init_MISC */
+ 0xEB,
+ { /* Init_SR0_SR4 */
+ 0x03, 0x01, 0x0F, 0x00, 0x0E,
+ },
+ { /* Init_SR10_SR24 */
+ 0xC8, 0x40, 0x14, 0x60, 0x00, 0x0A, 0x17, 0x20,
+ 0x51, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xC4, 0x30, 0x02, 0x00, 0x01,
+ },
+ { /* Init_SR30_SR75 */
+ 0x22, 0x03, 0x24, 0x09, 0xC0, 0x22, 0x22, 0x22,
+ 0x22, 0x22, 0x22, 0x22, 0x00, 0x00, 0x03, 0xFF,
+ 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC,
+ 0x20, 0x0C, 0x44, 0x20, 0x00, 0x22, 0x22, 0x22,
+ 0x06, 0x68, 0xA7, 0x7F, 0x83, 0x24, 0xFF, 0x03,
+ 0x00, 0x60, 0x59, 0x22, 0x22, 0x00, 0x00, 0x22,
+ 0x01, 0x80, 0x7A, 0x1A, 0x1A, 0x00, 0x00, 0x00,
+ 0x50, 0x03, 0x16, 0x02, 0x0D, 0x82, 0x09, 0x02,
+ 0x04, 0x45, 0x3F, 0x30, 0x40, 0x20,
+ },
+ { /* Init_SR80_SR93 */
+ 0xFF, 0x07, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x3A,
+ 0xF7, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x3A, 0x3A,
+ 0x00, 0x00, 0x00, 0x00,
+ },
+ { /* Init_SRA0_SRAF */
+ 0x00, 0xFB, 0x9F, 0x01, 0x00, 0xED, 0xED, 0xED,
+ 0x7B, 0xFB, 0xFF, 0xFF, 0x97, 0xEF, 0xBF, 0xDF,
+ },
+ { /* Init_GR00_GR08 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,
+ 0xFF,
+ },
+ { /* Init_AR00_AR14 */
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+ 0x41, 0x00, 0x0F, 0x00, 0x00,
+ },
+ { /* Init_CR00_CR18 */
+ 0xA3, 0x7F, 0x7F, 0x00, 0x85, 0x16, 0x24, 0xF5,
+ 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x03, 0x09, 0xFF, 0x80, 0x40, 0xFF, 0x00, 0xE3,
+ 0xFF,
+ },
+ { /* Init_CR30_CR4D */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x20,
+ 0x00, 0x00, 0x00, 0x40, 0x00, 0xFF, 0xBF, 0xFF,
+ 0xA3, 0x7F, 0x00, 0x82, 0x0b, 0x6f, 0x57, 0x00,
+ 0x5c, 0x0f, 0xE0, 0xe0, 0x7F, 0x57,
+ },
+ { /* Init_CR90_CRA7 */
+ 0x55, 0xD9, 0x5D, 0xE1, 0x86, 0x1B, 0x8E, 0x26,
+ 0xDA, 0x8D, 0xDE, 0x94, 0x00, 0x00, 0x18, 0x00,
+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x15, 0x03,
+ },
+ },
+ { /* mode#5: 1024 x 768 24Bpp 60Hz */
+ 1024, 768, 24, 60,
+ /* Init_MISC */
+ 0xEB,
+ { /* Init_SR0_SR4 */
+ 0x03, 0x01, 0x0F, 0x03, 0x0E,
+ },
+ { /* Init_SR10_SR24 */
+ 0xF3, 0xB6, 0xC0, 0xDD, 0x00, 0x0E, 0x17, 0x2C,
+ 0x99, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xC4, 0x30, 0x02, 0x01, 0x01,
+ },
+ { /* Init_SR30_SR75 */
+ 0x38, 0x03, 0x20, 0x09, 0xC0, 0x3A, 0x3A, 0x3A,
+ 0x3A, 0x3A, 0x3A, 0x3A, 0x00, 0x00, 0x03, 0xFF,
+ 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC,
+ 0x20, 0x0C, 0x44, 0x20, 0x00, 0x00, 0x00, 0x3A,
+ 0x06, 0x68, 0xA7, 0x7F, 0x83, 0x24, 0xFF, 0x03,
+ 0x00, 0x60, 0x59, 0x3A, 0x3A, 0x00, 0x00, 0x3A,
+ 0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00,
+ 0x50, 0x03, 0x74, 0x14, 0x3B, 0x0D, 0x09, 0x02,
+ 0x04, 0x45, 0x30, 0x30, 0x40, 0x20,
+ },
+ { /* Init_SR80_SR93 */
+ 0xFF, 0x07, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x3A,
+ 0xF7, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x3A, 0x3A,
+ 0x00, 0x00, 0x00, 0x00,
+ },
+ { /* Init_SRA0_SRAF */
+ 0x00, 0xFB, 0x9F, 0x01, 0x00, 0xED, 0xED, 0xED,
+ 0x7B, 0xFB, 0xFF, 0xFF, 0x97, 0xEF, 0xBF, 0xDF,
+ },
+ { /* Init_GR00_GR08 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,
+ 0xFF,
+ },
+ { /* Init_AR00_AR14 */
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+ 0x41, 0x00, 0x0F, 0x00, 0x00,
+ },
+ { /* Init_CR00_CR18 */
+ 0xA3, 0x7F, 0x7F, 0x00, 0x85, 0x16, 0x24, 0xF5,
+ 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x03, 0x09, 0xFF, 0x80, 0x40, 0xFF, 0x00, 0xE3,
+ 0xFF,
+ },
+ { /* Init_CR30_CR4D */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x20,
+ 0x00, 0x00, 0x00, 0x40, 0x00, 0xFF, 0xBF, 0xFF,
+ 0xA3, 0x7F, 0x00, 0x86, 0x15, 0x24, 0xFF, 0x00,
+ 0x01, 0x07, 0xE5, 0x20, 0x7F, 0xFF,
+ },
+ { /* Init_CR90_CRA7 */
+ 0x55, 0xD9, 0x5D, 0xE1, 0x86, 0x1B, 0x8E, 0x26,
+ 0xDA, 0x8D, 0xDE, 0x94, 0x00, 0x00, 0x18, 0x00,
+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x15, 0x03,
+ },
+ },
+ { /* mode#4: 1024 x 768 32Bpp 60Hz */
+ 1024, 768, 32, 60,
+ /* Init_MISC */
+ 0xEB,
+ { /* Init_SR0_SR4 */
+ 0x03, 0x01, 0x0F, 0x03, 0x0E,
+ },
+ { /* Init_SR10_SR24 */
+ 0xF3, 0xB6, 0xC0, 0xDD, 0x00, 0x0E, 0x17, 0x2C,
+ 0x99, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xC4, 0x32, 0x02, 0x01, 0x01,
+ },
+ { /* Init_SR30_SR75 */
+ 0x38, 0x03, 0x20, 0x09, 0xC0, 0x3A, 0x3A, 0x3A,
+ 0x3A, 0x3A, 0x3A, 0x3A, 0x00, 0x00, 0x03, 0xFF,
+ 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC,
+ 0x20, 0x0C, 0x44, 0x20, 0x00, 0x00, 0x00, 0x3A,
+ 0x06, 0x68, 0xA7, 0x7F, 0x83, 0x24, 0xFF, 0x03,
+ 0x00, 0x60, 0x59, 0x3A, 0x3A, 0x00, 0x00, 0x3A,
+ 0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00,
+ 0x50, 0x03, 0x74, 0x14, 0x3B, 0x0D, 0x09, 0x02,
+ 0x04, 0x45, 0x30, 0x30, 0x40, 0x20,
+ },
+ { /* Init_SR80_SR93 */
+ 0xFF, 0x07, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x3A,
+ 0xF7, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x3A, 0x3A,
+ 0x00, 0x00, 0x00, 0x00,
+ },
+ { /* Init_SRA0_SRAF */
+ 0x00, 0xFB, 0x9F, 0x01, 0x00, 0xED, 0xED, 0xED,
+ 0x7B, 0xFB, 0xFF, 0xFF, 0x97, 0xEF, 0xBF, 0xDF,
+ },
+ { /* Init_GR00_GR08 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,
+ 0xFF,
+ },
+ { /* Init_AR00_AR14 */
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+ 0x41, 0x00, 0x0F, 0x00, 0x00,
+ },
+ { /* Init_CR00_CR18 */
+ 0xA3, 0x7F, 0x7F, 0x00, 0x85, 0x16, 0x24, 0xF5,
+ 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x03, 0x09, 0xFF, 0x80, 0x40, 0xFF, 0x00, 0xE3,
+ 0xFF,
+ },
+ { /* Init_CR30_CR4D */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x20,
+ 0x00, 0x00, 0x00, 0x40, 0x00, 0xFF, 0xBF, 0xFF,
+ 0xA3, 0x7F, 0x00, 0x86, 0x15, 0x24, 0xFF, 0x00,
+ 0x01, 0x07, 0xE5, 0x20, 0x7F, 0xFF,
+ },
+ { /* Init_CR90_CRA7 */
+ 0x55, 0xD9, 0x5D, 0xE1, 0x86, 0x1B, 0x8E, 0x26,
+ 0xDA, 0x8D, 0xDE, 0x94, 0x00, 0x00, 0x18, 0x00,
+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x15, 0x03,
+ },
+ },
+ { /* mode#6: 320 x 240 16Bpp 60Hz */
+ 320, 240, 16, 60,
+ /* Init_MISC */
+ 0xEB,
+ { /* Init_SR0_SR4 */
+ 0x03, 0x01, 0x0F, 0x03, 0x0E,
+ },
+ { /* Init_SR10_SR24 */
+ 0xF3, 0xB6, 0xC0, 0xDD, 0x00, 0x0E, 0x17, 0x2C,
+ 0x99, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xC4, 0x32, 0x02, 0x01, 0x01,
+ },
+ { /* Init_SR30_SR75 */
+ 0x38, 0x03, 0x20, 0x09, 0xC0, 0x3A, 0x3A, 0x3A,
+ 0x3A, 0x3A, 0x3A, 0x3A, 0x00, 0x00, 0x03, 0xFF,
+ 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC,
+ 0x20, 0x0C, 0x44, 0x20, 0x00, 0x00, 0x00, 0x3A,
+ 0x06, 0x68, 0xA7, 0x7F, 0x83, 0x24, 0xFF, 0x03,
+ 0x00, 0x60, 0x59, 0x3A, 0x3A, 0x00, 0x00, 0x3A,
+ 0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00,
+ 0x50, 0x03, 0x74, 0x14, 0x08, 0x43, 0x08, 0x43,
+ 0x04, 0x45, 0x30, 0x30, 0x40, 0x20,
+ },
+ { /* Init_SR80_SR93 */
+ 0xFF, 0x07, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x3A,
+ 0xF7, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x3A, 0x3A,
+ 0x00, 0x00, 0x00, 0x00,
+ },
+ { /* Init_SRA0_SRAF */
+ 0x00, 0xFB, 0x9F, 0x01, 0x00, 0xED, 0xED, 0xED,
+ 0x7B, 0xFB, 0xFF, 0xFF, 0x97, 0xEF, 0xBF, 0xDF,
+ },
+ { /* Init_GR00_GR08 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,
+ 0xFF,
+ },
+ { /* Init_AR00_AR14 */
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+ 0x41, 0x00, 0x0F, 0x00, 0x00,
+ },
+ { /* Init_CR00_CR18 */
+ 0xA3, 0x7F, 0x7F, 0x00, 0x85, 0x16, 0x24, 0xF5,
+ 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x03, 0x09, 0xFF, 0x80, 0x40, 0xFF, 0x00, 0xE3,
+ 0xFF,
+ },
+ { /* Init_CR30_CR4D */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x20,
+ 0x00, 0x00, 0x30, 0x40, 0x00, 0xFF, 0xBF, 0xFF,
+ 0x2E, 0x27, 0x00, 0x2b, 0x0c, 0x0F, 0xEF, 0x00,
+ 0xFe, 0x0f, 0x01, 0xC0, 0x27, 0xEF,
+ },
+ { /* Init_CR90_CRA7 */
+ 0x55, 0xD9, 0x5D, 0xE1, 0x86, 0x1B, 0x8E, 0x26,
+ 0xDA, 0x8D, 0xDE, 0x94, 0x00, 0x00, 0x18, 0x00,
+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x15, 0x03,
+ },
+ },
+
+ { /* mode#8: 320 x 240 32Bpp 60Hz */
+ 320, 240, 32, 60,
+ /* Init_MISC */
+ 0xEB,
+ { /* Init_SR0_SR4 */
+ 0x03, 0x01, 0x0F, 0x03, 0x0E,
+ },
+ { /* Init_SR10_SR24 */
+ 0xF3, 0xB6, 0xC0, 0xDD, 0x00, 0x0E, 0x17, 0x2C,
+ 0x99, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xC4, 0x32, 0x02, 0x01, 0x01,
+ },
+ { /* Init_SR30_SR75 */
+ 0x38, 0x03, 0x20, 0x09, 0xC0, 0x3A, 0x3A, 0x3A,
+ 0x3A, 0x3A, 0x3A, 0x3A, 0x00, 0x00, 0x03, 0xFF,
+ 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC,
+ 0x20, 0x0C, 0x44, 0x20, 0x00, 0x00, 0x00, 0x3A,
+ 0x06, 0x68, 0xA7, 0x7F, 0x83, 0x24, 0xFF, 0x03,
+ 0x00, 0x60, 0x59, 0x3A, 0x3A, 0x00, 0x00, 0x3A,
+ 0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00,
+ 0x50, 0x03, 0x74, 0x14, 0x08, 0x43, 0x08, 0x43,
+ 0x04, 0x45, 0x30, 0x30, 0x40, 0x20,
+ },
+ { /* Init_SR80_SR93 */
+ 0xFF, 0x07, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x3A,
+ 0xF7, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x3A, 0x3A,
+ 0x00, 0x00, 0x00, 0x00,
+ },
+ { /* Init_SRA0_SRAF */
+ 0x00, 0xFB, 0x9F, 0x01, 0x00, 0xED, 0xED, 0xED,
+ 0x7B, 0xFB, 0xFF, 0xFF, 0x97, 0xEF, 0xBF, 0xDF,
+ },
+ { /* Init_GR00_GR08 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,
+ 0xFF,
+ },
+ { /* Init_AR00_AR14 */
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+ 0x41, 0x00, 0x0F, 0x00, 0x00,
+ },
+ { /* Init_CR00_CR18 */
+ 0xA3, 0x7F, 0x7F, 0x00, 0x85, 0x16, 0x24, 0xF5,
+ 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x03, 0x09, 0xFF, 0x80, 0x40, 0xFF, 0x00, 0xE3,
+ 0xFF,
+ },
+ { /* Init_CR30_CR4D */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x20,
+ 0x00, 0x00, 0x30, 0x40, 0x00, 0xFF, 0xBF, 0xFF,
+ 0x2E, 0x27, 0x00, 0x2b, 0x0c, 0x0F, 0xEF, 0x00,
+ 0xFe, 0x0f, 0x01, 0xC0, 0x27, 0xEF,
+ },
+ { /* Init_CR90_CRA7 */
+ 0x55, 0xD9, 0x5D, 0xE1, 0x86, 0x1B, 0x8E, 0x26,
+ 0xDA, 0x8D, 0xDE, 0x94, 0x00, 0x00, 0x18, 0x00,
+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x15, 0x03,
+ },
+ },
+};
+
+#define numVGAModes ARRAY_SIZE(VGAMode)
diff --git a/drivers/staging/sm7xxfb/sm7xxfb.c b/drivers/staging/sm7xxfb/sm7xxfb.c
new file mode 100644
index 0000000..c550b71
--- /dev/null
+++ b/drivers/staging/sm7xxfb/sm7xxfb.c
@@ -0,0 +1,1026 @@
+/*
+ * Silicon Motion SM7XX frame buffer device
+ *
+ * Copyright (C) 2006 Silicon Motion Technology Corp.
+ * Authors: Ge Wang, gewang@siliconmotion.com
+ * Boyod boyod.yang@siliconmotion.com.cn
+ *
+ * Copyright (C) 2009 Lemote, Inc.
+ * Author: Wu Zhangjin, wuzhangjin@gmail.com
+ *
+ * Copyright (C) 2011 Igalia, S.L.
+ * Author: Javier M. Mellid <jmunhoz@igalia.com>
+ *
+ * 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.
+ *
+ * Framebuffer driver for Silicon Motion SM710, SM712, SM721 and SM722 chips
+ */
+
+#include <linux/io.h>
+#include <linux/fb.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/uaccess.h>
+#include <linux/module.h>
+#include <linux/console.h>
+#include <linux/screen_info.h>
+
+#ifdef CONFIG_PM
+#include <linux/pm.h>
+#endif
+
+#include "sm7xx.h"
+
+/*
+* Private structure
+*/
+struct smtcfb_info {
+ struct pci_dev *pdev;
+ struct fb_info fb;
+ u16 chip_id;
+ u8 chip_rev_id;
+
+ void __iomem *lfb; /* linear frame buffer */
+ void __iomem *dp_regs; /* drawing processor control regs */
+ void __iomem *vp_regs; /* video processor control regs */
+ void __iomem *cp_regs; /* capture processor control regs */
+ void __iomem *mmio; /* memory map IO port */
+
+ u_int width;
+ u_int height;
+ u_int hz;
+
+ u32 colreg[17];
+};
+
+void __iomem *smtc_RegBaseAddress; /* Memory Map IO starting address */
+
+static struct fb_var_screeninfo smtcfb_var = {
+ .xres = 1024,
+ .yres = 600,
+ .xres_virtual = 1024,
+ .yres_virtual = 600,
+ .bits_per_pixel = 16,
+ .red = {16, 8, 0},
+ .green = {8, 8, 0},
+ .blue = {0, 8, 0},
+ .activate = FB_ACTIVATE_NOW,
+ .height = -1,
+ .width = -1,
+ .vmode = FB_VMODE_NONINTERLACED,
+ .nonstd = 0,
+ .accel_flags = FB_ACCELF_TEXT,
+};
+
+static struct fb_fix_screeninfo smtcfb_fix = {
+ .id = "smXXXfb",
+ .type = FB_TYPE_PACKED_PIXELS,
+ .visual = FB_VISUAL_TRUECOLOR,
+ .line_length = 800 * 3,
+ .accel = FB_ACCEL_SMI_LYNX,
+ .type_aux = 0,
+ .xpanstep = 0,
+ .ypanstep = 0,
+ .ywrapstep = 0,
+};
+
+struct vesa_mode {
+ char index[6];
+ u16 lfb_width;
+ u16 lfb_height;
+ u16 lfb_depth;
+};
+
+static struct vesa_mode vesa_mode_table[] = {
+ {"0x301", 640, 480, 8},
+ {"0x303", 800, 600, 8},
+ {"0x305", 1024, 768, 8},
+ {"0x307", 1280, 1024, 8},
+
+ {"0x311", 640, 480, 16},
+ {"0x314", 800, 600, 16},
+ {"0x317", 1024, 768, 16},
+ {"0x31A", 1280, 1024, 16},
+
+ {"0x312", 640, 480, 24},
+ {"0x315", 800, 600, 24},
+ {"0x318", 1024, 768, 24},
+ {"0x31B", 1280, 1024, 24},
+};
+
+struct screen_info smtc_scr_info;
+
+/* process command line options, get vga parameter */
+static int __init sm7xx_vga_setup(char *options)
+{
+ int i;
+
+ if (!options || !*options)
+ return -EINVAL;
+
+ smtc_scr_info.lfb_width = 0;
+ smtc_scr_info.lfb_height = 0;
+ smtc_scr_info.lfb_depth = 0;
+
+ pr_debug("sm7xx_vga_setup = %s\n", options);
+
+ for (i = 0; i < ARRAY_SIZE(vesa_mode_table); i++) {
+ if (strstr(options, vesa_mode_table[i].index)) {
+ smtc_scr_info.lfb_width = vesa_mode_table[i].lfb_width;
+ smtc_scr_info.lfb_height + vesa_mode_table[i].lfb_height;
+ smtc_scr_info.lfb_depth = vesa_mode_table[i].lfb_depth;
+ return 0;
+ }
+ }
+
+ return -1;
+}
+__setup("vga=", sm7xx_vga_setup);
+
+static void sm712_setpalette(int regno, unsigned red, unsigned green,
+ unsigned blue, struct fb_info *info)
+{
+ /* set bit 5:4 = 01 (write LCD RAM only) */
+ smtc_seqw(0x66, (smtc_seqr(0x66) & 0xC3) | 0x10);
+
+ smtc_mmiowb(regno, dac_reg);
+ smtc_mmiowb(red >> 10, dac_val);
+ smtc_mmiowb(green >> 10, dac_val);
+ smtc_mmiowb(blue >> 10, dac_val);
+}
+
+/* chan_to_field
+ *
+ * convert a colour value into a field position
+ *
+ * from pxafb.c
+ */
+
+static inline unsigned int chan_to_field(unsigned int chan,
+ struct fb_bitfield *bf)
+{
+ chan &= 0xffff;
+ chan >>= 16 - bf->length;
+ return chan << bf->offset;
+}
+
+static int smtc_blank(int blank_mode, struct fb_info *info)
+{
+ /* clear DPMS setting */
+ switch (blank_mode) {
+ case FB_BLANK_UNBLANK:
+ /* Screen On: HSync: On, VSync : On */
+ smtc_seqw(0x01, (smtc_seqr(0x01) & (~0x20)));
+ smtc_seqw(0x6a, 0x16);
+ smtc_seqw(0x6b, 0x02);
+ smtc_seqw(0x21, (smtc_seqr(0x21) & 0x77));
+ smtc_seqw(0x22, (smtc_seqr(0x22) & (~0x30)));
+ smtc_seqw(0x23, (smtc_seqr(0x23) & (~0xc0)));
+ smtc_seqw(0x24, (smtc_seqr(0x24) | 0x01));
+ smtc_seqw(0x31, (smtc_seqr(0x31) | 0x03));
+ break;
+ case FB_BLANK_NORMAL:
+ /* Screen Off: HSync: On, VSync : On Soft blank */
+ smtc_seqw(0x01, (smtc_seqr(0x01) & (~0x20)));
+ smtc_seqw(0x6a, 0x16);
+ smtc_seqw(0x6b, 0x02);
+ smtc_seqw(0x22, (smtc_seqr(0x22) & (~0x30)));
+ smtc_seqw(0x23, (smtc_seqr(0x23) & (~0xc0)));
+ smtc_seqw(0x24, (smtc_seqr(0x24) | 0x01));
+ smtc_seqw(0x31, ((smtc_seqr(0x31) & (~0x07)) | 0x00));
+ break;
+ case FB_BLANK_VSYNC_SUSPEND:
+ /* Screen On: HSync: On, VSync : Off */
+ smtc_seqw(0x01, (smtc_seqr(0x01) | 0x20));
+ smtc_seqw(0x20, (smtc_seqr(0x20) & (~0xB0)));
+ smtc_seqw(0x6a, 0x0c);
+ smtc_seqw(0x6b, 0x02);
+ smtc_seqw(0x21, (smtc_seqr(0x21) | 0x88));
+ smtc_seqw(0x22, ((smtc_seqr(0x22) & (~0x30)) | 0x20));
+ smtc_seqw(0x23, ((smtc_seqr(0x23) & (~0xc0)) | 0x20));
+ smtc_seqw(0x24, (smtc_seqr(0x24) & (~0x01)));
+ smtc_seqw(0x31, ((smtc_seqr(0x31) & (~0x07)) | 0x00));
+ smtc_seqw(0x34, (smtc_seqr(0x34) | 0x80));
+ break;
+ case FB_BLANK_HSYNC_SUSPEND:
+ /* Screen On: HSync: Off, VSync : On */
+ smtc_seqw(0x01, (smtc_seqr(0x01) | 0x20));
+ smtc_seqw(0x20, (smtc_seqr(0x20) & (~0xB0)));
+ smtc_seqw(0x6a, 0x0c);
+ smtc_seqw(0x6b, 0x02);
+ smtc_seqw(0x21, (smtc_seqr(0x21) | 0x88));
+ smtc_seqw(0x22, ((smtc_seqr(0x22) & (~0x30)) | 0x10));
+ smtc_seqw(0x23, ((smtc_seqr(0x23) & (~0xc0)) | 0xD8));
+ smtc_seqw(0x24, (smtc_seqr(0x24) & (~0x01)));
+ smtc_seqw(0x31, ((smtc_seqr(0x31) & (~0x07)) | 0x00));
+ smtc_seqw(0x34, (smtc_seqr(0x34) | 0x80));
+ break;
+ case FB_BLANK_POWERDOWN:
+ /* Screen On: HSync: Off, VSync : Off */
+ smtc_seqw(0x01, (smtc_seqr(0x01) | 0x20));
+ smtc_seqw(0x20, (smtc_seqr(0x20) & (~0xB0)));
+ smtc_seqw(0x6a, 0x0c);
+ smtc_seqw(0x6b, 0x02);
+ smtc_seqw(0x21, (smtc_seqr(0x21) | 0x88));
+ smtc_seqw(0x22, ((smtc_seqr(0x22) & (~0x30)) | 0x30));
+ smtc_seqw(0x23, ((smtc_seqr(0x23) & (~0xc0)) | 0xD8));
+ smtc_seqw(0x24, (smtc_seqr(0x24) & (~0x01)));
+ smtc_seqw(0x31, ((smtc_seqr(0x31) & (~0x07)) | 0x00));
+ smtc_seqw(0x34, (smtc_seqr(0x34) | 0x80));
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int smtc_setcolreg(unsigned regno, unsigned red, unsigned green,
+ unsigned blue, unsigned trans, struct fb_info *info)
+{
+ struct smtcfb_info *sfb;
+ u32 val;
+
+ sfb = info->par;
+
+ if (regno > 255)
+ return 1;
+
+ switch (sfb->fb.fix.visual) {
+ case FB_VISUAL_DIRECTCOLOR:
+ case FB_VISUAL_TRUECOLOR:
+ /*
+ * 16/32 bit true-colour, use pseudo-palette for 16 base color
+ */
+ if (regno < 16) {
+ if (sfb->fb.var.bits_per_pixel = 16) {
+ u32 *pal = sfb->fb.pseudo_palette;
+ val = chan_to_field(red, &sfb->fb.var.red);
+ val |= chan_to_field(green, &sfb->fb.var.green);
+ val |= chan_to_field(blue, &sfb->fb.var.blue);
+#ifdef __BIG_ENDIAN
+ pal[regno] + ((red & 0xf800) >> 8) |
+ ((green & 0xe000) >> 13) |
+ ((green & 0x1c00) << 3) |
+ ((blue & 0xf800) >> 3);
+#else
+ pal[regno] = val;
+#endif
+ } else {
+ u32 *pal = sfb->fb.pseudo_palette;
+ val = chan_to_field(red, &sfb->fb.var.red);
+ val |= chan_to_field(green, &sfb->fb.var.green);
+ val |= chan_to_field(blue, &sfb->fb.var.blue);
+#ifdef __BIG_ENDIAN
+ val + (val & 0xff00ff00 >> 8) |
+ (val & 0x00ff00ff << 8);
+#endif
+ pal[regno] = val;
+ }
+ }
+ break;
+
+ case FB_VISUAL_PSEUDOCOLOR:
+ /* color depth 8 bit */
+ sm712_setpalette(regno, red, green, blue, info);
+ break;
+
+ default:
+ return 1; /* unknown type */
+ }
+
+ return 0;
+
+}
+
+#ifdef __BIG_ENDIAN
+static ssize_t smtcfb_read(struct fb_info *info, char __user *buf, size_t
+ count, loff_t *ppos)
+{
+ unsigned long p = *ppos;
+
+ u32 *buffer, *dst;
+ u32 __iomem *src;
+ int c, i, cnt = 0, err = 0;
+ unsigned long total_size;
+
+ if (!info || !info->screen_base)
+ return -ENODEV;
+
+ if (info->state != FBINFO_STATE_RUNNING)
+ return -EPERM;
+
+ total_size = info->screen_size;
+
+ if (total_size = 0)
+ total_size = info->fix.smem_len;
+
+ if (p >= total_size)
+ return 0;
+
+ if (count >= total_size)
+ count = total_size;
+
+ if (count + p > total_size)
+ count = total_size - p;
+
+ buffer = kmalloc((count > PAGE_SIZE) ? PAGE_SIZE : count, GFP_KERNEL);
+ if (!buffer)
+ return -ENOMEM;
+
+ src = (u32 __iomem *) (info->screen_base + p);
+
+ if (info->fbops->fb_sync)
+ info->fbops->fb_sync(info);
+
+ while (count) {
+ c = (count > PAGE_SIZE) ? PAGE_SIZE : count;
+ dst = buffer;
+ for (i = c >> 2; i--;) {
+ *dst = fb_readl(src++);
+ *dst + (*dst & 0xff00ff00 >> 8) |
+ (*dst & 0x00ff00ff << 8);
+ dst++;
+ }
+ if (c & 3) {
+ u8 *dst8 = (u8 *) dst;
+ u8 __iomem *src8 = (u8 __iomem *) src;
+
+ for (i = c & 3; i--;) {
+ if (i & 1) {
+ *dst8++ = fb_readb(++src8);
+ } else {
+ *dst8++ = fb_readb(--src8);
+ src8 += 2;
+ }
+ }
+ src = (u32 __iomem *) src8;
+ }
+
+ if (copy_to_user(buf, buffer, c)) {
+ err = -EFAULT;
+ break;
+ }
+ *ppos += c;
+ buf += c;
+ cnt += c;
+ count -= c;
+ }
+
+ kfree(buffer);
+
+ return (err) ? err : cnt;
+}
+
+static ssize_t
+smtcfb_write(struct fb_info *info, const char __user *buf, size_t count,
+ loff_t *ppos)
+{
+ unsigned long p = *ppos;
+
+ u32 *buffer, *src;
+ u32 __iomem *dst;
+ int c, i, cnt = 0, err = 0;
+ unsigned long total_size;
+
+ if (!info || !info->screen_base)
+ return -ENODEV;
+
+ if (info->state != FBINFO_STATE_RUNNING)
+ return -EPERM;
+
+ total_size = info->screen_size;
+
+ if (total_size = 0)
+ total_size = info->fix.smem_len;
+
+ if (p > total_size)
+ return -EFBIG;
+
+ if (count > total_size) {
+ err = -EFBIG;
+ count = total_size;
+ }
+
+ if (count + p > total_size) {
+ if (!err)
+ err = -ENOSPC;
+
+ count = total_size - p;
+ }
+
+ buffer = kmalloc((count > PAGE_SIZE) ? PAGE_SIZE : count, GFP_KERNEL);
+ if (!buffer)
+ return -ENOMEM;
+
+ dst = (u32 __iomem *) (info->screen_base + p);
+
+ if (info->fbops->fb_sync)
+ info->fbops->fb_sync(info);
+
+ while (count) {
+ c = (count > PAGE_SIZE) ? PAGE_SIZE : count;
+ src = buffer;
+
+ if (copy_from_user(src, buf, c)) {
+ err = -EFAULT;
+ break;
+ }
+
+ for (i = c >> 2; i--;) {
+ fb_writel((*src & 0xff00ff00 >> 8) |
+ (*src & 0x00ff00ff << 8), dst++);
+ src++;
+ }
+ if (c & 3) {
+ u8 *src8 = (u8 *) src;
+ u8 __iomem *dst8 = (u8 __iomem *) dst;
+
+ for (i = c & 3; i--;) {
+ if (i & 1) {
+ fb_writeb(*src8++, ++dst8);
+ } else {
+ fb_writeb(*src8++, --dst8);
+ dst8 += 2;
+ }
+ }
+ dst = (u32 __iomem *) dst8;
+ }
+
+ *ppos += c;
+ buf += c;
+ cnt += c;
+ count -= c;
+ }
+
+ kfree(buffer);
+
+ return (cnt) ? cnt : err;
+}
+#endif /* ! __BIG_ENDIAN */
+
+static void sm7xx_set_timing(struct smtcfb_info *sfb)
+{
+ int i = 0, j = 0;
+ u32 m_nScreenStride;
+
+ dev_dbg(&sfb->pdev->dev,
+ "sfb->width=%d sfb->height=%d sfb->fb.var.bits_per_pixel=%d sfb->hz=%d\n",
+ sfb->width, sfb->height, sfb->fb.var.bits_per_pixel, sfb->hz);
+
+ for (j = 0; j < numVGAModes; j++) {
+ if (VGAMode[j].mmSizeX = sfb->width &&
+ VGAMode[j].mmSizeY = sfb->height &&
+ VGAMode[j].bpp = sfb->fb.var.bits_per_pixel &&
+ VGAMode[j].hz = sfb->hz) {
+
+ dev_dbg(&sfb->pdev->dev,
+ "VGAMode[j].mmSizeX=%d VGAMode[j].mmSizeY=%d VGAMode[j].bpp=%d VGAMode[j].hz=%d\n",
+ VGAMode[j].mmSizeX, VGAMode[j].mmSizeY,
+ VGAMode[j].bpp, VGAMode[j].hz);
+
+ dev_dbg(&sfb->pdev->dev, "VGAMode index=%d\n", j);
+
+ smtc_mmiowb(0x0, 0x3c6);
+
+ smtc_seqw(0, 0x1);
+
+ smtc_mmiowb(VGAMode[j].Init_MISC, 0x3c2);
+
+ /* init SEQ register SR00 - SR04 */
+ for (i = 0; i < SIZE_SR00_SR04; i++)
+ smtc_seqw(i, VGAMode[j].Init_SR00_SR04[i]);
+
+ /* init SEQ register SR10 - SR24 */
+ for (i = 0; i < SIZE_SR10_SR24; i++)
+ smtc_seqw(i + 0x10,
+ VGAMode[j].Init_SR10_SR24[i]);
+
+ /* init SEQ register SR30 - SR75 */
+ for (i = 0; i < SIZE_SR30_SR75; i++)
+ if ((i + 0x30) != 0x62 &&
+ (i + 0x30) != 0x6a &&
+ (i + 0x30) != 0x6b)
+ smtc_seqw(i + 0x30,
+ VGAMode[j].Init_SR30_SR75[i]);
+
+ /* init SEQ register SR80 - SR93 */
+ for (i = 0; i < SIZE_SR80_SR93; i++)
+ smtc_seqw(i + 0x80,
+ VGAMode[j].Init_SR80_SR93[i]);
+
+ /* init SEQ register SRA0 - SRAF */
+ for (i = 0; i < SIZE_SRA0_SRAF; i++)
+ smtc_seqw(i + 0xa0,
+ VGAMode[j].Init_SRA0_SRAF[i]);
+
+ /* init Graphic register GR00 - GR08 */
+ for (i = 0; i < SIZE_GR00_GR08; i++)
+ smtc_grphw(i, VGAMode[j].Init_GR00_GR08[i]);
+
+ /* init Attribute register AR00 - AR14 */
+ for (i = 0; i < SIZE_AR00_AR14; i++)
+ smtc_attrw(i, VGAMode[j].Init_AR00_AR14[i]);
+
+ /* init CRTC register CR00 - CR18 */
+ for (i = 0; i < SIZE_CR00_CR18; i++)
+ smtc_crtcw(i, VGAMode[j].Init_CR00_CR18[i]);
+
+ /* init CRTC register CR30 - CR4D */
+ for (i = 0; i < SIZE_CR30_CR4D; i++)
+ smtc_crtcw(i + 0x30,
+ VGAMode[j].Init_CR30_CR4D[i]);
+
+ /* init CRTC register CR90 - CRA7 */
+ for (i = 0; i < SIZE_CR90_CRA7; i++)
+ smtc_crtcw(i + 0x90,
+ VGAMode[j].Init_CR90_CRA7[i]);
+ }
+ }
+ smtc_mmiowb(0x67, 0x3c2);
+
+ /* set VPR registers */
+ writel(0x0, sfb->vp_regs + 0x0C);
+ writel(0x0, sfb->vp_regs + 0x40);
+
+ /* set data width */
+ m_nScreenStride + (sfb->width * sfb->fb.var.bits_per_pixel) / 64;
+ switch (sfb->fb.var.bits_per_pixel) {
+ case 8:
+ writel(0x0, sfb->vp_regs + 0x0);
+ break;
+ case 16:
+ writel(0x00020000, sfb->vp_regs + 0x0);
+ break;
+ case 24:
+ writel(0x00040000, sfb->vp_regs + 0x0);
+ break;
+ case 32:
+ writel(0x00030000, sfb->vp_regs + 0x0);
+ break;
+ }
+ writel((u32) (((m_nScreenStride + 2) << 16) | m_nScreenStride),
+ sfb->vp_regs + 0x10);
+
+}
+
+static void smtc_set_timing(struct smtcfb_info *sfb)
+{
+ switch (sfb->chip_id) {
+ case 0x710:
+ case 0x712:
+ case 0x720:
+ sm7xx_set_timing(sfb);
+ break;
+ }
+}
+
+static void smtcfb_setmode(struct smtcfb_info *sfb)
+{
+ switch (sfb->fb.var.bits_per_pixel) {
+ case 32:
+ sfb->fb.fix.visual = FB_VISUAL_TRUECOLOR;
+ sfb->fb.fix.line_length = sfb->fb.var.xres * 4;
+ sfb->fb.var.red.length = 8;
+ sfb->fb.var.green.length = 8;
+ sfb->fb.var.blue.length = 8;
+ sfb->fb.var.red.offset = 16;
+ sfb->fb.var.green.offset = 8;
+ sfb->fb.var.blue.offset = 0;
+ break;
+ case 24:
+ sfb->fb.fix.visual = FB_VISUAL_TRUECOLOR;
+ sfb->fb.fix.line_length = sfb->fb.var.xres * 3;
+ sfb->fb.var.red.length = 8;
+ sfb->fb.var.green.length = 8;
+ sfb->fb.var.blue.length = 8;
+ sfb->fb.var.red.offset = 16;
+ sfb->fb.var.green.offset = 8;
+ sfb->fb.var.blue.offset = 0;
+ break;
+ case 8:
+ sfb->fb.fix.visual = FB_VISUAL_PSEUDOCOLOR;
+ sfb->fb.fix.line_length = sfb->fb.var.xres;
+ sfb->fb.var.red.length = 3;
+ sfb->fb.var.green.length = 3;
+ sfb->fb.var.blue.length = 2;
+ sfb->fb.var.red.offset = 5;
+ sfb->fb.var.green.offset = 2;
+ sfb->fb.var.blue.offset = 0;
+ break;
+ case 16:
+ default:
+ sfb->fb.fix.visual = FB_VISUAL_TRUECOLOR;
+ sfb->fb.fix.line_length = sfb->fb.var.xres * 2;
+ sfb->fb.var.red.length = 5;
+ sfb->fb.var.green.length = 6;
+ sfb->fb.var.blue.length = 5;
+ sfb->fb.var.red.offset = 11;
+ sfb->fb.var.green.offset = 5;
+ sfb->fb.var.blue.offset = 0;
+ break;
+ }
+
+ sfb->width = sfb->fb.var.xres;
+ sfb->height = sfb->fb.var.yres;
+ sfb->hz = 60;
+ smtc_set_timing(sfb);
+}
+
+static int smtc_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
+{
+ /* sanity checks */
+ if (var->xres_virtual < var->xres)
+ var->xres_virtual = var->xres;
+
+ if (var->yres_virtual < var->yres)
+ var->yres_virtual = var->yres;
+
+ /* set valid default bpp */
+ if ((var->bits_per_pixel != 8) && (var->bits_per_pixel != 16) &&
+ (var->bits_per_pixel != 24) && (var->bits_per_pixel != 32))
+ var->bits_per_pixel = 16;
+
+ return 0;
+}
+
+static int smtc_set_par(struct fb_info *info)
+{
+ smtcfb_setmode(info->par);
+
+ return 0;
+}
+
+static struct fb_ops smtcfb_ops = {
+ .owner = THIS_MODULE,
+ .fb_check_var = smtc_check_var,
+ .fb_set_par = smtc_set_par,
+ .fb_setcolreg = smtc_setcolreg,
+ .fb_blank = smtc_blank,
+ .fb_fillrect = cfb_fillrect,
+ .fb_imageblit = cfb_imageblit,
+ .fb_copyarea = cfb_copyarea,
+#ifdef __BIG_ENDIAN
+ .fb_read = smtcfb_read,
+ .fb_write = smtcfb_write,
+#endif
+};
+
+/*
+ * alloc struct smtcfb_info and assign default values
+ */
+static struct smtcfb_info *smtc_alloc_fb_info(struct pci_dev *pdev)
+{
+ struct smtcfb_info *sfb;
+
+ sfb = kzalloc(sizeof(*sfb), GFP_KERNEL);
+
+ if (!sfb)
+ return NULL;
+
+ sfb->pdev = pdev;
+
+ sfb->fb.flags = FBINFO_FLAG_DEFAULT;
+ sfb->fb.fbops = &smtcfb_ops;
+ sfb->fb.fix = smtcfb_fix;
+ sfb->fb.var = smtcfb_var;
+ sfb->fb.pseudo_palette = sfb->colreg;
+ sfb->fb.par = sfb;
+
+ return sfb;
+}
+
+/*
+ * free struct smtcfb_info
+ */
+static void smtc_free_fb_info(struct smtcfb_info *sfb)
+{
+ kfree(sfb);
+}
+
+/*
+ * Unmap in the memory mapped IO registers
+ */
+
+static void smtc_unmap_mmio(struct smtcfb_info *sfb)
+{
+ if (sfb && smtc_RegBaseAddress)
+ smtc_RegBaseAddress = NULL;
+}
+
+/*
+ * Map in the screen memory
+ */
+
+static int smtc_map_smem(struct smtcfb_info *sfb,
+ struct pci_dev *pdev, u_long smem_len)
+{
+
+ sfb->fb.fix.smem_start = pci_resource_start(pdev, 0);
+
+#ifdef __BIG_ENDIAN
+ if (sfb->fb.var.bits_per_pixel = 32)
+ sfb->fb.fix.smem_start += 0x800000;
+#endif
+
+ sfb->fb.fix.smem_len = smem_len;
+
+ sfb->fb.screen_base = sfb->lfb;
+
+ if (!sfb->fb.screen_base) {
+ dev_err(&pdev->dev,
+ "%s: unable to map screen memory\n", sfb->fb.fix.id);
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+
+/*
+ * Unmap in the screen memory
+ *
+ */
+static void smtc_unmap_smem(struct smtcfb_info *sfb)
+{
+ if (sfb && sfb->fb.screen_base) {
+ iounmap(sfb->fb.screen_base);
+ sfb->fb.screen_base = NULL;
+ }
+}
+
+/*
+ * We need to wake up the device and make sure its in linear memory mode.
+ */
+static inline void sm7xx_init_hw(void)
+{
+ outb_p(0x18, 0x3c4);
+ outb_p(0x11, 0x3c5);
+}
+
+static int smtcfb_pci_probe(struct pci_dev *pdev,
+ const struct pci_device_id *ent)
+{
+ struct smtcfb_info *sfb;
+ u_long smem_size = 0x00800000; /* default 8MB */
+ int err;
+ unsigned long mmio_base;
+
+ dev_info(&pdev->dev, "Silicon Motion display driver.");
+
+ err = pci_enable_device(pdev); /* enable SMTC chip */
+ if (err)
+ return err;
+
+ sprintf(smtcfb_fix.id, "sm%Xfb", ent->device);
+
+ sfb = smtc_alloc_fb_info(pdev);
+
+ if (!sfb) {
+ err = -ENOMEM;
+ goto failed_free;
+ }
+
+ sfb->chip_id = ent->device;
+
+ pci_set_drvdata(pdev, sfb);
+
+ sm7xx_init_hw();
+
+ /* get mode parameter from smtc_scr_info */
+ if (smtc_scr_info.lfb_width != 0) {
+ sfb->fb.var.xres = smtc_scr_info.lfb_width;
+ sfb->fb.var.yres = smtc_scr_info.lfb_height;
+ sfb->fb.var.bits_per_pixel = smtc_scr_info.lfb_depth;
+ } else {
+ /* default resolution 1024x600 16bit mode */
+ sfb->fb.var.xres = SCREEN_X_RES;
+ sfb->fb.var.yres = SCREEN_Y_RES;
+ sfb->fb.var.bits_per_pixel = SCREEN_BPP;
+ }
+
+#ifdef __BIG_ENDIAN
+ if (sfb->fb.var.bits_per_pixel = 24)
+ sfb->fb.var.bits_per_pixel = (smtc_scr_info.lfb_depth = 32);
+#endif
+ /* Map address and memory detection */
+ mmio_base = pci_resource_start(pdev, 0);
+ pci_read_config_byte(pdev, PCI_REVISION_ID, &sfb->chip_rev_id);
+
+ switch (sfb->chip_id) {
+ case 0x710:
+ case 0x712:
+ sfb->fb.fix.mmio_start = mmio_base + 0x00400000;
+ sfb->fb.fix.mmio_len = 0x00400000;
+ smem_size = SM712_VIDEOMEMORYSIZE;
+#ifdef __BIG_ENDIAN
+ sfb->lfb = ioremap(mmio_base, 0x00c00000);
+#else
+ sfb->lfb = ioremap(mmio_base, 0x00800000);
+#endif
+ sfb->mmio = (smtc_RegBaseAddress + sfb->lfb + 0x00700000);
+ sfb->dp_regs = sfb->lfb + 0x00408000;
+ sfb->vp_regs = sfb->lfb + 0x0040c000;
+#ifdef __BIG_ENDIAN
+ if (sfb->fb.var.bits_per_pixel = 32) {
+ sfb->lfb += 0x800000;
+ dev_info(&pdev->dev, "sfb->lfb=%p", sfb->lfb);
+ }
+#endif
+ if (!smtc_RegBaseAddress) {
+ dev_err(&pdev->dev,
+ "%s: unable to map memory mapped IO!",
+ sfb->fb.fix.id);
+ err = -ENOMEM;
+ goto failed_fb;
+ }
+
+ /* set MCLK = 14.31818 * (0x16 / 0x2) */
+ smtc_seqw(0x6a, 0x16);
+ smtc_seqw(0x6b, 0x02);
+ smtc_seqw(0x62, 0x3e);
+ /* enable PCI burst */
+ smtc_seqw(0x17, 0x20);
+ /* enable word swap */
+#ifdef __BIG_ENDIAN
+ if (sfb->fb.var.bits_per_pixel = 32)
+ smtc_seqw(0x17, 0x30);
+#endif
+ break;
+ case 0x720:
+ sfb->fb.fix.mmio_start = mmio_base;
+ sfb->fb.fix.mmio_len = 0x00200000;
+ smem_size = SM722_VIDEOMEMORYSIZE;
+ sfb->dp_regs = ioremap(mmio_base, 0x00a00000);
+ sfb->lfb = sfb->dp_regs + 0x00200000;
+ sfb->mmio = (smtc_RegBaseAddress + sfb->dp_regs + 0x000c0000);
+ sfb->vp_regs = sfb->dp_regs + 0x800;
+
+ smtc_seqw(0x62, 0xff);
+ smtc_seqw(0x6a, 0x0d);
+ smtc_seqw(0x6b, 0x02);
+ break;
+ default:
+ dev_err(&pdev->dev,
+ "No valid Silicon Motion display chip was detected!");
+
+ goto failed_fb;
+ }
+
+ /* can support 32 bpp */
+ if (15 = sfb->fb.var.bits_per_pixel)
+ sfb->fb.var.bits_per_pixel = 16;
+
+ sfb->fb.var.xres_virtual = sfb->fb.var.xres;
+ sfb->fb.var.yres_virtual = sfb->fb.var.yres;
+ err = smtc_map_smem(sfb, pdev, smem_size);
+ if (err)
+ goto failed;
+
+ smtcfb_setmode(sfb);
+
+ err = register_framebuffer(&sfb->fb);
+ if (err < 0)
+ goto failed;
+
+ dev_info(&pdev->dev,
+ "Silicon Motion SM%X Rev%X primary display mode %dx%d-%d Init Complete.",
+ sfb->chip_id, sfb->chip_rev_id, sfb->fb.var.xres,
+ sfb->fb.var.yres, sfb->fb.var.bits_per_pixel);
+
+ return 0;
+
+failed:
+ dev_err(&pdev->dev, "Silicon Motion, Inc. primary display init fail.");
+
+ smtc_unmap_smem(sfb);
+ smtc_unmap_mmio(sfb);
+failed_fb:
+ smtc_free_fb_info(sfb);
+
+failed_free:
+ pci_disable_device(pdev);
+
+ return err;
+}
+
+/*
+ * 0x710 (LynxEM)
+ * 0x712 (LynxEM+)
+ * 0x720 (Lynx3DM, Lynx3DM+)
+ */
+static const struct pci_device_id smtcfb_pci_table[] = {
+ { PCI_DEVICE(0x126f, 0x710), },
+ { PCI_DEVICE(0x126f, 0x712), },
+ { PCI_DEVICE(0x126f, 0x720), },
+ {0,}
+};
+
+static void smtcfb_pci_remove(struct pci_dev *pdev)
+{
+ struct smtcfb_info *sfb;
+
+ sfb = pci_get_drvdata(pdev);
+ smtc_unmap_smem(sfb);
+ smtc_unmap_mmio(sfb);
+ unregister_framebuffer(&sfb->fb);
+ smtc_free_fb_info(sfb);
+}
+
+#ifdef CONFIG_PM
+static int smtcfb_pci_suspend(struct device *device)
+{
+ struct pci_dev *pdev = to_pci_dev(device);
+ struct smtcfb_info *sfb;
+
+ sfb = pci_get_drvdata(pdev);
+
+ /* set the hw in sleep mode use external clock and self memory refresh
+ * so that we can turn off internal PLLs later on
+ */
+ smtc_seqw(0x20, (smtc_seqr(0x20) | 0xc0));
+ smtc_seqw(0x69, (smtc_seqr(0x69) & 0xf7));
+
+ console_lock();
+ fb_set_suspend(&sfb->fb, 1);
+ console_unlock();
+
+ /* additionally turn off all function blocks including internal PLLs */
+ smtc_seqw(0x21, 0xff);
+
+ return 0;
+}
+
+static int smtcfb_pci_resume(struct device *device)
+{
+ struct pci_dev *pdev = to_pci_dev(device);
+ struct smtcfb_info *sfb;
+
+ sfb = pci_get_drvdata(pdev);
+
+ /* reinit hardware */
+ sm7xx_init_hw();
+ switch (sfb->chip_id) {
+ case 0x710:
+ case 0x712:
+ /* set MCLK = 14.31818 * (0x16 / 0x2) */
+ smtc_seqw(0x6a, 0x16);
+ smtc_seqw(0x6b, 0x02);
+ smtc_seqw(0x62, 0x3e);
+ /* enable PCI burst */
+ smtc_seqw(0x17, 0x20);
+#ifdef __BIG_ENDIAN
+ if (sfb->fb.var.bits_per_pixel = 32)
+ smtc_seqw(0x17, 0x30);
+#endif
+ break;
+ case 0x720:
+ smtc_seqw(0x62, 0xff);
+ smtc_seqw(0x6a, 0x0d);
+ smtc_seqw(0x6b, 0x02);
+ break;
+ }
+
+ smtc_seqw(0x34, (smtc_seqr(0x34) | 0xc0));
+ smtc_seqw(0x33, ((smtc_seqr(0x33) | 0x08) & 0xfb));
+
+ smtcfb_setmode(sfb);
+
+ console_lock();
+ fb_set_suspend(&sfb->fb, 0);
+ console_unlock();
+
+ return 0;
+}
+
+static SIMPLE_DEV_PM_OPS(sm7xx_pm_ops, smtcfb_pci_suspend, smtcfb_pci_resume);
+#define SM7XX_PM_OPS (&sm7xx_pm_ops)
+
+#else /* !CONFIG_PM */
+
+#define SM7XX_PM_OPS NULL
+
+#endif /* !CONFIG_PM */
+
+static struct pci_driver smtcfb_driver = {
+ .name = "smtcfb",
+ .id_table = smtcfb_pci_table,
+ .probe = smtcfb_pci_probe,
+ .remove = smtcfb_pci_remove,
+ .driver.pm = SM7XX_PM_OPS,
+};
+
+module_pci_driver(smtcfb_driver);
+
+MODULE_AUTHOR("Siliconmotion ");
+MODULE_DESCRIPTION("Framebuffer driver for SMI Graphic Cards");
+MODULE_LICENSE("GPL");
--
1.9.1
^ permalink raw reply related
* [PATCH 2/3] staging: sm7xxfb: update TODO file
From: Sudip Mukherjee @ 2014-12-31 12:38 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: Sudip Mukherjee, Teddy Wang, Sudip Mukherjee, linux-kernel, devel,
linux-fbdev
In-Reply-To: <1420028805-30488-1-git-send-email-sudipm.mukherjee@gmail.com>
update the email addresses in the TODO file, also update the final
destination of this driver.
Signed-off-by: Sudip Mukherjee <sudip@vectorindia.org>
---
drivers/staging/sm7xxfb/TODO | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/drivers/staging/sm7xxfb/TODO b/drivers/staging/sm7xxfb/TODO
index 1fcead5..6377380 100644
--- a/drivers/staging/sm7xxfb/TODO
+++ b/drivers/staging/sm7xxfb/TODO
@@ -3,7 +3,10 @@ TODO:
- 2D acceleration support
- use kernel coding style
- refine the code and remove unused code
-- move it to drivers/video/sm7xxfb.c
+- move it to drivers/video/fbdev/sm7xxfb.c
-Please send any patches to Greg Kroah-Hartman <greg@kroah.com> and
-Teddy Wang <teddy.wang@siliconmotion.com.cn>.
+Please send any patches to
+ Greg Kroah-Hartman <greg@kroah.com>
+ Sudip Mukherjee <sudipm.mukherjee@gmail.com>
+ Teddy Wang <teddy.wang@siliconmotion.com>
+ Sudip Mukherjee <sudip@vectorindia.org>
--
1.9.1
^ permalink raw reply related
* [PATCH 3/3] MAINTAINERS: update for SM7XX driver
From: Sudip Mukherjee @ 2014-12-31 12:38 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: Sudip Mukherjee, Teddy Wang, Sudip Mukherjee, linux-kernel, devel,
linux-fbdev
In-Reply-To: <1420028805-30488-1-git-send-email-sudipm.mukherjee@gmail.com>
add myself and Teddy Wang as the Maintainer of the
SM7XX FRAME BUFFER DRIVER.
Signed-off-by: Sudip Mukherjee <sudip@vectorindia.org>
---
MAINTAINERS | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/MAINTAINERS b/MAINTAINERS
index 6e18e65..4ffe882 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -9178,6 +9178,14 @@ L: linux-wireless@vger.kernel.org
S: Maintained
F: drivers/staging/rtl8723au/
+STAGING - SILICON MOTION SM7XX FRAME BUFFER DRIVER
+M: Sudip Mukherjee <sudipm.mukherjee@gmail.com>
+M: Teddy Wang <teddy.wang@siliconmotion.com>
+M: Sudip Mukherjee <sudip@vectorindia.org>
+L: linux-fbdev@vger.kernel.org
+S: Maintained
+F: drivers/staging/sm7xxfb/
+
STAGING - SLICOSS
M: Lior Dotan <liodot@gmail.com>
M: Christopher Harrer <charrer@alacritech.com>
--
1.9.1
^ permalink raw reply related
* [PATCH] video: fbdev: omap2: dss: dispc.c: Remove some unused functions
From: Rickard Strandqvist @ 2015-01-01 15:29 UTC (permalink / raw)
To: Tomi Valkeinen, Jean-Christophe Plagniol-Villard
Cc: Rickard Strandqvist, Grant Likely, Rob Herring, Archit Taneja,
linux-omap, linux-fbdev, linux-kernel, devicetree
Removes some functions that are not used anywhere:
dispc_wb_go() dispc_wb_go_busy() dispc_wb_get_framedone_irq()
dispc_mgr_get_clock_div() dispc_wb_is_enabled() dispc_wb_enable()
dispc_wb_setup() dispc_enable_fifomerge() dispc_wb_set_channel_in()
This was partially found by using a static code analysis program called cppcheck.
Signed-off-by: Rickard Strandqvist <rickard_strandqvist@spectrumdigital.se>
---
drivers/video/fbdev/omap2/dss/dispc.c | 124 ---------------------------------
drivers/video/fbdev/omap2/dss/dss.h | 12 ----
2 files changed, 136 deletions(-)
diff --git a/drivers/video/fbdev/omap2/dss/dispc.c b/drivers/video/fbdev/omap2/dss/dispc.c
index 0e9a74b..9fb2743 100644
--- a/drivers/video/fbdev/omap2/dss/dispc.c
+++ b/drivers/video/fbdev/omap2/dss/dispc.c
@@ -536,11 +536,6 @@ u32 dispc_mgr_get_sync_lost_irq(enum omap_channel channel)
}
EXPORT_SYMBOL(dispc_mgr_get_sync_lost_irq);
-u32 dispc_wb_get_framedone_irq(void)
-{
- return DISPC_IRQ_FRAMEDONEWB;
-}
-
bool dispc_mgr_go_busy(enum omap_channel channel)
{
return mgr_fld_read(channel, DISPC_MGR_FLD_GO) = 1;
@@ -558,30 +553,6 @@ void dispc_mgr_go(enum omap_channel channel)
}
EXPORT_SYMBOL(dispc_mgr_go);
-bool dispc_wb_go_busy(void)
-{
- return REG_GET(DISPC_CONTROL2, 6, 6) = 1;
-}
-
-void dispc_wb_go(void)
-{
- enum omap_plane plane = OMAP_DSS_WB;
- bool enable, go;
-
- enable = REG_GET(DISPC_OVL_ATTRIBUTES(plane), 0, 0) = 1;
-
- if (!enable)
- return;
-
- go = REG_GET(DISPC_CONTROL2, 6, 6) = 1;
- if (go) {
- DSSERR("GO bit not down for WB\n");
- return;
- }
-
- REG_FLD_MOD(DISPC_CONTROL2, 1, 6, 6);
-}
-
static void dispc_ovl_write_firh_reg(enum omap_plane plane, int reg, u32 value)
{
dispc_write_reg(DISPC_OVL_FIR_COEF_H(plane, reg), value);
@@ -1003,13 +974,6 @@ static enum omap_channel dispc_ovl_get_channel_out(enum omap_plane plane)
return channel;
}
-void dispc_wb_set_channel_in(enum dss_writeback_channel channel)
-{
- enum omap_plane plane = OMAP_DSS_WB;
-
- REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), channel, 18, 16);
-}
-
static void dispc_ovl_set_burst_size(enum omap_plane plane,
enum omap_burst_size burst_size)
{
@@ -1213,17 +1177,6 @@ void dispc_ovl_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high)
}
EXPORT_SYMBOL(dispc_ovl_set_fifo_threshold);
-void dispc_enable_fifomerge(bool enable)
-{
- if (!dss_has_feature(FEAT_FIFO_MERGE)) {
- WARN_ON(enable);
- return;
- }
-
- DSSDBG("FIFO merge %s\n", enable ? "enabled" : "disabled");
- REG_FLD_MOD(DISPC_CONFIG, enable ? 1 : 0, 14, 14);
-}
-
void dispc_ovl_compute_fifo_thresholds(enum omap_plane plane,
u32 *fifo_low, u32 *fifo_high, bool use_fifomerge,
bool manual_update)
@@ -2593,57 +2546,6 @@ int dispc_ovl_setup(enum omap_plane plane, const struct omap_overlay_info *oi,
}
EXPORT_SYMBOL(dispc_ovl_setup);
-int dispc_wb_setup(const struct omap_dss_writeback_info *wi,
- bool mem_to_mem, const struct omap_video_timings *mgr_timings)
-{
- int r;
- u32 l;
- enum omap_plane plane = OMAP_DSS_WB;
- const int pos_x = 0, pos_y = 0;
- const u8 zorder = 0, global_alpha = 0;
- const bool replication = false;
- bool truncation;
- int in_width = mgr_timings->x_res;
- int in_height = mgr_timings->y_res;
- enum omap_overlay_caps caps - OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA;
-
- DSSDBG("dispc_wb_setup, pa %x, pa_uv %x, %d,%d -> %dx%d, cmode %x, "
- "rot %d, mir %d\n", wi->paddr, wi->p_uv_addr, in_width,
- in_height, wi->width, wi->height, wi->color_mode, wi->rotation,
- wi->mirror);
-
- r = dispc_ovl_setup_common(plane, caps, wi->paddr, wi->p_uv_addr,
- wi->buf_width, pos_x, pos_y, in_width, in_height, wi->width,
- wi->height, wi->color_mode, wi->rotation, wi->mirror, zorder,
- wi->pre_mult_alpha, global_alpha, wi->rotation_type,
- replication, mgr_timings, mem_to_mem);
-
- switch (wi->color_mode) {
- case OMAP_DSS_COLOR_RGB16:
- case OMAP_DSS_COLOR_RGB24P:
- case OMAP_DSS_COLOR_ARGB16:
- case OMAP_DSS_COLOR_RGBA16:
- case OMAP_DSS_COLOR_RGB12U:
- case OMAP_DSS_COLOR_ARGB16_1555:
- case OMAP_DSS_COLOR_XRGB16_1555:
- case OMAP_DSS_COLOR_RGBX16:
- truncation = true;
- break;
- default:
- truncation = false;
- break;
- }
-
- /* setup extra DISPC_WB_ATTRIBUTES */
- l = dispc_read_reg(DISPC_OVL_ATTRIBUTES(plane));
- l = FLD_MOD(l, truncation, 10, 10); /* TRUNCATIONENABLE */
- l = FLD_MOD(l, mem_to_mem, 19, 19); /* WRITEBACKMODE */
- dispc_write_reg(DISPC_OVL_ATTRIBUTES(plane), l);
-
- return r;
-}
-
int dispc_ovl_enable(enum omap_plane plane, bool enable)
{
DSSDBG("dispc_enable_plane %d, %d\n", plane, enable);
@@ -2674,16 +2576,6 @@ bool dispc_mgr_is_enabled(enum omap_channel channel)
}
EXPORT_SYMBOL(dispc_mgr_is_enabled);
-void dispc_wb_enable(bool enable)
-{
- dispc_ovl_enable(OMAP_DSS_WB, enable);
-}
-
-bool dispc_wb_is_enabled(void)
-{
- return dispc_ovl_enabled(OMAP_DSS_WB);
-}
-
static void dispc_lcd_enable_signal_polarity(bool act_high)
{
if (!dss_has_feature(FEAT_LCDENABLEPOL))
@@ -3446,22 +3338,6 @@ void dispc_mgr_set_clock_div(enum omap_channel channel,
dispc_mgr_set_lcd_divisor(channel, cinfo->lck_div, cinfo->pck_div);
}
-int dispc_mgr_get_clock_div(enum omap_channel channel,
- struct dispc_clock_info *cinfo)
-{
- unsigned long fck;
-
- fck = dispc_fclk_rate();
-
- cinfo->lck_div = REG_GET(DISPC_DIVISORo(channel), 23, 16);
- cinfo->pck_div = REG_GET(DISPC_DIVISORo(channel), 7, 0);
-
- cinfo->lck = fck / cinfo->lck_div;
- cinfo->pck = cinfo->lck / cinfo->pck_div;
-
- return 0;
-}
-
u32 dispc_read_irqstatus(void)
{
return dispc_read_reg(DISPC_IRQSTATUS);
diff --git a/drivers/video/fbdev/omap2/dss/dss.h b/drivers/video/fbdev/omap2/dss/dss.h
index 8ff22c1..229c4c5 100644
--- a/drivers/video/fbdev/omap2/dss/dss.h
+++ b/drivers/video/fbdev/omap2/dss/dss.h
@@ -371,7 +371,6 @@ void dispc_disable_sidle(void);
void dispc_lcd_enable_signal(bool enable);
void dispc_pck_free_enable(bool enable);
-void dispc_enable_fifomerge(bool enable);
void dispc_enable_gamma_table(bool enable);
void dispc_set_loadmode(enum omap_dss_load_mode mode);
@@ -398,19 +397,8 @@ unsigned long dispc_mgr_pclk_rate(enum omap_channel channel);
unsigned long dispc_core_clk_rate(void);
void dispc_mgr_set_clock_div(enum omap_channel channel,
const struct dispc_clock_info *cinfo);
-int dispc_mgr_get_clock_div(enum omap_channel channel,
- struct dispc_clock_info *cinfo);
void dispc_set_tv_pclk(unsigned long pclk);
-u32 dispc_wb_get_framedone_irq(void);
-bool dispc_wb_go_busy(void);
-void dispc_wb_go(void);
-void dispc_wb_enable(bool enable);
-bool dispc_wb_is_enabled(void);
-void dispc_wb_set_channel_in(enum dss_writeback_channel channel);
-int dispc_wb_setup(const struct omap_dss_writeback_info *wi,
- bool mem_to_mem, const struct omap_video_timings *timings);
-
/* VENC */
int venc_init_platform_driver(void) __init;
void venc_uninit_platform_driver(void) __exit;
--
1.7.10.4
^ permalink raw reply related
* [PATCH] video: fbdev: omap2: dss: dss.c: Remove unused function
From: Rickard Strandqvist @ 2015-01-01 15:34 UTC (permalink / raw)
To: Tomi Valkeinen, Jean-Christophe Plagniol-Villard
Cc: Rickard Strandqvist, Grant Likely, Rob Herring, Archit Taneja,
Tony Lindgren, Jingoo Han, Sathya Prakash M R, Fabian Frederick,
linux-omap, linux-fbdev, linux-kernel, devicetree
Remove the function dss_get_hdmi_venc_clk_source() that is not used anywhere.
This was partially found by using a static code analysis program called cppcheck.
Signed-off-by: Rickard Strandqvist <rickard_strandqvist@spectrumdigital.se>
---
drivers/video/fbdev/omap2/dss/dss.c | 14 --------------
drivers/video/fbdev/omap2/dss/dss.h | 1 -
2 files changed, 15 deletions(-)
diff --git a/drivers/video/fbdev/omap2/dss/dss.c b/drivers/video/fbdev/omap2/dss/dss.c
index 14bcd6c..d9482c8 100644
--- a/drivers/video/fbdev/omap2/dss/dss.c
+++ b/drivers/video/fbdev/omap2/dss/dss.c
@@ -550,20 +550,6 @@ void dss_select_hdmi_venc_clk_source(enum dss_hdmi_venc_clk_source_select src)
REG_FLD_MOD(DSS_CONTROL, src, 15, 15); /* VENC_HDMI_SWITCH */
}
-enum dss_hdmi_venc_clk_source_select dss_get_hdmi_venc_clk_source(void)
-{
- enum omap_display_type displays;
-
- displays = dss_feat_get_supported_displays(OMAP_DSS_CHANNEL_DIGIT);
- if ((displays & OMAP_DISPLAY_TYPE_HDMI) = 0)
- return DSS_VENC_TV_CLK;
-
- if ((displays & OMAP_DISPLAY_TYPE_VENC) = 0)
- return DSS_HDMI_M_PCLK;
-
- return REG_GET(DSS_CONTROL, 15, 15);
-}
-
static int dss_dpi_select_source_omap2_omap3(enum omap_channel channel)
{
if (channel != OMAP_DSS_CHANNEL_LCD)
diff --git a/drivers/video/fbdev/omap2/dss/dss.h b/drivers/video/fbdev/omap2/dss/dss.h
index 8ff22c1..f4bb25b 100644
--- a/drivers/video/fbdev/omap2/dss/dss.h
+++ b/drivers/video/fbdev/omap2/dss/dss.h
@@ -211,7 +211,6 @@ void dss_uninit_platform_driver(void);
unsigned long dss_get_dispc_clk_rate(void);
int dss_dpi_select_source(enum omap_channel channel);
void dss_select_hdmi_venc_clk_source(enum dss_hdmi_venc_clk_source_select);
-enum dss_hdmi_venc_clk_source_select dss_get_hdmi_venc_clk_source(void);
const char *dss_get_generic_clk_source_name(enum omap_dss_clk_source clk_src);
void dss_dump_clocks(struct seq_file *s);
--
1.7.10.4
^ permalink raw reply related
* [PATCH] video: fbdev: exynos: exynos_mipi_dsi_common: Remove some unused functions
From: Rickard Strandqvist @ 2015-01-01 19:14 UTC (permalink / raw)
To: linux-arm-kernel
Removes some functions that are not used anywhere:
exynos_mipi_dsi_fifo_clear() exynos_mipi_dsi_set_data_transfer_mode()
exynos_mipi_dsi_enable_frame_done_int()
This was partially found by using a static code analysis program called cppcheck.
Signed-off-by: Rickard Strandqvist <rickard_strandqvist@spectrumdigital.se>
---
.../video/fbdev/exynos/exynos_mipi_dsi_common.c | 53 --------------------
.../video/fbdev/exynos/exynos_mipi_dsi_common.h | 7 ---
2 files changed, 60 deletions(-)
diff --git a/drivers/video/fbdev/exynos/exynos_mipi_dsi_common.c b/drivers/video/fbdev/exynos/exynos_mipi_dsi_common.c
index 85edabf..d7b4abc 100644
--- a/drivers/video/fbdev/exynos/exynos_mipi_dsi_common.c
+++ b/drivers/video/fbdev/exynos/exynos_mipi_dsi_common.c
@@ -690,15 +690,6 @@ void exynos_mipi_dsi_init_interrupt(struct mipi_dsim_device *dsim)
exynos_mipi_dsi_set_interrupt_mask(dsim, src, 1);
}
-int exynos_mipi_dsi_enable_frame_done_int(struct mipi_dsim_device *dsim,
- unsigned int enable)
-{
- /* enable only frame done interrupt */
- exynos_mipi_dsi_set_interrupt_mask(dsim, INTMSK_FRAME_DONE, enable);
-
- return 0;
-}
-
void exynos_mipi_dsi_stand_by(struct mipi_dsim_device *dsim,
unsigned int enable)
{
@@ -819,30 +810,6 @@ int exynos_mipi_dsi_set_hs_enable(struct mipi_dsim_device *dsim)
return 0;
}
-int exynos_mipi_dsi_set_data_transfer_mode(struct mipi_dsim_device *dsim,
- unsigned int mode)
-{
- if (mode) {
- if (dsim->state != DSIM_STATE_HSCLKEN) {
- dev_err(dsim->dev, "HS Clock lane is not enabled.\n");
- return -EINVAL;
- }
-
- exynos_mipi_dsi_set_lcdc_transfer_mode(dsim, 0);
- } else {
- if (dsim->state = DSIM_STATE_INIT || dsim->state =
- DSIM_STATE_ULPS) {
- dev_err(dsim->dev,
- "DSI Master is not STOP or HSDT state.\n");
- return -EINVAL;
- }
-
- exynos_mipi_dsi_set_cpu_transfer_mode(dsim, 0);
- }
-
- return 0;
-}
-
int exynos_mipi_dsi_get_frame_done_status(struct mipi_dsim_device *dsim)
{
return _exynos_mipi_dsi_get_frame_done_status(dsim);
@@ -855,26 +822,6 @@ int exynos_mipi_dsi_clear_frame_done(struct mipi_dsim_device *dsim)
return 0;
}
-int exynos_mipi_dsi_fifo_clear(struct mipi_dsim_device *dsim,
- unsigned int val)
-{
- int try = TRY_FIFO_CLEAR;
-
- exynos_mipi_dsi_sw_reset_release(dsim);
- exynos_mipi_dsi_func_reset(dsim);
-
- do {
- if (exynos_mipi_dsi_get_sw_reset_release(dsim)) {
- exynos_mipi_dsi_init_interrupt(dsim);
- dev_dbg(dsim->dev, "reset release done.\n");
- return 0;
- }
- } while (--try);
-
- dev_err(dsim->dev, "failed to clear dsim fifo.\n");
- return -EAGAIN;
-}
-
MODULE_AUTHOR("InKi Dae <inki.dae@samsung.com>");
MODULE_DESCRIPTION("Samusung SoC MIPI-DSI common driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/video/fbdev/exynos/exynos_mipi_dsi_common.h b/drivers/video/fbdev/exynos/exynos_mipi_dsi_common.h
index 4125522..5c1c30b 100644
--- a/drivers/video/fbdev/exynos/exynos_mipi_dsi_common.h
+++ b/drivers/video/fbdev/exynos/exynos_mipi_dsi_common.h
@@ -31,16 +31,9 @@ int exynos_mipi_dsi_set_display_mode(struct mipi_dsim_device *dsim,
struct mipi_dsim_config *dsim_info);
int exynos_mipi_dsi_init_link(struct mipi_dsim_device *dsim);
int exynos_mipi_dsi_set_hs_enable(struct mipi_dsim_device *dsim);
-int exynos_mipi_dsi_set_data_transfer_mode(struct mipi_dsim_device *dsim,
- unsigned int mode);
-int exynos_mipi_dsi_enable_frame_done_int(struct mipi_dsim_device *dsim,
- unsigned int enable);
int exynos_mipi_dsi_get_frame_done_status(struct mipi_dsim_device *dsim);
int exynos_mipi_dsi_clear_frame_done(struct mipi_dsim_device *dsim);
extern struct fb_info *registered_fb[FB_MAX] __read_mostly;
-int exynos_mipi_dsi_fifo_clear(struct mipi_dsim_device *dsim,
- unsigned int val);
-
#endif /* _EXYNOS_MIPI_DSI_COMMON_H */
--
1.7.10.4
^ permalink raw reply related
* [PATCH] atyfb: mark DMI system id table as __initconst
From: Mathias Krause @ 2015-01-04 14:04 UTC (permalink / raw)
To: linux-fbdev
We can mark the DMI system id table as __initconst by using a helper
variable that'll tell us if we need to unregister the reboot notifier in
atyfb_exit() instead of matching the DMI system id again.
This frees up ~680 bytes of runtime memory, the DMI table occupies.
Signed-off-by: Mathias Krause <minipli@googlemail.com>
---
drivers/video/fbdev/aty/atyfb_base.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/drivers/video/fbdev/aty/atyfb_base.c b/drivers/video/fbdev/aty/atyfb_base.c
index 37ec09b3fffd..8789e487b96e 100644
--- a/drivers/video/fbdev/aty/atyfb_base.c
+++ b/drivers/video/fbdev/aty/atyfb_base.c
@@ -3948,7 +3948,7 @@ static struct notifier_block atyfb_reboot_notifier = {
.notifier_call = atyfb_reboot_notify,
};
-static const struct dmi_system_id atyfb_reboot_ids[] = {
+static const struct dmi_system_id atyfb_reboot_ids[] __initconst = {
{
.ident = "HP OmniBook 500",
.matches = {
@@ -3960,6 +3960,7 @@ static const struct dmi_system_id atyfb_reboot_ids[] = {
{ }
};
+static bool registered_notifier = false;
static int __init atyfb_init(void)
{
@@ -3982,15 +3983,17 @@ static int __init atyfb_init(void)
if (err1 && err2)
return -ENODEV;
- if (dmi_check_system(atyfb_reboot_ids))
+ if (dmi_check_system(atyfb_reboot_ids)) {
register_reboot_notifier(&atyfb_reboot_notifier);
+ registered_notifier = true;
+ }
return 0;
}
static void __exit atyfb_exit(void)
{
- if (dmi_check_system(atyfb_reboot_ids))
+ if (registered_notifier)
unregister_reboot_notifier(&atyfb_reboot_notifier);
#ifdef CONFIG_PCI
--
1.7.10.4
^ permalink raw reply related
* [PATCH] simplefb: Fix build failure on Sparc
From: Hans de Goede @ 2015-01-05 8:15 UTC (permalink / raw)
To: linux-arm-kernel
of_platform_device_create is only defined when CONFIG_OF_ADDRESS is set,
which is normally always the case when CONFIG_OF is defined, except on Sparc,
so explicitly check for CONFIG_OF_ADDRESS rather then for CONFIG_OF.
Reported-by: kbuild test robot <fengguang.wu@intel.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
drivers/video/fbdev/simplefb.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/video/fbdev/simplefb.c b/drivers/video/fbdev/simplefb.c
index 92cac80..1085c04 100644
--- a/drivers/video/fbdev/simplefb.c
+++ b/drivers/video/fbdev/simplefb.c
@@ -402,7 +402,7 @@ static int __init simplefb_init(void)
if (ret)
return ret;
- if (IS_ENABLED(CONFIG_OF) && of_chosen) {
+ if (IS_ENABLED(CONFIG_OF_ADDRESS) && of_chosen) {
for_each_child_of_node(of_chosen, np) {
if (of_device_is_compatible(np, "simple-framebuffer"))
of_platform_device_create(np, NULL, NULL);
--
2.1.0
^ 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