* Re: fb: Rework locking to fix lock ordering on takeover
From: Rafael J. Wysocki @ 2013-01-15 22:15 UTC (permalink / raw)
To: sedat.dilek
Cc: Andrew Morton, Linus Torvalds, linux-fbdev, LKML,
Greg Kroah-Hartman
In-Reply-To: <CA+icZUVJ5hbPJvV4LMFGgD3Sto5=EV=MO9nutYdJwkiRrmpNJQ@mail.gmail.com>
On Sunday, January 13, 2013 04:14:38 PM Sedat Dilek wrote:
> Hi Andrew,
>
> your patch from [1] - as far as I followed - misses a lot of
> Reported-by#s and Tested-by#s (Boris, Jiri, etc.).
> Just one new R-b I have seen yesterday.
>
> I have the original patch from Alan plus the two follow-ups from you
> in my patch-series against v3.8-{rc2,rc3} for quite a while.
> So, please feel free to add a Tested-by.
>
> Unfortunately, your patch has introduced some (unwanted) extra chars
> like "_*" (comments only).
> I appreciate one single (new) patch like this, but please in a proper way.
Why don't you prepare such a patch? I suppose you know everything you need?
> A disappeared/busy/not-answering maintainer is not an excuse for
> handling serious regressions (even here in this case there are fixes
> around),
> Personally, I am still missing a mei-driver fix [2] and a libata-dev fix [3].
> Both issues are not new to the maintainers.
> Not sure if shouting louder is the best strategy here.
[2] seems to be in the Greg's tree, so I suppose it's on its way to Linus and
please note that we're after a several days vacation period and people need to
process their backlogs.
Perhaps just ping the relevant maintainers when 3.8-rc4 is out (and do the same
after -rc5 and so on).
> It would be great to have a place like a "board of arbitration" where
> someone can send blames.
> And I remember vaguely Rafael had a nice list of issues (w/ reference
> to patches!).
> This was a real cool helpful innoivation!
> I can't remember why Rafael stopped his nice service to the
> Linux-kernel community.
Because I don't have the time to do that any more. Yes, it was useful, but it
also was quite a bit of work. Would you volunteer to do that?
Rafael
> [1] https://patchwork.kernel.org/patch/1969391/
> [2] http://git.kernel.org/?p=linux/kernel/git/gregkh/char-misc.git;a=commitdiff;hæ028db0146cf5a68dbd1508225ea49840997880
> [3] http://patchwork.ozlabs.org/patch/206897/
--
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.
^ permalink raw reply
* [PATCH] drivers/video: fsl-diu-fb: add hardware cursor support
From: Timur Tabi @ 2013-01-15 20:17 UTC (permalink / raw)
To: linux-fbdev
From: Timur Tabi <timur@freescale.com>
The Freescale DIU supports a 32x32 color hardware cursor. Framebuffer
cursors are monochrome, so the driver converts the image data to the
format that the DIU expects and then programs to hardware accordingly.
The support cursor enabling/disabling, we provide two cursor image buffers.
One is always blank (all zeroes), and the other contains the real cursor
image data. To disable the cursor (used typically for cursor blinking),
we just tell the hardware to use the blank cursor data.
Signed-off-by: Timur Tabi <timur@freescale.com>
---
drivers/video/fsl-diu-fb.c | 157 +++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 155 insertions(+), 2 deletions(-)
diff --git a/drivers/video/fsl-diu-fb.c b/drivers/video/fsl-diu-fb.c
index 19cfd7a..acdde17 100644
--- a/drivers/video/fsl-diu-fb.c
+++ b/drivers/video/fsl-diu-fb.c
@@ -375,7 +375,10 @@ struct fsl_diu_data {
struct diu_ad dummy_ad __aligned(8);
struct diu_ad ad[NUM_AOIS] __aligned(8);
u8 gamma[256 * 3] __aligned(32);
- u8 cursor[MAX_CURS * MAX_CURS * 2] __aligned(32);
+ /* It's easier to parse the cursor data as little-endian */
+ __le16 cursor[MAX_CURS * MAX_CURS] __aligned(32);
+ /* Blank cursor data -- used to hide the cursor */
+ __le16 blank_cursor[MAX_CURS * MAX_CURS] __aligned(32);
uint8_t edid_data[EDID_LENGTH];
bool has_edid;
} __aligned(32);
@@ -824,7 +827,6 @@ static void update_lcdc(struct fb_info *info)
/* Program DIU registers */
out_be32(&hw->gamma, DMA_ADDR(data, gamma));
- out_be32(&hw->cursor, DMA_ADDR(data, cursor));
out_be32(&hw->bgnd, 0x007F7F7F); /* Set background to grey */
out_be32(&hw->disp_size, (var->yres << 16) | var->xres);
@@ -968,6 +970,156 @@ static u32 fsl_diu_get_pixel_format(unsigned int bits_per_pixel)
}
/*
+ * Copies a cursor image from user space to the proper place in driver
+ * memory so that the hardware can display the cursor image.
+ *
+ * Cursor data is represented as a sequence of 'width' bits packed into bytes.
+ * That is, the first 8 bits are in the first byte, the second 8 bits in the
+ * second byte, and so on. Therefore, the each row of the cursor is (width +
+ * 7) / 8 bytes of 'data'
+ *
+ * The DIU only supports cursors up to 32x32 (MAX_CURS). We reject cursors
+ * larger than this, so we already know that 'width' <= 32. Therefore, we can
+ * simplify our code by using a 32-bit big-endian integer ("line") to read in
+ * a single line of pixels, and only look at the top 'width' bits of that
+ * integer.
+ *
+ * This could result in an unaligned 32-bit read. For example, if the cursor
+ * is 24x24, then the first three bytes of 'image' contain the pixel data for
+ * the top line of the cursor. We do a 32-bit read of 'image', but we look
+ * only at the top 24 bits. Then we increment 'image' by 3 bytes. The next
+ * read is unaligned. The only problem is that we might read past the end of
+ * 'image' by 1-3 bytes, but that should not cause any problems.
+ */
+static void fsl_diu_load_cursor_image(struct fb_info *info,
+ const void *image, uint16_t bg, uint16_t fg,
+ unsigned int width, unsigned int height)
+{
+ struct mfb_info *mfbi = info->par;
+ struct fsl_diu_data *data = mfbi->parent;
+ __le16 *cursor = data->cursor;
+ __le16 _fg = cpu_to_le16(fg);
+ __le16 _bg = cpu_to_le16(bg);
+ unsigned int h, w;
+
+ for (h = 0; h < height; h++) {
+ uint32_t mask = 1 << 31;
+ uint32_t line = be32_to_cpup(image);
+
+ for (w = 0; w < width; w++) {
+ cursor[w] = (line & mask) ? _fg : _bg;
+ mask >>= 1;
+ }
+
+ cursor += MAX_CURS;
+ image += DIV_ROUND_UP(width, 8);
+ }
+}
+
+/*
+ * Set a hardware cursor. The image data for the cursor is passed via the
+ * fb_cursor object.
+ */
+static int fsl_diu_cursor(struct fb_info *info, struct fb_cursor *cursor)
+{
+ struct mfb_info *mfbi = info->par;
+ struct fsl_diu_data *data = mfbi->parent;
+ struct diu __iomem *hw = data->diu_reg;
+
+ if (cursor->image.width > MAX_CURS || cursor->image.height > MAX_CURS)
+ return -EINVAL;
+
+ /* The cursor size has changed */
+ if (cursor->set & FB_CUR_SETSIZE) {
+ /*
+ * The DIU cursor is a fixed size, so when we get this
+ * message, instead of resizing the cursor, we just clear
+ * all the image data, in expectation of new data. However,
+ * in tests this control does not appear to be normally
+ * called.
+ */
+ memset(data->cursor, 0, sizeof(data->cursor));
+ }
+
+ /* The cursor position has changed (cursor->image.dx|dy) */
+ if (cursor->set & FB_CUR_SETPOS) {
+ uint32_t xx, yy;
+
+ yy = (cursor->image.dy - info->var.yoffset) & 0x7ff;
+ xx = (cursor->image.dx - info->var.xoffset) & 0x7ff;
+
+ out_be32(&hw->curs_pos, yy << 16 | xx);
+ }
+
+ /*
+ * FB_CUR_SETIMAGE - the cursor image has changed
+ * FB_CUR_SETCMAP - the cursor colors has changed
+ * FB_CUR_SETSHAPE - the cursor bitmask has changed
+ */
+ if (cursor->set & (FB_CUR_SETSHAPE | FB_CUR_SETCMAP | FB_CUR_SETIMAGE)) {
+ unsigned int image_size + DIV_ROUND_UP(cursor->image.width, 8) * cursor->image.height;
+ unsigned int image_words + DIV_ROUND_UP(image_size, sizeof(uint32_t));
+ unsigned int bg_idx = cursor->image.bg_color;
+ unsigned int fg_idx = cursor->image.fg_color;
+ uint8_t buffer[image_size];
+ uint32_t *image, *source, *mask;
+ uint16_t fg, bg;
+ unsigned int i;
+
+ if (info->state != FBINFO_STATE_RUNNING)
+ return 0;
+
+ /*
+ * Determine the size of the cursor image data. Normally,
+ * it's 8x16.
+ */
+ image_size = DIV_ROUND_UP(cursor->image.width, 8) *
+ cursor->image.height;
+
+ bg = ((info->cmap.red[bg_idx] & 0xf8) << 7) |
+ ((info->cmap.green[bg_idx] & 0xf8) << 2) |
+ ((info->cmap.blue[bg_idx] & 0xf8) >> 3) |
+ 1 << 15;
+
+ fg = ((info->cmap.red[fg_idx] & 0xf8) << 7) |
+ ((info->cmap.green[fg_idx] & 0xf8) << 2) |
+ ((info->cmap.blue[fg_idx] & 0xf8) >> 3) |
+ 1 << 15;
+
+ /* Use 32-bit operations on the data to improve performance */
+ image = (uint32_t *)buffer;
+ source = (uint32_t *)cursor->image.data;
+ mask = (uint32_t *)cursor->mask;
+
+ if (cursor->rop = ROP_XOR)
+ for (i = 0; i < image_words; i++)
+ image[i] = source[i] ^ mask[i];
+ else
+ for (i = 0; i < image_words; i++)
+ image[i] = source[i] & mask[i];
+
+ fsl_diu_load_cursor_image(info, image, bg, fg,
+ cursor->image.width, cursor->image.height);
+ };
+
+ /*
+ * Show or hide the cursor. The cursor data is always stored in the
+ * 'cursor' memory block, and the actual cursor position is always in
+ * the DIU's CURS_POS register. To hide the cursor, we redirect the
+ * CURSOR register to a blank cursor. The show the cursor, we
+ * redirect the CURSOR register to the real cursor data.
+ */
+ if (cursor->enable)
+ out_be32(&hw->cursor, DMA_ADDR(data, cursor));
+ else
+ out_be32(&hw->cursor, DMA_ADDR(data, blank_cursor));
+
+ return 0;
+}
+
+/*
* Using the fb_var_screeninfo in fb_info we set the resolution of this
* particular framebuffer. This function alters the fb_fix_screeninfo stored
* in fb_info. It does not alter var in fb_info since we are using that
@@ -1305,6 +1457,7 @@ static struct fb_ops fsl_diu_ops = {
.fb_ioctl = fsl_diu_ioctl,
.fb_open = fsl_diu_open,
.fb_release = fsl_diu_release,
+ .fb_cursor = fsl_diu_cursor,
};
static int install_fb(struct fb_info *info)
--
1.7.3.4
^ permalink raw reply related
* Re: fb: Rework locking to fix lock ordering on takeover
From: Alan Cox @ 2013-01-15 18:41 UTC (permalink / raw)
To: sedat.dilek
Cc: Andrew Morton, Linus Torvalds, linux-fbdev, LKML,
Rafael J. Wysocki
In-Reply-To: <CA+icZUVJ5hbPJvV4LMFGgD3Sto5=EV=MO9nutYdJwkiRrmpNJQ@mail.gmail.com>
> A disappeared/busy/not-answering maintainer is not an excuse for
> handling serious regressions (even here in this case there are fixes
> around),
It's *not* a regression - that's the horrible bit. If it was a regression
we'd just back the changes out, wait for (or switch) maintainer and be
happy a release later.
Its a piece of terrible design that is years old and a bug that is at
least two years old which caused random hangs on Fedora boxes during boot
up and so on for several releases. What has happened is Daniel's changes
made the bug *visible* as it's now lockdep splatted and can thus be
analyzed and worked upon.
We are pretty good at regression squashing because you can just rewind a
bit, and try again later. In this case rewinding the lockdep splat
simply turns it back into random silent hangs.
> Personally, I am still missing a mei-driver fix [2] and a libata-dev fix [3].
> Both issues are not new to the maintainers.
> Not sure if shouting louder is the best strategy here.
Really its a kernel summit question. IMHO we ought to have a policy
that anything of any relevance has *two* maintainers or more. That way
there is always someone to help pick a new maintainer if one drops out
and we are mostly not at the mercy of real world happenings. We also need
to be much more active in giving maintainers the boot if they vanish (and
having two maintainers will balance the effect nicely).
In practice I think most maintainers can offhand name the person they'd
pick to replace them, so they can pretty easily switch to two maintainers.
> It would be great to have a place like a "board of arbitration" where
> someone can send blames.
There is a ton of stuff in bugzilla including fixes for some years old
stuff (eg bluetooth on some dongle types that broke in 2.6.3x). It's not
a case of inventing bodies to handle stuff, it's a case of two things
- people getting off their backsides to fix it
- enabling those people to get the job done
Finger pointing statistics and shame lists such as Rafael did are just
tools to help. At the end of the day its about people doing stuff.
Alan
^ permalink raw reply
* Re: 3.8-rc2 lockdep complains about console_lock vs. fb_notifier_list.rwsem
From: Takashi Iwai @ 2013-01-15 16:46 UTC (permalink / raw)
To: Andrew Morton; +Cc: sedat.dilek, Jiri Kosina, linux-fbdev, LKML, alan
In-Reply-To: <s5hip6yzeo9.wl%tiwai@suse.de>
At Tue, 15 Jan 2013 15:47:18 +0100,
Takashi Iwai wrote:
>
> At Tue, 15 Jan 2013 15:25:18 +0100,
> Takashi Iwai wrote:
> >
> > At Sat, 5 Jan 2013 13:13:27 +0100,
> > Sedat Dilek wrote:
> > >
> > > Hi Jiri,
> > >
> > > ...known issue (see thread in [1]), please feel free to test patches
> > > from Alan and Andrew (see [1], [2] and [3]) and report.
> > >
> > > Regards,
> > > - Sedat -
> > >
> > > [1] http://marc.info/?t\x135309396400003&r=1&w=2
> > > [2] http://ozlabs.org/~akpm/mmots/broken-out/fb-rework-locking-to-fix-lock-ordering-on-takeover.patch
> > > [3] http://ozlabs.org/~akpm/mmots/broken-out/fb-rework-locking-to-fix-lock-ordering-on-takeover-fix.patch
> > > [4] http://ozlabs.org/~akpm/mmots/broken-out/fb-rework-locking-to-fix-lock-ordering-on-takeover-fix-2.patch
> >
> > I've hit this bug and tried the patch [2] ([3] and [4] are gone).
> > Unfortunately the deadlock is still reported, as seen below.
> >
> > A similar fix for fbcon_unbind(), splitting an unlocked version of
> > unbind_con_driver() and call it?
> >
> > (BTW, the patch [2] contains strange characters in the comments, and
> > has a few coding issues easily detected by checkpatch.pl.)
>
> The fix patch for coding issue is below.
> Feel free to fold into the original patch.
... and the additional patch below fixed the lockdep warning on my
machine.
Takashi
=
From: Takashi Iwai <tiwai@suse.de>
Subject: [PATCH] fb: Yet another band-aid for fixing lockdep mess
I've still got lockdep warnings even after Alan's patch, and it seems
that yet more band aids are required to paper over similar paths for
unbind_con_driver() and unregister_con_driver(). After this hack,
lockdep warnings are finally gone.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
drivers/tty/vt/vt.c | 43 ++++++++++++++++++++++++++++---------------
drivers/video/console/fbcon.c | 4 ++--
drivers/video/fbmem.c | 4 ++++
include/linux/console.h | 1 +
include/linux/vt_kern.h | 2 ++
5 files changed, 37 insertions(+), 17 deletions(-)
diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index 1db1c8d..3947e8d 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -3135,6 +3135,18 @@ static int con_is_graphics(const struct consw *csw, int first, int last)
*/
int unbind_con_driver(const struct consw *csw, int first, int last, int deflt)
{
+ int retval;
+
+ console_lock();
+ retval = do_unbind_con_driver(csw, first, last, deflt);
+ console_unlock();
+ return retval;
+}
+EXPORT_SYMBOL(unbind_con_driver);
+
+/* unlocked version of unbind_con_driver() */
+int do_unbind_con_driver(const struct consw *csw, int first, int last, int deflt)
+{
struct module *owner = csw->owner;
const struct consw *defcsw = NULL;
struct con_driver *con_driver = NULL, *con_back = NULL;
@@ -3143,7 +3155,7 @@ int unbind_con_driver(const struct consw *csw, int first, int last, int deflt)
if (!try_module_get(owner))
return -ENODEV;
- console_lock();
+ WARN_CONSOLE_UNLOCKED();
/* check if driver is registered and if it is unbindable */
for (i = 0; i < MAX_NR_CON_DRIVER; i++) {
@@ -3156,10 +3168,8 @@ int unbind_con_driver(const struct consw *csw, int first, int last, int deflt)
}
}
- if (retval) {
- console_unlock();
+ if (retval)
goto err;
- }
retval = -ENODEV;
@@ -3175,15 +3185,11 @@ int unbind_con_driver(const struct consw *csw, int first, int last, int deflt)
}
}
- if (retval) {
- console_unlock();
+ if (retval)
goto err;
- }
- if (!con_is_bound(csw)) {
- console_unlock();
+ if (!con_is_bound(csw))
goto err;
- }
first = max(first, con_driver->first);
last = min(last, con_driver->last);
@@ -3212,13 +3218,12 @@ int unbind_con_driver(const struct consw *csw, int first, int last, int deflt)
/* ignore return value, binding should not fail */
do_bind_con_driver(defcsw, first, last, deflt);
- console_unlock();
err:
module_put(owner);
return retval;
}
-EXPORT_SYMBOL(unbind_con_driver);
+EXPORT_SYMBOL_GPL(do_unbind_con_driver);
static int vt_bind(struct con_driver *con)
{
@@ -3605,9 +3610,18 @@ EXPORT_SYMBOL(register_con_driver);
*/
int unregister_con_driver(const struct consw *csw)
{
- int i, retval = -ENODEV;
+ int retval;
console_lock();
+ retval = do_unregister_con_driver(csw);
+ console_unlock();
+ return retval;
+}
+EXPORT_SYMBOL(unregister_con_driver);
+
+int do_unregister_con_driver(const struct consw *csw)
+{
+ int i, retval = -ENODEV;
/* cannot unregister a bound driver */
if (con_is_bound(csw))
@@ -3633,10 +3647,9 @@ int unregister_con_driver(const struct consw *csw)
}
}
err:
- console_unlock();
return retval;
}
-EXPORT_SYMBOL(unregister_con_driver);
+EXPORT_SYMBOL_GPL(do_unregister_con_driver);
/*
* If we support more console drivers, this function is used
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index 4bd7820..2aef9ca 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -3004,7 +3004,7 @@ static int fbcon_unbind(void)
{
int ret;
- ret = unbind_con_driver(&fb_con, first_fb_vc, last_fb_vc,
+ ret = do_unbind_con_driver(&fb_con, first_fb_vc, last_fb_vc,
fbcon_is_default);
if (!ret)
@@ -3077,7 +3077,7 @@ static int fbcon_fb_unregistered(struct fb_info *info)
primary_device = -1;
if (!num_registered_fb)
- unregister_con_driver(&fb_con);
+ do_unregister_con_driver(&fb_con);
return 0;
}
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index d8d9831..070b9a1 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -1668,8 +1668,10 @@ static int do_unregister_framebuffer(struct fb_info *fb_info)
if (!lock_fb_info(fb_info))
return -ENODEV;
+ console_lock();
event.info = fb_info;
ret = fb_notifier_call_chain(FB_EVENT_FB_UNBIND, &event);
+ console_unlock();
unlock_fb_info(fb_info);
if (ret)
@@ -1684,7 +1686,9 @@ static int do_unregister_framebuffer(struct fb_info *fb_info)
num_registered_fb--;
fb_cleanup_device(fb_info);
event.info = fb_info;
+ console_lock();
fb_notifier_call_chain(FB_EVENT_FB_UNREGISTERED, &event);
+ console_unlock();
/* this may free fb info */
put_fb_info(fb_info);
diff --git a/include/linux/console.h b/include/linux/console.h
index 4ef4307..47b858c 100644
--- a/include/linux/console.h
+++ b/include/linux/console.h
@@ -77,6 +77,7 @@ extern const struct consw prom_con; /* SPARC PROM console */
int con_is_bound(const struct consw *csw);
int register_con_driver(const struct consw *csw, int first, int last);
int unregister_con_driver(const struct consw *csw);
+int do_unregister_con_driver(const struct consw *csw);
int take_over_console(const struct consw *sw, int first, int last, int deflt);
int do_take_over_console(const struct consw *sw, int first, int last, int deflt);
void give_up_console(const struct consw *sw);
diff --git a/include/linux/vt_kern.h b/include/linux/vt_kern.h
index 50ae7d0..dbbc6bf 100644
--- a/include/linux/vt_kern.h
+++ b/include/linux/vt_kern.h
@@ -130,6 +130,8 @@ void vt_event_post(unsigned int event, unsigned int old, unsigned int new);
int vt_waitactive(int n);
void change_console(struct vc_data *new_vc);
void reset_vc(struct vc_data *vc);
+extern int do_unbind_con_driver(const struct consw *csw, int first, int last,
+ int deflt);
extern int unbind_con_driver(const struct consw *csw, int first, int last,
int deflt);
int vty_init(const struct file_operations *console_fops);
--
1.8.1
^ permalink raw reply related
* Re: [PATCH] ARM: AM33XX: clock: SET_RATE_PARENT in lcd path
From: Mike Turquette @ 2013-01-15 16:16 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1358256897-26275-1-git-send-email-afzal@ti.com>
Quoting Afzal Mohammed (2013-01-15 05:34:57)
> LCDC clock node is a one that does not have set rate capability. It
> just passes on the rate that is sent downstream by it's parent. While
> lcdc clock parent and it's grand parent - dpll_disp_m2_ck and
> dpll_disp_ck has the capability to configure rate.
>
> And the default rates provided by LCDC clock's ancestors are not
> sufficient to obtain pixel clock for current LCDC use cases, hence
> currently display would not work on AM335x SoC's (with driver
> modifications in platfrom independent way).
>
> Hence inform clock framework to propogate set rate for LCDC clock as
> well as it's parent - dpll_disp_m2_ck. With this change, set rate on
> LCDC clock would get propogated till dpll_disp_ck via dpll_disp_m2_ck,
> hence allowing the driver (same driver is used in DaVinci too) to set
> rates using LCDC clock without worrying about platform dependent clock
> details.
>
> Signed-off-by: Afzal Mohammed <afzal@ti.com>
> ---
>
> Based on v3.8-rc3
>
> arch/arm/mach-omap2/cclock33xx_data.c | 9 ++++++---
> 1 file changed, 6 insertions(+), 3 deletions(-)
>
> diff --git a/arch/arm/mach-omap2/cclock33xx_data.c b/arch/arm/mach-omap2/cclock33xx_data.c
> index ea64ad6..b731216 100644
> --- a/arch/arm/mach-omap2/cclock33xx_data.c
> +++ b/arch/arm/mach-omap2/cclock33xx_data.c
> @@ -284,9 +284,10 @@ DEFINE_STRUCT_CLK(dpll_disp_ck, dpll_core_ck_parents, dpll_ddr_ck_ops);
> * TODO: Add clksel here (sys_clkin, CORE_CLKOUTM6, PER_CLKOUTM2
> * and ALT_CLK1/2)
> */
> -DEFINE_CLK_DIVIDER(dpll_disp_m2_ck, "dpll_disp_ck", &dpll_disp_ck, 0x0,
> - AM33XX_CM_DIV_M2_DPLL_DISP, AM33XX_DPLL_CLKOUT_DIV_SHIFT,
> - AM33XX_DPLL_CLKOUT_DIV_WIDTH, CLK_DIVIDER_ONE_BASED, NULL);
> +DEFINE_CLK_DIVIDER(dpll_disp_m2_ck, "dpll_disp_ck", &dpll_disp_ck,
> + CLK_SET_RATE_PARENT, AM33XX_CM_DIV_M2_DPLL_DISP,
> + AM33XX_DPLL_CLKOUT_DIV_SHIFT, AM33XX_DPLL_CLKOUT_DIV_WIDTH,
> + CLK_DIVIDER_ONE_BASED, NULL);
>
> /* DPLL_PER */
> static struct dpll_data dpll_per_dd = {
> @@ -932,6 +933,8 @@ int __init am33xx_clk_init(void)
> cpu_clkflg = CK_AM33XX;
> }
>
> + lcd_gclk.flags |= CLK_SET_RATE_PARENT;
> +
Afzal,
This is a bit hacky. Someone looking at the definition of struct
lcd_gclk above cannot easily tell that CLK_SET_RATE_PARENT is set below.
Also if other clocks need flags set at a later date then this will
become a big ugly block of flag setting.
I hope to move away from these macros some day, but in the mean time it
might be good to have a DEFINE_STRUCT_CLK_FLAGS macro which adds in an
argument struct clk->flags.
Paul, any thoughts on yet another macro?
Thanks,
Mike
> for (c = am33xx_clks; c < am33xx_clks + ARRAY_SIZE(am33xx_clks); c++) {
> if (c->cpu & cpu_clkflg) {
> clkdev_add(&c->lk);
> --
> 1.7.9.5
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH v2 12/12] video: da8xx-fb: set upstream clock rate (if reqd)
From: Mike Turquette @ 2013-01-15 15:32 UTC (permalink / raw)
To: Afzal Mohammed, Florian Tobias Schandinat, Tomi Valkeinen,
Grant Likely, Rob Herring, Rob Landley, Sekhar Nori, linux-omap,
linux-fbdev, devicetree-discuss, linux-doc, linux-kernel
In-Reply-To: <26e787b021cda89a080f80657c2094b9ff2decaf.1358251448.git.afzal@ti.com>
Quoting Afzal Mohammed (2013-01-15 05:44:36)
> LCDC IP has a clock divider to adjust pixel clock, this limits pixel
> clock range to fck/255 - fck/2(fck - rate of input clock to LCDC IP).
> In the case of AM335x, where this IP is present, default fck is not
> sufficient to provide normal pixel clock rates, hence rendering this
> driver unusable on AM335x.
>
> If input clock too is configurable, allowable range of pixel clock
> would increase. Here initially it is checked whether with present fck,
> divider in IP could be configured to obtain required rate, if not,
> fck is adjusted. This makes it usable on AM335x.
>
> Note:
> A better (if allowable) solution may be to represent clock divider in
> LCDC IP as a basic divider clock - the one defined in common clock
> framework. But for this to happen, all the platform's using this driver
> should be using common clock framework (DaVinci is yet to be converted
> to use common clock framework). And it has to be determined whether
> common clock framework allows this kind of a clock modelling inside a
> driver and for this to be part of clock tree. Advantage of doing so
> would be better resolution for pixel clock, even though without this
> existing use cases are working properly. Or another extreme alternative
> would be to replicate clk-divider of common clock framework inside the
> driver, but that probably is not preferred and not worth as it would be
> duplication and without much advantage to existing users.
>
Afzal,
Modeling the divider inside your IP block as a clock is supported in the
common clock framework. Linking up these sorts of clocks to the clock
tree was one of the original design goals of CCF.
Regarding DaVinci: converting that platform over to use CCF would be the
best approach. An alternative would be that you could break
single-image boot for AM335x and DaVinci, by having AM335x use CCF and
DaVinci use the legacy clock framework. From the LCDC driver's
perspective this should not matter and is indeed the purpose of the
clk.h api and clkdev interfaces, however looking at this driver I can
see there would still be a lot ifdef-ery going on... better to just
convert everything over to CCF.
Regards,
Mike
> Signed-off-by: Afzal Mohammed <afzal@ti.com>
> ---
>
> v2: new patch
>
> drivers/video/da8xx-fb.c | 76 +++++++++++++++++++++++++++++++++++-----------
> 1 file changed, 58 insertions(+), 18 deletions(-)
>
> diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
> index 5455682..09dfa12 100644
> --- a/drivers/video/da8xx-fb.c
> +++ b/drivers/video/da8xx-fb.c
> @@ -133,6 +133,9 @@
> #define WSI_TIMEOUT 50
> #define PALETTE_SIZE 256
>
> +#define CLK_MIN_DIV 2
> +#define CLK_MAX_DIV 255
> +
> static void __iomem *da8xx_fb_reg_base;
> static struct resource *lcdc_regs;
> static unsigned int lcd_revision;
> @@ -683,23 +686,21 @@ static void da8xx_fb_lcd_reset(void)
> }
> }
>
> -static inline unsigned da8xx_fb_calc_clk_divider(struct da8xx_fb_par *par,
> - unsigned pixclock)
> -{
> - return par->lcd_fck_rate / (PICOS2KHZ(pixclock) * 1000);
> -}
> -
> -static inline unsigned da8xx_fb_round_clk(struct da8xx_fb_par *par,
> - unsigned pixclock)
> +static int da8xx_fb_config_clk_divider(struct da8xx_fb_par *par,
> + unsigned div, unsigned rate)
> {
> - unsigned div;
> + int ret;
>
> - div = da8xx_fb_calc_clk_divider(par, pixclock);
> - return KHZ2PICOS(par->lcd_fck_rate / (1000 * div));
> -}
> + if (par->lcd_fck_rate != rate) {
> + ret = clk_set_rate(par->lcdc_clk, rate);
> + if (IS_ERR_VALUE(ret)) {
> + dev_err(par->dev,
> + "unable to set clock rate at %u\n", rate);
> + return ret;
> + }
> + par->lcd_fck_rate = clk_get_rate(par->lcdc_clk);
> + }
>
> -static inline void da8xx_fb_config_clk_divider(unsigned div)
> -{
> /* Configure the LCD clock divisor. */
> lcdc_write(LCD_CLK_DIVISOR(div) |
> (LCD_RASTER_MODE & 0x1), LCD_CTRL_REG);
> @@ -707,14 +708,49 @@ static inline void da8xx_fb_config_clk_divider(unsigned div)
> if (lcd_revision = LCD_VERSION_2)
> lcdc_write(LCD_V2_DMA_CLK_EN | LCD_V2_LIDD_CLK_EN |
> LCD_V2_CORE_CLK_EN, LCD_CLK_ENABLE_REG);
> +
> + return 0;
> +}
> +
> +static unsigned int da8xx_fb_calc_clk_divider(struct da8xx_fb_par *par,
> + unsigned pixclock,
> + unsigned *rate)
> +{
> + unsigned div;
> +
> + pixclock = PICOS2KHZ(pixclock) * 1000;
> +
> + *rate = par->lcd_fck_rate;
> +
> + if (pixclock < (*rate / CLK_MAX_DIV)) {
> + *rate = clk_round_rate(par->lcdc_clk, pixclock * CLK_MAX_DIV);
> + div = CLK_MAX_DIV;
> + } else if (pixclock > (*rate / CLK_MIN_DIV)) {
> + *rate = clk_round_rate(par->lcdc_clk, pixclock * CLK_MIN_DIV);
> + div = CLK_MIN_DIV;
> + } else {
> + div = *rate / pixclock;
> + }
> +
> + return div;
> }
>
> -static inline void da8xx_fb_calc_config_clk_divider(struct da8xx_fb_par *par,
> +static inline int da8xx_fb_calc_config_clk_divider(struct da8xx_fb_par *par,
> struct fb_videomode *mode)
> {
> - unsigned div = da8xx_fb_calc_clk_divider(par, mode->pixclock);
> + unsigned rate;
> + unsigned div = da8xx_fb_calc_clk_divider(par, mode->pixclock, &rate);
>
> - da8xx_fb_config_clk_divider(div);
> + return da8xx_fb_config_clk_divider(par, div, rate);
> +}
> +
> +static inline unsigned da8xx_fb_round_clk(struct da8xx_fb_par *par,
> + unsigned pixclock)
> +{
> + unsigned div, rate;
> +
> + div = da8xx_fb_calc_clk_divider(par, pixclock, &rate);
> + return KHZ2PICOS(rate / (1000 * div));
> }
>
> static int lcd_init(struct da8xx_fb_par *par, const struct lcd_ctrl_config *cfg,
> @@ -723,7 +759,11 @@ static int lcd_init(struct da8xx_fb_par *par, const struct lcd_ctrl_config *cfg,
> u32 bpp;
> int ret = 0;
>
> - da8xx_fb_calc_config_clk_divider(par, panel);
> + ret = da8xx_fb_calc_config_clk_divider(par, panel);
> + if (IS_ERR_VALUE(ret)) {
> + dev_err(par->dev, "unable to configure clock\n");
> + return ret;
> + }
>
> if (panel->sync & FB_SYNC_CLK_INVERT)
> lcdc_write((lcdc_read(LCD_RASTER_TIMING_2_REG) |
> --
> 1.7.9.5
^ permalink raw reply
* Re: 3.8-rc2 lockdep complains about console_lock vs. fb_notifier_list.rwsem
From: Takashi Iwai @ 2013-01-15 14:47 UTC (permalink / raw)
To: Andrew Morton; +Cc: sedat.dilek, Jiri Kosina, linux-fbdev, LKML, alan
In-Reply-To: <s5hpq16zfox.wl%tiwai@suse.de>
At Tue, 15 Jan 2013 15:25:18 +0100,
Takashi Iwai wrote:
>
> At Sat, 5 Jan 2013 13:13:27 +0100,
> Sedat Dilek wrote:
> >
> > Hi Jiri,
> >
> > ...known issue (see thread in [1]), please feel free to test patches
> > from Alan and Andrew (see [1], [2] and [3]) and report.
> >
> > Regards,
> > - Sedat -
> >
> > [1] http://marc.info/?t\x135309396400003&r=1&w=2
> > [2] http://ozlabs.org/~akpm/mmots/broken-out/fb-rework-locking-to-fix-lock-ordering-on-takeover.patch
> > [3] http://ozlabs.org/~akpm/mmots/broken-out/fb-rework-locking-to-fix-lock-ordering-on-takeover-fix.patch
> > [4] http://ozlabs.org/~akpm/mmots/broken-out/fb-rework-locking-to-fix-lock-ordering-on-takeover-fix-2.patch
>
> I've hit this bug and tried the patch [2] ([3] and [4] are gone).
> Unfortunately the deadlock is still reported, as seen below.
>
> A similar fix for fbcon_unbind(), splitting an unlocked version of
> unbind_con_driver() and call it?
>
> (BTW, the patch [2] contains strange characters in the comments, and
> has a few coding issues easily detected by checkpatch.pl.)
The fix patch for coding issue is below.
Feel free to fold into the original patch.
Takashi
=
From: Takashi Iwai <tiwai@suse.de>
Subject: [PATCH] fb: Fix coding style and remove stray non-ascii chars
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
drivers/tty/vt/vt.c | 4 ++--
drivers/video/console/fbcon.c | 3 +--
drivers/video/fbmem.c | 4 ++--
3 files changed, 5 insertions(+), 6 deletions(-)
diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index f307196..1db1c8d 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -3653,7 +3653,7 @@ int do_take_over_console(const struct consw *csw, int first, int last, int deflt
/*
* If we get an busy error we still want to bind the console driver
* and return success, as we may have unbound the console driver
- * but not unregistered it.
+ * but not unregistered it.
*/
if (err = -EBUSY)
err = 0;
@@ -3679,7 +3679,7 @@ int take_over_console(const struct consw *csw, int first, int last, int deflt)
/*
* If we get an busy error we still want to bind the console driver
* and return success, as we may have unbound the console driver
- * but not unregistered it.
+ * but not unregistered it.
*/
if (err = -EBUSY)
err = 0;
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index c75f8ce..4bd7820 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -546,9 +546,8 @@ static int do_fbcon_takeover(int show_logo)
fbcon_is_default);
if (err) {
- for (i = first_fb_vc; i <= last_fb_vc; i++) {
+ for (i = first_fb_vc; i <= last_fb_vc; i++)
con2fb_map[i] = -1;
- }
info_idx = -1;
} else {
fbcon_has_console_bind = 1;
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index 564ebe9..d8d9831 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -1650,9 +1650,9 @@ static int do_register_framebuffer(struct fb_info *fb_info)
event.info = fb_info;
if (!lock_fb_info(fb_info))
return -ENODEV;
- console_lock();
+ console_lock();
fb_notifier_call_chain(FB_EVENT_FB_REGISTERED, &event);
- console_unlock();
+ console_unlock();
unlock_fb_info(fb_info);
return 0;
}
--
1.8.1
^ permalink raw reply related
* Re: 3.8-rc2 lockdep complains about console_lock vs. fb_notifier_list.rwsem
From: Takashi Iwai @ 2013-01-15 14:25 UTC (permalink / raw)
To: sedat.dilek; +Cc: Jiri Kosina, linux-fbdev, LKML, alan, Andrew Morton
In-Reply-To: <CA+icZUUxgRsGkYAmZ=JxTwPvdhTzpGLcxm6+VSq9jnfYPVXj4Q@mail.gmail.com>
At Sat, 5 Jan 2013 13:13:27 +0100,
Sedat Dilek wrote:
>
> Hi Jiri,
>
> ...known issue (see thread in [1]), please feel free to test patches
> from Alan and Andrew (see [1], [2] and [3]) and report.
>
> Regards,
> - Sedat -
>
> [1] http://marc.info/?t\x135309396400003&r=1&w=2
> [2] http://ozlabs.org/~akpm/mmots/broken-out/fb-rework-locking-to-fix-lock-ordering-on-takeover.patch
> [3] http://ozlabs.org/~akpm/mmots/broken-out/fb-rework-locking-to-fix-lock-ordering-on-takeover-fix.patch
> [4] http://ozlabs.org/~akpm/mmots/broken-out/fb-rework-locking-to-fix-lock-ordering-on-takeover-fix-2.patch
I've hit this bug and tried the patch [2] ([3] and [4] are gone).
Unfortunately the deadlock is still reported, as seen below.
A similar fix for fbcon_unbind(), splitting an unlocked version of
unbind_con_driver() and call it?
(BTW, the patch [2] contains strange characters in the comments, and
has a few coding issues easily detected by checkpatch.pl.)
thanks,
Takashi
=
[ 3.228454] [drm] Initialized drm 1.1.0 20060810
[ 3.317144] [drm] radeon defaulting to kernel modesetting.
[ 3.330546] [drm] radeon kernel modesetting enabled.
[ 3.343942] checking generic (c0000000 1000000) vs hw (c0000000 10000000)
[ 3.343946] fb: conflicting fb hw usage radeondrmfb vs VESA VGA - removing generic driver
[ 3.357376]
[ 3.357377] ===========================
[ 3.357378] [ INFO: possible circular locking dependency detected ]
[ 3.357380] 3.8.0-rc3-test+ #82 Not tainted
[ 3.357381] -------------------------------------------------------
[ 3.357383] udevd/137 is trying to acquire lock:
[ 3.357394] (console_lock){+.+.+.}, at: [<ffffffff8140385f>] unbind_con_driver+0x3f/0x200
[ 3.357395]
[ 3.357395] but task is already holding lock:
[ 3.357402] ((fb_notifier_list).rwsem){.+.+.+}, at: [<ffffffff810799b1>] __blocking_notifier_call_chain+0x51/0xc0
[ 3.357403]
[ 3.357403] which lock already depends on the new lock.
[ 3.357403]
[ 3.357404]
[ 3.357404] the existing dependency chain (in reverse order) is:
[ 3.357407]
[ 3.357407] -> #1 ((fb_notifier_list).rwsem){.+.+.+}:
[ 3.357411] [<ffffffff810b605a>] lock_acquire+0xaa/0x210
[ 3.357417] [<ffffffff81643dc2>] down_read+0x42/0x57
[ 3.357419] [<ffffffff810799b1>] __blocking_notifier_call_chain+0x51/0xc0
[ 3.357422] [<ffffffff81079a31>] blocking_notifier_call_chain+0x11/0x20
[ 3.357426] [<ffffffff8138cbe6>] fb_notifier_call_chain+0x16/0x20
[ 3.357428] [<ffffffff8138e302>] register_framebuffer+0x1c2/0x2f0
[ 3.357433] [<ffffffff81d1748e>] vesafb_probe+0x6e0/0x760
[ 3.357437] [<ffffffff8142afbe>] platform_drv_probe+0x3e/0x70
[ 3.357440] [<ffffffff81428d26>] driver_probe_device+0x86/0x390
[ 3.357442] [<ffffffff814290d3>] __driver_attach+0xa3/0xb0
[ 3.357445] [<ffffffff81426dbd>] bus_for_each_dev+0x4d/0x90
[ 3.357447] [<ffffffff814286a9>] driver_attach+0x19/0x20
[ 3.357450] [<ffffffff81428308>] bus_add_driver+0x1a8/0x290
[ 3.357452] [<ffffffff81429792>] driver_register+0x72/0x170
[ 3.357455] [<ffffffff8142a7e1>] platform_driver_register+0x41/0x50
[ 3.357458] [<ffffffff8142a806>] platform_driver_probe+0x16/0xa0
[ 3.357460] [<ffffffff81d16d6b>] vesafb_init+0x215/0x258
[ 3.357464] [<ffffffff810002e2>] do_one_initcall+0x122/0x180
[ 3.357468] [<ffffffff816258ec>] kernel_init+0x1fc/0x370
[ 3.357471] [<ffffffff8164e1fc>] ret_from_fork+0x7c/0xb0
[ 3.357474]
[ 3.357474] -> #0 (console_lock){+.+.+.}:
[ 3.357476] [<ffffffff810b5055>] __lock_acquire+0x1385/0x1cc0
[ 3.357478] [<ffffffff810b605a>] lock_acquire+0xaa/0x210
[ 3.357482] [<ffffffff81048fbf>] console_lock+0x6f/0x80
[ 3.357485] [<ffffffff8140385f>] unbind_con_driver+0x3f/0x200
[ 3.357489] [<ffffffff8139aeb7>] fbcon_event_notify+0x447/0x8b0
[ 3.357492] [<ffffffff8164a225>] notifier_call_chain+0x55/0x110
[ 3.357495] [<ffffffff810799c7>] __blocking_notifier_call_chain+0x67/0xc0
[ 3.357497] [<ffffffff81079a31>] blocking_notifier_call_chain+0x11/0x20
[ 3.357500] [<ffffffff8138cbe6>] fb_notifier_call_chain+0x16/0x20
[ 3.357502] [<ffffffff8138debb>] do_unregister_framebuffer+0x5b/0x110
[ 3.357505] [<ffffffff8138e108>] do_remove_conflicting_framebuffers+0x158/0x190
[ 3.357507] [<ffffffff8138e46a>] remove_conflicting_framebuffers+0x3a/0x60
[ 3.357532] [<ffffffffa00df16b>] radeon_pci_probe+0x8b/0xd0 [radeon]
[ 3.357536] [<ffffffff8136d5a6>] local_pci_probe+0x46/0x80
[ 3.357539] [<ffffffff8136d7f1>] pci_device_probe+0x101/0x110
[ 3.357542] [<ffffffff81428d26>] driver_probe_device+0x86/0x390
[ 3.357544] [<ffffffff814290d3>] __driver_attach+0xa3/0xb0
[ 3.357547] [<ffffffff81426dbd>] bus_for_each_dev+0x4d/0x90
[ 3.357549] [<ffffffff814286a9>] driver_attach+0x19/0x20
[ 3.357552] [<ffffffff81428308>] bus_add_driver+0x1a8/0x290
[ 3.357554] [<ffffffff81429792>] driver_register+0x72/0x170
[ 3.357557] [<ffffffff8136c60f>] __pci_register_driver+0x5f/0x70
[ 3.357577] [<ffffffffa006ec3a>] drm_pci_init+0x11a/0x130 [drm]
[ 3.357594] [<ffffffffa01c20ec>] radeon_init+0xec/0x1000 [radeon]
[ 3.357597] [<ffffffff810002e2>] do_one_initcall+0x122/0x180
[ 3.357600] [<ffffffff810c4b53>] load_module+0x1043/0x1510
[ 3.357603] [<ffffffff810c50f7>] sys_init_module+0xd7/0x120
[ 3.357605] [<ffffffff8164e2ad>] system_call_fastpath+0x1a/0x1f
[ 3.357606]
[ 3.357606] other info that might help us debug this:
[ 3.357606]
[ 3.357607] Possible unsafe locking scenario:
[ 3.357607]
[ 3.357608] CPU0 CPU1
[ 3.357609] ---- ----
[ 3.357611] lock((fb_notifier_list).rwsem);
[ 3.357613] lock(console_lock);
[ 3.357615] lock((fb_notifier_list).rwsem);
[ 3.357616] lock(console_lock);
[ 3.357617]
[ 3.357617] *** DEADLOCK ***
[ 3.357617]
[ 3.357619] 5 locks held by udevd/137:
[ 3.357624] #0: (&__lockdep_no_validate__){......}, at: [<ffffffff81429083>] __driver_attach+0x53/0xb0
[ 3.357628] #1: (&__lockdep_no_validate__){......}, at: [<ffffffff81429091>] __driver_attach+0x61/0xb0
[ 3.357633] #2: (registration_lock){+.+.+.}, at: [<ffffffff8138e45b>] remove_conflicting_framebuffers+0x2b/0x60
[ 3.357637] #3: (&fb_info->lock){+.+.+.}, at: [<ffffffff8138d0c1>] lock_fb_info+0x21/0x60
[ 3.357642] #4: ((fb_notifier_list).rwsem){.+.+.+}, at: [<ffffffff810799b1>] __blocking_notifier_call_chain+0x51/0xc0
[ 3.357643]
[ 3.357643] stack backtrace:
[ 3.357645] Pid: 137, comm: udevd Not tainted 3.8.0-rc3-test+ #82
[ 3.357646] Call Trace:
[ 3.357652] [<ffffffff8163b136>] print_circular_bug+0x1fb/0x20c
[ 3.357655] [<ffffffff810b5055>] __lock_acquire+0x1385/0x1cc0
[ 3.357658] [<ffffffff810b605a>] lock_acquire+0xaa/0x210
[ 3.357661] [<ffffffff8140385f>] ? unbind_con_driver+0x3f/0x200
[ 3.357664] [<ffffffff810b2b0d>] ? trace_hardirqs_on+0xd/0x10
[ 3.357667] [<ffffffff81048fbf>] console_lock+0x6f/0x80
[ 3.357670] [<ffffffff8140385f>] ? unbind_con_driver+0x3f/0x200
[ 3.357673] [<ffffffff8140385f>] unbind_con_driver+0x3f/0x200
[ 3.357676] [<ffffffff8134c01e>] ? trace_hardirqs_on_thunk+0x3a/0x3f
[ 3.357680] [<ffffffff8139aeb7>] fbcon_event_notify+0x447/0x8b0
[ 3.357683] [<ffffffff8164a225>] notifier_call_chain+0x55/0x110
[ 3.357685] [<ffffffff810799c7>] __blocking_notifier_call_chain+0x67/0xc0
[ 3.357688] [<ffffffff81079a31>] blocking_notifier_call_chain+0x11/0x20
[ 3.357690] [<ffffffff8138cbe6>] fb_notifier_call_chain+0x16/0x20
[ 3.357693] [<ffffffff8138debb>] do_unregister_framebuffer+0x5b/0x110
[ 3.357696] [<ffffffff8138e108>] do_remove_conflicting_framebuffers+0x158/0x190
[ 3.357698] [<ffffffff8138e46a>] remove_conflicting_framebuffers+0x3a/0x60
[ 3.357717] [<ffffffffa00df16b>] radeon_pci_probe+0x8b/0xd0 [radeon]
[ 3.357721] [<ffffffff8136d5a6>] local_pci_probe+0x46/0x80
[ 3.357724] [<ffffffff8136d7f1>] pci_device_probe+0x101/0x110
[ 3.357727] [<ffffffff81428d26>] driver_probe_device+0x86/0x390
[ 3.357729] [<ffffffff814290d3>] __driver_attach+0xa3/0xb0
[ 3.357732] [<ffffffff81429030>] ? driver_probe_device+0x390/0x390
[ 3.357734] [<ffffffff81426dbd>] bus_for_each_dev+0x4d/0x90
[ 3.357737] [<ffffffff814286a9>] driver_attach+0x19/0x20
[ 3.357740] [<ffffffff81428308>] bus_add_driver+0x1a8/0x290
[ 3.357744] [<ffffffffa01c2000>] ? 0xffffffffa01c1fff
[ 3.357747] [<ffffffff81429792>] driver_register+0x72/0x170
[ 3.357749] [<ffffffffa01c2000>] ? 0xffffffffa01c1fff
[ 3.357752] [<ffffffff8136c60f>] __pci_register_driver+0x5f/0x70
[ 3.357762] [<ffffffffa006ec3a>] drm_pci_init+0x11a/0x130 [drm]
[ 3.357764] [<ffffffffa01c2000>] ? 0xffffffffa01c1fff
[ 3.357767] [<ffffffffa01c2000>] ? 0xffffffffa01c1fff
[ 3.357784] [<ffffffffa01c20ec>] radeon_init+0xec/0x1000 [radeon]
[ 3.357786] [<ffffffff810002e2>] do_one_initcall+0x122/0x180
[ 3.357789] [<ffffffff810c4b53>] load_module+0x1043/0x1510
[ 3.357792] [<ffffffff8135d260>] ? ddebug_proc_open+0xb0/0xb0
[ 3.357796] [<ffffffff810c50f7>] sys_init_module+0xd7/0x120
[ 3.357798] [<ffffffff8164e2ad>] system_call_fastpath+0x1a/0x1f
^ permalink raw reply
* RE: [PATCH 08/10] video: da8xx-fb: obtain fb_videomode info from dt
From: Mohammed, Afzal @ 2013-01-15 13:59 UTC (permalink / raw)
To: Steffen Trumtrar
Cc: linux-fbdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
Florian Tobias Schandinat,
devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org,
linux-doc-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, Nori, Sekhar,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, Rob Herring,
Valkeinen, Tomi,
linux-omap-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
In-Reply-To: <C8443D0743D26F4388EA172BF4E2A7A93EA7FC7A-Er742YJ7I/eIQmiDNMet8wC/G2K4zDHf@public.gmane.org>
SGkgU3RlZmZlbiwNCg0KT24gTW9uLCBKYW4gMDcsIDIwMTMgYXQgMTQ6NTE6MTUsIE1vaGFtbWVk
LCBBZnphbCB3cm90ZToNCj4gT24gTW9uLCBKYW4gMDcsIDIwMTMgYXQgMTQ6NDE6MzEsIFN0ZWZm
ZW4gVHJ1bXRyYXIgd3JvdGU6DQo+ID4gT24gTW9uLCBKYW4gMDcsIDIwMTMgYXQgMTA6NDE6MzBB
TSArMDUzMCwgQWZ6YWwgTW9oYW1tZWQgd3JvdGU6DQoNCj4gPiA+ICstIGRpc3BsYXktdGltaW5n
czogbGlzdCBvZiBkaWZmZXJlbnQgdmlkZW9tb2RlcyBzdXBwb3J0ZWQgYnkgdGhlIGxjZA0KPiA+
ID4gKyAgcGFuZWwsIHJlcHJlc2VudGVkIGFzIGNoaWxkcywgY2FuIGhhdmUgbXVsdGlwbGUgbW9k
ZXMgc3VwcG9ydGVkLCBpZg0KPiA+ID4gKyAgb25seSBvbmUsIHRoZW4gaXQgaXMgY29uc2lkZXJl
ZCBuYXRpdmUgbW9kZSwgaWYgbXVsdGlwbGUgbW9kZXMgYXJlDQo+ID4gPiArICBwcm92aWRlZCwg
bmF0aXZlIG1vZGUgY2FuIGJlIHNldCBleHBsaWNpdGx5LCBtb3JlIGRldGFpbHMgYXZhaWxhYmxl
DQo+ID4gPiArICBARG9jdW1lbnRhdGlvbi9kZXZpY2V0cmVlL2JpbmRpbmdzL3ZpZGVvL2Rpc3Bs
YXktdGltaW5nLnR4dA0KPiANCj4gPiBLZWVwIGluIG1pbmQgdGhhdCB0aGUgdGV4dCBjb21iaW5l
ZCB3aXRoLi4uDQo+IA0KPiA+ID4gKwkJaWYgKG9mX2dldF9mYl92aWRlb21vZGUobnAsIGxjZGNf
aW5mbywgMCkpIHsNCj4gPiA+ICsJCQlkZXZfZXJyKCZkZXYtPmRldiwgInRpbWluZ3Mgbm90IGF2
YWlsYWJsZSBpbiBEVFxuIik7DQo+ID4gPiArCQkJcmV0dXJuIE5VTEw7DQo+ID4gPiArCQl9DQo+
ID4gPiArCQlyZXR1cm4gbGNkY19pbmZvOw0KPiA+ID4gKwl9DQo+ID4gDQo+ID4gLi4uIHRoaXMg
aXMgbm90IGNvcnJlY3QuIFlvdSBhcmUganVzdCBzdXBwb3J0aW5nIHRoZSBmaXJzdCBkaXNwbGF5
LXRpbWluZ3MNCj4gPiBzdWJub2RlIChvZl9nZXRfZmJfdmlkZW9tb2RlKC4uLiwgMCkpLg0KPiAN
Cj4gDQo+IFllcyByaWdodCwgSSB3aWxsIG1vZGlmeSB0aGUgdGV4dCB0byByZWZsZWN0IHdoYXQg
dGhlIGRyaXZlciBkb2VzLg0KDQpUaGlua2luZyBhYm91dCBpdCBmdXJ0aGVyLCBpdCBzZWVtcyB0
aGUgcmlnaHQgdGhpbmcgdG8gZG8NCmluIHRoaXMgY2FzZSB3b3VsZCBiZSB0byBpbnZva2UgYXMs
DQoNCiJvZl9nZXRfZmJfdmlkZW9tb2RlKG5wLCBsY2RfaW5mbywgT0ZfVVNFX05BVElWRV9NT0RF
KSIuDQoNClVwZGF0ZWQgdmVyc2lvbiBoYXMgYmVlbiBwb3N0ZWQgdG8gdGhlIGxpc3RzIChmb3Jn
b3QgdG8gY2MgeW91KQ0KDQpSZWdhcmRzDQpBZnphbA0KDQo
^ permalink raw reply
* [PATCH v2 12/12] video: da8xx-fb: set upstream clock rate (if reqd)
From: Afzal Mohammed @ 2013-01-15 13:56 UTC (permalink / raw)
To: Florian Tobias Schandinat, Tomi Valkeinen, Grant Likely,
Rob Herring, Rob Landley, Mike Turquette, Sekhar Nori, linux-omap,
linux-fbdev, devicetree-discuss, linux-doc, linux-kernel
In-Reply-To: <cover.1358251447.git.afzal@ti.com>
LCDC IP has a clock divider to adjust pixel clock, this limits pixel
clock range to fck/255 - fck/2(fck - rate of input clock to LCDC IP).
In the case of AM335x, where this IP is present, default fck is not
sufficient to provide normal pixel clock rates, hence rendering this
driver unusable on AM335x.
If input clock too is configurable, allowable range of pixel clock
would increase. Here initially it is checked whether with present fck,
divider in IP could be configured to obtain required rate, if not,
fck is adjusted. This makes it usable on AM335x.
Note:
A better (if allowable) solution may be to represent clock divider in
LCDC IP as a basic divider clock - the one defined in common clock
framework. But for this to happen, all the platform's using this driver
should be using common clock framework (DaVinci is yet to be converted
to use common clock framework). And it has to be determined whether
common clock framework allows this kind of a clock modelling inside a
driver and for this to be part of clock tree. Advantage of doing so
would be better resolution for pixel clock, even though without this
existing use cases are working properly. Or another extreme alternative
would be to replicate clk-divider of common clock framework inside the
driver, but that probably is not preferred and not worth as it would be
duplication and without much advantage to existing users.
Signed-off-by: Afzal Mohammed <afzal@ti.com>
---
v2: new patch
drivers/video/da8xx-fb.c | 76 +++++++++++++++++++++++++++++++++++-----------
1 file changed, 58 insertions(+), 18 deletions(-)
diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
index 5455682..09dfa12 100644
--- a/drivers/video/da8xx-fb.c
+++ b/drivers/video/da8xx-fb.c
@@ -133,6 +133,9 @@
#define WSI_TIMEOUT 50
#define PALETTE_SIZE 256
+#define CLK_MIN_DIV 2
+#define CLK_MAX_DIV 255
+
static void __iomem *da8xx_fb_reg_base;
static struct resource *lcdc_regs;
static unsigned int lcd_revision;
@@ -683,23 +686,21 @@ static void da8xx_fb_lcd_reset(void)
}
}
-static inline unsigned da8xx_fb_calc_clk_divider(struct da8xx_fb_par *par,
- unsigned pixclock)
-{
- return par->lcd_fck_rate / (PICOS2KHZ(pixclock) * 1000);
-}
-
-static inline unsigned da8xx_fb_round_clk(struct da8xx_fb_par *par,
- unsigned pixclock)
+static int da8xx_fb_config_clk_divider(struct da8xx_fb_par *par,
+ unsigned div, unsigned rate)
{
- unsigned div;
+ int ret;
- div = da8xx_fb_calc_clk_divider(par, pixclock);
- return KHZ2PICOS(par->lcd_fck_rate / (1000 * div));
-}
+ if (par->lcd_fck_rate != rate) {
+ ret = clk_set_rate(par->lcdc_clk, rate);
+ if (IS_ERR_VALUE(ret)) {
+ dev_err(par->dev,
+ "unable to set clock rate at %u\n", rate);
+ return ret;
+ }
+ par->lcd_fck_rate = clk_get_rate(par->lcdc_clk);
+ }
-static inline void da8xx_fb_config_clk_divider(unsigned div)
-{
/* Configure the LCD clock divisor. */
lcdc_write(LCD_CLK_DIVISOR(div) |
(LCD_RASTER_MODE & 0x1), LCD_CTRL_REG);
@@ -707,14 +708,49 @@ static inline void da8xx_fb_config_clk_divider(unsigned div)
if (lcd_revision = LCD_VERSION_2)
lcdc_write(LCD_V2_DMA_CLK_EN | LCD_V2_LIDD_CLK_EN |
LCD_V2_CORE_CLK_EN, LCD_CLK_ENABLE_REG);
+
+ return 0;
+}
+
+static unsigned int da8xx_fb_calc_clk_divider(struct da8xx_fb_par *par,
+ unsigned pixclock,
+ unsigned *rate)
+{
+ unsigned div;
+
+ pixclock = PICOS2KHZ(pixclock) * 1000;
+
+ *rate = par->lcd_fck_rate;
+
+ if (pixclock < (*rate / CLK_MAX_DIV)) {
+ *rate = clk_round_rate(par->lcdc_clk, pixclock * CLK_MAX_DIV);
+ div = CLK_MAX_DIV;
+ } else if (pixclock > (*rate / CLK_MIN_DIV)) {
+ *rate = clk_round_rate(par->lcdc_clk, pixclock * CLK_MIN_DIV);
+ div = CLK_MIN_DIV;
+ } else {
+ div = *rate / pixclock;
+ }
+
+ return div;
}
-static inline void da8xx_fb_calc_config_clk_divider(struct da8xx_fb_par *par,
+static inline int da8xx_fb_calc_config_clk_divider(struct da8xx_fb_par *par,
struct fb_videomode *mode)
{
- unsigned div = da8xx_fb_calc_clk_divider(par, mode->pixclock);
+ unsigned rate;
+ unsigned div = da8xx_fb_calc_clk_divider(par, mode->pixclock, &rate);
- da8xx_fb_config_clk_divider(div);
+ return da8xx_fb_config_clk_divider(par, div, rate);
+}
+
+static inline unsigned da8xx_fb_round_clk(struct da8xx_fb_par *par,
+ unsigned pixclock)
+{
+ unsigned div, rate;
+
+ div = da8xx_fb_calc_clk_divider(par, pixclock, &rate);
+ return KHZ2PICOS(rate / (1000 * div));
}
static int lcd_init(struct da8xx_fb_par *par, const struct lcd_ctrl_config *cfg,
@@ -723,7 +759,11 @@ static int lcd_init(struct da8xx_fb_par *par, const struct lcd_ctrl_config *cfg,
u32 bpp;
int ret = 0;
- da8xx_fb_calc_config_clk_divider(par, panel);
+ ret = da8xx_fb_calc_config_clk_divider(par, panel);
+ if (IS_ERR_VALUE(ret)) {
+ dev_err(par->dev, "unable to configure clock\n");
+ return ret;
+ }
if (panel->sync & FB_SYNC_CLK_INVERT)
lcdc_write((lcdc_read(LCD_RASTER_TIMING_2_REG) |
--
1.7.9.5
^ permalink raw reply related
* [PATCH v2 11/12] video: da8xx-fb: setup struct lcd_ctrl_config for dt
From: Afzal Mohammed @ 2013-01-15 13:55 UTC (permalink / raw)
To: Florian Tobias Schandinat, Tomi Valkeinen, Grant Likely,
Rob Herring, Rob Landley, Sekhar Nori, linux-omap, linux-fbdev,
devicetree-discuss, linux-doc, linux-kernel
In-Reply-To: <cover.1358251447.git.afzal@ti.com>
strcut lcd_ctrl_config information required for driver is currently
obtained via platform data. To handle DT probing, create
lcd_ctrl_config and populate it with default values, these values are
sufficient for the panels so far used with this controller to work.
Signed-off-by: Afzal Mohammed <afzal@ti.com>
---
drivers/video/da8xx-fb.c | 34 +++++++++++++++++++++++++++++++++-
1 file changed, 33 insertions(+), 1 deletion(-)
diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
index 1c1a616..5455682 100644
--- a/drivers/video/da8xx-fb.c
+++ b/drivers/video/da8xx-fb.c
@@ -1254,6 +1254,35 @@ static struct fb_ops da8xx_fb_ops = {
.fb_blank = cfb_blank,
};
+static struct lcd_ctrl_config *da8xx_fb_create_cfg(struct platform_device *dev)
+{
+ struct lcd_ctrl_config *cfg;
+
+ cfg = devm_kzalloc(&dev->dev, sizeof(struct fb_videomode), GFP_KERNEL);
+ if (!cfg) {
+ dev_err(&dev->dev, "memory allocation failed\n");
+ return NULL;
+ }
+
+ /* default values */
+
+ if (lcd_revision = LCD_VERSION_1)
+ cfg->bpp = 16;
+ else
+ cfg->bpp = 32;
+
+ /*
+ * For panels so far used with this LCDC, below statement is sufficient.
+ * For new panels, if required, struct lcd_ctrl_cfg fields to be updated
+ * with additional/modified values. Those values would have to be then
+ * obtained from dt(requiring new dt bindings).
+ */
+
+ cfg->panel_shade = COLOR_ACTIVE;
+
+ return cfg;
+}
+
static struct fb_videomode *da8xx_fb_get_videomode(struct platform_device *dev)
{
struct da8xx_lcdc_platform_data *fb_pdata = dev->dev.platform_data;
@@ -1345,7 +1374,10 @@ static int fb_probe(struct platform_device *device)
break;
}
- lcd_cfg = (struct lcd_ctrl_config *)fb_pdata->controller_data;
+ if (device->dev.of_node)
+ lcd_cfg = da8xx_fb_create_cfg(device);
+ else
+ lcd_cfg = (struct lcd_ctrl_config *)fb_pdata->controller_data;
if (!lcd_cfg) {
ret = -EINVAL;
--
1.7.9.5
^ permalink raw reply related
* [PATCH v2 10/12] video: da8xx-fb: ensure pdata only for non-dt
From: Afzal Mohammed @ 2013-01-15 13:55 UTC (permalink / raw)
To: Florian Tobias Schandinat, Tomi Valkeinen, Grant Likely,
Rob Herring, Rob Landley, Sekhar Nori, linux-omap, linux-fbdev,
devicetree-discuss, linux-doc, linux-kernel
In-Reply-To: <cover.1358251447.git.afzal@ti.com>
This driver is DT probe-able, hence ensure presence of platform data
only for non-DT boot.
Signed-off-by: Afzal Mohammed <afzal@ti.com>
---
drivers/video/da8xx-fb.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
index 0c68712..1c1a616 100644
--- a/drivers/video/da8xx-fb.c
+++ b/drivers/video/da8xx-fb.c
@@ -1303,7 +1303,7 @@ static int fb_probe(struct platform_device *device)
int ret;
unsigned long ulcm;
- if (fb_pdata = NULL) {
+ if (fb_pdata = NULL && !device->dev.of_node) {
dev_err(&device->dev, "Can not get platform data\n");
return -ENOENT;
}
--
1.7.9.5
^ permalink raw reply related
* [PATCH v2 09/12] video: da8xx-fb: obtain fb_videomode info from dt
From: Afzal Mohammed @ 2013-01-15 13:54 UTC (permalink / raw)
To: Florian Tobias Schandinat, Tomi Valkeinen, Grant Likely,
Rob Herring, Rob Landley, Sekhar Nori, linux-omap, linux-fbdev,
devicetree-discuss, linux-doc, linux-kernel
In-Reply-To: <cover.1358251447.git.afzal@ti.com>
Obtain fb_videomode details for the connected lcd panel using the
display timing details present in DT.
Signed-off-by: Afzal Mohammed <afzal@ti.com>
---
.../devicetree/bindings/video/fb-da8xx.txt | 21 ++++++++++++++++++++
drivers/video/da8xx-fb.c | 17 ++++++++++++++++
2 files changed, 38 insertions(+)
diff --git a/Documentation/devicetree/bindings/video/fb-da8xx.txt b/Documentation/devicetree/bindings/video/fb-da8xx.txt
index 581e014..0741f78 100644
--- a/Documentation/devicetree/bindings/video/fb-da8xx.txt
+++ b/Documentation/devicetree/bindings/video/fb-da8xx.txt
@@ -6,6 +6,12 @@ Required properties:
AM335x SoC's - "ti,am3352-lcdc", "ti,da830-lcdc"
- reg: Address range of lcdc register set
- interrupts: lcdc interrupt
+- display-timings: typical videomode of lcd panel, represented as child.
+ Refer Documentation/devicetree/bindings/video/display-timing.txt for
+ display timing binding details. If multiple videomodes are mentioned
+ in display timings node, typical videomode has to be mentioned as the
+ native mode or it has to be first child (driver cares only for native
+ videomode).
Example:
@@ -13,4 +19,19 @@ lcdc@4830e000 {
compatible = "ti,am3352-lcdc", "ti,da830-lcdc";
reg = <0x4830e000 0x1000>;
interrupts = <36>;
+ display-timings {
+ 800x480p62 {
+ clock-frequency = <30000000>;
+ hactive = <800>;
+ vactive = <480>;
+ hfront-porch = <39>;
+ hback-porch = <39>;
+ hsync-len = <47>;
+ vback-porch = <29>;
+ vfront-porch = <13>;
+ vsync-len = <2>;
+ hsync-active = <1>;
+ vsync-active = <1>;
+ };
+ };
};
diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
index 0beed20..0c68712 100644
--- a/drivers/video/da8xx-fb.c
+++ b/drivers/video/da8xx-fb.c
@@ -36,6 +36,7 @@
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/lcm.h>
+#include <video/of_display_timing.h>
#include <video/da8xx-fb.h>
#include <asm/div64.h>
@@ -1257,8 +1258,24 @@ static struct fb_videomode *da8xx_fb_get_videomode(struct platform_device *dev)
{
struct da8xx_lcdc_platform_data *fb_pdata = dev->dev.platform_data;
struct fb_videomode *lcdc_info;
+ struct device_node *np = dev->dev.of_node;
int i;
+ if (np) {
+ lcdc_info = devm_kzalloc(&dev->dev,
+ sizeof(struct fb_videomode),
+ GFP_KERNEL);
+ if (!lcdc_info) {
+ dev_err(&dev->dev, "memory allocation failed\n");
+ return NULL;
+ }
+ if (of_get_fb_videomode(np, lcdc_info, OF_USE_NATIVE_MODE)) {
+ dev_err(&dev->dev, "timings not available in DT\n");
+ return NULL;
+ }
+ return lcdc_info;
+ }
+
for (i = 0, lcdc_info = known_lcd_panels;
i < ARRAY_SIZE(known_lcd_panels); i++, lcdc_info++) {
if (strcmp(fb_pdata->type, lcdc_info->name) = 0)
--
1.7.9.5
^ permalink raw reply related
* [PATCH v2 08/12] video: da8xx-fb: invoke platform callback safely
From: Afzal Mohammed @ 2013-01-15 13:54 UTC (permalink / raw)
To: Florian Tobias Schandinat, Tomi Valkeinen, Grant Likely,
Rob Herring, Rob Landley, Sekhar Nori, linux-omap, linux-fbdev,
devicetree-discuss, linux-doc, linux-kernel
In-Reply-To: <cover.1358251447.git.afzal@ti.com>
Ensure that platform data is present before checking whether platform
callback is present (the one used to control backlight). So far this
was not an issue as driver was purely non-DT triggered, but now DT
support has been added.
Signed-off-by: Afzal Mohammed <afzal@ti.com>
---
drivers/video/da8xx-fb.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
index 08ee8eb..0beed20 100644
--- a/drivers/video/da8xx-fb.c
+++ b/drivers/video/da8xx-fb.c
@@ -1347,7 +1347,7 @@ static int fb_probe(struct platform_device *device)
par->dev = &device->dev;
par->lcdc_clk = fb_clk;
par->lcd_fck_rate = clk_get_rate(fb_clk);
- if (fb_pdata->panel_power_ctrl) {
+ if (fb_pdata && fb_pdata->panel_power_ctrl) {
par->panel_power_ctrl = fb_pdata->panel_power_ctrl;
par->panel_power_ctrl(1);
}
--
1.7.9.5
^ permalink raw reply related
* [PATCH v2 07/12] video: da8xx-fb: minimal dt support
From: Afzal Mohammed @ 2013-01-15 13:54 UTC (permalink / raw)
To: Florian Tobias Schandinat, Tomi Valkeinen, Grant Likely,
Rob Herring, Rob Landley, Sekhar Nori, linux-omap, linux-fbdev,
devicetree-discuss, linux-doc, linux-kernel
In-Reply-To: <cover.1358251447.git.afzal@ti.com>
Driver is provided a means to have the probe triggered by DT.
Signed-off-by: Afzal Mohammed <afzal@ti.com>
---
.../devicetree/bindings/video/fb-da8xx.txt | 16 ++++++++++++++++
drivers/video/da8xx-fb.c | 7 +++++++
2 files changed, 23 insertions(+)
create mode 100644 Documentation/devicetree/bindings/video/fb-da8xx.txt
diff --git a/Documentation/devicetree/bindings/video/fb-da8xx.txt b/Documentation/devicetree/bindings/video/fb-da8xx.txt
new file mode 100644
index 0000000..581e014
--- /dev/null
+++ b/Documentation/devicetree/bindings/video/fb-da8xx.txt
@@ -0,0 +1,16 @@
+TI LCD Controller on DA830/DA850/AM335x SoC's
+
+Required properties:
+- compatible:
+ DA830 - "ti,da830-lcdc"
+ AM335x SoC's - "ti,am3352-lcdc", "ti,da830-lcdc"
+- reg: Address range of lcdc register set
+- interrupts: lcdc interrupt
+
+Example:
+
+lcdc@4830e000 {
+ compatible = "ti,am3352-lcdc", "ti,da830-lcdc";
+ reg = <0x4830e000 0x1000>;
+ interrupts = <36>;
+};
diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
index b6ea5e9..08ee8eb 100644
--- a/drivers/video/da8xx-fb.c
+++ b/drivers/video/da8xx-fb.c
@@ -1595,6 +1595,12 @@ static int fb_resume(struct platform_device *dev)
#define fb_resume NULL
#endif
+static const struct of_device_id da8xx_fb_of_match[] = {
+ {.compatible = "ti,da830-lcdc", },
+ {},
+};
+MODULE_DEVICE_TABLE(of, da8xx_fb_of_match);
+
static struct platform_driver da8xx_fb_driver = {
.probe = fb_probe,
.remove = fb_remove,
@@ -1603,6 +1609,7 @@ static struct platform_driver da8xx_fb_driver = {
.driver = {
.name = DRIVER_NAME,
.owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(da8xx_fb_of_match),
},
};
--
1.7.9.5
^ permalink raw reply related
* [PATCH v2 06/12] video: da8xx-fb: reorganize panel detection
From: Afzal Mohammed @ 2013-01-15 13:54 UTC (permalink / raw)
To: Florian Tobias Schandinat, Tomi Valkeinen, Grant Likely,
Rob Herring, Rob Landley, Sekhar Nori,
linux-omap-u79uwXL29TY76Z2rM5mHXA,
linux-fbdev-u79uwXL29TY76Z2rM5mHXA,
devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
linux-doc-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <cover.1358251447.git.afzal-l0cyMroinI0@public.gmane.org>
Move panel detection to a separate function, this helps in readability
as well as makes DT support cleaner.
Signed-off-by: Afzal Mohammed <afzal@ti.com>
---
drivers/video/da8xx-fb.c | 42 ++++++++++++++++++++++++++----------------
1 file changed, 26 insertions(+), 16 deletions(-)
diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
index 3b146bc..b6ea5e9 100644
--- a/drivers/video/da8xx-fb.c
+++ b/drivers/video/da8xx-fb.c
@@ -1253,6 +1253,27 @@ static struct fb_ops da8xx_fb_ops = {
.fb_blank = cfb_blank,
};
+static struct fb_videomode *da8xx_fb_get_videomode(struct platform_device *dev)
+{
+ struct da8xx_lcdc_platform_data *fb_pdata = dev->dev.platform_data;
+ struct fb_videomode *lcdc_info;
+ int i;
+
+ for (i = 0, lcdc_info = known_lcd_panels;
+ i < ARRAY_SIZE(known_lcd_panels); i++, lcdc_info++) {
+ if (strcmp(fb_pdata->type, lcdc_info->name) = 0)
+ break;
+ }
+
+ if (i = ARRAY_SIZE(known_lcd_panels)) {
+ dev_err(&dev->dev, "no panel found\n");
+ return NULL;
+ }
+ dev_info(&dev->dev, "found %s panel\n", lcdc_info->name);
+
+ return lcdc_info;
+}
+
static int fb_probe(struct platform_device *device)
{
struct da8xx_lcdc_platform_data *fb_pdata @@ -1262,7 +1283,7 @@ static int fb_probe(struct platform_device *device)
struct fb_info *da8xx_fb_info;
struct clk *fb_clk = NULL;
struct da8xx_fb_par *par;
- int ret, i;
+ int ret;
unsigned long ulcm;
if (fb_pdata = NULL) {
@@ -1270,6 +1291,10 @@ static int fb_probe(struct platform_device *device)
return -ENOENT;
}
+ lcdc_info = da8xx_fb_get_videomode(device);
+ if (lcdc_info = NULL)
+ return -ENODEV;
+
lcdc_regs = platform_get_resource(device, IORESOURCE_MEM, 0);
da8xx_fb_reg_base = devm_request_and_ioremap(&device->dev, lcdc_regs);
if (!da8xx_fb_reg_base) {
@@ -1303,21 +1328,6 @@ static int fb_probe(struct platform_device *device)
break;
}
- for (i = 0, lcdc_info = known_lcd_panels;
- i < ARRAY_SIZE(known_lcd_panels);
- i++, lcdc_info++) {
- if (strcmp(fb_pdata->type, lcdc_info->name) = 0)
- break;
- }
-
- if (i = ARRAY_SIZE(known_lcd_panels)) {
- dev_err(&device->dev, "GLCD: No valid panel found\n");
- ret = -ENODEV;
- goto err_pm_runtime_disable;
- } else
- dev_info(&device->dev, "GLCD: Found %s panel\n",
- fb_pdata->type);
-
lcd_cfg = (struct lcd_ctrl_config *)fb_pdata->controller_data;
if (!lcd_cfg) {
--
1.7.9.5
^ permalink raw reply related
* [PATCH v2 05/12] video: da8xx-fb: ensure non-null cfg in pdata
From: Afzal Mohammed @ 2013-01-15 13:54 UTC (permalink / raw)
To: Florian Tobias Schandinat, Tomi Valkeinen, Grant Likely,
Rob Herring, Rob Landley, Sekhar Nori, linux-omap, linux-fbdev,
devicetree-discuss, linux-doc, linux-kernel
In-Reply-To: <cover.1358251447.git.afzal@ti.com>
Ensure that platform data contains pointer for lcd_ctrl_config.
Signed-off-by: Afzal Mohammed <afzal@ti.com>
---
drivers/video/da8xx-fb.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
index 7a32e83..3b146bc 100644
--- a/drivers/video/da8xx-fb.c
+++ b/drivers/video/da8xx-fb.c
@@ -1320,6 +1320,11 @@ static int fb_probe(struct platform_device *device)
lcd_cfg = (struct lcd_ctrl_config *)fb_pdata->controller_data;
+ if (!lcd_cfg) {
+ ret = -EINVAL;
+ goto err_pm_runtime_disable;
+ }
+
da8xx_fb_info = framebuffer_alloc(sizeof(struct da8xx_fb_par),
&device->dev);
if (!da8xx_fb_info) {
--
1.7.9.5
^ permalink raw reply related
* [PATCH v2 04/12] video: da8xx-fb: use devres
From: Afzal Mohammed @ 2013-01-15 13:54 UTC (permalink / raw)
To: Florian Tobias Schandinat, Tomi Valkeinen, Grant Likely,
Rob Herring, Rob Landley, Sekhar Nori,
linux-omap-u79uwXL29TY76Z2rM5mHXA,
linux-fbdev-u79uwXL29TY76Z2rM5mHXA,
devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
linux-doc-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <cover.1358251447.git.afzal-l0cyMroinI0@public.gmane.org>
Replace existing resource handling in the driver with managed device
resource.
Signed-off-by: Afzal Mohammed <afzal@ti.com>
---
drivers/video/da8xx-fb.c | 35 ++++++-----------------------------
1 file changed, 6 insertions(+), 29 deletions(-)
diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
index ca69e01..7a32e83 100644
--- a/drivers/video/da8xx-fb.c
+++ b/drivers/video/da8xx-fb.c
@@ -1036,12 +1036,9 @@ static int fb_remove(struct platform_device *dev)
par->p_palette_base);
dma_free_coherent(NULL, par->vram_size, par->vram_virt,
par->vram_phys);
- free_irq(par->irq, par);
pm_runtime_put_sync(&dev->dev);
pm_runtime_disable(&dev->dev);
framebuffer_release(info);
- iounmap(da8xx_fb_reg_base);
- release_mem_region(lcdc_regs->start, resource_size(lcdc_regs));
}
return 0;
@@ -1265,7 +1262,6 @@ static int fb_probe(struct platform_device *device)
struct fb_info *da8xx_fb_info;
struct clk *fb_clk = NULL;
struct da8xx_fb_par *par;
- resource_size_t len;
int ret, i;
unsigned long ulcm;
@@ -1275,29 +1271,16 @@ static int fb_probe(struct platform_device *device)
}
lcdc_regs = platform_get_resource(device, IORESOURCE_MEM, 0);
- if (!lcdc_regs) {
- dev_err(&device->dev,
- "Can not get memory resource for LCD controller\n");
- return -ENOENT;
- }
-
- len = resource_size(lcdc_regs);
-
- lcdc_regs = request_mem_region(lcdc_regs->start, len, lcdc_regs->name);
- if (!lcdc_regs)
- return -EBUSY;
-
- da8xx_fb_reg_base = ioremap(lcdc_regs->start, len);
+ da8xx_fb_reg_base = devm_request_and_ioremap(&device->dev, lcdc_regs);
if (!da8xx_fb_reg_base) {
- ret = -EBUSY;
- goto err_request_mem;
+ dev_err(&device->dev, "memory resource setup failed\n");
+ return -EADDRNOTAVAIL;
}
- fb_clk = clk_get(&device->dev, "fck");
+ fb_clk = devm_clk_get(&device->dev, "fck");
if (IS_ERR(fb_clk)) {
dev_err(&device->dev, "Can not get device clock\n");
- ret = -ENODEV;
- goto err_ioremap;
+ return -ENODEV;
}
pm_runtime_enable(&device->dev);
@@ -1458,7 +1441,7 @@ static int fb_probe(struct platform_device *device)
lcdc_irq_handler = lcdc_irq_handler_rev02;
}
- ret = request_irq(par->irq, lcdc_irq_handler, 0,
+ ret = devm_request_irq(&device->dev, par->irq, lcdc_irq_handler, 0,
DRIVER_NAME, par);
if (ret)
goto irq_freq;
@@ -1488,12 +1471,6 @@ err_pm_runtime_disable:
pm_runtime_put_sync(&device->dev);
pm_runtime_disable(&device->dev);
-err_ioremap:
- iounmap(da8xx_fb_reg_base);
-
-err_request_mem:
- release_mem_region(lcdc_regs->start, len);
-
return ret;
}
--
1.7.9.5
^ permalink raw reply related
* [PATCH v2 03/12] video: da8xx-fb: enable sync lost intr for v2 ip
From: Afzal Mohammed @ 2013-01-15 13:54 UTC (permalink / raw)
To: Florian Tobias Schandinat, Tomi Valkeinen, Grant Likely,
Rob Herring, Rob Landley, Sekhar Nori, linux-omap, linux-fbdev,
devicetree-discuss, linux-doc, linux-kernel
In-Reply-To: <cover.1358251447.git.afzal@ti.com>
interrupt handler is checking for sync lost interrupt, but it was not
enabled, enable it.
Signed-off-by: Afzal Mohammed <afzal@ti.com>
---
drivers/video/da8xx-fb.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
index 7f92f37..ca69e01 100644
--- a/drivers/video/da8xx-fb.c
+++ b/drivers/video/da8xx-fb.c
@@ -318,7 +318,7 @@ static void lcd_blit(int load_mode, struct da8xx_fb_par *par)
reg_int = lcdc_read(LCD_INT_ENABLE_SET_REG) |
LCD_V2_END_OF_FRAME0_INT_ENA |
LCD_V2_END_OF_FRAME1_INT_ENA |
- LCD_FRAME_DONE;
+ LCD_FRAME_DONE | LCD_SYNC_LOST;
lcdc_write(reg_int, LCD_INT_ENABLE_SET_REG);
}
reg_dma |= LCD_DUAL_FRAME_BUFFER_ENABLE;
--
1.7.9.5
^ permalink raw reply related
* [PATCH v2 02/12] video: da8xx-fb: fix 24bpp raster configuration
From: Afzal Mohammed @ 2013-01-15 13:53 UTC (permalink / raw)
To: Florian Tobias Schandinat, Tomi Valkeinen, Grant Likely,
Rob Herring, Rob Landley, Sekhar Nori,
linux-omap-u79uwXL29TY76Z2rM5mHXA,
linux-fbdev-u79uwXL29TY76Z2rM5mHXA,
devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
linux-doc-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA
Cc: Manjunathappa, Prakash
In-Reply-To: <cover.1358251447.git.afzal-l0cyMroinI0@public.gmane.org>
From: "Manjunathappa, Prakash" <prakash.pm@ti.com>
Set only LCD_V2_TFT_24BPP_MODE bit for 24bpp and LCD_V2_TFT_24BPP_UNPACK
bit along with LCD_V2_TFT_24BPP_MODE for 32bpp configuration.
Patch is tested on am335x-evm for 24bpp and da850-evm for 16bpp
configurations.
Signed-off-by: Manjunathappa, Prakash <prakash.pm@ti.com>
Signed-off-by: Afzal Mohammed <afzal@ti.com>
---
drivers/video/da8xx-fb.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
index 35a33ca..7f92f37 100644
--- a/drivers/video/da8xx-fb.c
+++ b/drivers/video/da8xx-fb.c
@@ -550,10 +550,10 @@ static int lcd_cfg_frame_buffer(struct da8xx_fb_par *par, u32 width, u32 height,
case 4:
case 16:
break;
- case 24:
- reg |= LCD_V2_TFT_24BPP_MODE;
case 32:
reg |= LCD_V2_TFT_24BPP_UNPACK;
+ case 24:
+ reg |= LCD_V2_TFT_24BPP_MODE;
break;
case 8:
--
1.7.9.5
^ permalink raw reply related
* [PATCH v2 01/12] video: da8xx-fb: make io operations safe
From: Afzal Mohammed @ 2013-01-15 13:53 UTC (permalink / raw)
To: Florian Tobias Schandinat, Tomi Valkeinen, Grant Likely,
Rob Herring, Rob Landley, Sekhar Nori,
linux-omap-u79uwXL29TY76Z2rM5mHXA,
linux-fbdev-u79uwXL29TY76Z2rM5mHXA,
devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
linux-doc-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <cover.1358251447.git.afzal-l0cyMroinI0@public.gmane.org>
Replace __raw_readl/__raw_writel with readl/writel; this driver is
reused on ARMv7 (AM335x SoC).
Signed-off-by: Afzal Mohammed <afzal@ti.com>
---
v2: new patch
drivers/video/da8xx-fb.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
index 720604c..35a33ca 100644
--- a/drivers/video/da8xx-fb.c
+++ b/drivers/video/da8xx-fb.c
@@ -141,12 +141,12 @@ static int frame_done_flag;
static inline unsigned int lcdc_read(unsigned int addr)
{
- return (unsigned int)__raw_readl(da8xx_fb_reg_base + (addr));
+ return (unsigned int)readl(da8xx_fb_reg_base + (addr));
}
static inline void lcdc_write(unsigned int val, unsigned int addr)
{
- __raw_writel(val, da8xx_fb_reg_base + (addr));
+ writel(val, da8xx_fb_reg_base + (addr));
}
struct da8xx_fb_par {
--
1.7.9.5
^ permalink raw reply related
* [PATCH v2 00/12] video: da8xx-fb: DT support
From: Afzal Mohammed @ 2013-01-15 13:53 UTC (permalink / raw)
To: Florian Tobias Schandinat, Tomi Valkeinen, Grant Likely,
Rob Herring, Rob Landley, Sekhar Nori, linux-omap, linux-fbdev,
devicetree-discuss, linux-doc, linux-kernel
Hi,
This series adds DT support to da8xx-fb driver (device found on
DaVinci and AM335x SoC's). It does certain cleanup's in the process.
This series as compared to previous version handles configuration of
the LCDC input clock to required value if clock divider in IP cannot
take care of required pixel clock. In the case of AM335x (where there
is requirement of configuring input clock), it's clock tree has to be
updated with proper flags, relevant patch is,
"ARM: AM33XX: clock: SET_RATE_PARENT in lcd path".
There is an additional patch in this new series to make io operations
safe.
This makes use of Steffen Trumtrar's v16 of display timing DT support.
Testing has been done on AM335x SoC based boards like AM335x EVM and
AM335x EVM-SK. It has also been verified that display on DA850 EVM
(non-DT boot) works as earlier.
This series is based on v3.8-rc3,
and is dependent on,
1. Series v16 "of: add display helper" by,
Steffen Trumtrar <s.trumtrar@pengutronix.de>
2. Patch "da8xx: Allow use by am33xx based devices" by,
Pantelis Antoniou <panto@antoniou-consulting.com>
3. Series v3 "video: da8xx-fb: runtime timing configuration" by,
me (Afzal Mohammed <afzal@ti.com>)
To test this series on AM335x based boards,
1. Series v2 "ARM: dts: AM33XX: lcdc support" by,
me (Afzal Mohammed <afzal@ti.com>),
2. Patch "ARM: AM33XX: clock: SET_RATE_PARENT in lcd path" by,
me (Afzal Mohammed <afzal@ti.com>),
3. Series "HWMOD fixes for AM33xx PWM submodules and device tree nodes" by,
Philip, Avinash <avinashphilip@ti.com>
would be needed.
All above dependencies along with those required for testing is available
@git://gitorious.org/x0148406-public/linux-kernel.git tags/da8xx-fb-dt-v3.8-rc3
Regards
Afzal
v2: 2 new patches - one to configure clock rate properly (12/12)and
other to make io operations safe (1/12)
Afzal Mohammed (11):
video: da8xx-fb: make io operations safe
video: da8xx-fb: enable sync lost intr for v2 ip
video: da8xx-fb: use devres
video: da8xx-fb: ensure non-null cfg in pdata
video: da8xx-fb: reorganize panel detection
video: da8xx-fb: minimal dt support
video: da8xx-fb: invoke platform callback safely
video: da8xx-fb: obtain fb_videomode info from dt
video: da8xx-fb: ensure pdata only for non-dt
video: da8xx-fb: setup struct lcd_ctrl_config for dt
video: da8xx-fb: set upstream clock rate (if reqd)
Manjunathappa, Prakash (1):
video: da8xx-fb: fix 24bpp raster configuration
.../devicetree/bindings/video/fb-da8xx.txt | 37 ++++
drivers/video/da8xx-fb.c | 226 ++++++++++++++------
2 files changed, 194 insertions(+), 69 deletions(-)
create mode 100644 Documentation/devicetree/bindings/video/fb-da8xx.txt
--
1.7.9.5
^ permalink raw reply
* [PATCH v2 2/5] ARM: dts: AM33XX: Add am335x-evm lcdc panel timings
From: Afzal Mohammed @ 2013-01-15 13:52 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <cover.1358252955.git.afzal@ti.com>
Update lcdc node with panel timings (typical) for AM335X-EVM.
Signed-off-by: Afzal Mohammed <afzal@ti.com>
---
arch/arm/boot/dts/am335x-evm.dts | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/arch/arm/boot/dts/am335x-evm.dts b/arch/arm/boot/dts/am335x-evm.dts
index d649644..a4229aa 100644
--- a/arch/arm/boot/dts/am335x-evm.dts
+++ b/arch/arm/boot/dts/am335x-evm.dts
@@ -244,3 +244,23 @@
&cpsw_emac1 {
phy_id = <&davinci_mdio>, <1>;
};
+
+&lcdc {
+ status = "okay";
+
+ display-timings {
+ 800x480p62 {
+ clock-frequency = <30000000>;
+ hactive = <800>;
+ vactive = <480>;
+ hfront-porch = <39>;
+ hback-porch = <39>;
+ hsync-len = <47>;
+ vback-porch = <29>;
+ vfront-porch = <13>;
+ vsync-len = <2>;
+ hsync-active = <1>;
+ vsync-active = <1>;
+ };
+ };
+};
--
1.7.9.5
^ permalink raw reply related
* [PATCH v2 1/5] ARM: dts: AM33XX: Add lcdc node
From: Afzal Mohammed @ 2013-01-15 13:51 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <cover.1358252955.git.afzal@ti.com>
Add lcdc node.
Signed-off-by: Afzal Mohammed <afzal@ti.com>
---
arch/arm/boot/dts/am33xx.dtsi | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi
index c2f14e8..432d4bb8 100644
--- a/arch/arm/boot/dts/am33xx.dtsi
+++ b/arch/arm/boot/dts/am33xx.dtsi
@@ -385,5 +385,13 @@
mac-address = [ 00 00 00 00 00 00 ];
};
};
+
+ lcdc: lcdc@4830e000 {
+ compatible = "ti,am3352-lcdc", "ti,da830-lcdc";
+ reg = <0x4830e000 0x1000>;
+ interrupts = <36>;
+ status = "disabled";
+ ti,hwmods = "lcdc";
+ };
};
};
--
1.7.9.5
^ permalink raw reply related
* [PATCH v2 3/5] ARM: dts: AM33XX: Add am335x-evm lcdc pincontrol info
From: Afzal Mohammed @ 2013-01-15 13:51 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <cover.1358252955.git.afzal@ti.com>
From: "Manjunathappa, Prakash" <prakash.pm@ti.com>
Update pin mux information for lcd panel on AM335X-EVM
[afzal@ti.com: comment specifying user understandable pinmux details]
Signed-off-by: Manjunathappa, Prakash <prakash.pm@ti.com>
Signed-off-by: Afzal Mohammed <afzal@ti.com>
---
v2: correct authorship, add comment on pinmux
arch/arm/boot/dts/am335x-evm.dts | 35 ++++++++++++++++++++++++++++++++++-
1 file changed, 34 insertions(+), 1 deletion(-)
diff --git a/arch/arm/boot/dts/am335x-evm.dts b/arch/arm/boot/dts/am335x-evm.dts
index a4229aa..0527885 100644
--- a/arch/arm/boot/dts/am335x-evm.dts
+++ b/arch/arm/boot/dts/am335x-evm.dts
@@ -26,7 +26,7 @@
am33xx_pinmux: pinmux@44e10800 {
pinctrl-names = "default";
- pinctrl-0 = <&matrix_keypad_s0 &volume_keys_s0>;
+ pinctrl-0 = <&matrix_keypad_s0 &volume_keys_s0 &lcd_pins_s0>;
matrix_keypad_s0: matrix_keypad_s0 {
pinctrl-single,pins = <
@@ -44,6 +44,39 @@
0x154 0x27 /* spi0_d0.gpio0_3, INPUT | MODE7 */
>;
};
+
+ lcd_pins_s0: lcd_pins_s0 {
+ pinctrl-single,pins = <
+ 0x20 0x01 /* gpmc_ad8.lcd_data16, OUTPUT | MODE1 */
+ 0x24 0x01 /* gpmc_ad9.lcd_data17, OUTPUT | MODE1 */
+ 0x28 0x01 /* gpmc_ad10.lcd_data18, OUTPUT | MODE1 */
+ 0x2c 0x01 /* gpmc_ad11.lcd_data19, OUTPUT | MODE1 */
+ 0x30 0x01 /* gpmc_ad12.lcd_data20, OUTPUT | MODE1 */
+ 0x34 0x01 /* gpmc_ad13.lcd_data21, OUTPUT | MODE1 */
+ 0x38 0x01 /* gpmc_ad14.lcd_data22, OUTPUT | MODE1 */
+ 0x3c 0x01 /* gpmc_ad15.lcd_data23, OUTPUT | MODE1 */
+ 0xa0 0x00 /* lcd_data0.lcd_data0, OUTPUT | MODE0 */
+ 0xa4 0x00 /* lcd_data1.lcd_data1, OUTPUT | MODE0 */
+ 0xa8 0x00 /* lcd_data2.lcd_data2, OUTPUT | MODE0 */
+ 0xac 0x00 /* lcd_data3.lcd_data3, OUTPUT | MODE0 */
+ 0xb0 0x00 /* lcd_data4.lcd_data4, OUTPUT | MODE0 */
+ 0xb4 0x00 /* lcd_data5.lcd_data5, OUTPUT | MODE0 */
+ 0xb8 0x00 /* lcd_data6.lcd_data6, OUTPUT | MODE0 */
+ 0xbc 0x00 /* lcd_data7.lcd_data7, OUTPUT | MODE0 */
+ 0xc0 0x00 /* lcd_data8.lcd_data8, OUTPUT | MODE0 */
+ 0xc4 0x00 /* lcd_data9.lcd_data9, OUTPUT | MODE0 */
+ 0xc8 0x00 /* lcd_data10.lcd_data10, OUTPUT | MODE0 */
+ 0xcc 0x00 /* lcd_data11.lcd_data11, OUTPUT | MODE0 */
+ 0xd0 0x00 /* lcd_data12.lcd_data12, OUTPUT | MODE0 */
+ 0xd4 0x00 /* lcd_data13.lcd_data13, OUTPUT | MODE0 */
+ 0xd8 0x00 /* lcd_data14.lcd_data14, OUTPUT | MODE0 */
+ 0xdc 0x00 /* lcd_data15.lcd_data15, OUTPUT | MODE0 */
+ 0xe0 0x00 /* lcd_vsync.lcd_vsync, OUTPUT | MODE0 */
+ 0xe4 0x00 /* lcd_hsync.lcd_hsync, OUTPUT | MODE0 */
+ 0xe8 0x00 /* lcd_pclk.lcd_pclk, OUTPUT | MODE0 */
+ 0xec 0x00 /* lcd_ac_bias_en.lcd_ac_bias_en, OUTPUT | MODE0 */
+ >;
+ };
};
ocp {
--
1.7.9.5
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox