* [PATCH 2/4] viafb: fill xres and yres
From: Florian Tobias Schandinat @ 2012-02-14 5:51 UTC (permalink / raw)
To: linux-fbdev; +Cc: linux-kernel, Florian Tobias Schandinat
In-Reply-To: <cover.1329194838.git.FlorianSchandinat@gmx.de>
This patch fills xres and yres in var which is required when a
temporary var is genereated when viafb_SAMM_ON is set and
viafb_dual_fb is not set. It also removes an obsolete comment.
Signed-off-by: Florian Tobias Schandinat <FlorianSchandinat@gmx.de>
---
drivers/video/via/hw.c | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/drivers/video/via/hw.c b/drivers/video/via/hw.c
index 08c1036..399d507 100644
--- a/drivers/video/via/hw.c
+++ b/drivers/video/via/hw.c
@@ -2125,7 +2125,6 @@ void viafb_set_dpa_gfx(int output_interface, struct GFX_DPA_SETTING\
}
}
-/*According var's xres, yres fill var's other timing information*/
void viafb_fill_var_timing_info(struct fb_var_screeninfo *var,
struct crt_mode_table *mode)
{
@@ -2134,6 +2133,8 @@ void viafb_fill_var_timing_info(struct fb_var_screeninfo *var,
crt_reg = mode->crtc;
var->pixclock = 1000000000 / (crt_reg.hor_total * crt_reg.ver_total)
* 1000 / mode->refresh_rate;
+ var->xres = crt_reg.hor_addr;
+ var->yres = crt_reg.ver_addr;
var->left_margin crt_reg.hor_total - (crt_reg.hor_sync_start + crt_reg.hor_sync_end);
var->right_margin = crt_reg.hor_sync_start - crt_reg.hor_addr;
--
1.7.9
^ permalink raw reply related
* [PATCH 1/4] viafb: set correct polarity for second adapter
From: Florian Tobias Schandinat @ 2012-02-14 5:51 UTC (permalink / raw)
To: linux-fbdev; +Cc: linux-kernel, Florian Tobias Schandinat
In-Reply-To: <cover.1329194838.git.FlorianSchandinat@gmx.de>
This patch sets the correct polarity for the second adapter when
viafb_SAMM_ON is set and viafb_dual_fb is not set. Just one step to
make this mode useful.
Signed-off-by: Florian Tobias Schandinat <FlorianSchandinat@gmx.de>
---
drivers/video/via/hw.c | 14 +++++++-------
1 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/drivers/video/via/hw.c b/drivers/video/via/hw.c
index d5aaca9..08c1036 100644
--- a/drivers/video/via/hw.c
+++ b/drivers/video/via/hw.c
@@ -1758,13 +1758,13 @@ static void set_display_channel(void)
}
}
-static u8 get_sync(struct fb_info *info)
+static u8 get_sync(struct fb_var_screeninfo *var)
{
u8 polarity = 0;
- if (!(info->var.sync & FB_SYNC_HOR_HIGH_ACT))
+ if (!(var->sync & FB_SYNC_HOR_HIGH_ACT))
polarity |= VIA_HSYNC_NEGATIVE;
- if (!(info->var.sync & FB_SYNC_VERT_HIGH_ACT))
+ if (!(var->sync & FB_SYNC_VERT_HIGH_ACT))
polarity |= VIA_VSYNC_NEGATIVE;
return polarity;
}
@@ -1976,13 +1976,13 @@ int viafb_setmode(int video_bpp, int video_bpp1)
viafb_DeviceStatus = CRT_Device;
}
device_on();
- if (!viafb_dual_fb)
- via_set_sync_polarity(devices, get_sync(viafbinfo));
+ if (!viafb_SAMM_ON)
+ via_set_sync_polarity(devices, get_sync(&viafbinfo->var));
else {
via_set_sync_polarity(viaparinfo->shared->iga1_devices,
- get_sync(viafbinfo));
+ get_sync(&viafbinfo->var));
via_set_sync_polarity(viaparinfo->shared->iga2_devices,
- get_sync(viafbinfo1));
+ get_sync(&var2));
}
clock.set_engine_pll_state(VIA_STATE_ON);
--
1.7.9
^ permalink raw reply related
* [PATCH 0/4] implement viafb SAMM mode
From: Florian Tobias Schandinat @ 2012-02-14 5:51 UTC (permalink / raw)
To: linux-fbdev; +Cc: linux-kernel, Florian Tobias Schandinat
Hi all,
this patch series implements viafb single adapter multiple monitor
mode in a useful way. It allows showing the same image on 2 devices
with different video modes by centering the smaller image.
It is useful for presentation or similar tasks, whenever dual fb is
not desired. I have now used it for quite some time.
Best regards,
Florian Tobias Schandinat
Florian Tobias Schandinat (4):
viafb: set correct polarity for second adapter
viafb: fill xres and yres
viafb: make single framebuffer multiple adapter mode work
viafb: make SAMM to also work on LCD
drivers/video/via/chip.h | 2 -
drivers/video/via/dvi.c | 5 ++-
drivers/video/via/dvi.h | 3 +-
drivers/video/via/hw.c | 85 +++++++++++++++++++++++----------------------
drivers/video/via/hw.h | 3 +-
drivers/video/via/lcd.c | 18 +++++-----
drivers/video/via/lcd.h | 3 +-
7 files changed, 61 insertions(+), 58 deletions(-)
--
1.7.9
^ permalink raw reply
* Re: [PATCH v2] video:da8xx-fb: calculate pixel clock period for the panel
From: Florian Tobias Schandinat @ 2012-02-13 21:28 UTC (permalink / raw)
To: Manjunathappa, Prakash
Cc: linux-fbdev, davinci-linux-open-source, linux-kernel
In-Reply-To: <1328768646-25169-1-git-send-email-prakash.pm@ti.com>
On 02/09/2012 06:24 AM, Manjunathappa, Prakash wrote:
> Patch calculates pixel clock period in pico seconds and updates
> the same in variable screen information structure. fbset utility
> uses this information.
>
> Signed-off-by: Manjunathappa, Prakash <prakash.pm@ti.com>
Applied.
Thanks,
Florian Tobias Schandinat
> ---
> Since v1:
> Fixed the spelling mistake.
>
> drivers/video/da8xx-fb.c | 19 ++++++++++++++++++-
> 1 files changed, 18 insertions(+), 1 deletions(-)
>
> diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
> index f360d62..882dd67 100644
> --- a/drivers/video/da8xx-fb.c
> +++ b/drivers/video/da8xx-fb.c
> @@ -32,6 +32,7 @@
> #include <linux/console.h>
> #include <linux/slab.h>
> #include <video/da8xx-fb.h>
> +#include <asm/div64.h>
>
> #define DRIVER_NAME "da8xx_lcdc"
>
> @@ -174,7 +175,6 @@ static struct fb_var_screeninfo da8xx_fb_var __devinitdata = {
> .activate = 0,
> .height = -1,
> .width = -1,
> - .pixclock = 46666, /* 46us - AUO display */
> .accel_flags = 0,
> .left_margin = LEFT_MARGIN,
> .right_margin = RIGHT_MARGIN,
> @@ -1048,6 +1048,22 @@ static struct fb_ops da8xx_fb_ops = {
> .fb_blank = cfb_blank,
> };
>
> +/* Calculate and return pixel clock period in pico seconds */
> +static unsigned int da8xxfb_pixel_clk_period(struct da8xx_fb_par *par)
> +{
> + unsigned int lcd_clk, div;
> + unsigned int configured_pix_clk;
> + unsigned long long pix_clk_period_picosec = 1000000000000ULL;
> +
> + lcd_clk = clk_get_rate(par->lcdc_clk);
> + div = lcd_clk / par->pxl_clk;
> + configured_pix_clk = (lcd_clk / div);
> +
> + do_div(pix_clk_period_picosec, configured_pix_clk);
> +
> + return pix_clk_period_picosec;
> +}
> +
> static int __devinit fb_probe(struct platform_device *device)
> {
> struct da8xx_lcdc_platform_data *fb_pdata > @@ -1209,6 +1225,7 @@ static int __devinit fb_probe(struct platform_device *device)
>
> da8xx_fb_var.hsync_len = lcdc_info->hsw;
> da8xx_fb_var.vsync_len = lcdc_info->vsw;
> + da8xx_fb_var.pixclock = da8xxfb_pixel_clk_period(par);
>
> /* Initialize fbinfo */
> da8xx_fb_info->flags = FBINFO_FLAG_DEFAULT;
^ permalink raw reply
* Re: [PATCH] video: da8xx-fb: Fix build warning on unused label
From: Florian Tobias Schandinat @ 2012-02-13 21:27 UTC (permalink / raw)
To: Manjunathappa, Prakash
Cc: linux-fbdev, davinci-linux-open-source, linux-kernel
In-Reply-To: <1328763879-16345-1-git-send-email-prakash.pm@ti.com>
On 02/09/2012 05:04 AM, Manjunathappa, Prakash wrote:
> Patch fixes build warning on label "err_cpu_freq" when CONFIG_CPU_FREQ
> is not defined.
>
> Signed-off-by: Manjunathappa, Prakash <prakash.pm@ti.com>
Applied.
Thanks,
Florian Tobias Schandinat
> ---
> drivers/video/da8xx-fb.c | 2 +-
> 1 files changed, 1 insertions(+), 1 deletions(-)
>
> diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
> index 29577bf..f360d62 100644
> --- a/drivers/video/da8xx-fb.c
> +++ b/drivers/video/da8xx-fb.c
> @@ -1264,8 +1264,8 @@ static int __devinit fb_probe(struct platform_device *device)
> irq_freq:
> #ifdef CONFIG_CPU_FREQ
> lcd_da8xx_cpufreq_deregister(par);
> -#endif
> err_cpu_freq:
> +#endif
> unregister_framebuffer(da8xx_fb_info);
>
> err_dealloc_cmap:
^ permalink raw reply
* Re: [PATCH 13/16] riva/fbdev: fix several -Wuninitialized
From: Florian Tobias Schandinat @ 2012-02-13 21:26 UTC (permalink / raw)
To: Danny Kukawka; +Cc: Antonino Daplas, linux-fbdev, linux-kernel
In-Reply-To: <1327960820-11867-14-git-send-email-danny.kukawka@bisect.de>
On 01/30/2012 10:00 PM, Danny Kukawka wrote:
> Fix several -Wuninitialized compiler warnings by changing the
> order of getting modedb in riva_update_default_var() to set
> first the fallback and then the prefered timing.
>
> Signed-off-by: Danny Kukawka <danny.kukawka@bisect.de>
Applied.
Thanks,
Florian Tobias Schandinat
> ---
> drivers/video/riva/fbdev.c | 5 ++---
> 1 files changed, 2 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/video/riva/fbdev.c b/drivers/video/riva/fbdev.c
> index 2f58cf9..90df1a6 100644
> --- a/drivers/video/riva/fbdev.c
> +++ b/drivers/video/riva/fbdev.c
> @@ -1816,6 +1816,8 @@ static void __devinit riva_update_default_var(struct fb_var_screeninfo *var,
> specs->modedb, specs->modedb_len,
> NULL, 8);
> } else if (specs->modedb != NULL) {
> + /* get first mode in database as fallback */
> + modedb = specs->modedb[0];
> /* get preferred timing */
> if (info->monspecs.misc & FB_MISC_1ST_DETAIL) {
> int i;
> @@ -1826,9 +1828,6 @@ static void __devinit riva_update_default_var(struct fb_var_screeninfo *var,
> break;
> }
> }
> - } else {
> - /* otherwise, get first mode in database */
> - modedb = specs->modedb[0];
> }
> var->bits_per_pixel = 8;
> riva_update_var(var, &modedb);
^ permalink raw reply
* Re: [PATCH] ARM: OMAP1: ams-delta: correct init data section assignments
From: Russell King - ARM Linux @ 2012-02-11 10:24 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1580046.EEGIFOPvyy@vclass>
On Fri, Feb 10, 2012 at 05:31:31PM +0100, Janusz Krzysztofik wrote:
> On Thursday 09 of February 2012 14:48:53 Russell King - ARM Linux wrote:
> > > -static struct map_desc ams_delta_io_desc[] __initdata = {
> > > +static struct map_desc ams_delta_io_desc[] __initconst = {
> >
> > You're not making this comst so don't change it to __initconst.
>
> OK, however, I think there must be a bug in gcc, otherwise it should probably
> never accept such wrong constructs, while sometimes it does (not only mine,
> see [1]).
No - because you don't understand what's going on with these tags.
The __initconst and other tags are just tell the compiler to place
stuff into a named section. The name is interpreted by GCC as a mere
string which it passes through to the ELF file.
So, gcc has no idea that a section named '.init.rodata' could be placed
in read-only memory, and therefore has no idea that it should also be
marked 'const'.
Therefore, gcc has no way to verify that 'const' and '__initconst' are
always paired.
> > > -static struct omap_lcd_config ams_delta_lcd_config = {
> > > +static struct omap_lcd_config ams_delta_lcd_config __initconst = {
> >
> > This change probably adds a bug. Are you sure this will never be used
> > outside init context?
>
> I may be wrong, but before I've changed this, and now once again, I've verified
> that a copy of this data is made inside __init omap_init_fb() by means of a
> structure assignment operation.
Ok, in that case add a 'const' to it.
> > > -static struct omap_usb_config ams_delta_usb_config __initdata = {
> > > +static struct omap_usb_config ams_delta_usb_config __initdata_or_module
> > > = {
> > Even if you don't have modules enabled, have you checked whether the
> > driver can be bound and unbound via
> > /sys/bus/platform/driver/<name>/{bind,unbind} ?
>
> No, I didn't even think of it, I am afraid.
>
> > I suspect this is a bug.
>
> Indeed, that data is not copied on init, only pointed to, moreover, the
> ohci-omap driver provides bind/unbind opearations.
>
> BTW, what are those bind/unbind operations intended for in case of a
> driver dedicated to a non-hotplugable SoC hardware exclusively?
If the driver can be built as a module, they allow exercising the
probe/remove paths for drivers which have been built-in. Moreover,
it allows you to disable a device driver if desired.
For example, I have two platforms which are essentially the same, except
one has a daughterboard attached (which isn't hotpluggable). The support
for the daughterboard, although it is a platform driver, can't be
modularised at the moment because quite a bit of other stuff needs it
and it contains IRQ chip code.
One has far less idle wakeups than the other. Using unbind, I can
effectively detach this board by unbinding its platform device, which
results the entire sub-tree of its on-board devices being unregistered
and released in one big go, all the way down to things like USB devices
on the USB host. I can then rebind it and bring all that hardware back.
That allows me to evaluate whether there's any impact from those drivers.
However, this bind/unbind is not the only issue here: how do you know
whether the driver takes a copy of the platform data, or merely stores a
pointer to it - and may access your platform data at runtime.
Unless you check, and recheck it regularly (it can change) then placing
this stuff into sections which will be discarded is asking for bugs.
> > > -static struct platform_device *ams_delta_devices[] __initdata = {
> > > +static struct platform_device *ams_delta_devices[] __initconst = {
> >
> > Missing const. If you can't const it, don't put it in __initconst.
>
> I gave up trying to use both const and __initconst together after my gcc-4.2.4
> (and not only mine, see [1], [2]) refused to accept such constructs a few
> times. Now I see that this false reporting may probably happen in presence of other
> incorrect uses of __initconst without const or __initdata with const.
I doubt that the compiler was refusing to accept them. What you were
probably getting were warnings about where these were used not accepting
a const pointer.
If that's the case, more analysis needs to be done to find out whether
those uses can be converted to accept a const pointer before defining
the data with const and optionally __initconst.
^ permalink raw reply
* [PATCH v5] [resend] Resurrect Intel740 driver: i740fb
From: Ondrej Zary @ 2012-02-10 17:59 UTC (permalink / raw)
To: linux-fbdev
Cc: Andrey Ulanov, Florian Tobias Schandinat, Paul Mundt,
Kernel development list
This is a resurrection of an old (like 2.4.19) out-of-tree driver for
Intel740 graphics cards and adaptation for recent kernels. The old driver by
Andrey Ulanov is located at: http://sourceforge.net/projects/i740fbdev/files/
This is a new driver based on skeletonfb, using most of the low level HW code
from the old driver. The DDC code is completely new.
The driver was tested on two 8MB cards: Protac AG240D and Diamond Stealth II
G460.
Signed-off-by: Ondrej Zary <linux@rainbow-software.org>
---
Changes in v5:
- fixed checkpatch problems
- added Kconfig dependency on FB_DDC
- cleaned up i740_calc_vclk()
- fixed SDRAM/SGRAM detection
- fixed wrong colors in 16bpp mode when neither 555 nor 565 specified
--- linux-3.2.1-orig/drivers/video/Kconfig 2012-01-12 20:42:45.000000000 +0100
+++ linux-3.2.1/drivers/video/Kconfig 2012-01-23 20:52:32.000000000 +0100
@@ -1123,6 +1123,18 @@ config FB_RIVA_BACKLIGHT
help
Say Y here if you want to control the backlight of your display.
+config FB_I740
+ tristate "Intel740 support (EXPERIMENTAL)"
+ depends on EXPERIMENTAL && FB && PCI
+ select FB_MODE_HELPERS
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ select VGASTATE
+ select FB_DDC
+ help
+ This driver supports graphics cards based on Intel740 chip.
+
config FB_I810
tristate "Intel 810/815 support (EXPERIMENTAL)"
depends on EXPERIMENTAL && FB && PCI && X86_32 && AGP_INTEL
--- linux-3.2.1-orig/drivers/video/Makefile 2012-01-12 20:42:45.000000000 +0100
+++ linux-3.2.1/drivers/video/Makefile 2012-01-23 20:52:32.000000000 +0100
@@ -37,6 +37,7 @@ obj-$(CONFIG_FB_GRVGA) += grv
obj-$(CONFIG_FB_PM2) += pm2fb.o
obj-$(CONFIG_FB_PM3) += pm3fb.o
+obj-$(CONFIG_FB_I740) += i740fb.o
obj-$(CONFIG_FB_MATROX) += matrox/
obj-$(CONFIG_FB_RIVA) += riva/
obj-$(CONFIG_FB_NVIDIA) += nvidia/
--- /dev/null 2012-01-24 00:06:39.330222901 +0100
+++ linux-3.2.1/drivers/video/i740fb.c 2012-01-24 00:01:54.000000000 +0100
@@ -0,0 +1,1337 @@
+/*
+ * i740fb - framebuffer driver for Intel740
+ * Copyright (c) 2011 Ondrej Zary
+ *
+ * Based on old i740fb driver (c) 2001-2002 Andrey Ulanov <drey@rt.mipt.ru>
+ * which was partially based on:
+ * VGA 16-color framebuffer driver (c) 1999 Ben Pfaff <pfaffben@debian.org>
+ * and Petr Vandrovec <VANDROVE@vc.cvut.cz>
+ * i740 driver from XFree86 (c) 1998-1999 Precision Insight, Inc., Cedar Park,
+ * Texas.
+ * i740fb by Patrick LERDA, v0.9
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/pci_ids.h>
+#include <linux/i2c.h>
+#include <linux/i2c-algo-bit.h>
+#include <linux/console.h>
+#include <video/vga.h>
+
+#ifdef CONFIG_MTRR
+#include <asm/mtrr.h>
+#endif
+
+#include "i740_reg.h"
+
+static char *mode_option __devinitdata;
+
+#ifdef CONFIG_MTRR
+static int mtrr __devinitdata = 1;
+#endif
+
+struct i740fb_par {
+ unsigned char __iomem *regs;
+ bool has_sgram;
+#ifdef CONFIG_MTRR
+ int mtrr_reg;
+#endif
+ bool ddc_registered;
+ struct i2c_adapter ddc_adapter;
+ struct i2c_algo_bit_data ddc_algo;
+ u32 pseudo_palette[16];
+ struct mutex open_lock;
+ unsigned int ref_count;
+
+ u8 crtc[VGA_CRT_C];
+ u8 atc[VGA_ATT_C];
+ u8 gdc[VGA_GFX_C];
+ u8 seq[VGA_SEQ_C];
+ u8 misc;
+ u8 vss;
+
+ /* i740 specific registers */
+ u8 display_cntl;
+ u8 pixelpipe_cfg0;
+ u8 pixelpipe_cfg1;
+ u8 pixelpipe_cfg2;
+ u8 video_clk2_m;
+ u8 video_clk2_n;
+ u8 video_clk2_mn_msbs;
+ u8 video_clk2_div_sel;
+ u8 pll_cntl;
+ u8 address_mapping;
+ u8 io_cntl;
+ u8 bitblt_cntl;
+ u8 ext_vert_total;
+ u8 ext_vert_disp_end;
+ u8 ext_vert_sync_start;
+ u8 ext_vert_blank_start;
+ u8 ext_horiz_total;
+ u8 ext_horiz_blank;
+ u8 ext_offset;
+ u8 interlace_cntl;
+ u32 lmi_fifo_watermark;
+ u8 ext_start_addr;
+ u8 ext_start_addr_hi;
+};
+
+#define DACSPEED8 203
+#define DACSPEED16 163
+#define DACSPEED24_SG 136
+#define DACSPEED24_SD 128
+#define DACSPEED32 86
+
+static struct fb_fix_screeninfo i740fb_fix __devinitdata = {
+ .id = "i740fb",
+ .type = FB_TYPE_PACKED_PIXELS,
+ .visual = FB_VISUAL_TRUECOLOR,
+ .xpanstep = 8,
+ .ypanstep = 1,
+ .accel = FB_ACCEL_NONE,
+};
+
+static inline void i740outb(struct i740fb_par *par, u16 port, u8 val)
+{
+ vga_mm_w(par->regs, port, val);
+}
+static inline u8 i740inb(struct i740fb_par *par, u16 port)
+{
+ return vga_mm_r(par->regs, port);
+}
+static inline void i740outreg(struct i740fb_par *par, u16 port, u8 reg, u8 val)
+{
+ vga_mm_w_fast(par->regs, port, reg, val);
+}
+static inline u8 i740inreg(struct i740fb_par *par, u16 port, u8 reg)
+{
+ vga_mm_w(par->regs, port, reg);
+ return vga_mm_r(par->regs, port+1);
+}
+static inline void i740outreg_mask(struct i740fb_par *par, u16 port, u8 reg,
+ u8 val, u8 mask)
+{
+ vga_mm_w_fast(par->regs, port, reg, (val & mask)
+ | (i740inreg(par, port, reg) & ~mask));
+}
+
+#define REG_DDC_DRIVE 0x62
+#define REG_DDC_STATE 0x63
+#define DDC_SCL (1 << 3)
+#define DDC_SDA (1 << 2)
+
+static void i740fb_ddc_setscl(void *data, int val)
+{
+ struct i740fb_par *par = data;
+
+ i740outreg_mask(par, XRX, REG_DDC_DRIVE, DDC_SCL, DDC_SCL);
+ i740outreg_mask(par, XRX, REG_DDC_STATE, val ? DDC_SCL : 0, DDC_SCL);
+}
+
+static void i740fb_ddc_setsda(void *data, int val)
+{
+ struct i740fb_par *par = data;
+
+ i740outreg_mask(par, XRX, REG_DDC_DRIVE, DDC_SDA, DDC_SDA);
+ i740outreg_mask(par, XRX, REG_DDC_STATE, val ? DDC_SDA : 0, DDC_SDA);
+}
+
+static int i740fb_ddc_getscl(void *data)
+{
+ struct i740fb_par *par = data;
+
+ i740outreg_mask(par, XRX, REG_DDC_DRIVE, 0, DDC_SCL);
+
+ return !!(i740inreg(par, XRX, REG_DDC_STATE) & DDC_SCL);
+}
+
+static int i740fb_ddc_getsda(void *data)
+{
+ struct i740fb_par *par = data;
+
+ i740outreg_mask(par, XRX, REG_DDC_DRIVE, 0, DDC_SDA);
+
+ return !!(i740inreg(par, XRX, REG_DDC_STATE) & DDC_SDA);
+}
+
+static int __devinit i740fb_setup_ddc_bus(struct fb_info *info)
+{
+ struct i740fb_par *par = info->par;
+
+ strlcpy(par->ddc_adapter.name, info->fix.id,
+ sizeof(par->ddc_adapter.name));
+ par->ddc_adapter.owner = THIS_MODULE;
+ par->ddc_adapter.class = I2C_CLASS_DDC;
+ par->ddc_adapter.algo_data = &par->ddc_algo;
+ par->ddc_adapter.dev.parent = info->device;
+ par->ddc_algo.setsda = i740fb_ddc_setsda;
+ par->ddc_algo.setscl = i740fb_ddc_setscl;
+ par->ddc_algo.getsda = i740fb_ddc_getsda;
+ par->ddc_algo.getscl = i740fb_ddc_getscl;
+ par->ddc_algo.udelay = 10;
+ par->ddc_algo.timeout = 20;
+ par->ddc_algo.data = par;
+
+ i2c_set_adapdata(&par->ddc_adapter, par);
+
+ return i2c_bit_add_bus(&par->ddc_adapter);
+}
+
+static int i740fb_open(struct fb_info *info, int user)
+{
+ struct i740fb_par *par = info->par;
+
+ mutex_lock(&(par->open_lock));
+ par->ref_count++;
+ mutex_unlock(&(par->open_lock));
+
+ return 0;
+}
+
+static int i740fb_release(struct fb_info *info, int user)
+{
+ struct i740fb_par *par = info->par;
+
+ mutex_lock(&(par->open_lock));
+ if (par->ref_count = 0) {
+ printk(KERN_ERR "fb%d: release called with zero refcount\n",
+ info->node);
+ mutex_unlock(&(par->open_lock));
+ return -EINVAL;
+ }
+
+ par->ref_count--;
+ mutex_unlock(&(par->open_lock));
+
+ return 0;
+}
+
+static u32 i740_calc_fifo(struct i740fb_par *par, u32 freq, int bpp)
+{
+ /*
+ * Would like to calculate these values automatically, but a generic
+ * algorithm does not seem possible. Note: These FIFO water mark
+ * values were tested on several cards and seem to eliminate the
+ * all of the snow and vertical banding, but fine adjustments will
+ * probably be required for other cards.
+ */
+
+ u32 wm;
+
+ switch (bpp) {
+ case 8:
+ if (freq > 200)
+ wm = 0x18120000;
+ else if (freq > 175)
+ wm = 0x16110000;
+ else if (freq > 135)
+ wm = 0x120E0000;
+ else
+ wm = 0x100D0000;
+ break;
+ case 15:
+ case 16:
+ if (par->has_sgram) {
+ if (freq > 140)
+ wm = 0x2C1D0000;
+ else if (freq > 120)
+ wm = 0x2C180000;
+ else if (freq > 100)
+ wm = 0x24160000;
+ else if (freq > 90)
+ wm = 0x18120000;
+ else if (freq > 50)
+ wm = 0x16110000;
+ else if (freq > 32)
+ wm = 0x13100000;
+ else
+ wm = 0x120E0000;
+ } else {
+ if (freq > 160)
+ wm = 0x28200000;
+ else if (freq > 140)
+ wm = 0x2A1E0000;
+ else if (freq > 130)
+ wm = 0x2B1A0000;
+ else if (freq > 120)
+ wm = 0x2C180000;
+ else if (freq > 100)
+ wm = 0x24180000;
+ else if (freq > 90)
+ wm = 0x18120000;
+ else if (freq > 50)
+ wm = 0x16110000;
+ else if (freq > 32)
+ wm = 0x13100000;
+ else
+ wm = 0x120E0000;
+ }
+ break;
+ case 24:
+ if (par->has_sgram) {
+ if (freq > 130)
+ wm = 0x31200000;
+ else if (freq > 120)
+ wm = 0x2E200000;
+ else if (freq > 100)
+ wm = 0x2C1D0000;
+ else if (freq > 80)
+ wm = 0x25180000;
+ else if (freq > 64)
+ wm = 0x24160000;
+ else if (freq > 49)
+ wm = 0x18120000;
+ else if (freq > 32)
+ wm = 0x16110000;
+ else
+ wm = 0x13100000;
+ } else {
+ if (freq > 120)
+ wm = 0x311F0000;
+ else if (freq > 100)
+ wm = 0x2C1D0000;
+ else if (freq > 80)
+ wm = 0x25180000;
+ else if (freq > 64)
+ wm = 0x24160000;
+ else if (freq > 49)
+ wm = 0x18120000;
+ else if (freq > 32)
+ wm = 0x16110000;
+ else
+ wm = 0x13100000;
+ }
+ break;
+ case 32:
+ if (par->has_sgram) {
+ if (freq > 80)
+ wm = 0x2A200000;
+ else if (freq > 60)
+ wm = 0x281A0000;
+ else if (freq > 49)
+ wm = 0x25180000;
+ else if (freq > 32)
+ wm = 0x18120000;
+ else
+ wm = 0x16110000;
+ } else {
+ if (freq > 80)
+ wm = 0x29200000;
+ else if (freq > 60)
+ wm = 0x281A0000;
+ else if (freq > 49)
+ wm = 0x25180000;
+ else if (freq > 32)
+ wm = 0x18120000;
+ else
+ wm = 0x16110000;
+ }
+ break;
+ }
+
+ return wm;
+}
+
+/* clock calculation from i740fb by Patrick LERDA */
+
+#define I740_RFREQ 1000000
+#define TARGET_MAX_N 30
+#define I740_FFIX (1 << 8)
+#define I740_RFREQ_FIX (I740_RFREQ / I740_FFIX)
+#define I740_REF_FREQ (6667 * I740_FFIX / 100) /* 66.67 MHz */
+#define I740_MAX_VCO_FREQ (450 * I740_FFIX) /* 450 MHz */
+
+static void i740_calc_vclk(u32 freq, struct i740fb_par *par)
+{
+ const u32 err_max = freq / (200 * I740_RFREQ / I740_FFIX);
+ const u32 err_target = freq / (1000 * I740_RFREQ / I740_FFIX);
+ u32 err_best = 512 * I740_FFIX;
+ u32 f_err, f_vco;
+ int m_best = 0, n_best = 0, p_best = 0, d_best = 0;
+ int m, n;
+
+ p_best = min(15, ilog2(I740_MAX_VCO_FREQ / (freq / I740_RFREQ_FIX)));
+ d_best = 0;
+ f_vco = (freq * (1 << p_best)) / I740_RFREQ_FIX;
+ freq = freq / I740_RFREQ_FIX;
+
+ n = 2;
+ do {
+ n++;
+ m = ((f_vco * n) / I740_REF_FREQ + 2) / 4;
+
+ if (m < 3)
+ m = 3;
+
+ {
+ u32 f_out = (((m * I740_REF_FREQ * (4 << 2 * d_best))
+ / n) + ((1 << p_best) / 2)) / (1 << p_best);
+
+ f_err = (freq - f_out);
+
+ if (abs(f_err) < err_max) {
+ m_best = m;
+ n_best = n;
+ err_best = f_err;
+ }
+ }
+ } while ((abs(f_err) >= err_target) &&
+ ((n <= TARGET_MAX_N) || (abs(err_best) > err_max)));
+
+ if (abs(f_err) < err_target) {
+ m_best = m;
+ n_best = n;
+ }
+
+ par->video_clk2_m = (m_best - 2) & 0xFF;
+ par->video_clk2_n = (n_best - 2) & 0xFF;
+ par->video_clk2_mn_msbs = ((((n_best - 2) >> 4) & VCO_N_MSBS)
+ | (((m_best - 2) >> 8) & VCO_M_MSBS));
+ par->video_clk2_div_sel + ((p_best << 4) | (d_best ? 4 : 0) | REF_DIV_1);
+}
+
+static int i740fb_decode_var(const struct fb_var_screeninfo *var,
+ struct i740fb_par *par, struct fb_info *info)
+{
+ /*
+ * Get the video params out of 'var'.
+ * If a value doesn't fit, round it up, if it's too big, return -EINVAL.
+ */
+
+ u32 xres, right, hslen, left, xtotal;
+ u32 yres, lower, vslen, upper, ytotal;
+ u32 vxres, xoffset, vyres, yoffset;
+ u32 bpp, base, dacspeed24, mem;
+ u8 r7;
+ int i;
+
+ dev_dbg(info->device, "decode_var: xres: %i, yres: %i, xres_v: %i, xres_v: %i\n",
+ var->xres, var->yres, var->xres_virtual, var->xres_virtual);
+ dev_dbg(info->device, " xoff: %i, yoff: %i, bpp: %i, graysc: %i\n",
+ var->xoffset, var->yoffset, var->bits_per_pixel,
+ var->grayscale);
+ dev_dbg(info->device, " activate: %i, nonstd: %i, vmode: %i\n",
+ var->activate, var->nonstd, var->vmode);
+ dev_dbg(info->device, " pixclock: %i, hsynclen:%i, vsynclen:%i\n",
+ var->pixclock, var->hsync_len, var->vsync_len);
+ dev_dbg(info->device, " left: %i, right: %i, up:%i, lower:%i\n",
+ var->left_margin, var->right_margin, var->upper_margin,
+ var->lower_margin);
+
+
+ bpp = var->bits_per_pixel;
+ switch (bpp) {
+ case 1 ... 8:
+ bpp = 8;
+ if ((1000000 / var->pixclock) > DACSPEED8) {
+ dev_err(info->device, "requested pixclock %i MHz out of range (max. %i MHz at 8bpp)\n",
+ 1000000 / var->pixclock, DACSPEED8);
+ return -EINVAL;
+ }
+ break;
+ case 9 ... 15:
+ bpp = 15;
+ case 16:
+ if ((1000000 / var->pixclock) > DACSPEED16) {
+ dev_err(info->device, "requested pixclock %i MHz out of range (max. %i MHz at 15/16bpp)\n",
+ 1000000 / var->pixclock, DACSPEED16);
+ return -EINVAL;
+ }
+ break;
+ case 17 ... 24:
+ bpp = 24;
+ dacspeed24 = par->has_sgram ? DACSPEED24_SG : DACSPEED24_SD;
+ if ((1000000 / var->pixclock) > dacspeed24) {
+ dev_err(info->device, "requested pixclock %i MHz out of range (max. %i MHz at 24bpp)\n",
+ 1000000 / var->pixclock, dacspeed24);
+ return -EINVAL;
+ }
+ break;
+ case 25 ... 32:
+ bpp = 32;
+ if ((1000000 / var->pixclock) > DACSPEED32) {
+ dev_err(info->device, "requested pixclock %i MHz out of range (max. %i MHz at 32bpp)\n",
+ 1000000 / var->pixclock, DACSPEED32);
+ return -EINVAL;
+ }
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ xres = ALIGN(var->xres, 8);
+ vxres = ALIGN(var->xres_virtual, 16);
+ if (vxres < xres)
+ vxres = xres;
+
+ xoffset = ALIGN(var->xoffset, 8);
+ if (xres + xoffset > vxres)
+ xoffset = vxres - xres;
+
+ left = ALIGN(var->left_margin, 8);
+ right = ALIGN(var->right_margin, 8);
+ hslen = ALIGN(var->hsync_len, 8);
+
+ yres = var->yres;
+ vyres = var->yres_virtual;
+ if (yres > vyres)
+ vyres = yres;
+
+ yoffset = var->yoffset;
+ if (yres + yoffset > vyres)
+ yoffset = vyres - yres;
+
+ lower = var->lower_margin;
+ vslen = var->vsync_len;
+ upper = var->upper_margin;
+
+ mem = vxres * vyres * ((bpp + 1) / 8);
+ if (mem > info->screen_size) {
+ dev_err(info->device, "not enough video memory (%d KB requested, %ld KB avaliable)\n",
+ mem >> 10, info->screen_size >> 10);
+ return -ENOMEM;
+ }
+
+ if (yoffset + yres > vyres)
+ yoffset = vyres - yres;
+
+ xtotal = xres + right + hslen + left;
+ ytotal = yres + lower + vslen + upper;
+
+ par->crtc[VGA_CRTC_H_TOTAL] = (xtotal >> 3) - 5;
+ par->crtc[VGA_CRTC_H_DISP] = (xres >> 3) - 1;
+ par->crtc[VGA_CRTC_H_BLANK_START] = ((xres + right) >> 3) - 1;
+ par->crtc[VGA_CRTC_H_SYNC_START] = (xres + right) >> 3;
+ par->crtc[VGA_CRTC_H_SYNC_END] = (((xres + right + hslen) >> 3) & 0x1F)
+ | ((((xres + right + hslen) >> 3) & 0x20) << 2);
+ par->crtc[VGA_CRTC_H_BLANK_END] = ((xres + right + hslen) >> 3 & 0x1F)
+ | 0x80;
+
+ par->crtc[VGA_CRTC_V_TOTAL] = ytotal - 2;
+
+ r7 = 0x10; /* disable linecompare */
+ if (ytotal & 0x100)
+ r7 |= 0x01;
+ if (ytotal & 0x200)
+ r7 |= 0x20;
+
+ par->crtc[VGA_CRTC_PRESET_ROW] = 0;
+ par->crtc[VGA_CRTC_MAX_SCAN] = 0x40; /* 1 scanline, no linecmp */
+ if (var->vmode & FB_VMODE_DOUBLE)
+ par->crtc[VGA_CRTC_MAX_SCAN] |= 0x80;
+ par->crtc[VGA_CRTC_CURSOR_START] = 0x00;
+ par->crtc[VGA_CRTC_CURSOR_END] = 0x00;
+ par->crtc[VGA_CRTC_CURSOR_HI] = 0x00;
+ par->crtc[VGA_CRTC_CURSOR_LO] = 0x00;
+ par->crtc[VGA_CRTC_V_DISP_END] = yres-1;
+ if ((yres-1) & 0x100)
+ r7 |= 0x02;
+ if ((yres-1) & 0x200)
+ r7 |= 0x40;
+
+ par->crtc[VGA_CRTC_V_BLANK_START] = yres + lower - 1;
+ par->crtc[VGA_CRTC_V_SYNC_START] = yres + lower - 1;
+ if ((yres + lower - 1) & 0x100)
+ r7 |= 0x0C;
+ if ((yres + lower - 1) & 0x200) {
+ par->crtc[VGA_CRTC_MAX_SCAN] |= 0x20;
+ r7 |= 0x80;
+ }
+
+ /* disabled IRQ */
+ par->crtc[VGA_CRTC_V_SYNC_END] + ((yres + lower - 1 + vslen) & 0x0F) & ~0x10;
+ /* 0x7F for VGA, but some SVGA chips require all 8 bits to be set */
+ par->crtc[VGA_CRTC_V_BLANK_END] = (yres + lower - 1 + vslen) & 0xFF;
+
+ par->crtc[VGA_CRTC_UNDERLINE] = 0x00;
+ par->crtc[VGA_CRTC_MODE] = 0xC3 ;
+ par->crtc[VGA_CRTC_LINE_COMPARE] = 0xFF;
+ par->crtc[VGA_CRTC_OVERFLOW] = r7;
+
+ par->vss = 0x00; /* 3DA */
+
+ for (i = 0x00; i < 0x10; i++)
+ par->atc[i] = i;
+ par->atc[VGA_ATC_MODE] = 0x81;
+ par->atc[VGA_ATC_OVERSCAN] = 0x00; /* 0 for EGA, 0xFF for VGA */
+ par->atc[VGA_ATC_PLANE_ENABLE] = 0x0F;
+ par->atc[VGA_ATC_COLOR_PAGE] = 0x00;
+
+ par->misc = 0xC3;
+ if (var->sync & FB_SYNC_HOR_HIGH_ACT)
+ par->misc &= ~0x40;
+ if (var->sync & FB_SYNC_VERT_HIGH_ACT)
+ par->misc &= ~0x80;
+
+ par->seq[VGA_SEQ_CLOCK_MODE] = 0x01;
+ par->seq[VGA_SEQ_PLANE_WRITE] = 0x0F;
+ par->seq[VGA_SEQ_CHARACTER_MAP] = 0x00;
+ par->seq[VGA_SEQ_MEMORY_MODE] = 0x06;
+
+ par->gdc[VGA_GFX_SR_VALUE] = 0x00;
+ par->gdc[VGA_GFX_SR_ENABLE] = 0x00;
+ par->gdc[VGA_GFX_COMPARE_VALUE] = 0x00;
+ par->gdc[VGA_GFX_DATA_ROTATE] = 0x00;
+ par->gdc[VGA_GFX_PLANE_READ] = 0;
+ par->gdc[VGA_GFX_MODE] = 0x02;
+ par->gdc[VGA_GFX_MISC] = 0x05;
+ par->gdc[VGA_GFX_COMPARE_MASK] = 0x0F;
+ par->gdc[VGA_GFX_BIT_MASK] = 0xFF;
+
+ base = (yoffset * vxres + (xoffset & ~7)) >> 2;
+ switch (bpp) {
+ case 8:
+ par->crtc[VGA_CRTC_OFFSET] = vxres >> 3;
+ par->ext_offset = vxres >> 11;
+ par->pixelpipe_cfg1 = DISPLAY_8BPP_MODE;
+ par->bitblt_cntl = COLEXP_8BPP;
+ break;
+ case 15: /* 0rrrrrgg gggbbbbb */
+ case 16: /* rrrrrggg gggbbbbb */
+ par->pixelpipe_cfg1 = (var->green.length = 6) ?
+ DISPLAY_16BPP_MODE : DISPLAY_15BPP_MODE;
+ par->crtc[VGA_CRTC_OFFSET] = vxres >> 2;
+ par->ext_offset = vxres >> 10;
+ par->bitblt_cntl = COLEXP_16BPP;
+ base *= 2;
+ break;
+ case 24:
+ par->crtc[VGA_CRTC_OFFSET] = (vxres * 3) >> 3;
+ par->ext_offset = (vxres * 3) >> 11;
+ par->pixelpipe_cfg1 = DISPLAY_24BPP_MODE;
+ par->bitblt_cntl = COLEXP_24BPP;
+ base &= 0xFFFFFFFE; /* ...ignore the last bit. */
+ base *= 3;
+ break;
+ case 32:
+ par->crtc[VGA_CRTC_OFFSET] = vxres >> 1;
+ par->ext_offset = vxres >> 9;
+ par->pixelpipe_cfg1 = DISPLAY_32BPP_MODE;
+ par->bitblt_cntl = COLEXP_RESERVED; /* Unimplemented on i740 */
+ base *= 4;
+ break;
+ }
+
+ par->crtc[VGA_CRTC_START_LO] = base & 0x000000FF;
+ par->crtc[VGA_CRTC_START_HI] = (base & 0x0000FF00) >> 8;
+ par->ext_start_addr + ((base & 0x003F0000) >> 16) | EXT_START_ADDR_ENABLE;
+ par->ext_start_addr_hi = (base & 0x3FC00000) >> 22;
+
+ par->pixelpipe_cfg0 = DAC_8_BIT;
+
+ par->pixelpipe_cfg2 = DISPLAY_GAMMA_ENABLE | OVERLAY_GAMMA_ENABLE;
+ par->io_cntl = EXTENDED_CRTC_CNTL;
+ par->address_mapping = LINEAR_MODE_ENABLE | PAGE_MAPPING_ENABLE;
+ par->display_cntl = HIRES_MODE;
+
+ /* Set the MCLK freq */
+ par->pll_cntl = PLL_MEMCLK_100000KHZ; /* 100 MHz -- use as default */
+
+ /* Calculate the extended CRTC regs */
+ par->ext_vert_total = (ytotal - 2) >> 8;
+ par->ext_vert_disp_end = (yres - 1) >> 8;
+ par->ext_vert_sync_start = (yres + lower) >> 8;
+ par->ext_vert_blank_start = (yres + lower) >> 8;
+ par->ext_horiz_total = ((xtotal >> 3) - 5) >> 8;
+ par->ext_horiz_blank = (((xres + right) >> 3) & 0x40) >> 6;
+
+ par->interlace_cntl = INTERLACE_DISABLE;
+
+ /* Set the overscan color to 0. (NOTE: This only affects >8bpp mode) */
+ par->atc[VGA_ATC_OVERSCAN] = 0;
+
+ /* Calculate VCLK that most closely matches the requested dot clock */
+ i740_calc_vclk((((u32)1e9) / var->pixclock) * (u32)(1e3), par);
+
+ /* Since we program the clocks ourselves, always use VCLK2. */
+ par->misc |= 0x0C;
+
+ /* Calculate the FIFO Watermark and Burst Length. */
+ par->lmi_fifo_watermark + i740_calc_fifo(par, 1000000 / var->pixclock, bpp);
+
+ return 0;
+}
+
+static int i740fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
+{
+ switch (var->bits_per_pixel) {
+ case 8:
+ var->red.offset = var->green.offset = var->blue.offset = 0;
+ var->red.length = var->green.length = var->blue.length = 8;
+ break;
+ case 16:
+ switch (var->green.length) {
+ default:
+ case 5:
+ var->red.offset = 10;
+ var->green.offset = 5;
+ var->blue.offset = 0;
+ var->red.length = 5;
+ var->green.length = 5;
+ var->blue.length = 5;
+ break;
+ case 6:
+ var->red.offset = 11;
+ var->green.offset = 5;
+ var->blue.offset = 0;
+ var->red.length = var->blue.length = 5;
+ break;
+ }
+ break;
+ case 24:
+ var->red.offset = 16;
+ var->green.offset = 8;
+ var->blue.offset = 0;
+ var->red.length = var->green.length = var->blue.length = 8;
+ break;
+ case 32:
+ var->transp.offset = 24;
+ var->red.offset = 16;
+ var->green.offset = 8;
+ var->blue.offset = 0;
+ var->transp.length = 8;
+ var->red.length = var->green.length = var->blue.length = 8;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ if (var->xres > var->xres_virtual)
+ var->xres_virtual = var->xres;
+
+ if (var->yres > var->yres_virtual)
+ var->yres_virtual = var->yres;
+
+ if (info->monspecs.hfmax && info->monspecs.vfmax &&
+ info->monspecs.dclkmax && fb_validate_mode(var, info) < 0)
+ return -EINVAL;
+
+ return 0;
+}
+
+static void vga_protect(struct i740fb_par *par)
+{
+ /* disable the display */
+ i740outreg_mask(par, VGA_SEQ_I, VGA_SEQ_CLOCK_MODE, 0x20, 0x20);
+
+ i740inb(par, 0x3DA);
+ i740outb(par, VGA_ATT_W, 0x00); /* enable pallete access */
+}
+
+static void vga_unprotect(struct i740fb_par *par)
+{
+ /* reenable display */
+ i740outreg_mask(par, VGA_SEQ_I, VGA_SEQ_CLOCK_MODE, 0, 0x20);
+
+ i740inb(par, 0x3DA);
+ i740outb(par, VGA_ATT_W, 0x20); /* disable pallete access */
+}
+
+static int i740fb_set_par(struct fb_info *info)
+{
+ struct i740fb_par *par = info->par;
+ u32 itemp;
+ int i;
+
+ i = i740fb_decode_var(&info->var, par, info);
+ if (i)
+ return i;
+
+ memset(info->screen_base, 0, info->screen_size);
+
+ vga_protect(par);
+
+ i740outreg(par, XRX, DRAM_EXT_CNTL, DRAM_REFRESH_DISABLE);
+
+ mdelay(1);
+
+ i740outreg(par, XRX, VCLK2_VCO_M, par->video_clk2_m);
+ i740outreg(par, XRX, VCLK2_VCO_N, par->video_clk2_n);
+ i740outreg(par, XRX, VCLK2_VCO_MN_MSBS, par->video_clk2_mn_msbs);
+ i740outreg(par, XRX, VCLK2_VCO_DIV_SEL, par->video_clk2_div_sel);
+
+ i740outreg_mask(par, XRX, PIXPIPE_CONFIG_0,
+ par->pixelpipe_cfg0 & DAC_8_BIT, 0x80);
+
+ i740inb(par, 0x3DA);
+ i740outb(par, 0x3C0, 0x00);
+
+ /* update misc output register */
+ i740outb(par, VGA_MIS_W, par->misc | 0x01);
+
+ /* synchronous reset on */
+ i740outreg(par, VGA_SEQ_I, VGA_SEQ_RESET, 0x01);
+ /* write sequencer registers */
+ i740outreg(par, VGA_SEQ_I, VGA_SEQ_CLOCK_MODE,
+ par->seq[VGA_SEQ_CLOCK_MODE] | 0x20);
+ for (i = 2; i < VGA_SEQ_C; i++)
+ i740outreg(par, VGA_SEQ_I, i, par->seq[i]);
+
+ /* synchronous reset off */
+ i740outreg(par, VGA_SEQ_I, VGA_SEQ_RESET, 0x03);
+
+ /* deprotect CRT registers 0-7 */
+ i740outreg(par, VGA_CRT_IC, VGA_CRTC_V_SYNC_END,
+ par->crtc[VGA_CRTC_V_SYNC_END]);
+
+ /* write CRT registers */
+ for (i = 0; i < VGA_CRT_C; i++)
+ i740outreg(par, VGA_CRT_IC, i, par->crtc[i]);
+
+ /* write graphics controller registers */
+ for (i = 0; i < VGA_GFX_C; i++)
+ i740outreg(par, VGA_GFX_I, i, par->gdc[i]);
+
+ /* write attribute controller registers */
+ for (i = 0; i < VGA_ATT_C; i++) {
+ i740inb(par, VGA_IS1_RC); /* reset flip-flop */
+ i740outb(par, VGA_ATT_IW, i);
+ i740outb(par, VGA_ATT_IW, par->atc[i]);
+ }
+
+ i740inb(par, VGA_IS1_RC);
+ i740outb(par, VGA_ATT_IW, 0x20);
+
+ i740outreg(par, VGA_CRT_IC, EXT_VERT_TOTAL, par->ext_vert_total);
+ i740outreg(par, VGA_CRT_IC, EXT_VERT_DISPLAY, par->ext_vert_disp_end);
+ i740outreg(par, VGA_CRT_IC, EXT_VERT_SYNC_START,
+ par->ext_vert_sync_start);
+ i740outreg(par, VGA_CRT_IC, EXT_VERT_BLANK_START,
+ par->ext_vert_blank_start);
+ i740outreg(par, VGA_CRT_IC, EXT_HORIZ_TOTAL, par->ext_horiz_total);
+ i740outreg(par, VGA_CRT_IC, EXT_HORIZ_BLANK, par->ext_horiz_blank);
+ i740outreg(par, VGA_CRT_IC, EXT_OFFSET, par->ext_offset);
+ i740outreg(par, VGA_CRT_IC, EXT_START_ADDR_HI, par->ext_start_addr_hi);
+ i740outreg(par, VGA_CRT_IC, EXT_START_ADDR, par->ext_start_addr);
+
+ i740outreg_mask(par, VGA_CRT_IC, INTERLACE_CNTL,
+ par->interlace_cntl, INTERLACE_ENABLE);
+ i740outreg_mask(par, XRX, ADDRESS_MAPPING, par->address_mapping, 0x1F);
+ i740outreg_mask(par, XRX, BITBLT_CNTL, par->bitblt_cntl, COLEXP_MODE);
+ i740outreg_mask(par, XRX, DISPLAY_CNTL,
+ par->display_cntl, VGA_WRAP_MODE | GUI_MODE);
+ i740outreg_mask(par, XRX, PIXPIPE_CONFIG_0, par->pixelpipe_cfg0, 0x9B);
+ i740outreg_mask(par, XRX, PIXPIPE_CONFIG_2, par->pixelpipe_cfg2, 0x0C);
+
+ i740outreg(par, XRX, PLL_CNTL, par->pll_cntl);
+
+ i740outreg_mask(par, XRX, PIXPIPE_CONFIG_1,
+ par->pixelpipe_cfg1, DISPLAY_COLOR_MODE);
+
+ itemp = readl(par->regs + FWATER_BLC);
+ itemp &= ~(LMI_BURST_LENGTH | LMI_FIFO_WATERMARK);
+ itemp |= par->lmi_fifo_watermark;
+ writel(itemp, par->regs + FWATER_BLC);
+
+ i740outreg(par, XRX, DRAM_EXT_CNTL, DRAM_REFRESH_60HZ);
+
+ i740outreg_mask(par, MRX, COL_KEY_CNTL_1, 0, BLANK_DISP_OVERLAY);
+ i740outreg_mask(par, XRX, IO_CTNL,
+ par->io_cntl, EXTENDED_ATTR_CNTL | EXTENDED_CRTC_CNTL);
+
+ if (par->pixelpipe_cfg1 != DISPLAY_8BPP_MODE) {
+ i740outb(par, VGA_PEL_MSK, 0xFF);
+ i740outb(par, VGA_PEL_IW, 0x00);
+ for (i = 0; i < 256; i++) {
+ itemp = (par->pixelpipe_cfg0 & DAC_8_BIT) ? i : i >> 2;
+ i740outb(par, VGA_PEL_D, itemp);
+ i740outb(par, VGA_PEL_D, itemp);
+ i740outb(par, VGA_PEL_D, itemp);
+ }
+ }
+
+ /* Wait for screen to stabilize. */
+ mdelay(50);
+ vga_unprotect(par);
+
+ info->fix.line_length + info->var.xres_virtual * info->var.bits_per_pixel / 8;
+ if (info->var.bits_per_pixel = 8)
+ info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
+ else
+ info->fix.visual = FB_VISUAL_TRUECOLOR;
+
+ return 0;
+}
+
+static int i740fb_setcolreg(unsigned regno, unsigned red, unsigned green,
+ unsigned blue, unsigned transp,
+ struct fb_info *info)
+{
+ u32 r, g, b;
+
+ dev_dbg(info->device, "setcolreg: regno: %i, red=%d, green=%d, blue=%d, transp=%d, bpp=%d\n",
+ regno, red, green, blue, transp, info->var.bits_per_pixel);
+
+ switch (info->fix.visual) {
+ case FB_VISUAL_PSEUDOCOLOR:
+ if (regno >= 256)
+ return -EINVAL;
+ i740outb(info->par, VGA_PEL_IW, regno);
+ i740outb(info->par, VGA_PEL_D, red >> 8);
+ i740outb(info->par, VGA_PEL_D, green >> 8);
+ i740outb(info->par, VGA_PEL_D, blue >> 8);
+ break;
+ case FB_VISUAL_TRUECOLOR:
+ if (regno >= 16)
+ return -EINVAL;
+ r = (red >> (16 - info->var.red.length))
+ << info->var.red.offset;
+ b = (blue >> (16 - info->var.blue.length))
+ << info->var.blue.offset;
+ g = (green >> (16 - info->var.green.length))
+ << info->var.green.offset;
+ ((u32 *) info->pseudo_palette)[regno] = r | g | b;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int i740fb_pan_display(struct fb_var_screeninfo *var,
+ struct fb_info *info)
+{
+ struct i740fb_par *par = info->par;
+ u32 base = (var->yoffset * info->var.xres_virtual
+ + (var->xoffset & ~7)) >> 2;
+
+ dev_dbg(info->device, "pan_display: xoffset: %i yoffset: %i base: %i\n",
+ var->xoffset, var->yoffset, base);
+
+ switch (info->var.bits_per_pixel) {
+ case 8:
+ break;
+ case 15:
+ case 16:
+ base *= 2;
+ break;
+ case 24:
+ /*
+ * The last bit does not seem to have any effect on the start
+ * address register in 24bpp mode, so...
+ */
+ base &= 0xFFFFFFFE; /* ...ignore the last bit. */
+ base *= 3;
+ break;
+ case 32:
+ base *= 4;
+ break;
+ }
+
+ par->crtc[VGA_CRTC_START_LO] = base & 0x000000FF;
+ par->crtc[VGA_CRTC_START_HI] = (base & 0x0000FF00) >> 8;
+ par->ext_start_addr_hi = (base & 0x3FC00000) >> 22;
+ par->ext_start_addr + ((base & 0x003F0000) >> 16) | EXT_START_ADDR_ENABLE;
+
+ i740outreg(par, VGA_CRT_IC, VGA_CRTC_START_LO, base & 0x000000FF);
+ i740outreg(par, VGA_CRT_IC, VGA_CRTC_START_HI,
+ (base & 0x0000FF00) >> 8);
+ i740outreg(par, VGA_CRT_IC, EXT_START_ADDR_HI,
+ (base & 0x3FC00000) >> 22);
+ i740outreg(par, VGA_CRT_IC, EXT_START_ADDR,
+ ((base & 0x003F0000) >> 16) | EXT_START_ADDR_ENABLE);
+
+ return 0;
+}
+
+static int i740fb_blank(int blank_mode, struct fb_info *info)
+{
+ struct i740fb_par *par = info->par;
+
+ unsigned char SEQ01;
+ int DPMSSyncSelect;
+
+ switch (blank_mode) {
+ case FB_BLANK_UNBLANK:
+ case FB_BLANK_NORMAL:
+ SEQ01 = 0x00;
+ DPMSSyncSelect = HSYNC_ON | VSYNC_ON;
+ break;
+ case FB_BLANK_VSYNC_SUSPEND:
+ SEQ01 = 0x20;
+ DPMSSyncSelect = HSYNC_ON | VSYNC_OFF;
+ break;
+ case FB_BLANK_HSYNC_SUSPEND:
+ SEQ01 = 0x20;
+ DPMSSyncSelect = HSYNC_OFF | VSYNC_ON;
+ break;
+ case FB_BLANK_POWERDOWN:
+ SEQ01 = 0x20;
+ DPMSSyncSelect = HSYNC_OFF | VSYNC_OFF;
+ break;
+ default:
+ return -EINVAL;
+ }
+ /* Turn the screen on/off */
+ i740outb(par, SRX, 0x01);
+ SEQ01 |= i740inb(par, SRX + 1) & ~0x20;
+ i740outb(par, SRX, 0x01);
+ i740outb(par, SRX + 1, SEQ01);
+
+ /* Set the DPMS mode */
+ i740outreg(par, XRX, DPMS_SYNC_SELECT, DPMSSyncSelect);
+
+ /* Let fbcon do a soft blank for us */
+ return (blank_mode = FB_BLANK_NORMAL) ? 1 : 0;
+}
+
+static struct fb_ops i740fb_ops = {
+ .owner = THIS_MODULE,
+ .fb_open = i740fb_open,
+ .fb_release = i740fb_release,
+ .fb_check_var = i740fb_check_var,
+ .fb_set_par = i740fb_set_par,
+ .fb_setcolreg = i740fb_setcolreg,
+ .fb_blank = i740fb_blank,
+ .fb_pan_display = i740fb_pan_display,
+ .fb_fillrect = cfb_fillrect,
+ .fb_copyarea = cfb_copyarea,
+ .fb_imageblit = cfb_imageblit,
+};
+
+/* ------------------------------------------------------------------------- */
+
+static int __devinit i740fb_probe(struct pci_dev *dev,
+ const struct pci_device_id *ent)
+{
+ struct fb_info *info;
+ struct i740fb_par *par;
+ int ret, tmp;
+ bool found = false;
+ u8 *edid;
+
+ info = framebuffer_alloc(sizeof(struct i740fb_par), &(dev->dev));
+ if (!info) {
+ dev_err(&(dev->dev), "cannot allocate framebuffer\n");
+ return -ENOMEM;
+ }
+
+ par = info->par;
+ mutex_init(&par->open_lock);
+
+ info->var.activate = FB_ACTIVATE_NOW;
+ info->var.bits_per_pixel = 8;
+ info->fbops = &i740fb_ops;
+ info->pseudo_palette = par->pseudo_palette;
+
+ ret = pci_enable_device(dev);
+ if (ret) {
+ dev_err(info->device, "cannot enable PCI device\n");
+ goto err_enable_device;
+ }
+
+ ret = pci_request_regions(dev, info->fix.id);
+ if (ret) {
+ dev_err(info->device, "error requesting regions\n");
+ goto err_request_regions;
+ }
+
+ info->screen_base = pci_ioremap_bar(dev, 0);
+ if (!info->screen_base) {
+ dev_err(info->device, "error remapping base\n");
+ ret = -ENOMEM;
+ goto err_ioremap_1;
+ }
+
+ par->regs = pci_ioremap_bar(dev, 1);
+ if (!par->regs) {
+ dev_err(info->device, "error remapping MMIO\n");
+ ret = -ENOMEM;
+ goto err_ioremap_2;
+ }
+
+ /* detect memory size */
+ if ((i740inreg(par, XRX, DRAM_ROW_TYPE) & DRAM_ROW_1)
+ = DRAM_ROW_1_SDRAM)
+ i740outb(par, XRX, DRAM_ROW_BNDRY_1);
+ else
+ i740outb(par, XRX, DRAM_ROW_BNDRY_0);
+ info->screen_size = i740inb(par, XRX + 1) * 1024 * 1024;
+ /* detect memory type */
+ tmp = i740inreg(par, XRX, DRAM_ROW_CNTL_LO);
+ par->has_sgram = !((tmp & DRAM_RAS_TIMING) ||
+ (tmp & DRAM_RAS_PRECHARGE));
+
+ printk(KERN_INFO "fb%d: Intel740 on %s, %ld KB %s\n", info->node,
+ pci_name(dev), info->screen_size >> 10,
+ par->has_sgram ? "SGRAM" : "SDRAM");
+
+ info->fix = i740fb_fix;
+ info->fix.mmio_start = pci_resource_start(dev, 1);
+ info->fix.mmio_len = pci_resource_len(dev, 1);
+ info->fix.smem_start = pci_resource_start(dev, 0);
+ info->fix.smem_len = info->screen_size;
+ info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN;
+
+ if (i740fb_setup_ddc_bus(info) = 0) {
+ par->ddc_registered = true;
+ edid = fb_ddc_read(&par->ddc_adapter);
+ if (edid) {
+ fb_edid_to_monspecs(edid, &info->monspecs);
+ kfree(edid);
+ if (!info->monspecs.modedb)
+ dev_err(info->device,
+ "error getting mode database\n");
+ else {
+ const struct fb_videomode *m;
+
+ fb_videomode_to_modelist(
+ info->monspecs.modedb,
+ info->monspecs.modedb_len,
+ &info->modelist);
+ m = fb_find_best_display(&info->monspecs,
+ &info->modelist);
+ if (m) {
+ fb_videomode_to_var(&info->var, m);
+ /* fill all other info->var's fields */
+ if (!i740fb_check_var(&info->var, info))
+ found = true;
+ }
+ }
+ }
+ }
+
+ if (!mode_option && !found)
+ mode_option = "640x480-8@60";
+
+ if (mode_option) {
+ ret = fb_find_mode(&info->var, info, mode_option,
+ info->monspecs.modedb,
+ info->monspecs.modedb_len,
+ NULL, info->var.bits_per_pixel);
+ if (!ret || ret = 4) {
+ dev_err(info->device, "mode %s not found\n",
+ mode_option);
+ ret = -EINVAL;
+ }
+ }
+
+ fb_destroy_modedb(info->monspecs.modedb);
+ info->monspecs.modedb = NULL;
+
+ /* maximize virtual vertical size for fast scrolling */
+ info->var.yres_virtual = info->fix.smem_len * 8 /
+ (info->var.bits_per_pixel * info->var.xres_virtual);
+
+ if (ret = -EINVAL)
+ goto err_find_mode;
+
+ ret = fb_alloc_cmap(&info->cmap, 256, 0);
+ if (ret) {
+ dev_err(info->device, "cannot allocate colormap\n");
+ goto err_alloc_cmap;
+ }
+
+ ret = register_framebuffer(info);
+ if (ret) {
+ dev_err(info->device, "error registering framebuffer\n");
+ goto err_reg_framebuffer;
+ }
+
+ printk(KERN_INFO "fb%d: %s frame buffer device\n",
+ info->node, info->fix.id);
+ pci_set_drvdata(dev, info);
+#ifdef CONFIG_MTRR
+ if (mtrr) {
+ par->mtrr_reg = -1;
+ par->mtrr_reg = mtrr_add(info->fix.smem_start,
+ info->fix.smem_len, MTRR_TYPE_WRCOMB, 1);
+ }
+#endif
+ return 0;
+
+err_reg_framebuffer:
+ fb_dealloc_cmap(&info->cmap);
+err_alloc_cmap:
+err_find_mode:
+ if (par->ddc_registered)
+ i2c_del_adapter(&par->ddc_adapter);
+ pci_iounmap(dev, par->regs);
+err_ioremap_2:
+ pci_iounmap(dev, info->screen_base);
+err_ioremap_1:
+ pci_release_regions(dev);
+err_request_regions:
+/* pci_disable_device(dev); */
+err_enable_device:
+ framebuffer_release(info);
+ return ret;
+}
+
+static void __devexit i740fb_remove(struct pci_dev *dev)
+{
+ struct fb_info *info = pci_get_drvdata(dev);
+
+ if (info) {
+#ifdef CONFIG_MTRR
+ struct i740fb_par *par = info->par;
+
+ if (par->mtrr_reg >= 0) {
+ mtrr_del(par->mtrr_reg, 0, 0);
+ par->mtrr_reg = -1;
+ }
+#endif
+ unregister_framebuffer(info);
+ fb_dealloc_cmap(&info->cmap);
+ if (par->ddc_registered)
+ i2c_del_adapter(&par->ddc_adapter);
+ pci_iounmap(dev, par->regs);
+ pci_iounmap(dev, info->screen_base);
+ pci_release_regions(dev);
+/* pci_disable_device(dev); */
+ pci_set_drvdata(dev, NULL);
+ framebuffer_release(info);
+ }
+}
+
+#ifdef CONFIG_PM
+static int i740fb_suspend(struct pci_dev *dev, pm_message_t state)
+{
+ struct fb_info *info = pci_get_drvdata(dev);
+ struct i740fb_par *par = info->par;
+
+ /* don't disable console during hibernation and wakeup from it */
+ if (state.event = PM_EVENT_FREEZE || state.event = PM_EVENT_PRETHAW)
+ return 0;
+
+ console_lock();
+ mutex_lock(&(par->open_lock));
+
+ /* do nothing if framebuffer is not active */
+ if (par->ref_count = 0) {
+ mutex_unlock(&(par->open_lock));
+ console_unlock();
+ return 0;
+ }
+
+ fb_set_suspend(info, 1);
+
+ pci_save_state(dev);
+ pci_disable_device(dev);
+ pci_set_power_state(dev, pci_choose_state(dev, state));
+
+ mutex_unlock(&(par->open_lock));
+ console_unlock();
+
+ return 0;
+}
+
+static int i740fb_resume(struct pci_dev *dev)
+{
+ struct fb_info *info = pci_get_drvdata(dev);
+ struct i740fb_par *par = info->par;
+
+ console_lock();
+ mutex_lock(&(par->open_lock));
+
+ if (par->ref_count = 0)
+ goto fail;
+
+ pci_set_power_state(dev, PCI_D0);
+ pci_restore_state(dev);
+ if (pci_enable_device(dev))
+ goto fail;
+
+ i740fb_set_par(info);
+ fb_set_suspend(info, 0);
+
+fail:
+ mutex_unlock(&(par->open_lock));
+ console_unlock();
+ return 0;
+}
+#else
+#define i740fb_suspend NULL
+#define i740fb_resume NULL
+#endif /* CONFIG_PM */
+
+#define I740_ID_PCI 0x00d1
+#define I740_ID_AGP 0x7800
+
+static DEFINE_PCI_DEVICE_TABLE(i740fb_id_table) = {
+ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, I740_ID_PCI) },
+ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, I740_ID_AGP) },
+ { 0 }
+};
+MODULE_DEVICE_TABLE(pci, i740fb_id_table);
+
+static struct pci_driver i740fb_driver = {
+ .name = "i740fb",
+ .id_table = i740fb_id_table,
+ .probe = i740fb_probe,
+ .remove = __devexit_p(i740fb_remove),
+ .suspend = i740fb_suspend,
+ .resume = i740fb_resume,
+};
+
+#ifndef MODULE
+static int __init i740fb_setup(char *options)
+{
+ char *opt;
+
+ if (!options || !*options)
+ return 0;
+
+ while ((opt = strsep(&options, ",")) != NULL) {
+ if (!*opt)
+ continue;
+#ifdef CONFIG_MTRR
+ else if (!strncmp(opt, "mtrr:", 5))
+ mtrr = simple_strtoul(opt + 5, NULL, 0);
+#endif
+ else
+ mode_option = opt;
+ }
+
+ return 0;
+}
+#endif
+
+int __init i740fb_init(void)
+{
+#ifndef MODULE
+ char *option = NULL;
+
+ if (fb_get_options("i740fb", &option))
+ return -ENODEV;
+ i740fb_setup(option);
+#endif
+
+ return pci_register_driver(&i740fb_driver);
+}
+
+static void __exit i740fb_exit(void)
+{
+ pci_unregister_driver(&i740fb_driver);
+}
+
+module_init(i740fb_init);
+module_exit(i740fb_exit);
+
+MODULE_AUTHOR("(c) 2011 Ondrej Zary <linux@rainbow-software.org>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("fbdev driver for Intel740");
+
+module_param(mode_option, charp, 0444);
+MODULE_PARM_DESC(mode_option, "Default video mode ('640x480-8@60', etc)");
+
+#ifdef CONFIG_MTRR
+module_param(mtrr, int, 0444);
+MODULE_PARM_DESC(mtrr, "Enable write-combining with MTRR (1=enable, 0=disable, default=1)");
+#endif
--- /dev/null 2012-01-24 00:06:39.330222901 +0100
+++ linux-3.2.1/drivers/video/i740_reg.h 2012-01-23 22:55:57.000000000 +0100
@@ -0,0 +1,309 @@
+/**************************************************************************
+
+Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sub license, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <kevin@precisioninsight.com>
+ */
+
+/* I/O register offsets */
+#define SRX VGA_SEQ_I
+#define GRX VGA_GFX_I
+#define ARX VGA_ATT_IW
+#define XRX 0x3D6
+#define MRX 0x3D2
+
+/* VGA Color Palette Registers */
+#define DACMASK 0x3C6
+#define DACSTATE 0x3C7
+#define DACRX 0x3C7
+#define DACWX 0x3C8
+#define DACDATA 0x3C9
+
+/* CRT Controller Registers (CRX) */
+#define START_ADDR_HI 0x0C
+#define START_ADDR_LO 0x0D
+#define VERT_SYNC_END 0x11
+#define EXT_VERT_TOTAL 0x30
+#define EXT_VERT_DISPLAY 0x31
+#define EXT_VERT_SYNC_START 0x32
+#define EXT_VERT_BLANK_START 0x33
+#define EXT_HORIZ_TOTAL 0x35
+#define EXT_HORIZ_BLANK 0x39
+#define EXT_START_ADDR 0x40
+#define EXT_START_ADDR_ENABLE 0x80
+#define EXT_OFFSET 0x41
+#define EXT_START_ADDR_HI 0x42
+#define INTERLACE_CNTL 0x70
+#define INTERLACE_ENABLE 0x80
+#define INTERLACE_DISABLE 0x00
+
+/* Miscellaneous Output Register */
+#define MSR_R 0x3CC
+#define MSR_W 0x3C2
+#define IO_ADDR_SELECT 0x01
+
+#define MDA_BASE 0x3B0
+#define CGA_BASE 0x3D0
+
+/* System Configuration Extension Registers (XRX) */
+#define IO_CTNL 0x09
+#define EXTENDED_ATTR_CNTL 0x02
+#define EXTENDED_CRTC_CNTL 0x01
+
+#define ADDRESS_MAPPING 0x0A
+#define PACKED_MODE_ENABLE 0x04
+#define LINEAR_MODE_ENABLE 0x02
+#define PAGE_MAPPING_ENABLE 0x01
+
+#define BITBLT_CNTL 0x20
+#define COLEXP_MODE 0x30
+#define COLEXP_8BPP 0x00
+#define COLEXP_16BPP 0x10
+#define COLEXP_24BPP 0x20
+#define COLEXP_RESERVED 0x30
+#define CHIP_RESET 0x02
+#define BITBLT_STATUS 0x01
+
+#define DISPLAY_CNTL 0x40
+#define VGA_WRAP_MODE 0x02
+#define VGA_WRAP_AT_256KB 0x00
+#define VGA_NO_WRAP 0x02
+#define GUI_MODE 0x01
+#define STANDARD_VGA_MODE 0x00
+#define HIRES_MODE 0x01
+
+#define DRAM_ROW_TYPE 0x50
+#define DRAM_ROW_0 0x07
+#define DRAM_ROW_0_SDRAM 0x00
+#define DRAM_ROW_0_EMPTY 0x07
+#define DRAM_ROW_1 0x38
+#define DRAM_ROW_1_SDRAM 0x00
+#define DRAM_ROW_1_EMPTY 0x38
+#define DRAM_ROW_CNTL_LO 0x51
+#define DRAM_CAS_LATENCY 0x10
+#define DRAM_RAS_TIMING 0x08
+#define DRAM_RAS_PRECHARGE 0x04
+#define DRAM_ROW_CNTL_HI 0x52
+#define DRAM_EXT_CNTL 0x53
+#define DRAM_REFRESH_RATE 0x03
+#define DRAM_REFRESH_DISABLE 0x00
+#define DRAM_REFRESH_60HZ 0x01
+#define DRAM_REFRESH_FAST_TEST 0x02
+#define DRAM_REFRESH_RESERVED 0x03
+#define DRAM_TIMING 0x54
+#define DRAM_ROW_BNDRY_0 0x55
+#define DRAM_ROW_BNDRY_1 0x56
+
+#define DPMS_SYNC_SELECT 0x61
+#define VSYNC_CNTL 0x08
+#define VSYNC_ON 0x00
+#define VSYNC_OFF 0x08
+#define HSYNC_CNTL 0x02
+#define HSYNC_ON 0x00
+#define HSYNC_OFF 0x02
+
+#define PIXPIPE_CONFIG_0 0x80
+#define DAC_8_BIT 0x80
+#define DAC_6_BIT 0x00
+#define HW_CURSOR_ENABLE 0x10
+#define EXTENDED_PALETTE 0x01
+
+#define PIXPIPE_CONFIG_1 0x81
+#define DISPLAY_COLOR_MODE 0x0F
+#define DISPLAY_VGA_MODE 0x00
+#define DISPLAY_8BPP_MODE 0x02
+#define DISPLAY_15BPP_MODE 0x04
+#define DISPLAY_16BPP_MODE 0x05
+#define DISPLAY_24BPP_MODE 0x06
+#define DISPLAY_32BPP_MODE 0x07
+
+#define PIXPIPE_CONFIG_2 0x82
+#define DISPLAY_GAMMA_ENABLE 0x08
+#define DISPLAY_GAMMA_DISABLE 0x00
+#define OVERLAY_GAMMA_ENABLE 0x04
+#define OVERLAY_GAMMA_DISABLE 0x00
+
+#define CURSOR_CONTROL 0xA0
+#define CURSOR_ORIGIN_SCREEN 0x00
+#define CURSOR_ORIGIN_DISPLAY 0x10
+#define CURSOR_MODE 0x07
+#define CURSOR_MODE_DISABLE 0x00
+#define CURSOR_MODE_32_4C_AX 0x01
+#define CURSOR_MODE_128_2C 0x02
+#define CURSOR_MODE_128_1C 0x03
+#define CURSOR_MODE_64_3C 0x04
+#define CURSOR_MODE_64_4C_AX 0x05
+#define CURSOR_MODE_64_4C 0x06
+#define CURSOR_MODE_RESERVED 0x07
+#define CURSOR_BASEADDR_LO 0xA2
+#define CURSOR_BASEADDR_HI 0xA3
+#define CURSOR_X_LO 0xA4
+#define CURSOR_X_HI 0xA5
+#define CURSOR_X_POS 0x00
+#define CURSOR_X_NEG 0x80
+#define CURSOR_Y_LO 0xA6
+#define CURSOR_Y_HI 0xA7
+#define CURSOR_Y_POS 0x00
+#define CURSOR_Y_NEG 0x80
+
+#define VCLK2_VCO_M 0xC8
+#define VCLK2_VCO_N 0xC9
+#define VCLK2_VCO_MN_MSBS 0xCA
+#define VCO_N_MSBS 0x30
+#define VCO_M_MSBS 0x03
+#define VCLK2_VCO_DIV_SEL 0xCB
+#define POST_DIV_SELECT 0x70
+#define POST_DIV_1 0x00
+#define POST_DIV_2 0x10
+#define POST_DIV_4 0x20
+#define POST_DIV_8 0x30
+#define POST_DIV_16 0x40
+#define POST_DIV_32 0x50
+#define VCO_LOOP_DIV_BY_4M 0x00
+#define VCO_LOOP_DIV_BY_16M 0x04
+#define REF_CLK_DIV_BY_5 0x02
+#define REF_DIV_4 0x00
+#define REF_DIV_1 0x01
+
+#define PLL_CNTL 0xCE
+#define PLL_MEMCLK_SEL 0x03
+#define PLL_MEMCLK__66667KHZ 0x00
+#define PLL_MEMCLK__75000KHZ 0x01
+#define PLL_MEMCLK__88889KHZ 0x02
+#define PLL_MEMCLK_100000KHZ 0x03
+
+/* Multimedia Extension Registers (MRX) */
+#define ACQ_CNTL_1 0x02
+#define ACQ_CNTL_2 0x03
+#define FRAME_CAP_MODE 0x01
+#define CONT_CAP_MODE 0x00
+#define SINGLE_CAP_MODE 0x01
+#define ACQ_CNTL_3 0x04
+#define COL_KEY_CNTL_1 0x3C
+#define BLANK_DISP_OVERLAY 0x20
+
+/* FIFOs */
+#define LP_FIFO 0x1000
+#define HP_FIFO 0x2000
+#define INSTPNT 0x3040
+#define LP_FIFO_COUNT 0x3040
+#define HP_FIFO_COUNT 0x3041
+
+/* FIFO Commands */
+#define CLIENT 0xE0000000
+#define CLIENT_2D 0x60000000
+
+/* Command Parser Mode Register */
+#define COMPARS 0x3038
+#define TWO_D_INST_DISABLE 0x08
+#define THREE_D_INST_DISABLE 0x04
+#define STATE_VAR_UPDATE_DISABLE 0x02
+#define PAL_STIP_DISABLE 0x01
+
+/* Interrupt Control Registers */
+#define IER 0x3030
+#define IIR 0x3032
+#define IMR 0x3034
+#define ISR 0x3036
+#define VMIINTB_EVENT 0x2000
+#define GPIO4_INT 0x1000
+#define DISP_FLIP_EVENT 0x0800
+#define DVD_PORT_DMA 0x0400
+#define DISP_VBLANK 0x0200
+#define FIFO_EMPTY_DMA_DONE 0x0100
+#define INST_PARSER_ERROR 0x0080
+#define USER_DEFINED 0x0040
+#define BREAKPOINT 0x0020
+#define DISP_HORIZ_COUNT 0x0010
+#define DISP_VSYNC 0x0008
+#define CAPTURE_HORIZ_COUNT 0x0004
+#define CAPTURE_VSYNC 0x0002
+#define THREE_D_PIPE_FLUSHED 0x0001
+
+/* FIFO Watermark and Burst Length Control Register */
+#define FWATER_BLC 0x00006000
+#define LMI_BURST_LENGTH 0x7F000000
+#define LMI_FIFO_WATERMARK 0x003F0000
+#define AGP_BURST_LENGTH 0x00007F00
+#define AGP_FIFO_WATERMARK 0x0000003F
+
+/* BitBLT Registers */
+#define SRC_DST_PITCH 0x00040000
+#define DST_PITCH 0x1FFF0000
+#define SRC_PITCH 0x00001FFF
+#define COLEXP_BG_COLOR 0x00040004
+#define COLEXP_FG_COLOR 0x00040008
+#define MONO_SRC_CNTL 0x0004000C
+#define MONO_USE_COLEXP 0x00000000
+#define MONO_USE_SRCEXP 0x08000000
+#define MONO_DATA_ALIGN 0x07000000
+#define MONO_BIT_ALIGN 0x01000000
+#define MONO_BYTE_ALIGN 0x02000000
+#define MONO_WORD_ALIGN 0x03000000
+#define MONO_DWORD_ALIGN 0x04000000
+#define MONO_QWORD_ALIGN 0x05000000
+#define MONO_SRC_INIT_DSCRD 0x003F0000
+#define MONO_SRC_RIGHT_CLIP 0x00003F00
+#define MONO_SRC_LEFT_CLIP 0x0000003F
+#define BITBLT_CONTROL 0x00040010
+#define BLTR_STATUS 0x80000000
+#define DYN_DEPTH 0x03000000
+#define DYN_DEPTH_8BPP 0x00000000
+#define DYN_DEPTH_16BPP 0x01000000
+#define DYN_DEPTH_24BPP 0x02000000
+#define DYN_DEPTH_32BPP 0x03000000 /* Unimplemented on the i740 */
+#define DYN_DEPTH_ENABLE 0x00800000
+#define PAT_VERT_ALIGN 0x00700000
+#define SOLID_PAT_SELECT 0x00080000
+#define PAT_IS_IN_COLOR 0x00000000
+#define PAT_IS_MONO 0x00040000
+#define MONO_PAT_TRANSP 0x00020000
+#define COLOR_TRANSP_ROP 0x00000000
+#define COLOR_TRANSP_DST 0x00008000
+#define COLOR_TRANSP_EQ 0x00000000
+#define COLOR_TRANSP_NOT_EQ 0x00010000
+#define COLOR_TRANSP_ENABLE 0x00004000
+#define MONO_SRC_TRANSP 0x00002000
+#define SRC_IS_IN_COLOR 0x00000000
+#define SRC_IS_MONO 0x00001000
+#define SRC_USE_SRC_ADDR 0x00000000
+#define SRC_USE_BLTDATA 0x00000400
+#define BLT_TOP_TO_BOT 0x00000000
+#define BLT_BOT_TO_TOP 0x00000200
+#define BLT_LEFT_TO_RIGHT 0x00000000
+#define BLT_RIGHT_TO_LEFT 0x00000100
+#define BLT_ROP 0x000000FF
+#define BLT_PAT_ADDR 0x00040014
+#define BLT_SRC_ADDR 0x00040018
+#define BLT_DST_ADDR 0x0004001C
+#define BLT_DST_H_W 0x00040020
+#define BLT_DST_HEIGHT 0x1FFF0000
+#define BLT_DST_WIDTH 0x00001FFF
+#define SRCEXP_BG_COLOR 0x00040024
+#define SRCEXP_FG_COLOR 0x00040028
+#define BLTDATA 0x00050000
--
Ondrej Zary
^ permalink raw reply
* [PATCH v2] ARM: OMAP1: ams-delta: clean up init data section assignments
From: Janusz Krzysztofik @ 2012-02-10 16:48 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1580046.EEGIFOPvyy@vclass>
The main purpose of this patch is to fix several section mismatch
warnings from the board file and a few board specific drivers,
introduced with recent Amstrad Delta patch series, some of them rising
up only when building with CONFIG_MODULES not set.
While being at it, section tagging of all init data found in the board
file have been revised and hopefully corrected and/or optimized.
Created and tested on top of current linux-omap/omap1, commit
967809bd7faf71ddc29c8081e0f21db8b201a0f4.
Signed-off-by: Janusz Krzysztofik <jkrzyszt@tis.icnet.pl>
---
arch/arm/mach-omap1/board-ams-delta.c | 18 +++++++++---------
drivers/input/serio/ams_delta_serio.c | 2 +-
drivers/mtd/nand/ams-delta.c | 2 +-
drivers/video/omap/lcd_ams_delta.c | 2 +-
4 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/arch/arm/mach-omap1/board-ams-delta.c b/arch/arm/mach-omap1/board-ams-delta.c
index 87b1303..bfe6fd1 100644
--- a/arch/arm/mach-omap1/board-ams-delta.c
+++ b/arch/arm/mach-omap1/board-ams-delta.c
@@ -150,7 +150,7 @@ static struct map_desc ams_delta_io_desc[] __initdata = {
}
};
-static struct omap_lcd_config ams_delta_lcd_config = {
+static struct omap_lcd_config ams_delta_lcd_config __initdata = {
.ctrl_name = "internal",
};
@@ -167,7 +167,7 @@ static struct omap_board_config_kernel ams_delta_config[] __initdata = {
#define LATCH1_GPIO_BASE 232
#define LATCH1_NGPIO 8
-static struct resource latch1_resources[] __initconst = {
+static struct resource latch1_resources[] = {
[0] = {
.name = "dat",
.start = LATCH1_PHYS,
@@ -176,7 +176,7 @@ static struct resource latch1_resources[] __initconst = {
},
};
-static struct bgpio_pdata latch1_pdata __initconst = {
+static struct bgpio_pdata latch1_pdata = {
.base = LATCH1_GPIO_BASE,
.ngpio = LATCH1_NGPIO,
};
@@ -191,7 +191,7 @@ static struct platform_device latch1_gpio_device = {
},
};
-static struct resource latch2_resources[] __initconst = {
+static struct resource latch2_resources[] = {
[0] = {
.name = "dat",
.start = LATCH2_PHYS,
@@ -200,7 +200,7 @@ static struct resource latch2_resources[] __initconst = {
},
};
-static struct bgpio_pdata latch2_pdata __initconst = {
+static struct bgpio_pdata latch2_pdata = {
.base = AMS_DELTA_LATCH2_GPIO_BASE,
.ngpio = AMS_DELTA_LATCH2_NGPIO,
};
@@ -215,7 +215,7 @@ static struct platform_device latch2_gpio_device = {
},
};
-static struct gpio latch_gpios[] __initconst = {
+static const struct gpio latch_gpios[] __initconst = {
{
.gpio = LATCH1_GPIO_BASE + 6,
.flags = GPIOF_OUT_INIT_LOW,
@@ -322,7 +322,7 @@ static struct platform_device ams_delta_lcd_device = {
.id = -1,
};
-static struct gpio_led gpio_leds[] __initconst = {
+static const struct gpio_led gpio_leds[] __initconst = {
{
.name = "camera",
.gpio = LATCH1_GPIO_BASE + 0,
@@ -358,7 +358,7 @@ static struct gpio_led gpio_leds[] __initconst = {
},
};
-static struct gpio_led_platform_data leds_pdata __initconst = {
+static const struct gpio_led_platform_data leds_pdata __initconst = {
.leds = gpio_leds,
.num_leds = ARRAY_SIZE(gpio_leds),
};
@@ -415,7 +415,7 @@ static struct platform_device *ams_delta_devices[] __initdata = {
&ams_delta_camera_device,
};
-static struct platform_device *late_devices[] __initconst = {
+static struct platform_device *late_devices[] __initdata = {
&ams_delta_nand_device,
&ams_delta_lcd_device,
};
diff --git a/drivers/input/serio/ams_delta_serio.c b/drivers/input/serio/ams_delta_serio.c
index 0571e2e..bd5b10e 100644
--- a/drivers/input/serio/ams_delta_serio.c
+++ b/drivers/input/serio/ams_delta_serio.c
@@ -103,7 +103,7 @@ static void ams_delta_serio_close(struct serio *serio)
gpio_set_value(AMS_DELTA_GPIO_PIN_KEYBRD_PWR, 0);
}
-static struct gpio ams_delta_gpios[] __initconst_or_module = {
+static const struct gpio ams_delta_gpios[] __initconst_or_module = {
{
.gpio = AMS_DELTA_GPIO_PIN_KEYBRD_DATA,
.flags = GPIOF_DIR_IN,
diff --git a/drivers/mtd/nand/ams-delta.c b/drivers/mtd/nand/ams-delta.c
index 85934dc..7341695 100644
--- a/drivers/mtd/nand/ams-delta.c
+++ b/drivers/mtd/nand/ams-delta.c
@@ -145,7 +145,7 @@ static int ams_delta_nand_ready(struct mtd_info *mtd)
return gpio_get_value(AMS_DELTA_GPIO_PIN_NAND_RB);
}
-static struct gpio _mandatory_gpio[] __initconst_or_module = {
+static const struct gpio _mandatory_gpio[] = {
{
.gpio = AMS_DELTA_GPIO_PIN_NAND_NCE,
.flags = GPIOF_OUT_INIT_HIGH,
diff --git a/drivers/video/omap/lcd_ams_delta.c b/drivers/video/omap/lcd_ams_delta.c
index 0e71e28..d3a3113 100644
--- a/drivers/video/omap/lcd_ams_delta.c
+++ b/drivers/video/omap/lcd_ams_delta.c
@@ -99,7 +99,7 @@ static struct lcd_ops ams_delta_lcd_ops = {
/* omapfb panel section */
-static struct gpio _gpios[] __initconst_or_module = {
+static const struct gpio _gpios[] = {
{
.gpio = AMS_DELTA_GPIO_PIN_LCD_VBLEN,
.flags = GPIOF_OUT_INIT_LOW,
--
1.7.3.4
^ permalink raw reply related
* Re: [PATCH] ARM: OMAP1: ams-delta: correct init data section assignments
From: Janusz Krzysztofik @ 2012-02-10 16:31 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20120209144853.GU1275@n2100.arm.linux.org.uk>
On Thursday 09 of February 2012 14:48:53 Russell King - ARM Linux wrote:
> There is no optimisation to adding __refdata to stuff. That's screaming
> that you have lots of bugs here.
Thanks for your teaching. I find those aspects not very exhaustively documented
under Documentation/, so any hints are much appreciated.
> > -static struct map_desc ams_delta_io_desc[] __initdata = {
> > +static struct map_desc ams_delta_io_desc[] __initconst = {
>
> You're not making this comst so don't change it to __initconst.
OK, however, I think there must be a bug in gcc, otherwise it should probably
never accept such wrong constructs, while sometimes it does (not only mine,
see [1]).
> > -static struct omap_lcd_config ams_delta_lcd_config = {
> > +static struct omap_lcd_config ams_delta_lcd_config __initconst = {
>
> This change probably adds a bug. Are you sure this will never be used
> outside init context?
I may be wrong, but before I've changed this, and now once again, I've verified
that a copy of this data is made inside __init omap_init_fb() by means of a
structure assignment operation.
> > -static struct omap_usb_config ams_delta_usb_config __initdata = {
> > +static struct omap_usb_config ams_delta_usb_config __initdata_or_module
> > = {
> Even if you don't have modules enabled, have you checked whether the
> driver can be bound and unbound via
> /sys/bus/platform/driver/<name>/{bind,unbind} ?
No, I didn't even think of it, I am afraid.
> I suspect this is a bug.
Indeed, that data is not copied on init, only pointed to, moreover, the
ohci-omap driver provides bind/unbind opearations.
BTW, what are those bind/unbind operations intended for in case of a driver
dedicated to a non-hotplugable SoC hardware exclusively?
> > -static struct resource ams_delta_nand_resources[] = {
> > +static struct resource ams_delta_nand_resources[] __initconst_or_module
> > = {
> This change definitely adds a bug. The resources are _used_ _all_ _the_
> _time_ _the_ _device_ _is_ _registered_. Try catting /proc/iomem after
> boot.
Indeed, I didn't think of that. I expected that standard init data of only
those devices which can be actually found during init should be copied for
runtime access, then all (found and not found) dropped instead of keeping them
all in memory for only some of them being actually used.
> > -static struct i2c_board_info ams_delta_camera_board_info[] = {
> > +static struct i2c_board_info __initconst_or_module
> > +ams_delta_camera_board_info[] = {
>
> No. It's
>
> static struct foo blah[] __whatever_init_attribute
>
> not
>
> static struct foo __whatever_init_attribute blah[]
>
> I've no idea where this fucked idea came from but it's something that's
> wasting a lot of review time with complaints like this about it.
My bad, I blindly copied that pattern from another broken example under
arch/arm instead of examining the docs carefully enough.
> > -static struct soc_camera_link ams_delta_iclink = {
> > +static struct soc_camera_link ams_delta_iclink __initconst_or_module > > {
>
> Probably buggy.
Indeed. Even if the soc-camera-pdrv driver doesn't support
unbindind/rebinding, it doesn't seem to make a copy of that platform data,
only stores a pointer to it for runtime access, wich I missed.
> > -static struct platform_device *ams_delta_devices[] __initdata = {
> > +static struct platform_device *ams_delta_devices[] __initconst = {
>
> Missing const. If you can't const it, don't put it in __initconst.
I gave up trying to use both const and __initconst together after my gcc-4.2.4
(and not only mine, see [1], [2]) refused to accept such constructs a few
times. Now I see that this false reporting may probably happen in presence of other
incorrect uses of __initconst without const or __initdata with const.
Hopefully better patches will follow.
Thanks,
Janusz
[1] http://lists.infradead.org/pipermail/linux-arm-kernel/2011-August/062421.html
[2] http://permalink.gmane.org/gmane.linux.kernel.commits.head/202285
^ permalink raw reply
* [PATCH v2] OMAPDSS: HACK: Ensure DSS clock domain gets out of idle when HDMI is enabled
From: Archit Taneja @ 2012-02-10 6:27 UTC (permalink / raw)
To: linux-omap; +Cc: tomi.valkeinen, linux, linux-fbdev, Archit Taneja
For DSS clock domain to transition from idle to active state. It's necessary
to enable the optional clock DSS_FCLK before we enable the module using the
MODULEMODE bits in the clock domain's CM_DSS_DSS_CLKCTRL register.
This sequence was not followed correctly for the 'dss_hdmi' hwmod and it led
to DSS clock domain not getting out of idle when pm_runtime_get_sync() was
called for hdmi's platform device.
Since the clock domain failed to change it's state to active, the hwmod code
disables any clocks it had enabled before for this hwmod. This led to the clock
'dss_48mhz_clk' gettind disabled.
When hdmi's runtime_resume() op is called, the call to dss_runtime_get()
correctly enables the DSS clock domain this time. However, the clock
'dss_48mhz_clk' is needed for HDMI's PHY to function correctly. Since it was
disabled previously, the driver fails when it tries to enable HDMI's PHY.
Fix this for now by ensuring that dss_runtime_get() is called before we call
pm_runtime_get_sync() for hdmi's platform device. A correct fix for later would
be to modify the DSS related hwmod's mainclks, and also some changes in how
opt clocks are handled in the DSS driver.
This fixes the issue of HDMI not working when it's the default display. The
issue is not seen if any other display is already enabled as the first display
would have correctly enabled the DSS clockdomain.
Signed-off-by: Archit Taneja <archit@ti.com>
---
Changes in v2:
- Rewrite an unclear paragraph in the commit message
- Add comments mentioning that this is a hack
drivers/video/omap2/dss/hdmi.c | 24 +++++++++++++++++++++++-
1 files changed, 23 insertions(+), 1 deletions(-)
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
index d7aa3b0..a36b934 100644
--- a/drivers/video/omap2/dss/hdmi.c
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -165,9 +165,25 @@ static int hdmi_runtime_get(void)
DSSDBG("hdmi_runtime_get\n");
+ /*
+ * HACK: Add dss_runtime_get() to ensure DSS clock domain is enabled.
+ * This should be removed later.
+ */
+ r = dss_runtime_get();
+ if (r < 0)
+ goto err_get_dss;
+
r = pm_runtime_get_sync(&hdmi.pdev->dev);
WARN_ON(r < 0);
- return r < 0 ? r : 0;
+ if (r < 0)
+ goto err_get_hdmi;
+
+ return 0;
+
+err_get_hdmi:
+ dss_runtime_put();
+err_get_dss:
+ return r;
}
static void hdmi_runtime_put(void)
@@ -178,6 +194,12 @@ static void hdmi_runtime_put(void)
r = pm_runtime_put_sync(&hdmi.pdev->dev);
WARN_ON(r < 0);
+
+ /*
+ * HACK: This is added to complement the dss_runtime_get() call in
+ * hdmi_runtime_get(). This should be removed later.
+ */
+ dss_runtime_put();
}
int hdmi_init_display(struct omap_dss_device *dssdev)
--
1.7.5.4
^ permalink raw reply related
* Re: [PATCH] OMAPDSS: HACK: Ensure DSS clock domain gets out of idle when HDMI is enabled
From: Archit Taneja @ 2012-02-10 6:17 UTC (permalink / raw)
To: Tomi Valkeinen; +Cc: Archit Taneja, linux-omap, linux, linux-fbdev
In-Reply-To: <1328788924.1909.67.camel@deskari>
On Thursday 09 February 2012 05:32 PM, Tomi Valkeinen wrote:
> Hi,
>
> On Thu, 2012-02-09 at 12:14 +0530, Archit Taneja wrote:
>> For DSS clock domain to transition from idle to active state, it's necessary
>> to enable the optional clock DSS_FCLK before we enable the module using the
>> MODULEMODE bits in the DSS clock domain's CM_DSS_DSS_CLKCTRL register.
>>
>> This sequence was not followed correctly for the 'dss_hdmi' hwmod and it led
>> to DSS clock domain not getting out of idle when pm_runtime_get_sync() was
>> called for hdmi's platform device.
>>
>> Since the clock domain failed to change it's state to active, the hwmod code
>> disables any clocks it had enabled before for this hwmod. This led to the clock
>> 'dss_48mhz_clk' getting disabled.
>>
>> When hdmi's runtime_resume() op is called, the call to dss_runtime_get()
>> correctly enables the DSS clock domain this time. But the clock 'dss_48mhz_clk'
>> disabled before is needed for HDMI's PHY to function. Hence, the driver fails
>
> There's something wrong with the "But the clock..." sentence above.
>
> The patch looks good, but I think it'd be better to add brief HACK
> comments in the code also. Otherwise it's too easy to forget about this.
I'll make the changes and repost.
Archit
>
> Tomi
>
^ permalink raw reply
* Re: [PATCH] ARM: OMAP1: ams-delta: clean up init data section assignments
From: Russell King - ARM Linux @ 2012-02-09 14:48 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1328786302-25131-1-git-send-email-jkrzyszt@tis.icnet.pl>
On Thu, Feb 09, 2012 at 12:18:22PM +0100, Janusz Krzysztofik wrote:
> The main purpose of this patch is to fix several section mismatch
> warnings from the board file and a few board specific drivers,
> introduced mostly with recent Amstrad Delta patch series, some of them
> rising up only when building with CONFIG_MODULES not set.
>
> While being at it, section assignments of all init data found in the
> board file have been revised and hopefully optimised.
There is no optimisation to adding __refdata to stuff. That's screaming
that you have lots of bugs here.
>
> Created and tested on top of current linux-omap/omap1, commit
> 967809bd7faf71ddc29c8081e0f21db8b201a0f4.
>
> Signed-off-by: Janusz Krzysztofik <jkrzyszt@tis.icnet.pl>
> ---
> arch/arm/mach-omap1/board-ams-delta.c | 35 +++++++++++++++++----------------
> drivers/input/serio/ams_delta_serio.c | 2 +-
> drivers/mtd/nand/ams-delta.c | 2 +-
> drivers/video/omap/lcd_ams_delta.c | 2 +-
> 4 files changed, 21 insertions(+), 20 deletions(-)
>
> diff --git a/arch/arm/mach-omap1/board-ams-delta.c b/arch/arm/mach-omap1/board-ams-delta.c
> index 87b1303..dc2455f 100644
> --- a/arch/arm/mach-omap1/board-ams-delta.c
> +++ b/arch/arm/mach-omap1/board-ams-delta.c
> @@ -126,7 +126,7 @@ static const unsigned int ams_delta_keymap[] = {
> #define LATCH2_PHYS 0x08000000
> #define LATCH2_VIRT 0xEC000000
>
> -static struct map_desc ams_delta_io_desc[] __initdata = {
> +static struct map_desc ams_delta_io_desc[] __initconst = {
You're not making this comst so don't change it to __initconst.
> /* AMS_DELTA_LATCH1 */
> {
> .virtual = LATCH1_VIRT,
> @@ -150,17 +150,17 @@ static struct map_desc ams_delta_io_desc[] __initdata = {
> }
> };
>
> -static struct omap_lcd_config ams_delta_lcd_config = {
> +static struct omap_lcd_config ams_delta_lcd_config __initconst = {
This change probably adds a bug. Are you sure this will never be used
outside init context?
> .ctrl_name = "internal",
> };
>
> -static struct omap_usb_config ams_delta_usb_config __initdata = {
> +static struct omap_usb_config ams_delta_usb_config __initdata_or_module = {
Even if you don't have modules enabled, have you checked whether the
driver can be bound and unbound via
/sys/bus/platform/driver/<name>/{bind,unbind} ?
I suspect this is a bug.
> .register_host = 1,
> .hmc_mode = 16,
> .pins[0] = 2,
> };
>
> -static struct omap_board_config_kernel ams_delta_config[] __initdata = {
> +static struct omap_board_config_kernel ams_delta_config[] __initconst = {
> { OMAP_TAG_LCD, &ams_delta_lcd_config },
> };
>
> @@ -181,7 +181,7 @@ static struct bgpio_pdata latch1_pdata __initconst = {
> .ngpio = LATCH1_NGPIO,
> };
>
> -static struct platform_device latch1_gpio_device = {
> +static struct platform_device latch1_gpio_device __refdata = {
> .name = "basic-mmio-gpio",
> .id = 0,
> .resource = latch1_resources,
> @@ -205,7 +205,7 @@ static struct bgpio_pdata latch2_pdata __initconst = {
> .ngpio = AMS_DELTA_LATCH2_NGPIO,
> };
>
> -static struct platform_device latch2_gpio_device = {
> +static struct platform_device latch2_gpio_device __refdata = {
> .name = "basic-mmio-gpio",
> .id = 1,
> .resource = latch2_resources,
> @@ -271,7 +271,7 @@ void ams_delta_latch_write(int base, int ngpio, u16 mask, u16 value)
> }
> EXPORT_SYMBOL(ams_delta_latch_write);
>
> -static struct resource ams_delta_nand_resources[] = {
> +static struct resource ams_delta_nand_resources[] __initconst_or_module = {
This change definitely adds a bug. The resources are _used_ _all_ _the_
_time_ _the_ _device_ _is_ _registered_. Try catting /proc/iomem after
boot.
> [0] = {
> .start = OMAP1_MPUIO_BASE,
> .end = OMAP1_MPUIO_BASE +
> @@ -280,14 +280,14 @@ static struct resource ams_delta_nand_resources[] = {
> },
> };
>
> -static struct platform_device ams_delta_nand_device = {
> +static struct platform_device ams_delta_nand_device __refdata = {
Therefore, bug.
> .name = "ams-delta-nand",
> .id = -1,
> .num_resources = ARRAY_SIZE(ams_delta_nand_resources),
> .resource = ams_delta_nand_resources,
> };
>
> -static struct resource ams_delta_kp_resources[] = {
> +static struct resource ams_delta_kp_resources[] __initconst_or_module = {
Bug.
> [0] = {
> .start = INT_KEYBOARD,
> .end = INT_KEYBOARD,
> @@ -300,14 +300,14 @@ static const struct matrix_keymap_data ams_delta_keymap_data = {
> .keymap_size = ARRAY_SIZE(ams_delta_keymap),
> };
>
> -static struct omap_kp_platform_data ams_delta_kp_data __initdata = {
> +static struct omap_kp_platform_data ams_delta_kp_data __initconst_or_module = {
Probably a bug if you unbind/rebind the associated driver with modules
disabled.
> .rows = 8,
> .cols = 8,
> .keymap_data = &ams_delta_keymap_data,
> .delay = 9,
> };
>
> -static struct platform_device ams_delta_kp_device = {
> +static struct platform_device ams_delta_kp_device __refdata = {
> .name = "omap-keypad",
> .id = -1,
> .dev = {
> @@ -363,7 +363,8 @@ static struct gpio_led_platform_data leds_pdata __initconst = {
> .num_leds = ARRAY_SIZE(gpio_leds),
> };
>
> -static struct i2c_board_info ams_delta_camera_board_info[] = {
> +static struct i2c_board_info __initconst_or_module
> +ams_delta_camera_board_info[] = {
No. It's
static struct foo blah[] __whatever_init_attribute
not
static struct foo __whatever_init_attribute blah[]
I've no idea where this fucked idea came from but it's something that's
wasting a lot of review time with complaints like this about it.
> {
> I2C_BOARD_INFO("ov6650", 0x60),
> },
> @@ -387,7 +388,7 @@ static int ams_delta_camera_power(struct device *dev, int power)
> #define ams_delta_camera_power NULL
> #endif
>
> -static struct soc_camera_link ams_delta_iclink = {
> +static struct soc_camera_link ams_delta_iclink __initconst_or_module = {
Probably buggy.
> .bus_id = 0, /* OMAP1 SoC camera bus */
> .i2c_adapter_id = 1,
> .board_info = &ams_delta_camera_board_info[0],
> @@ -395,7 +396,7 @@ static struct soc_camera_link ams_delta_iclink = {
> .power = ams_delta_camera_power,
> };
>
> -static struct platform_device ams_delta_camera_device = {
> +static struct platform_device ams_delta_camera_device __refdata = {
> .name = "soc-camera-pdrv",
> .id = 0,
> .dev = {
> @@ -408,7 +409,7 @@ static struct omap1_cam_platform_data ams_delta_camera_platform_data = {
> .lclk_khz_max = 1334, /* results in 5fps CIF, 10fps QCIF */
> };
>
> -static struct platform_device *ams_delta_devices[] __initdata = {
> +static struct platform_device *ams_delta_devices[] __initconst = {
Missing const. If you can't const it, don't put it in __initconst.
> &latch1_gpio_device,
> &latch2_gpio_device,
> &ams_delta_kp_device,
> @@ -459,7 +460,7 @@ static void __init ams_delta_init(void)
> omap_writew(omap_readw(ARM_RSTCT1) | 0x0004, ARM_RSTCT1);
> }
>
> -static struct plat_serial8250_port ams_delta_modem_ports[] = {
> +static struct plat_serial8250_port ams_delta_modem_ports[] __initdata = {
Buggy.
> {
> .membase = IOMEM(MODEM_VIRT),
> .mapbase = MODEM_PHYS,
> @@ -473,7 +474,7 @@ static struct plat_serial8250_port ams_delta_modem_ports[] = {
> { },
> };
>
> -static struct platform_device ams_delta_modem_device = {
> +static struct platform_device ams_delta_modem_device __refdata = {
> .name = "serial8250",
> .id = PLAT8250_DEV_PLATFORM1,
> .dev = {
^ permalink raw reply
* Re: [PATCH] OMAPDSS: HACK: Ensure DSS clock domain gets out of idle when HDMI is enabled
From: Tomi Valkeinen @ 2012-02-09 12:02 UTC (permalink / raw)
To: Archit Taneja; +Cc: linux-omap, linux, linux-fbdev
In-Reply-To: <1328769888-24790-1-git-send-email-archit@ti.com>
[-- Attachment #1: Type: text/plain, Size: 1171 bytes --]
Hi,
On Thu, 2012-02-09 at 12:14 +0530, Archit Taneja wrote:
> For DSS clock domain to transition from idle to active state, it's necessary
> to enable the optional clock DSS_FCLK before we enable the module using the
> MODULEMODE bits in the DSS clock domain's CM_DSS_DSS_CLKCTRL register.
>
> This sequence was not followed correctly for the 'dss_hdmi' hwmod and it led
> to DSS clock domain not getting out of idle when pm_runtime_get_sync() was
> called for hdmi's platform device.
>
> Since the clock domain failed to change it's state to active, the hwmod code
> disables any clocks it had enabled before for this hwmod. This led to the clock
> 'dss_48mhz_clk' getting disabled.
>
> When hdmi's runtime_resume() op is called, the call to dss_runtime_get()
> correctly enables the DSS clock domain this time. But the clock 'dss_48mhz_clk'
> disabled before is needed for HDMI's PHY to function. Hence, the driver fails
There's something wrong with the "But the clock..." sentence above.
The patch looks good, but I think it'd be better to add brief HACK
comments in the code also. Otherwise it's too easy to forget about this.
Tomi
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply
* [PATCH] ARM: OMAP1: ams-delta: clean up init data section assignments
From: Janusz Krzysztofik @ 2012-02-09 11:18 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1328696173-17226-1-git-send-email-grinberg@compulab.co.il>
The main purpose of this patch is to fix several section mismatch
warnings from the board file and a few board specific drivers,
introduced mostly with recent Amstrad Delta patch series, some of them
rising up only when building with CONFIG_MODULES not set.
While being at it, section assignments of all init data found in the
board file have been revised and hopefully optimised.
Created and tested on top of current linux-omap/omap1, commit
967809bd7faf71ddc29c8081e0f21db8b201a0f4.
Signed-off-by: Janusz Krzysztofik <jkrzyszt@tis.icnet.pl>
---
arch/arm/mach-omap1/board-ams-delta.c | 35 +++++++++++++++++----------------
drivers/input/serio/ams_delta_serio.c | 2 +-
drivers/mtd/nand/ams-delta.c | 2 +-
drivers/video/omap/lcd_ams_delta.c | 2 +-
4 files changed, 21 insertions(+), 20 deletions(-)
diff --git a/arch/arm/mach-omap1/board-ams-delta.c b/arch/arm/mach-omap1/board-ams-delta.c
index 87b1303..dc2455f 100644
--- a/arch/arm/mach-omap1/board-ams-delta.c
+++ b/arch/arm/mach-omap1/board-ams-delta.c
@@ -126,7 +126,7 @@ static const unsigned int ams_delta_keymap[] = {
#define LATCH2_PHYS 0x08000000
#define LATCH2_VIRT 0xEC000000
-static struct map_desc ams_delta_io_desc[] __initdata = {
+static struct map_desc ams_delta_io_desc[] __initconst = {
/* AMS_DELTA_LATCH1 */
{
.virtual = LATCH1_VIRT,
@@ -150,17 +150,17 @@ static struct map_desc ams_delta_io_desc[] __initdata = {
}
};
-static struct omap_lcd_config ams_delta_lcd_config = {
+static struct omap_lcd_config ams_delta_lcd_config __initconst = {
.ctrl_name = "internal",
};
-static struct omap_usb_config ams_delta_usb_config __initdata = {
+static struct omap_usb_config ams_delta_usb_config __initdata_or_module = {
.register_host = 1,
.hmc_mode = 16,
.pins[0] = 2,
};
-static struct omap_board_config_kernel ams_delta_config[] __initdata = {
+static struct omap_board_config_kernel ams_delta_config[] __initconst = {
{ OMAP_TAG_LCD, &ams_delta_lcd_config },
};
@@ -181,7 +181,7 @@ static struct bgpio_pdata latch1_pdata __initconst = {
.ngpio = LATCH1_NGPIO,
};
-static struct platform_device latch1_gpio_device = {
+static struct platform_device latch1_gpio_device __refdata = {
.name = "basic-mmio-gpio",
.id = 0,
.resource = latch1_resources,
@@ -205,7 +205,7 @@ static struct bgpio_pdata latch2_pdata __initconst = {
.ngpio = AMS_DELTA_LATCH2_NGPIO,
};
-static struct platform_device latch2_gpio_device = {
+static struct platform_device latch2_gpio_device __refdata = {
.name = "basic-mmio-gpio",
.id = 1,
.resource = latch2_resources,
@@ -271,7 +271,7 @@ void ams_delta_latch_write(int base, int ngpio, u16 mask, u16 value)
}
EXPORT_SYMBOL(ams_delta_latch_write);
-static struct resource ams_delta_nand_resources[] = {
+static struct resource ams_delta_nand_resources[] __initconst_or_module = {
[0] = {
.start = OMAP1_MPUIO_BASE,
.end = OMAP1_MPUIO_BASE +
@@ -280,14 +280,14 @@ static struct resource ams_delta_nand_resources[] = {
},
};
-static struct platform_device ams_delta_nand_device = {
+static struct platform_device ams_delta_nand_device __refdata = {
.name = "ams-delta-nand",
.id = -1,
.num_resources = ARRAY_SIZE(ams_delta_nand_resources),
.resource = ams_delta_nand_resources,
};
-static struct resource ams_delta_kp_resources[] = {
+static struct resource ams_delta_kp_resources[] __initconst_or_module = {
[0] = {
.start = INT_KEYBOARD,
.end = INT_KEYBOARD,
@@ -300,14 +300,14 @@ static const struct matrix_keymap_data ams_delta_keymap_data = {
.keymap_size = ARRAY_SIZE(ams_delta_keymap),
};
-static struct omap_kp_platform_data ams_delta_kp_data __initdata = {
+static struct omap_kp_platform_data ams_delta_kp_data __initconst_or_module = {
.rows = 8,
.cols = 8,
.keymap_data = &ams_delta_keymap_data,
.delay = 9,
};
-static struct platform_device ams_delta_kp_device = {
+static struct platform_device ams_delta_kp_device __refdata = {
.name = "omap-keypad",
.id = -1,
.dev = {
@@ -363,7 +363,8 @@ static struct gpio_led_platform_data leds_pdata __initconst = {
.num_leds = ARRAY_SIZE(gpio_leds),
};
-static struct i2c_board_info ams_delta_camera_board_info[] = {
+static struct i2c_board_info __initconst_or_module
+ams_delta_camera_board_info[] = {
{
I2C_BOARD_INFO("ov6650", 0x60),
},
@@ -387,7 +388,7 @@ static int ams_delta_camera_power(struct device *dev, int power)
#define ams_delta_camera_power NULL
#endif
-static struct soc_camera_link ams_delta_iclink = {
+static struct soc_camera_link ams_delta_iclink __initconst_or_module = {
.bus_id = 0, /* OMAP1 SoC camera bus */
.i2c_adapter_id = 1,
.board_info = &ams_delta_camera_board_info[0],
@@ -395,7 +396,7 @@ static struct soc_camera_link ams_delta_iclink = {
.power = ams_delta_camera_power,
};
-static struct platform_device ams_delta_camera_device = {
+static struct platform_device ams_delta_camera_device __refdata = {
.name = "soc-camera-pdrv",
.id = 0,
.dev = {
@@ -408,7 +409,7 @@ static struct omap1_cam_platform_data ams_delta_camera_platform_data = {
.lclk_khz_max = 1334, /* results in 5fps CIF, 10fps QCIF */
};
-static struct platform_device *ams_delta_devices[] __initdata = {
+static struct platform_device *ams_delta_devices[] __initconst = {
&latch1_gpio_device,
&latch2_gpio_device,
&ams_delta_kp_device,
@@ -459,7 +460,7 @@ static void __init ams_delta_init(void)
omap_writew(omap_readw(ARM_RSTCT1) | 0x0004, ARM_RSTCT1);
}
-static struct plat_serial8250_port ams_delta_modem_ports[] = {
+static struct plat_serial8250_port ams_delta_modem_ports[] __initdata = {
{
.membase = IOMEM(MODEM_VIRT),
.mapbase = MODEM_PHYS,
@@ -473,7 +474,7 @@ static struct plat_serial8250_port ams_delta_modem_ports[] = {
{ },
};
-static struct platform_device ams_delta_modem_device = {
+static struct platform_device ams_delta_modem_device __refdata = {
.name = "serial8250",
.id = PLAT8250_DEV_PLATFORM1,
.dev = {
diff --git a/drivers/input/serio/ams_delta_serio.c b/drivers/input/serio/ams_delta_serio.c
index 0571e2e..0830a76 100644
--- a/drivers/input/serio/ams_delta_serio.c
+++ b/drivers/input/serio/ams_delta_serio.c
@@ -103,7 +103,7 @@ static void ams_delta_serio_close(struct serio *serio)
gpio_set_value(AMS_DELTA_GPIO_PIN_KEYBRD_PWR, 0);
}
-static struct gpio ams_delta_gpios[] __initconst_or_module = {
+static const struct gpio ams_delta_gpios[] = {
{
.gpio = AMS_DELTA_GPIO_PIN_KEYBRD_DATA,
.flags = GPIOF_DIR_IN,
diff --git a/drivers/mtd/nand/ams-delta.c b/drivers/mtd/nand/ams-delta.c
index 85934dc..7341695 100644
--- a/drivers/mtd/nand/ams-delta.c
+++ b/drivers/mtd/nand/ams-delta.c
@@ -145,7 +145,7 @@ static int ams_delta_nand_ready(struct mtd_info *mtd)
return gpio_get_value(AMS_DELTA_GPIO_PIN_NAND_RB);
}
-static struct gpio _mandatory_gpio[] __initconst_or_module = {
+static const struct gpio _mandatory_gpio[] = {
{
.gpio = AMS_DELTA_GPIO_PIN_NAND_NCE,
.flags = GPIOF_OUT_INIT_HIGH,
diff --git a/drivers/video/omap/lcd_ams_delta.c b/drivers/video/omap/lcd_ams_delta.c
index 0e71e28..d3a3113 100644
--- a/drivers/video/omap/lcd_ams_delta.c
+++ b/drivers/video/omap/lcd_ams_delta.c
@@ -99,7 +99,7 @@ static struct lcd_ops ams_delta_lcd_ops = {
/* omapfb panel section */
-static struct gpio _gpios[] __initconst_or_module = {
+static const struct gpio _gpios[] = {
{
.gpio = AMS_DELTA_GPIO_PIN_LCD_VBLEN,
.flags = GPIOF_OUT_INIT_LOW,
--
1.7.3.4
^ permalink raw reply related
* Re: [PATCH 00/16] rmk's patch series for fixing OMAP
From: Tomi Valkeinen @ 2012-02-09 10:24 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1328776220.12747.5.camel@lws-gamez>
[-- Attachment #1: Type: text/plain, Size: 545 bytes --]
On Thu, 2012-02-09 at 09:30 +0100, Teresa Gamez wrote:
> Am Donnerstag, den 09.02.2012, 09:02 +0200 schrieb Tomi Valkeinen:
> > The problem is present in all kernels where we have the HDMI driver, so
> > 2.6.39+.
>
> Are there already backported patches out there for 3.0/3.1?
> We are quite interested in this.
I pushed three branches to git://gitorious.org/linux-omap-dss2/linux.git
fixes/for-3.0-stable
fixes/for-3.1-stable
fixes/for-3.2-stable
Which contain the necessary backported patches for each version.
Tomi
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply
* Re: [PATCH 00/16] rmk's patch series for fixing OMAP
From: Teresa Gamez @ 2012-02-09 8:30 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1328770969.1909.11.camel@deskari>
Am Donnerstag, den 09.02.2012, 09:02 +0200 schrieb Tomi Valkeinen:
> On Thu, 2012-02-09 at 00:53 +0000, Russell King - ARM Linux wrote:
>
> > Moreover, only last Monday did I enable the OMAP2 DSS subsystem on the
> > 4430 SDP platform, _including_ the HDMI code, and looking at the commit
> > it could be one of those platforms which is affected.
> >
> > As I don't have a HDMI cable connected to the system, and I ran that
> > kernel overnight, and I tried opening each /dev/fb* device, what I'm now
> > wondering is: have I destroyed the HDMI PHY on my 4430SDP?
>
> Probably not. I don't know the exact details of the HW bug (I wrote the
> patch as it took too long for the person responsible for it to come up
> with a decent patch), but my understanding is that the cable needs to be
> plugged in at some point, and then removed.
>
> Thinking about this now, I guess I should've sent queries to get a
> proper description of the situation where the bug happens.
>
> > However, you raise another point, a much more serious one at that. Is
> > this problem also present in 3.2? The patch seems to apply almost cleanly
> > to that kernel version, so I guess it is. It fails to apply to v3.1
> > because of missing files, so I guess 3.1 is unaffected.
> >
> > So, why isn't this patch copied to the stable people?
>
> Good point, I'll take it to the stable people.
>
> The problem is present in all kernels where we have the HDMI driver, so
> 2.6.39+.
Are there already backported patches out there for 3.0/3.1?
We are quite interested in this.
Regards,
Teresa
>
> > For hardware destruction issues, once the problem has been identified, it
> > should be shouted about very loudly to get it upstream as quickly as
> > possible. I'm sure Linus would've even taken it in patch form.
> >
> > (You do realise that Linus does apply patches as well as pulling trees?)
>
> Yes, I should've taken this directly to Linus.
>
> Tomi
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH 00/16] rmk's patch series for fixing OMAP
From: Tomi Valkeinen @ 2012-02-09 7:02 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20120209005334.GG25414@n2100.arm.linux.org.uk>
[-- Attachment #1: Type: text/plain, Size: 1726 bytes --]
On Thu, 2012-02-09 at 00:53 +0000, Russell King - ARM Linux wrote:
> Moreover, only last Monday did I enable the OMAP2 DSS subsystem on the
> 4430 SDP platform, _including_ the HDMI code, and looking at the commit
> it could be one of those platforms which is affected.
>
> As I don't have a HDMI cable connected to the system, and I ran that
> kernel overnight, and I tried opening each /dev/fb* device, what I'm now
> wondering is: have I destroyed the HDMI PHY on my 4430SDP?
Probably not. I don't know the exact details of the HW bug (I wrote the
patch as it took too long for the person responsible for it to come up
with a decent patch), but my understanding is that the cable needs to be
plugged in at some point, and then removed.
Thinking about this now, I guess I should've sent queries to get a
proper description of the situation where the bug happens.
> However, you raise another point, a much more serious one at that. Is
> this problem also present in 3.2? The patch seems to apply almost cleanly
> to that kernel version, so I guess it is. It fails to apply to v3.1
> because of missing files, so I guess 3.1 is unaffected.
>
> So, why isn't this patch copied to the stable people?
Good point, I'll take it to the stable people.
The problem is present in all kernels where we have the HDMI driver, so
2.6.39+.
> For hardware destruction issues, once the problem has been identified, it
> should be shouted about very loudly to get it upstream as quickly as
> possible. I'm sure Linus would've even taken it in patch form.
>
> (You do realise that Linus does apply patches as well as pulling trees?)
Yes, I should've taken this directly to Linus.
Tomi
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply
* [PATCH] OMAPDSS: HACK: Ensure DSS clock domain gets out of idle when HDMI is enabled
From: Archit Taneja @ 2012-02-09 6:56 UTC (permalink / raw)
To: linux-omap; +Cc: tomi.valkeinen, linux, linux-fbdev, Archit Taneja
For DSS clock domain to transition from idle to active state, it's necessary
to enable the optional clock DSS_FCLK before we enable the module using the
MODULEMODE bits in the DSS clock domain's CM_DSS_DSS_CLKCTRL register.
This sequence was not followed correctly for the 'dss_hdmi' hwmod and it led
to DSS clock domain not getting out of idle when pm_runtime_get_sync() was
called for hdmi's platform device.
Since the clock domain failed to change it's state to active, the hwmod code
disables any clocks it had enabled before for this hwmod. This led to the clock
'dss_48mhz_clk' getting disabled.
When hdmi's runtime_resume() op is called, the call to dss_runtime_get()
correctly enables the DSS clock domain this time. But the clock 'dss_48mhz_clk'
disabled before is needed for HDMI's PHY to function. Hence, the driver fails
when it tries to enable HDMI's PHY.
Fix this for now by ensuring that dss_runtime_get() is called before we call
pm_runtime_get_sync() for hdmi's platform device. A correct fix for later would
be to modify the DSS related hwmod's mainclks, and also some changes in how
opt clocks are handled in the DSS driver.
This fixes the issue of HDMI not working when it's the default display. The
issue is not seen if any other display is already enabled as the first display
would have already correctly enabled the DSS clock domain.
Signed-off-by: Archit Taneja <archit@ti.com>
---
drivers/video/omap2/dss/hdmi.c | 16 +++++++++++++++-
1 files changed, 15 insertions(+), 1 deletions(-)
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
index d7aa3b0..ce16a91 100644
--- a/drivers/video/omap2/dss/hdmi.c
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -165,9 +165,21 @@ static int hdmi_runtime_get(void)
DSSDBG("hdmi_runtime_get\n");
+ r = dss_runtime_get();
+ if (r < 0)
+ goto err_get_dss;
+
r = pm_runtime_get_sync(&hdmi.pdev->dev);
WARN_ON(r < 0);
- return r < 0 ? r : 0;
+ if (r < 0)
+ goto err_get_hdmi;
+
+ return 0;
+
+err_get_hdmi:
+ dss_runtime_put();
+err_get_dss:
+ return r;
}
static void hdmi_runtime_put(void)
@@ -178,6 +190,8 @@ static void hdmi_runtime_put(void)
r = pm_runtime_put_sync(&hdmi.pdev->dev);
WARN_ON(r < 0);
+
+ dss_runtime_put();
}
int hdmi_init_display(struct omap_dss_device *dssdev)
--
1.7.5.4
^ permalink raw reply related
* [PATCH v2] video:da8xx-fb: calculate pixel clock period for the panel
From: Manjunathappa, Prakash @ 2012-02-09 6:36 UTC (permalink / raw)
To: linux-fbdev
Cc: Florian Tobias Schandinat, davinci-linux-open-source,
linux-kernel, Manjunathappa, Prakash
Patch calculates pixel clock period in pico seconds and updates
the same in variable screen information structure. fbset utility
uses this information.
Signed-off-by: Manjunathappa, Prakash <prakash.pm@ti.com>
---
Since v1:
Fixed the spelling mistake.
drivers/video/da8xx-fb.c | 19 ++++++++++++++++++-
1 files changed, 18 insertions(+), 1 deletions(-)
diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
index f360d62..882dd67 100644
--- a/drivers/video/da8xx-fb.c
+++ b/drivers/video/da8xx-fb.c
@@ -32,6 +32,7 @@
#include <linux/console.h>
#include <linux/slab.h>
#include <video/da8xx-fb.h>
+#include <asm/div64.h>
#define DRIVER_NAME "da8xx_lcdc"
@@ -174,7 +175,6 @@ static struct fb_var_screeninfo da8xx_fb_var __devinitdata = {
.activate = 0,
.height = -1,
.width = -1,
- .pixclock = 46666, /* 46us - AUO display */
.accel_flags = 0,
.left_margin = LEFT_MARGIN,
.right_margin = RIGHT_MARGIN,
@@ -1048,6 +1048,22 @@ static struct fb_ops da8xx_fb_ops = {
.fb_blank = cfb_blank,
};
+/* Calculate and return pixel clock period in pico seconds */
+static unsigned int da8xxfb_pixel_clk_period(struct da8xx_fb_par *par)
+{
+ unsigned int lcd_clk, div;
+ unsigned int configured_pix_clk;
+ unsigned long long pix_clk_period_picosec = 1000000000000ULL;
+
+ lcd_clk = clk_get_rate(par->lcdc_clk);
+ div = lcd_clk / par->pxl_clk;
+ configured_pix_clk = (lcd_clk / div);
+
+ do_div(pix_clk_period_picosec, configured_pix_clk);
+
+ return pix_clk_period_picosec;
+}
+
static int __devinit fb_probe(struct platform_device *device)
{
struct da8xx_lcdc_platform_data *fb_pdata @@ -1209,6 +1225,7 @@ static int __devinit fb_probe(struct platform_device *device)
da8xx_fb_var.hsync_len = lcdc_info->hsw;
da8xx_fb_var.vsync_len = lcdc_info->vsw;
+ da8xx_fb_var.pixclock = da8xxfb_pixel_clk_period(par);
/* Initialize fbinfo */
da8xx_fb_info->flags = FBINFO_FLAG_DEFAULT;
--
1.7.1
^ permalink raw reply related
* [PATCH] video:da8xx-fb: calculate pixel clock period for the panel
From: Manjunathappa, Prakash @ 2012-02-09 5:16 UTC (permalink / raw)
To: linux-fbdev
Cc: Florian Tobias Schandinat, davinci-linux-open-source,
linux-kernel, Manjunathappa, Prakash
In-Reply-To: <1328763879-16345-1-git-send-email-prakash.pm@ti.com>
Patch calculates pixel clock period in pico seconds and updates
the same in variable screen information structure. fbset utility
uses this information.
Signed-off-by: Manjunathappa, Prakash <prakash.pm@ti.com>
---
drivers/video/da8xx-fb.c | 21 ++++++++++++++++++++-
1 files changed, 20 insertions(+), 1 deletions(-)
diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
index f360d62..8b0a174 100644
--- a/drivers/video/da8xx-fb.c
+++ b/drivers/video/da8xx-fb.c
@@ -32,6 +32,7 @@
#include <linux/console.h>
#include <linux/slab.h>
#include <video/da8xx-fb.h>
+#include <asm/div64.h>
#define DRIVER_NAME "da8xx_lcdc"
@@ -174,7 +175,6 @@ static struct fb_var_screeninfo da8xx_fb_var __devinitdata = {
.activate = 0,
.height = -1,
.width = -1,
- .pixclock = 46666, /* 46us - AUO display */
.accel_flags = 0,
.left_margin = LEFT_MARGIN,
.right_margin = RIGHT_MARGIN,
@@ -1048,6 +1048,24 @@ static struct fb_ops da8xx_fb_ops = {
.fb_blank = cfb_blank,
};
+/*
+ * Calculate and return pixel clock period in pico secods
+ */
+static unsigned int da8xxfb_pixel_clk_period(struct da8xx_fb_par *par)
+{
+ unsigned int lcd_clk, div;
+ unsigned int configured_pix_clk;
+ unsigned long long pix_clk_period_picosec = 1000000000000ULL;
+
+ lcd_clk = clk_get_rate(par->lcdc_clk);
+ div = lcd_clk / par->pxl_clk;
+ configured_pix_clk = (lcd_clk / div);
+
+ do_div(pix_clk_period_picosec, configured_pix_clk);
+
+ return pix_clk_period_picosec;
+}
+
static int __devinit fb_probe(struct platform_device *device)
{
struct da8xx_lcdc_platform_data *fb_pdata @@ -1209,6 +1227,7 @@ static int __devinit fb_probe(struct platform_device *device)
da8xx_fb_var.hsync_len = lcdc_info->hsw;
da8xx_fb_var.vsync_len = lcdc_info->vsw;
+ da8xx_fb_var.pixclock = da8xxfb_pixel_clk_period(par);
/* Initialize fbinfo */
da8xx_fb_info->flags = FBINFO_FLAG_DEFAULT;
--
1.7.1
^ permalink raw reply related
* [PATCH] video: da8xx-fb: Fix build warning on unused label
From: Manjunathappa, Prakash @ 2012-02-09 5:16 UTC (permalink / raw)
To: linux-fbdev
Cc: Florian Tobias Schandinat, davinci-linux-open-source,
linux-kernel, Manjunathappa, Prakash
Patch fixes build warning on label "err_cpu_freq" when CONFIG_CPU_FREQ
is not defined.
Signed-off-by: Manjunathappa, Prakash <prakash.pm@ti.com>
---
drivers/video/da8xx-fb.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
index 29577bf..f360d62 100644
--- a/drivers/video/da8xx-fb.c
+++ b/drivers/video/da8xx-fb.c
@@ -1264,8 +1264,8 @@ static int __devinit fb_probe(struct platform_device *device)
irq_freq:
#ifdef CONFIG_CPU_FREQ
lcd_da8xx_cpufreq_deregister(par);
-#endif
err_cpu_freq:
+#endif
unregister_framebuffer(da8xx_fb_info);
err_dealloc_cmap:
--
1.7.1
^ permalink raw reply related
* Re: [PATCH 00/16] rmk's patch series for fixing OMAP
From: Russell King - ARM Linux @ 2012-02-09 0:53 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <4F32DBB5.4010004@gmx.de>
On Wed, Feb 08, 2012 at 08:31:49PM +0000, Florian Tobias Schandinat wrote:
> Hi Russell,
>
> On 02/08/2012 04:35 PM, Russell King - ARM Linux wrote:
> > commit c49d005b6cc8491fad5b24f82805be2d6bcbd3dd
> > Author: Tomi Valkeinen <tomi.valkeinen@ti.com>
> > Date: Tue Jan 17 11:09:57 2012 +0200
> >
> > OMAPDSS: HDMI: PHY burnout fix
> >
> > A hardware bug in the OMAP4 HDMI PHY causes physical damage to the board
> > if the HDMI PHY is kept powered on when the cable is not connected.
>
> I agree this is a serious issue.
>
> > which now has me wondering if, by trying to boot v3.3-rc2 on this board
> > during the past week, I have a destroyed HDMI interface on it.
>
> I am not sure as I don't keep track of all OMAP changes, but you make it
> sound like a regression, is there any difference to 3.2 behavior?
I've no idea when the problem was introduced, that's not the point that
I'm making. The point that I'm making is that the patch is dated January
17th, it was apparantly committed on the 26th, and it went into mainline
on the 8th February.
For a patch which fixes a _hardware_ _destruction_ issue, three weeks is
_FAR_ too long for it to take to get into mainline.
Moreover, only last Monday did I enable the OMAP2 DSS subsystem on the
4430 SDP platform, _including_ the HDMI code, and looking at the commit
it could be one of those platforms which is affected.
As I don't have a HDMI cable connected to the system, and I ran that
kernel overnight, and I tried opening each /dev/fb* device, what I'm now
wondering is: have I destroyed the HDMI PHY on my 4430SDP?
But that's not really the point. The point is, for someone to sit on such
a patch for weeks is, in my opinion, as good as saying to your users "I
don't care if you bust your hardware."
However, you raise another point, a much more serious one at that. Is
this problem also present in 3.2? The patch seems to apply almost cleanly
to that kernel version, so I guess it is. It fails to apply to v3.1
because of missing files, so I guess 3.1 is unaffected.
So, why isn't this patch copied to the stable people?
And why is there this seemingly lack of care for hardware destruction bugs?
Please, if it affects v3.2, PLEASE PLEASE PLEASE tell the stable people
who know nothing about this commit until I asked them this evening about
it.
> > So, a big thanks for sitting on that fix and exposing peoples hardware
> > to damage, that shows real professionalism.
>
> Well, I am no professional to begin with, at least in the sense of getting paid
> for it. That said I'm quite happy if I manage to find a few hours every weekend
> to do the work. Given that the final thing should be tested in -next before I
> ask Linus to pull, it is completely usual (and even quite fast) if things take
> 8-13 days on my end. If this isn't fast enough for Tomi, he'd better ask Linus
> to pull directly for such issues.
For hardware destruction issues, once the problem has been identified, it
should be shouted about very loudly to get it upstream as quickly as
possible. I'm sure Linus would've even taken it in patch form.
(You do realise that Linus does apply patches as well as pulling trees?)
^ permalink raw reply
* [PATCH v2] backlight: add support for Pandora backlight
From: Grazvydas Ignotas @ 2012-02-08 23:42 UTC (permalink / raw)
To: linux-fbdev
This patch adds support for pandora (openpandora.org) backlight.
It might look like all this could be done using pwm_bl.c instead,
but there is a need of special programming sequence when turning
on the LED driver chip or else it will misbehave. Doing this using
pwm_bl.c would require to use some register programming and pwm
functions from platform code, and ARM maintainers are allergic to
driver-like code in /arch/arm nowadays. The PMIC PWM driver is
currently missing too, so pwm_bl.c can't be used anyway.
Signed-off-by: Grazvydas Ignotas <notasas@gmail.com>
---
changed in v2: fixed a bug where setting brightness to 0 twice
would actually turn the backlight on.
We had this driver in pandora tree for a couple of years now, but
while cleaning it up for mainline submission I've introduced this
bug, sorry for the noise.
drivers/video/backlight/Kconfig | 7 ++
drivers/video/backlight/Makefile | 1 +
drivers/video/backlight/pandora_bl.c | 171 ++++++++++++++++++++++++++++++++++
3 files changed, 179 insertions(+), 0 deletions(-)
create mode 100644 drivers/video/backlight/pandora_bl.c
diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig
index 681b369..3f03954 100644
--- a/drivers/video/backlight/Kconfig
+++ b/drivers/video/backlight/Kconfig
@@ -334,6 +334,13 @@ config BACKLIGHT_AAT2870
If you have a AnalogicTech AAT2870 say Y to enable the
backlight driver.
+config BACKLIGHT_PANDORA
+ tristate "Backlight driver for Pandora console"
+ depends on TWL4030_CORE
+ help
+ If you have a Pandora console, say Y to enable the
+ backlight driver.
+
endif # BACKLIGHT_CLASS_DEVICE
endif # BACKLIGHT_LCD_SUPPORT
diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile
index af5cf65..c73169c 100644
--- a/drivers/video/backlight/Makefile
+++ b/drivers/video/backlight/Makefile
@@ -38,4 +38,5 @@ obj-$(CONFIG_BACKLIGHT_ADP8870) += adp8870_bl.o
obj-$(CONFIG_BACKLIGHT_88PM860X) += 88pm860x_bl.o
obj-$(CONFIG_BACKLIGHT_PCF50633) += pcf50633-backlight.o
obj-$(CONFIG_BACKLIGHT_AAT2870) += aat2870_bl.o
+obj-$(CONFIG_BACKLIGHT_PANDORA) += pandora_bl.o
diff --git a/drivers/video/backlight/pandora_bl.c b/drivers/video/backlight/pandora_bl.c
new file mode 100644
index 0000000..4ec3074
--- /dev/null
+++ b/drivers/video/backlight/pandora_bl.c
@@ -0,0 +1,171 @@
+/*
+ * Backlight driver for Pandora handheld.
+ * Pandora uses TWL4030 PWM0 -> TPS61161 combo for control backlight.
+ * Based on pwm_bl.c
+ *
+ * Copyright 2009,2012 Gražvydas Ignotas <notasas@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/fb.h>
+#include <linux/backlight.h>
+#include <linux/i2c/twl.h>
+#include <linux/err.h>
+
+#define TWL_PWM0_ON 0x00
+#define TWL_PWM0_OFF 0x01
+
+#define TWL_INTBR_GPBR1 0x0c
+#define TWL_INTBR_PMBR1 0x0d
+
+#define TWL_PMBR1_PWM0_MUXMASK 0x0c
+#define TWL_PMBR1_PWM0 0x04
+#define PWM0_CLK_ENABLE BIT(0)
+#define PWM0_ENABLE BIT(2)
+
+/* range accepted by hardware */
+#define MIN_VALUE 9
+#define MAX_VALUE 63
+#define MAX_USER_VALUE (MAX_VALUE - MIN_VALUE)
+
+#define PANDORABL_WAS_OFF BL_CORE_DRIVER1
+
+static int pandora_backlight_update_status(struct backlight_device *bl)
+{
+ int brightness = bl->props.brightness;
+ u8 r;
+
+ if (bl->props.power != FB_BLANK_UNBLANK)
+ brightness = 0;
+ if (bl->props.state & BL_CORE_FBBLANK)
+ brightness = 0;
+ if (bl->props.state & BL_CORE_SUSPENDED)
+ brightness = 0;
+
+ if ((unsigned int)brightness > MAX_USER_VALUE)
+ brightness = MAX_USER_VALUE;
+
+ if (brightness = 0) {
+ if (bl->props.state & PANDORABL_WAS_OFF)
+ goto done;
+
+ /* first disable PWM0 output, then clock */
+ twl_i2c_read_u8(TWL4030_MODULE_INTBR, &r, TWL_INTBR_GPBR1);
+ r &= ~PWM0_ENABLE;
+ twl_i2c_write_u8(TWL4030_MODULE_INTBR, r, TWL_INTBR_GPBR1);
+ r &= ~PWM0_CLK_ENABLE;
+ twl_i2c_write_u8(TWL4030_MODULE_INTBR, r, TWL_INTBR_GPBR1);
+
+ goto done;
+ }
+
+ if (bl->props.state & PANDORABL_WAS_OFF) {
+ /*
+ * set PWM duty cycle to max. TPS61161 seems to use this
+ * to calibrate it's PWM sensitivity when it starts.
+ */
+ twl_i2c_write_u8(TWL4030_MODULE_PWM0, MAX_VALUE,
+ TWL_PWM0_OFF);
+
+ /* first enable clock, then PWM0 out */
+ twl_i2c_read_u8(TWL4030_MODULE_INTBR, &r, TWL_INTBR_GPBR1);
+ r &= ~PWM0_ENABLE;
+ r |= PWM0_CLK_ENABLE;
+ twl_i2c_write_u8(TWL4030_MODULE_INTBR, r, TWL_INTBR_GPBR1);
+ r |= PWM0_ENABLE;
+ twl_i2c_write_u8(TWL4030_MODULE_INTBR, r, TWL_INTBR_GPBR1);
+
+ /*
+ * TI made it very easy to enable digital control, so easy that
+ * it often triggers unintentionally and disabes PWM control,
+ * so wait until 1 wire mode detection window ends.
+ */
+ usleep_range(2000, 10000);
+ }
+
+ twl_i2c_write_u8(TWL4030_MODULE_PWM0, MIN_VALUE + brightness,
+ TWL_PWM0_OFF);
+
+done:
+ if (brightness != 0)
+ bl->props.state &= ~PANDORABL_WAS_OFF;
+ else
+ bl->props.state |= PANDORABL_WAS_OFF;
+
+ return 0;
+}
+
+static int pandora_backlight_get_brightness(struct backlight_device *bl)
+{
+ return bl->props.brightness;
+}
+
+static const struct backlight_ops pandora_backlight_ops = {
+ .options = BL_CORE_SUSPENDRESUME,
+ .update_status = pandora_backlight_update_status,
+ .get_brightness = pandora_backlight_get_brightness,
+};
+
+static int pandora_backlight_probe(struct platform_device *pdev)
+{
+ struct backlight_properties props;
+ struct backlight_device *bl;
+ u8 r;
+
+ memset(&props, 0, sizeof(props));
+ props.max_brightness = MAX_USER_VALUE;
+ props.type = BACKLIGHT_RAW;
+ bl = backlight_device_register(pdev->name, &pdev->dev,
+ NULL, &pandora_backlight_ops, &props);
+ if (IS_ERR(bl)) {
+ dev_err(&pdev->dev, "failed to register backlight\n");
+ return PTR_ERR(bl);
+ }
+
+ platform_set_drvdata(pdev, bl);
+
+ /* 64 cycle period, ON position 0 */
+ twl_i2c_write_u8(TWL4030_MODULE_PWM0, 0x80, TWL_PWM0_ON);
+
+ bl->props.state |= PANDORABL_WAS_OFF;
+ bl->props.brightness = MAX_USER_VALUE;
+ backlight_update_status(bl);
+
+ /* enable PWM function in pin mux */
+ twl_i2c_read_u8(TWL4030_MODULE_INTBR, &r, TWL_INTBR_PMBR1);
+ r &= ~TWL_PMBR1_PWM0_MUXMASK;
+ r |= TWL_PMBR1_PWM0;
+ twl_i2c_write_u8(TWL4030_MODULE_INTBR, r, TWL_INTBR_PMBR1);
+
+ return 0;
+}
+
+static int pandora_backlight_remove(struct platform_device *pdev)
+{
+ struct backlight_device *bl = platform_get_drvdata(pdev);
+ backlight_device_unregister(bl);
+ return 0;
+}
+
+static struct platform_driver pandora_backlight_driver = {
+ .driver = {
+ .name = "pandora-backlight",
+ .owner = THIS_MODULE,
+ },
+ .probe = pandora_backlight_probe,
+ .remove = pandora_backlight_remove,
+};
+
+module_platform_driver(pandora_backlight_driver);
+
+MODULE_AUTHOR("Gražvydas Ignotas <notasas@gmail.com>");
+MODULE_DESCRIPTION("Pandora Backlight Driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:pandora-backlight");
--
1.7.0.4
^ permalink raw reply related
* Re: [PATCH 02/16] ARM: omap: fix oops in drivers/video/omap2/dss/dpi.c
From: Tony Lindgren @ 2012-02-08 23:32 UTC (permalink / raw)
To: Russell King - ARM Linux
Cc: linux-omap, Tomi Valkeinen, Florian Tobias Schandinat,
linux-fbdev
In-Reply-To: <20120208225012.GA25414@n2100.arm.linux.org.uk>
* Russell King - ARM Linux <linux@arm.linux.org.uk> [120208 14:19]:
> On Wed, Feb 08, 2012 at 10:36:07AM -0800, Tony Lindgren wrote:
> > * Russell King - ARM Linux <linux@arm.linux.org.uk> [120208 08:05]:
> > > When a PMIC is not found, this driver is unable to obtain its
> > > 'vdds_dsi_reg' regulator. Even through its initialization function
> > > fails, other code still calls its enable function, which fails to
> > > check whether it has this regulator before asking for it to be enabled.
> > >
> > > This fixes the oops, however a better fix would be to sort out the
> > > upper layers to prevent them calling into a module which failed to
> > > initialize.
> > >
> > > Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
> >
> > Tomi can look into fixing this properly for v3.4:
> >
> > Acked-by: Tony Lindgren <tony@atomide.com>
>
> No, it's a thing for v3.3, because you can still get this oops.
>
> I expect _most_ of these patches will go into v3.3, and anything with
> 'fix' or 'oops' in especially I want to see in v3.3.
I acked your patch for -rc. Then Tomi can work on the "better fix part"
you mention above for v3.4 and that's what I meant by my comment
above.
Or is there something else that needs fixing for the -rc series there?
Regards,
Tony
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox