[PATCH 2/3] acpi_video: Intel video is not always i915

2012-04-24 Thread Alan Cox
On Tue, 24 Apr 2012 22:02:18 +0100
Matthew Garrett  wrote:

> On Tue, Apr 24, 2012 at 04:45:01PM +0100, Alan Cox wrote:
> > From: Alan Cox 
> > 
> > Handle the GMA500/600/36x0 cases. Also stop it poking at random registers on
> > the i740 cards that may be out there still.
> 
> The PowerVR Intels I'd seen had the opregion address in the 0xfc 
> register as well. Is this no longer true on the latest?

PowerVR does - i740 never did.

The PowerVR 0xfc poking also doesn't currently work once the driver takes
over because it isn't yet implementing the driver end of the weird ACPI
messaging/event stuff.

Once it does the GMA500 will be able to do an ACPI video register, but we
will still need the check to get the ifdeffery right for what drivers are
compiled for the kernel.

Alan


[PATCH 2/3] acpi_video: Intel video is not always i915

2012-04-24 Thread Matthew Garrett
On Tue, Apr 24, 2012 at 11:31:17PM +0100, Alan Cox wrote:
> On Tue, 24 Apr 2012 22:02:18 +0100
> Matthew Garrett  wrote:
> > The PowerVR Intels I'd seen had the opregion address in the 0xfc 
> > register as well. Is this no longer true on the latest?
> 
> PowerVR does - i740 never did.
> 
> The PowerVR 0xfc poking also doesn't currently work once the driver takes
> over because it isn't yet implementing the driver end of the weird ACPI
> messaging/event stuff.
> 
> Once it does the GMA500 will be able to do an ACPI video register, but we
> will still need the check to get the ifdeffery right for what drivers are
> compiled for the kernel.

Right now you seem to set opregion unconditionally on PVR, which seems 
to be equivalent to the 0xfc check that was there before - I can 
understand excluding i740, but the PVR check could be left with the gen 
hardware one?

-- 
Matthew Garrett | mjg59 at srcf.ucam.org


[Bug 49110] AMDILCFGStructurizer.cpp:1751:3: error: 'isCurrentDebugType' was not declared in this scope

2012-04-24 Thread bugzilla-dae...@freedesktop.org
https://bugs.freedesktop.org/show_bug.cgi?id=49110

--- Comment #1 from Tom Stellard  2012-04-24 16:04:18 
PDT ---
I think this happens when you build Mesa with debugging enabled and LLVM
without it enabled.  It's still a bug though.  For now, you could try building
a debug version of both Mesa and LLVM.  I think that will fix it.

-- 
Configure bugmail: https://bugs.freedesktop.org/userprefs.cgi?tab=email
--- You are receiving this mail because: ---
You are the assignee for the bug.


[PATCH 2/3] acpi_video: Intel video is not always i915

2012-04-24 Thread Matthew Garrett
On Tue, Apr 24, 2012 at 04:45:01PM +0100, Alan Cox wrote:
> From: Alan Cox 
> 
> Handle the GMA500/600/36x0 cases. Also stop it poking at random registers on
> the i740 cards that may be out there still.

The PowerVR Intels I'd seen had the opregion address in the 0xfc 
register as well. Is this no longer true on the latest?

-- 
Matthew Garrett | mjg59 at srcf.ucam.org


Linux 3.4-rc4

2012-04-24 Thread Nick Bowler
On 2012-04-23 21:03 -0400, Nick Bowler wrote:
> On 2012-04-22 22:45 -0400, Konrad Rzeszutek Wilk wrote:
> > On Sun, Apr 22, 2012 at 08:05:54PM -0400, Nick Bowler wrote:
> > > Following up on the above, the commit which introduces the panics during
> > > boot is this one:
> > >
> > > commit 8e7e70522d760c4ccd4cd370ebfa0ba69e006c6e
> > > Author: Jerome Glisse 
> > > Date:   Wed Nov 9 17:15:26 2011 -0500
> > > 
> > > drm/ttm: isolate dma data from ttm_tt V4
[...]
> > dea7e0a ttm: fix agp since ttm tt rework
> > 
> > fixed that.
> 
> Yes, I just tested this commit and the one immediately before it.  The
> one before crashes in the usual way, and dea7e0a boots (with the VGA
> output black as in the original report).  So this fixed the crash.

OK, here's what I did:

 - Since dea7e0a is the first commit that both (a) boots and (b) has
   broken VGA, I checked it out on a new branch:

 git checkout -b crazy dea7e0a

 - Next, I reverted *all* (well, I missed one by accident) the remaining
   nouveau-specific commits between 3230cfc34 ("drm/nouveau: enable the
   ttm dma pool when swiotlb is active V3") (i.e., the last commit that
   (a) boots and (b) has non-broken VGA) and dea7e0a:

 git revert --no-edit 0c101461e267..f7b24c42da1a

 - Amazingly, the resulting kernel booted and had working VGA, so I did
   a "backwards" bisect on this branch of reverts.  In a strange twist
   of fate, this actually managed to produce bootable kernels the entire
   time.  The bisection pinpointed the following commit as the culprit:

commit a0b25635515ef5049f93b032a1e37f18b16e0f6f
Author: Ben Skeggs 
Date:   Mon Nov 21 16:41:48 2011 +1000

drm/nouveau/gpio: reimplement as nouveau_gpio.c, fixing a number of issues

- moves out of nouveau_bios.c and demagics the logical state definitions
- simplifies chipset-specific driver interface
- makes most of gpio irq handling common, will use for nv4x hpd later
- api extended to allow both direct gpio access, and access using the
  logical function states
- api extended to allow for future use of gpio extender chips
- pre-nv50 was handled very badly, the main issue being that all GPIOs
  were being treated as output-only.
- fixes nvd0 so gpio changes actually stick, magic reg needs bashing

Signed-off-by: Ben Skeggs 

Unfortunately, there are a number of seemingly non-trivial conflicts
trying to revert just this one gigantic commit.  So to avoid any
conflicts, I reverted all of the following (in this order) on top of
3.3.3 (there are even more conflicts trying to revert on top of Linus'
master):

  7df898b1a70b ("drm/nouveau/disp: check that panel power gpio is enabled at 
init time")
  52c4d767437b ("drm/nouveau: move hpd enable/disable to common code")
  47e5d5cb83d4 ("drm/nv40/disp: implement support for hotplug irq")
  a0b25635515e ("drm/nouveau/gpio: reimplement as nouveau_gpio.c, fixing a 
number of issues")

and my VGA is working again!

Cheers,
-- 
Nick Bowler, Elliptic Technologies (http://www.elliptictech.com/)



[RFC PATCH 5/5] drm/nouveau: gpu lockup recovery

2012-04-24 Thread Marcin Slusarz
On Mon, Apr 23, 2012 at 06:56:44PM +0200, Martin Peres wrote:
> Le 23/04/2012 18:32, Marcin Slusarz a ?crit :
> >
> > Just run piglit. Even "quick" tests can cause ~5 lockups (it eventually 
> > messes
> > up DDX channel, but this patchset can't fix this case).
> > You can run fs-discard-exit-2 test first - for me it causes instant GPU 
> > lockup.
> >
> > Marcin
> Great, Thanks.
> 
> Did you have a look at 
> https://bugs.freedesktop.org/show_bug.cgi?id=40886 and 
> http://xorg.freedesktop.org/wiki/SummerOfCodeIdeas ?

Yeah, I've seen them some time ago.

> The Ubuntu xorg devs were looking for something like this, but they also 
> wanted a lockup report. Are you also interested on working on it ?

Yes, when this patchset will be applied, I'm going to work on improving
error reporting.

Marcin


[PATCH 1/5] drm: add optional per device rwsem for all ioctls

2012-04-24 Thread Marcin Slusarz
On Mon, Apr 23, 2012 at 09:51:48AM +0200, Daniel Vetter wrote:
> On Mon, Apr 23, 2012 at 12:18:28AM +0200, Marcin Slusarz wrote:
> > Nouveau, in normal circumstances, does not need device lock for every ioctl,
> > but incoming "gpu reset" code needs exclusive access to the device.
> > This commit adds drm_driver flag which turns on read lock ioctl 
> > encapsulation.
> > 
> > Signed-off-by: Marcin Slusarz 
> 
> Why can't we just move this down to nouveau driver code?

Ok, I think it's easily possible by wrapping drm_ioctl.

> So why can't nouveau do the same? Also, if this is indeed necessary and we
> add this as some mandatory core infrastructure, it's not good enough: In
> i915 we go to great lengths to ensure that all processes waiting for gpu
> reset are still interruptible, in case the gpu reset dies unexpectedly
> (which happens), so this would need to be improved.

I came up with a scheme where down_read can be made interruptible.

I'll post both changes in a few days.

(Unfortunately adding proper down_read_interruptible / down_write_interruptible
require a bit of unfunny work - 8 architectures have their own code for rwsems)

Marcin


[Nouveau] [PATCH 2/5] drm/nouveau: base fence timeout on time of emission

2012-04-24 Thread Marcin Slusarz
On Tue, Apr 24, 2012 at 12:37:34PM +1000, Ben Skeggs wrote:
> On Mon, 2012-04-23 at 00:18 +0200, Marcin Slusarz wrote:
> > Wait loop can be interrupted by signal, so if signals are raised
> > periodically (e.g. SIGALRM) this loop may never finish. Use
> > emission time as a base for fence timeout.
> Ah, thanks for tackling this issue.  It's been long on my list of things
> to do, but never quite made it to the top.
> 
> Rather than hardcoding the timeout in fence_wait(), I think perhaps
> storing "fence->timeout = jiffies + (whatever * HZ);" is a better plan.
> I can forsee us wanting longer timeouts for certain operations
> (particularly long compute operations) in the future.

Yeah, good idea. Later, we will probably need to add code which will keep 
extending
this timeout as long as gpu is progressing.

Marcin


[PATCH] drm/edid: Try harder to fix up base EDID blocks

2012-04-24 Thread Chris Wilson
On Mon, 16 Apr 2012 10:40:08 -0400, Adam Jackson  wrote:
> Requiring the first byte of the EDID base block header to be 0 means we
> don't fix up as many transfer errors as we could.  Instead have the
> callers specify whether it's meant to be block 0 or not, and
> conditionally run header fixup based on that.
> 
> Bugzilla: https://bugzilla.redhat.com/812890
> Signed-off-by: Adam Jackson 

The patch does watch it says on the tin. I don't pretend to know how
frequent this corruption is, but as it stands the current code fails to
be as effective as it could be.

Reviewed-by: Chris Wilson 
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre


Re: Linux 3.4-rc4

2012-04-24 Thread Ben Skeggs
On Tue, 2012-04-24 at 21:35 -0400, Nick Bowler wrote:
> On 2012-04-23 21:03 -0400, Nick Bowler wrote:
> > On 2012-04-22 22:45 -0400, Konrad Rzeszutek Wilk wrote:
> > > On Sun, Apr 22, 2012 at 08:05:54PM -0400, Nick Bowler wrote:
> > > > Following up on the above, the commit which introduces the panics during
> > > > boot is this one:
> > > >
> > > > commit 8e7e70522d760c4ccd4cd370ebfa0ba69e006c6e
> > > > Author: Jerome Glisse 
> > > > Date:   Wed Nov 9 17:15:26 2011 -0500
> > > > 
> > > > drm/ttm: isolate dma data from ttm_tt V4
> [...]
> > > dea7e0a ttm: fix agp since ttm tt rework
> > > 
> > > fixed that.
> > 
> > Yes, I just tested this commit and the one immediately before it.  The
> > one before crashes in the usual way, and dea7e0a boots (with the VGA
> > output black as in the original report).  So this fixed the crash.
> 
> OK, here's what I did:
> 
>  - Since dea7e0a is the first commit that both (a) boots and (b) has
>broken VGA, I checked it out on a new branch:
> 
>  git checkout -b crazy dea7e0a
> 
>  - Next, I reverted *all* (well, I missed one by accident) the remaining
>nouveau-specific commits between 3230cfc34 ("drm/nouveau: enable the
>ttm dma pool when swiotlb is active V3") (i.e., the last commit that
>(a) boots and (b) has non-broken VGA) and dea7e0a:
> 
>  git revert --no-edit 0c101461e267..f7b24c42da1a
> 
>  - Amazingly, the resulting kernel booted and had working VGA, so I did
>a "backwards" bisect on this branch of reverts.  In a strange twist
>of fate, this actually managed to produce bootable kernels the entire
>time.  The bisection pinpointed the following commit as the culprit:
> 
> commit a0b25635515ef5049f93b032a1e37f18b16e0f6f
> Author: Ben Skeggs 
> Date:   Mon Nov 21 16:41:48 2011 +1000
> 
> drm/nouveau/gpio: reimplement as nouveau_gpio.c, fixing a number of issues
> 
> - moves out of nouveau_bios.c and demagics the logical state definitions
> - simplifies chipset-specific driver interface
> - makes most of gpio irq handling common, will use for nv4x hpd later
> - api extended to allow both direct gpio access, and access using the
>   logical function states
> - api extended to allow for future use of gpio extender chips
> - pre-nv50 was handled very badly, the main issue being that all GPIOs
>   were being treated as output-only.
> - fixes nvd0 so gpio changes actually stick, magic reg needs bashing
> 
> Signed-off-by: Ben Skeggs 
Excellent!  That makes things possible.

Are you able to mount debugfs, and email /debugfs/dri/0/vbios.rom for me
(privately if you wish) and I'll attempt to track down what broke for
you.

Thanks!
Ben.

> 
> Unfortunately, there are a number of seemingly non-trivial conflicts
> trying to revert just this one gigantic commit.  So to avoid any
> conflicts, I reverted all of the following (in this order) on top of
> 3.3.3 (there are even more conflicts trying to revert on top of Linus'
> master):
> 
>   7df898b1a70b ("drm/nouveau/disp: check that panel power gpio is enabled at 
> init time")
>   52c4d767437b ("drm/nouveau: move hpd enable/disable to common code")
>   47e5d5cb83d4 ("drm/nv40/disp: implement support for hotplug irq")
>   a0b25635515e ("drm/nouveau/gpio: reimplement as nouveau_gpio.c, fixing a 
> number of issues")
> 
> and my VGA is working again!
> 
> Cheers,


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 5/5] drm/exynos: added vp scaling feature for hdmi

2012-04-24 Thread Seung-Woo Kim
This patch adds vp scaling feature for exynos hdmi. Scaling ratio
between source and destination is used for width and height.
Also meaningless variables to set registers are cleaned.

Signed-off-by: Seung-Woo Kim 
Signed-off-by: Kyungmin Park 
---
 drivers/gpu/drm/exynos/exynos_mixer.c |   88 
 1 files changed, 33 insertions(+), 55 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c 
b/drivers/gpu/drm/exynos/exynos_mixer.c
index 3bc01a6..68ef010 100644
--- a/drivers/gpu/drm/exynos/exynos_mixer.c
+++ b/drivers/gpu/drm/exynos/exynos_mixer.c
@@ -54,6 +54,8 @@ struct hdmi_win_data {
unsigned intfb_y;
unsigned intfb_width;
unsigned intfb_height;
+   unsigned intsrc_width;
+   unsigned intsrc_height;
unsigned intmode_width;
unsigned intmode_height;
unsigned intscan_flags;
@@ -351,10 +353,7 @@ static void vp_video_buffer(struct mixer_context *ctx, int 
win)
struct mixer_resources *res = &ctx->mixer_res;
unsigned long flags;
struct hdmi_win_data *win_data;
-   unsigned int full_width, full_height, width, height;
unsigned int x_ratio, y_ratio;
-   unsigned int src_x_offset, src_y_offset, dst_x_offset, dst_y_offset;
-   unsigned int mode_width, mode_height;
unsigned int buf_num;
dma_addr_t luma_addr[2], chroma_addr[2];
bool tiled_mode = false;
@@ -381,21 +380,9 @@ static void vp_video_buffer(struct mixer_context *ctx, int 
win)
return;
}

-   full_width = win_data->fb_width;
-   full_height = win_data->fb_height;
-   width = win_data->crtc_width;
-   height = win_data->crtc_height;
-   mode_width = win_data->mode_width;
-   mode_height = win_data->mode_height;
-
/* scaling feature: (src << 16) / dst */
-   x_ratio = (width << 16) / width;
-   y_ratio = (height << 16) / height;
-
-   src_x_offset = win_data->fb_x;
-   src_y_offset = win_data->fb_y;
-   dst_x_offset = win_data->crtc_x;
-   dst_y_offset = win_data->crtc_y;
+   x_ratio = (win_data->src_width << 16) / win_data->crtc_width;
+   y_ratio = (win_data->src_height << 16) / win_data->crtc_height;

if (buf_num == 2) {
luma_addr[0] = win_data->dma_addr;
@@ -403,7 +390,7 @@ static void vp_video_buffer(struct mixer_context *ctx, int 
win)
} else {
luma_addr[0] = win_data->dma_addr;
chroma_addr[0] = win_data->dma_addr
-   + (full_width * full_height);
+   + (win_data->fb_width * win_data->fb_height);
}

if (win_data->scan_flags & DRM_MODE_FLAG_INTERLACE) {
@@ -412,8 +399,8 @@ static void vp_video_buffer(struct mixer_context *ctx, int 
win)
luma_addr[1] = luma_addr[0] + 0x40;
chroma_addr[1] = chroma_addr[0] + 0x40;
} else {
-   luma_addr[1] = luma_addr[0] + full_width;
-   chroma_addr[1] = chroma_addr[0] + full_width;
+   luma_addr[1] = luma_addr[0] + win_data->fb_width;
+   chroma_addr[1] = chroma_addr[0] + win_data->fb_width;
}
} else {
ctx->interlace = false;
@@ -434,26 +421,26 @@ static void vp_video_buffer(struct mixer_context *ctx, 
int win)
vp_reg_writemask(res, VP_MODE, val, VP_MODE_FMT_MASK);

/* setting size of input image */
-   vp_reg_write(res, VP_IMG_SIZE_Y, VP_IMG_HSIZE(full_width) |
-   VP_IMG_VSIZE(full_height));
+   vp_reg_write(res, VP_IMG_SIZE_Y, VP_IMG_HSIZE(win_data->fb_width) |
+   VP_IMG_VSIZE(win_data->fb_height));
/* chroma height has to reduced by 2 to avoid chroma distorions */
-   vp_reg_write(res, VP_IMG_SIZE_C, VP_IMG_HSIZE(full_width) |
-   VP_IMG_VSIZE(full_height / 2));
+   vp_reg_write(res, VP_IMG_SIZE_C, VP_IMG_HSIZE(win_data->fb_width) |
+   VP_IMG_VSIZE(win_data->fb_height / 2));

-   vp_reg_write(res, VP_SRC_WIDTH, width);
-   vp_reg_write(res, VP_SRC_HEIGHT, height);
+   vp_reg_write(res, VP_SRC_WIDTH, win_data->src_width);
+   vp_reg_write(res, VP_SRC_HEIGHT, win_data->src_height);
vp_reg_write(res, VP_SRC_H_POSITION,
-   VP_SRC_H_POSITION_VAL(src_x_offset));
-   vp_reg_write(res, VP_SRC_V_POSITION, src_y_offset);
+   VP_SRC_H_POSITION_VAL(win_data->fb_x));
+   vp_reg_write(res, VP_SRC_V_POSITION, win_data->fb_y);

-   vp_reg_write(res, VP_DST_WIDTH, width);
-   vp_reg_write(res, VP_DST_H_POSITION, dst_x_offset);
+   vp_reg_write(res, VP_DST_WIDTH, win_data->crtc_width);
+   vp_reg_write(res, VP_DST_H_POSITION, win_data->crtc_x);
if (ctx->interlace) {
-   vp_reg_write(res, VP_DST_HEIGHT, h

[PATCH 4/5] drm/exynos: added source size to overlay structure

2012-04-24 Thread Seung-Woo Kim
Set plane has source size but exynos overlay structure did
not consider it. This patch adds source size to overlay
structure. For set crtc, source size is set from crtc size.

Signed-off-by: Seung-Woo Kim 
Signed-off-by: Kyungmin Park 
---
 drivers/gpu/drm/exynos/exynos_drm_crtc.c  |4 
 drivers/gpu/drm/exynos/exynos_drm_crtc.h  |4 
 drivers/gpu/drm/exynos/exynos_drm_drv.h   |4 
 drivers/gpu/drm/exynos/exynos_drm_plane.c |   10 +-
 4 files changed, 17 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.c 
b/drivers/gpu/drm/exynos/exynos_drm_crtc.c
index 3486ffe..4afb625 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_crtc.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.c
@@ -105,6 +105,8 @@ int exynos_drm_overlay_update(struct exynos_drm_overlay 
*overlay,
overlay->fb_y = pos->fb_y;
overlay->fb_width = fb->width;
overlay->fb_height = fb->height;
+   overlay->src_width = pos->src_w;
+   overlay->src_height = pos->src_h;
overlay->bpp = fb->bits_per_pixel;
overlay->pitch = fb->pitches[0];
overlay->pixel_format = fb->pixel_format;
@@ -153,6 +155,8 @@ static int exynos_drm_crtc_update(struct drm_crtc *crtc)
pos.crtc_y = 0;
pos.crtc_w = fb->width - crtc->x;
pos.crtc_h = fb->height - crtc->y;
+   pos.src_w = pos.crtc_w;
+   pos.src_h = pos.crtc_h;

return exynos_drm_overlay_update(overlay, crtc->fb, mode, &pos);
 }
diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.h 
b/drivers/gpu/drm/exynos/exynos_drm_crtc.h
index 25f72a6..16b8e21 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_crtc.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.h
@@ -42,6 +42,8 @@ void exynos_drm_crtc_disable_vblank(struct drm_device *dev, 
int crtc);
  * - the unit is screen coordinates.
  * @fb_y: offset y on a framebuffer to be displayed
  * - the unit is screen coordinates.
+ * @src_w: width of source area to be displayed from a framebuffer.
+ * @src_h: height of source area to be displayed from a framebuffer.
  * @crtc_x: offset x on hardware screen.
  * @crtc_y: offset y on hardware screen.
  * @crtc_w: width of hardware screen.
@@ -50,6 +52,8 @@ void exynos_drm_crtc_disable_vblank(struct drm_device *dev, 
int crtc);
 struct exynos_drm_crtc_pos {
unsigned int fb_x;
unsigned int fb_y;
+   unsigned int src_w;
+   unsigned int src_h;
unsigned int crtc_x;
unsigned int crtc_y;
unsigned int crtc_w;
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h 
b/drivers/gpu/drm/exynos/exynos_drm_drv.h
index 1d81417..5f5b362 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h
@@ -77,6 +77,8 @@ struct exynos_drm_overlay_ops {
  * - the unit is screen coordinates.
  * @fb_width: width of a framebuffer.
  * @fb_height: height of a framebuffer.
+ * @src_width: width of a partial image to be displayed from framebuffer.
+ * @src_height: height of a partial image to be displayed from framebuffer.
  * @crtc_x: offset x on hardware screen.
  * @crtc_y: offset y on hardware screen.
  * @crtc_width: window width to be displayed (hardware screen).
@@ -108,6 +110,8 @@ struct exynos_drm_overlay {
unsigned int fb_y;
unsigned int fb_width;
unsigned int fb_height;
+   unsigned int src_width;
+   unsigned int src_height;
unsigned int crtc_x;
unsigned int crtc_y;
unsigned int crtc_width;
diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane.c 
b/drivers/gpu/drm/exynos/exynos_drm_plane.c
index f92fe4c..c4c6525 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_plane.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_plane.c
@@ -41,8 +41,6 @@ exynos_update_plane(struct drm_plane *plane, struct drm_crtc 
*crtc,
container_of(plane, struct exynos_plane, base);
struct exynos_drm_overlay *overlay = &exynos_plane->overlay;
struct exynos_drm_crtc_pos pos;
-   unsigned int x = src_x >> 16;
-   unsigned int y = src_y >> 16;
int ret;

DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
@@ -53,10 +51,12 @@ exynos_update_plane(struct drm_plane *plane, struct 
drm_crtc *crtc,
pos.crtc_w = crtc_w;
pos.crtc_h = crtc_h;

-   pos.fb_x = x;
-   pos.fb_y = y;
+   /* considering 16.16 fixed point of source values */
+   pos.fb_x = src_x >> 16;
+   pos.fb_y = src_y >> 16;
+   pos.src_w = src_w >> 16;
+   pos.src_h = src_h >> 16;

-   /* TODO: scale feature */
ret = exynos_drm_overlay_update(overlay, fb, &crtc->mode, &pos);
if (ret < 0)
return ret;
-- 
1.7.4.1



[PATCH 3/5] drm/exynos: add additional display mode for hdmi

2012-04-24 Thread Seung-Woo Kim
1080p at 30Hz mode is added to hdmi display mode.

Signed-off-by: Seung-Woo Kim 
Signed-off-by: Kyungmin Park 
---
 drivers/gpu/drm/exynos/exynos_hdmi.c |   65 ++
 1 files changed, 65 insertions(+), 0 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c 
b/drivers/gpu/drm/exynos/exynos_hdmi.c
index 5ca0a9f..a137e9e 100644
--- a/drivers/gpu/drm/exynos/exynos_hdmi.c
+++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
@@ -362,6 +362,13 @@ static const u8 hdmiphy_conf27_027[32] = {
0x54, 0xe3, 0x24, 0x00, 0x00, 0x00, 0x01, 0x00,
 };

+static const u8 hdmiphy_conf74_176[32] = {
+   0x01, 0xd1, 0x1f, 0x10, 0x40, 0x5b, 0xef, 0x08,
+   0x81, 0xa0, 0xb9, 0xd8, 0x45, 0xa0, 0xac, 0x80,
+   0x5a, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
+   0x54, 0xa6, 0x24, 0x01, 0x00, 0x00, 0x01, 0x00,
+};
+
 static const u8 hdmiphy_conf74_25[32] = {
0x01, 0xd1, 0x1f, 0x10, 0x40, 0x40, 0xf8, 0x08,
0x81, 0xa0, 0xba, 0xd8, 0x45, 0xa0, 0xac, 0x80,
@@ -751,6 +758,63 @@ static const struct hdmi_preset_conf hdmi_conf_1080i60 = {
},
 };

+static const struct hdmi_preset_conf hdmi_conf_1080p30 = {
+   .core = {
+   .h_blank = {0x18, 0x01},
+   .v2_blank = {0x65, 0x04},
+   .v1_blank = {0x2d, 0x00},
+   .v_line = {0x65, 0x04},
+   .h_line = {0x98, 0x08},
+   .hsync_pol = {0x00},
+   .vsync_pol = {0x00},
+   .int_pro_mode = {0x00},
+   .v_blank_f0 = {0xff, 0xff},
+   .v_blank_f1 = {0xff, 0xff},
+   .h_sync_start = {0x56, 0x00},
+   .h_sync_end = {0x82, 0x00},
+   .v_sync_line_bef_2 = {0x09, 0x00},
+   .v_sync_line_bef_1 = {0x04, 0x00},
+   .v_sync_line_aft_2 = {0xff, 0xff},
+   .v_sync_line_aft_1 = {0xff, 0xff},
+   .v_sync_line_aft_pxl_2 = {0xff, 0xff},
+   .v_sync_line_aft_pxl_1 = {0xff, 0xff},
+   .v_blank_f2 = {0xff, 0xff},
+   .v_blank_f3 = {0xff, 0xff},
+   .v_blank_f4 = {0xff, 0xff},
+   .v_blank_f5 = {0xff, 0xff},
+   .v_sync_line_aft_3 = {0xff, 0xff},
+   .v_sync_line_aft_4 = {0xff, 0xff},
+   .v_sync_line_aft_5 = {0xff, 0xff},
+   .v_sync_line_aft_6 = {0xff, 0xff},
+   .v_sync_line_aft_pxl_3 = {0xff, 0xff},
+   .v_sync_line_aft_pxl_4 = {0xff, 0xff},
+   .v_sync_line_aft_pxl_5 = {0xff, 0xff},
+   .v_sync_line_aft_pxl_6 = {0xff, 0xff},
+   .vact_space_1 = {0xff, 0xff},
+   .vact_space_2 = {0xff, 0xff},
+   .vact_space_3 = {0xff, 0xff},
+   .vact_space_4 = {0xff, 0xff},
+   .vact_space_5 = {0xff, 0xff},
+   .vact_space_6 = {0xff, 0xff},
+   /* other don't care */
+   },
+   .tg = {
+   0x00, /* cmd */
+   0x98, 0x08, /* h_fsz */
+   0x18, 0x01, 0x80, 0x07, /* hact */
+   0x65, 0x04, /* v_fsz */
+   0x01, 0x00, 0x33, 0x02, /* vsync */
+   0x2d, 0x00, 0x38, 0x04, /* vact */
+   0x33, 0x02, /* field_chg */
+   0x48, 0x02, /* vact_st2 */
+   0x00, 0x00, /* vact_st3 */
+   0x00, 0x00, /* vact_st4 */
+   0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
+   0x01, 0x00, 0x33, 0x02, /* field top/bot */
+   0x00, /* 3d FP */
+   },
+};
+
 static const struct hdmi_preset_conf hdmi_conf_1080p50 = {
.core = {
.h_blank = {0xd0, 0x02},
@@ -865,6 +929,7 @@ static const struct hdmi_conf hdmi_confs[] = {
{ 1280, 720, 60, false, hdmiphy_conf74_25, &hdmi_conf_720p60 },
{ 1920, 1080, 50, true, hdmiphy_conf74_25, &hdmi_conf_1080i50 },
{ 1920, 1080, 60, true, hdmiphy_conf74_25, &hdmi_conf_1080i60 },
+   { 1920, 1080, 30, false, hdmiphy_conf74_176, &hdmi_conf_1080p30 },
{ 1920, 1080, 50, false, hdmiphy_conf148_5, &hdmi_conf_1080p50 },
{ 1920, 1080, 60, false, hdmiphy_conf148_5, &hdmi_conf_1080p60 },
 };
-- 
1.7.4.1



[PATCH 2/5] drm/exynos: enable dvi mode for dvi monitor

2012-04-24 Thread Seung-Woo Kim
Hdmi monitor and dvi monitor can be distinguished with edid.
This patch enables dvi mode if dvi monitor is connected and does
not enable audio feature for dvi mode because dvi has no audio
feature.

Signed-off-by: Seung-Woo Kim 
Signed-off-by: Kyungmin Park 
---
 drivers/gpu/drm/exynos/exynos_hdmi.c |   20 ++--
 drivers/gpu/drm/exynos/regs-hdmi.h   |6 --
 2 files changed, 18 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c 
b/drivers/gpu/drm/exynos/exynos_hdmi.c
index ad53c48..5ca0a9f 100644
--- a/drivers/gpu/drm/exynos/exynos_hdmi.c
+++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
@@ -60,6 +60,7 @@ struct hdmi_context {
boolhpd;
boolpowered;
boolis_v13;
+   booldvi_mode;
struct mutexhdmi_mutex;

struct resource *regs_res;
@@ -1211,10 +1212,12 @@ static int hdmi_get_edid(void *ctx, struct 
drm_connector *connector,

raw_edid = drm_get_edid(connector, hdata->ddc_port->adapter);
if (raw_edid) {
+   hdata->dvi_mode = !drm_detect_hdmi_monitor(raw_edid);
memcpy(edid, raw_edid, min((1 + raw_edid->extensions)
* EDID_LENGTH, len));
-   DRM_DEBUG_KMS("width[%d] x height[%d]\n",
-   raw_edid->width_cm, raw_edid->height_cm);
+   DRM_DEBUG_KMS("%s : width[%d] x height[%d]\n",
+   (hdata->dvi_mode ? "dvi monitor" : "hdmi monitor"),
+   raw_edid->width_cm, raw_edid->height_cm);
} else {
return -ENODEV;
}
@@ -1437,10 +1440,7 @@ static void hdmi_audio_init(struct hdmi_context *hdata)

 static void hdmi_audio_control(struct hdmi_context *hdata, bool onoff)
 {
-   u32 mod;
-
-   mod = hdmi_reg_read(hdata, HDMI_MODE_SEL);
-   if (mod & HDMI_DVI_MODE_EN)
+   if (hdata->dvi_mode)
return;

hdmi_reg_writeb(hdata, HDMI_AUI_CON, onoff ? 2 : 0);
@@ -1479,6 +1479,14 @@ static void hdmi_conf_init(struct hdmi_context *hdata)
/* disable bluescreen */
hdmi_reg_writemask(hdata, HDMI_CON_0, 0, HDMI_BLUE_SCR_EN);

+   if (hdata->dvi_mode) {
+   /* choose DVI mode */
+   hdmi_reg_writemask(hdata, HDMI_MODE_SEL,
+   HDMI_MODE_DVI_EN, HDMI_MODE_MASK);
+   hdmi_reg_writeb(hdata, HDMI_CON_2,
+   HDMI_VID_PREAMBLE_DIS | HDMI_GUARD_BAND_DIS);
+   }
+
if (hdata->is_v13) {
/* choose bluescreen (fecal) color */
hdmi_reg_writeb(hdata, HDMI_V13_BLUE_SCREEN_0, 0x12);
diff --git a/drivers/gpu/drm/exynos/regs-hdmi.h 
b/drivers/gpu/drm/exynos/regs-hdmi.h
index 3c04bea..9cc7c5e 100644
--- a/drivers/gpu/drm/exynos/regs-hdmi.h
+++ b/drivers/gpu/drm/exynos/regs-hdmi.h
@@ -138,14 +138,16 @@
 #define HDMI_ASP_MASK  (1 << 2)
 #define HDMI_EN(1 << 0)

+/* HDMI_CON_2 */
+#define HDMI_VID_PREAMBLE_DIS  (1 << 5)
+#define HDMI_GUARD_BAND_DIS(1 << 1)
+
 /* HDMI_PHY_STATUS */
 #define HDMI_PHY_STATUS_READY  (1 << 0)

 /* HDMI_MODE_SEL */
 #define HDMI_MODE_HDMI_EN  (1 << 1)
 #define HDMI_MODE_DVI_EN   (1 << 0)
-#define HDMI_DVI_MODE_EN   (1)
-#define HDMI_DVI_MODE_DIS  (0)
 #define HDMI_MODE_MASK (3 << 0)

 /* HDMI_TG_CMD */
-- 
1.7.4.1



[PATCH 1/5] drm/exynos: fixed wrong pageflip finish event for interlace mode

2012-04-24 Thread Seung-Woo Kim
Pageflip finish event for interlace mode has bug on checking top
field vsync because of comparing between dma address converted
by start coordinates and non-converted dma address.

Signed-off-by: Seung-Woo Kim 
Signed-off-by: Kyungmin Park 
---
 drivers/gpu/drm/exynos/exynos_mixer.c |   12 +++-
 1 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c 
b/drivers/gpu/drm/exynos/exynos_mixer.c
index 2f6727a..3bc01a6 100644
--- a/drivers/gpu/drm/exynos/exynos_mixer.c
+++ b/drivers/gpu/drm/exynos/exynos_mixer.c
@@ -886,7 +886,7 @@ static irqreturn_t mixer_irq_handler(int irq, void *arg)
struct exynos_drm_hdmi_context *drm_hdmi_ctx = arg;
struct mixer_context *ctx = drm_hdmi_ctx->ctx;
struct mixer_resources *res = &ctx->mixer_res;
-   u32 val, val_base;
+   u32 val, base, shadow;

spin_lock(&res->reg_slock);

@@ -897,12 +897,14 @@ static irqreturn_t mixer_irq_handler(int irq, void *arg)
if (val & MXR_INT_STATUS_VSYNC) {
/* interlace scan need to check shadow register */
if (ctx->interlace) {
-   val_base = mixer_reg_read(res, MXR_GRAPHIC_BASE_S(0));
-   if (ctx->win_data[0].dma_addr != val_base)
+   base = mixer_reg_read(res, MXR_GRAPHIC_BASE(0));
+   shadow = mixer_reg_read(res, MXR_GRAPHIC_BASE_S(0));
+   if (base != shadow)
goto out;

-   val_base = mixer_reg_read(res, MXR_GRAPHIC_BASE_S(1));
-   if (ctx->win_data[1].dma_addr != val_base)
+   base = mixer_reg_read(res, MXR_GRAPHIC_BASE(1));
+   shadow = mixer_reg_read(res, MXR_GRAPHIC_BASE_S(1));
+   if (base != shadow)
goto out;
}

-- 
1.7.4.1



[PATCH 0/5] various patches related with hdmi of exynos drm

2012-04-24 Thread Seung-Woo Kim
This patch set adds dvi mode, 1080p at 30Hz mode, and vp scaling feature to
hdmi of exynos drm and fixes pageflip bug in interlace mode for hdmi.

This patch set is for drm-next branch and based on current patch sets from
Inki Dae and Joonyoung Shim. You can refer below links:
http://www.spinics.net/lists/dri-devel/msg21739.html
http://www.spinics.net/lists/dri-devel/msg21746.html
http://www.spinics.net/lists/dri-devel/msg21734.html


Seung-Woo Kim (5):
  drm/exynos: fixed wrong pageflip finish event for interlace mode
  drm/exynos: enable dvi mode for dvi monitor
  drm/exynos: add additional display mode for hdmi
  drm/exynos: added source size to overlay structure
  drm/exynos: added vp scaling feature for hdmi

 drivers/gpu/drm/exynos/exynos_drm_crtc.c  |4 +
 drivers/gpu/drm/exynos/exynos_drm_crtc.h  |4 +
 drivers/gpu/drm/exynos/exynos_drm_drv.h   |4 +
 drivers/gpu/drm/exynos/exynos_drm_plane.c |   10 ++--
 drivers/gpu/drm/exynos/exynos_hdmi.c  |   85 +++--
 drivers/gpu/drm/exynos/exynos_mixer.c |  100 -
 drivers/gpu/drm/exynos/regs-hdmi.h|6 +-
 7 files changed, 140 insertions(+), 73 deletions(-)

-- 
1.7.4.1



Re: [PATCH 1/3] drivers-gpu-drm-allow-to-load-edid-firmware.patch

2012-04-24 Thread Michael Witten
On Sun, 11 Mar 2012 22:23:22 +0100, Carsten Emde wrote:

> On 03/11/2012 02:44 PM, Alan Cox wrote:
>
>>> This patch allows to load an EDID data set via the firmware interface.
>>> It contains data sets of frequently used screen resolutions (1024x768,
>>> 1280x1024, 1680x1050 and 1920x1080). The requested EDID data are
>>> specified as a module parameter of the drm_kms_helper module, e.g.
>>> options drm_kms_helper edid_firmware=edid/1280x1024.bin or as kernel
>>> command line parameter.
>>
>> What if the DRM layer and driver are compiled in. They'll come up as
>> console before the file system so the firmware request will hang ?
>
> Admittedly I did not try to compile the DRM layer and driver into the 
> kernel. However, I created an error condition by specifying a 
> non-existing EDID file. In this case, the function returns with error, 
> the mode count remains 0, and the system continues to run as if the 
> edid_firmware= parameter had not been specified.

Unfortunately, as of at least last month, my system hangs when I try to
use your feature (just as described by Alan Cox); the log shows that
during the boot process, there is a one-minute hang:

  [0.175207] [drm] radeon: power management initialized
  [   60.896507] [drm:edid_load] *ERROR* Requesting EDID firmware 
"edid/1920x1200.bin" failed (err=-2)

Is there any way to make your feature smarter about its timing with
relation to file system accessibility?

Sincerely,
Michael Witten
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH] dma-buf: mmap support

2012-04-24 Thread InKi Dae
2012/4/25, Daniel Vetter :
> On Wed, Apr 25, 2012 at 01:37:51AM +0900, InKi Dae wrote:
>> Hi,
>>
>> >
>> > +static int dma_buf_mmap_internal(struct file *file, struct
>> > vm_area_struct *vma)
>> > +{
>> > +   struct dma_buf *dmabuf;
>> > +
>> > +   if (!is_dma_buf_file(file))
>> > +   return -EINVAL;
>> > +
>> > +   dmabuf = file->private_data;
>> > +
>> > +   /* check for overflowing the buffer's size */
>> > +   if (vma->vm_pgoff + ((vma->vm_end - vma->vm_start) >>
>> > PAGE_SHIFT) >
>> > +   dmabuf->size >> PAGE_SHIFT)
>>
>> is this condition right? your intention is for checking buffer's size
>> is valid or not. by the way why is vma->vm_pgoff added to vm region
>> size?
>
> This check here is to ensure that userspace cannot mmap beyong the end of
> the dma_buf object. vm_pgoff is the offset userspace passed in at mmap
> time and hence needs to be added. Note that vm_end and vm_start are in
> bytes, wheres vm_pgoff is in pages.
>

You're right, vma area region would be decided by user-desired size
that this is passed by mmap syscall so user should set size and
vm_pgoff appropriately. it's my missing point. well if any part of
dmabuf buffer region had already been mmaped and after that user
requested mmap for another region of the dmabuf buffer region again
then isn't there any problem? I mean that dmabuf->size would always
have same value since any memory region allocated by any allocators
such as gem, ump and so on have been exported to dmabuf. so at second
mmap request, dmabuf->size wouldn't have reasonable value because with
first mmap request, any part of the dmabuf buffer region had already
beem mmaped. for example, dmabuf size is 1MB and 512Kb region of the
dmabuf was mmaped by first mmap request and then with second mmap
request, your code would check whether user-desired size is valid or
not with dmabuf->size but dmabuf->size would still have 1MB it means
at second mmap request, any size between 512KB ~ 1MB would be ok. it's
just my concern and there could be my missing point.

Thanks,
Inki Dae.

>> > +   return -EINVAL;
>> > +
>> > +   return dmabuf->ops->mmap(dmabuf, vma);
>> > +}
>> > +
>> >  static const struct file_operations dma_buf_fops = {
>> >.release= dma_buf_release,
>> > +   .mmap   = dma_buf_mmap_internal,
>> >  };
>> >
>> >  /*
>> > @@ -82,7 +100,8 @@ struct dma_buf *dma_buf_export(void *priv, const
>> > struct dma_buf_ops *ops,
>> >  || !ops->unmap_dma_buf
>> >  || !ops->release
>> >  || !ops->kmap_atomic
>> > - || !ops->kmap)) {
>> > + || !ops->kmap
>> > + || !ops->mmap)) {
>> >return ERR_PTR(-EINVAL);
>> >}
>> >
>> > @@ -406,3 +425,46 @@ void dma_buf_kunmap(struct dma_buf *dmabuf,
>> > unsigned long page_num,
>> >dmabuf->ops->kunmap(dmabuf, page_num, vaddr);
>> >  }
>> >  EXPORT_SYMBOL_GPL(dma_buf_kunmap);
>> > +
>> > +
>> > +/**
>> > + * dma_buf_mmap - Setup up a userspace mmap with the given vma
>> > + * @dma_buf:   [in]buffer that should back the vma
>> > + * @vma:   [in]vma for the mmap
>> > + * @pgoff: [in]offset in pages where this mmap should start
>> > within the
>> > + * dma-buf buffer.
>> > + *
>> > + * This function adjusts the passed in vma so that it points at the
>> > file of the
>> > + * dma_buf operation. It alsog adjusts the starting pgoff and does
>> > bounds
>> > + * checking on the size of the vma. Then it calls the exporters mmap
>> > function to
>> > + * set up the mapping.
>> > + *
>> > + * Can return negative error values, returns 0 on success.
>> > + */
>> > +int dma_buf_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma,
>> > +unsigned long pgoff)
>> > +{
>> > +   if (WARN_ON(!dmabuf || !vma))
>> > +   return -EINVAL;
>> > +
>> > +   /* check for offset overflow */
>> > +   if (pgoff + ((vma->vm_end - vma->vm_start) >> PAGE_SHIFT) <
>> > pgoff)
>>
>> ditto. isn't it checked whether page offset to be mmaped is placed
>> within vm region or not with the condition, if ((vma->vm_end -
>> vma->vm_start) >> PAGE_SHIFT) < pgoff)?
>
> Nope, this check only checks for overflow. The pgoff is the offset within
> the dma_buf object. E.g. a drm driver splits up it mmap space into pieces,
> which map to individual buffers. If userspace just mmaps parts of such a
> buffer, the importer can pass the offset in pgoff. But I expect this to be
> 0 for almost all cases.
>
> Note that we don't need this overflow check in the internal mmap function
> because do_mmap will do it for us. But here the importer potentially sets
> a completely different pgoff, so we need to do it. dma_buf documentation
> also mentions this (and that importers do not have to do these checks).
>
> Yours, Daniel
>
>>
>> > +   return -EOVERFL

Re: [Patch 0/3] Add ability to override a monitor's EDID information

2012-04-24 Thread Michael Witten
On Tue, 24 Apr 2012 10:49:06 +0200, Thorsten Schoel wrote:

> Hello everybody,
>
> having a monitor provide wrong or invalid EDID information---or none at
> all---seems to be a problem quite a number of people are facing. A few
> of the non-KMS X-drivers provide individual mechanisms for overriding
> such an EDID with user provided data. To my knowledge at least the
> kernel currently falls short of providing such a mechanism. This set of
> patches attempts to provide one.
>
> It has a number of potential shortcoming to which I was not yet able to
> find any solution. These are:
>
> 1. It uses drm_get_connector_name to identify a connector. I am not
> entirely sure though if these names are guaranteed to be unique (the
> names used in /sys/class/drm seem to suggest they are not). Since they
> are good enough for the kernel's video parameter, though, I figured they
> should be good enough for the present purpose as well.
>
> 2. One of the patches introduces a new kernel parameter (edid_override).
> This parameter takes either the raw edid-data encoded as a hex-string or
> the name of a firmware file from which to load the data. I am a bit
> unhappy with both solutions since the first puts raw data on the command
> line and makes it rather long and the second... well edid-data is not
> exactly firmware in the strict sense. It may be firm, but it is probably
> not ware.
>
> 3. I thought about making the sysfs code more sophisticated so that
> individual bytes could be written at any position within the data. Yet,
> there seems to be no way to truncate a file in sysfs which would be
> important when changing the number of 128 byte blocks the data is made
> up of. In addition, I cannot see what good such a behaviour would be or
> how the obscure use probably is somewhere out there could justify the
> additional complexity. I therefore opted for the approach of only
> allowing writes of complete edid-blobs in one pass.
>
> The patches I submit were tested on an x64 with radeon graphics and on
> an x86 with i915. They were made for 3.4.
>
>  drivers/gpu/drm/drm_edid.c  |  399 
> +++-
>  drivers/gpu/drm/drm_sysfs.c |   43 
>  include/drm/drm_crtc.h  |2
>  3 files changed, 435 insertions(+), 9 deletions(-)

Are you aware of the following recent commit?

  commit da0df92b57311aa1b26a2a90599ed16e1e968b90
  Author: Carsten Emde 
  Date:   Sun Mar 18 22:37:33 2012 +0100
  drm: allow loading an EDID as firmware to override broken monitor

Has some of your work already been implemented?

That being said, the firmware-loading feature of the above commit is not
useful to me, because on my system, it tries to load the EDID data BEFORE
the kernel knows how to access the file system where the requisite file
resides; perhaps something like your command-line EDID data would be useful
to me (and others).

Sincerely,
Michael Witten
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH] dma-buf: mmap support

2012-04-24 Thread Daniel Vetter
On Wed, Apr 25, 2012 at 01:37:51AM +0900, InKi Dae wrote:
> Hi,
> 
> >
> > +static int dma_buf_mmap_internal(struct file *file, struct vm_area_struct 
> > *vma)
> > +{
> > + ? ? ? struct dma_buf *dmabuf;
> > +
> > + ? ? ? if (!is_dma_buf_file(file))
> > + ? ? ? ? ? ? ? return -EINVAL;
> > +
> > + ? ? ? dmabuf = file->private_data;
> > +
> > + ? ? ? /* check for overflowing the buffer's size */
> > + ? ? ? if (vma->vm_pgoff + ((vma->vm_end - vma->vm_start) >> PAGE_SHIFT) >
> > + ? ? ? ? ? dmabuf->size >> PAGE_SHIFT)
> 
> is this condition right? your intention is for checking buffer's size
> is valid or not. by the way why is vma->vm_pgoff added to vm region
> size?

This check here is to ensure that userspace cannot mmap beyong the end of
the dma_buf object. vm_pgoff is the offset userspace passed in at mmap
time and hence needs to be added. Note that vm_end and vm_start are in
bytes, wheres vm_pgoff is in pages.

> > + ? ? ? ? ? ? ? return -EINVAL;
> > +
> > + ? ? ? return dmabuf->ops->mmap(dmabuf, vma);
> > +}
> > +
> > ?static const struct file_operations dma_buf_fops = {
> > ? ? ? ?.release ? ? ? ?= dma_buf_release,
> > + ? ? ? .mmap ? ? ? ? ? = dma_buf_mmap_internal,
> > ?};
> >
> > ?/*
> > @@ -82,7 +100,8 @@ struct dma_buf *dma_buf_export(void *priv, const struct 
> > dma_buf_ops *ops,
> > ? ? ? ? ? ? ? ? ? ? ? ? ?|| !ops->unmap_dma_buf
> > ? ? ? ? ? ? ? ? ? ? ? ? ?|| !ops->release
> > ? ? ? ? ? ? ? ? ? ? ? ? ?|| !ops->kmap_atomic
> > - ? ? ? ? ? ? ? ? ? ? ? ? || !ops->kmap)) {
> > + ? ? ? ? ? ? ? ? ? ? ? ? || !ops->kmap
> > + ? ? ? ? ? ? ? ? ? ? ? ? || !ops->mmap)) {
> > ? ? ? ? ? ? ? ?return ERR_PTR(-EINVAL);
> > ? ? ? ?}
> >
> > @@ -406,3 +425,46 @@ void dma_buf_kunmap(struct dma_buf *dmabuf, unsigned 
> > long page_num,
> > ? ? ? ? ? ? ? ?dmabuf->ops->kunmap(dmabuf, page_num, vaddr);
> > ?}
> > ?EXPORT_SYMBOL_GPL(dma_buf_kunmap);
> > +
> > +
> > +/**
> > + * dma_buf_mmap - Setup up a userspace mmap with the given vma
> > + * @dma_buf: ? [in] ? ?buffer that should back the vma
> > + * @vma: ? ? ? [in] ? ?vma for the mmap
> > + * @pgoff: ? ? [in] ? ?offset in pages where this mmap should start within 
> > the
> > + * ? ? ? ? ? ? ? ? ? ? dma-buf buffer.
> > + *
> > + * This function adjusts the passed in vma so that it points at the file 
> > of the
> > + * dma_buf operation. It alsog adjusts the starting pgoff and does bounds
> > + * checking on the size of the vma. Then it calls the exporters mmap 
> > function to
> > + * set up the mapping.
> > + *
> > + * Can return negative error values, returns 0 on success.
> > + */
> > +int dma_buf_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma,
> > + ? ? ? ? ? ? ? ?unsigned long pgoff)
> > +{
> > + ? ? ? if (WARN_ON(!dmabuf || !vma))
> > + ? ? ? ? ? ? ? return -EINVAL;
> > +
> > + ? ? ? /* check for offset overflow */
> > + ? ? ? if (pgoff + ((vma->vm_end - vma->vm_start) >> PAGE_SHIFT) < pgoff)
> 
> ditto. isn't it checked whether page offset to be mmaped is placed
> within vm region or not with the condition, if ((vma->vm_end -
> vma->vm_start) >> PAGE_SHIFT) < pgoff)?

Nope, this check only checks for overflow. The pgoff is the offset within
the dma_buf object. E.g. a drm driver splits up it mmap space into pieces,
which map to individual buffers. If userspace just mmaps parts of such a
buffer, the importer can pass the offset in pgoff. But I expect this to be
0 for almost all cases.

Note that we don't need this overflow check in the internal mmap function
because do_mmap will do it for us. But here the importer potentially sets
a completely different pgoff, so we need to do it. dma_buf documentation
also mentions this (and that importers do not have to do these checks).

Yours, Daniel

> 
> > + ? ? ? ? ? ? ? return -EOVERFLOW;
> > +
> > + ? ? ? /* check for overflowing the buffer's size */
> > + ? ? ? if (pgoff + ((vma->vm_end - vma->vm_start) >> PAGE_SHIFT) >
> > + ? ? ? ? ? dmabuf->size >> PAGE_SHIFT)
> > + ? ? ? ? ? ? ? return -EINVAL;
> > +
> > + ? ? ? /* readjust the vma */
> > + ? ? ? if (vma->vm_file)
> > + ? ? ? ? ? ? ? fput(vma->vm_file);
> > +
> > + ? ? ? vma->vm_file = dmabuf->file;
> > + ? ? ? get_file(vma->vm_file);
> > +
> > + ? ? ? vma->vm_pgoff = pgoff;
> > +
> > + ? ? ? return dmabuf->ops->mmap(dmabuf, vma);
> > +}
> > +EXPORT_SYMBOL_GPL(dma_buf_mmap);
> > diff --git a/include/linux/dma-buf.h b/include/linux/dma-buf.h
> > index 3efbfc2..1f78d15 100644
> > --- a/include/linux/dma-buf.h
> > +++ b/include/linux/dma-buf.h
> > @@ -61,6 +61,10 @@ struct dma_buf_attachment;
> > ?* ? ? ? ? ? ? ? ?This Callback must not sleep.
> > ?* @kmap: maps a page from the buffer into kernel address space.
> > ?* @kunmap: [optional] unmaps a page from the buffer.
> > + * @mmap: used to expose the backing storage to userspace. Note that the
> > + * ? ? ? mapping needs to be coherent - if the exporter doesn't directly
> > + * ? ? ? support this, it needs to fake coherency by shooting down any ptes
> > + * ? ? ? when transitioning away from the cpu d

Re: Linux 3.4-rc4

2012-04-24 Thread Nick Bowler
On 2012-04-23 21:03 -0400, Nick Bowler wrote:
> On 2012-04-22 22:45 -0400, Konrad Rzeszutek Wilk wrote:
> > On Sun, Apr 22, 2012 at 08:05:54PM -0400, Nick Bowler wrote:
> > > Following up on the above, the commit which introduces the panics during
> > > boot is this one:
> > >
> > > commit 8e7e70522d760c4ccd4cd370ebfa0ba69e006c6e
> > > Author: Jerome Glisse 
> > > Date:   Wed Nov 9 17:15:26 2011 -0500
> > > 
> > > drm/ttm: isolate dma data from ttm_tt V4
[...]
> > dea7e0a ttm: fix agp since ttm tt rework
> > 
> > fixed that.
> 
> Yes, I just tested this commit and the one immediately before it.  The
> one before crashes in the usual way, and dea7e0a boots (with the VGA
> output black as in the original report).  So this fixed the crash.

OK, here's what I did:

 - Since dea7e0a is the first commit that both (a) boots and (b) has
   broken VGA, I checked it out on a new branch:

 git checkout -b crazy dea7e0a

 - Next, I reverted *all* (well, I missed one by accident) the remaining
   nouveau-specific commits between 3230cfc34 ("drm/nouveau: enable the
   ttm dma pool when swiotlb is active V3") (i.e., the last commit that
   (a) boots and (b) has non-broken VGA) and dea7e0a:

 git revert --no-edit 0c101461e267..f7b24c42da1a

 - Amazingly, the resulting kernel booted and had working VGA, so I did
   a "backwards" bisect on this branch of reverts.  In a strange twist
   of fate, this actually managed to produce bootable kernels the entire
   time.  The bisection pinpointed the following commit as the culprit:

commit a0b25635515ef5049f93b032a1e37f18b16e0f6f
Author: Ben Skeggs 
Date:   Mon Nov 21 16:41:48 2011 +1000

drm/nouveau/gpio: reimplement as nouveau_gpio.c, fixing a number of issues

- moves out of nouveau_bios.c and demagics the logical state definitions
- simplifies chipset-specific driver interface
- makes most of gpio irq handling common, will use for nv4x hpd later
- api extended to allow both direct gpio access, and access using the
  logical function states
- api extended to allow for future use of gpio extender chips
- pre-nv50 was handled very badly, the main issue being that all GPIOs
  were being treated as output-only.
- fixes nvd0 so gpio changes actually stick, magic reg needs bashing

Signed-off-by: Ben Skeggs 

Unfortunately, there are a number of seemingly non-trivial conflicts
trying to revert just this one gigantic commit.  So to avoid any
conflicts, I reverted all of the following (in this order) on top of
3.3.3 (there are even more conflicts trying to revert on top of Linus'
master):

  7df898b1a70b ("drm/nouveau/disp: check that panel power gpio is enabled at 
init time")
  52c4d767437b ("drm/nouveau: move hpd enable/disable to common code")
  47e5d5cb83d4 ("drm/nv40/disp: implement support for hotplug irq")
  a0b25635515e ("drm/nouveau/gpio: reimplement as nouveau_gpio.c, fixing a 
number of issues")

and my VGA is working again!

Cheers,
-- 
Nick Bowler, Elliptic Technologies (http://www.elliptictech.com/)

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [RFC PATCH 5/5] drm/nouveau: gpu lockup recovery

2012-04-24 Thread Ben Skeggs
On Tue, 2012-04-24 at 21:31 +0200, Marcin Slusarz wrote:
> On Mon, Apr 23, 2012 at 06:56:44PM +0200, Martin Peres wrote:
> > Le 23/04/2012 18:32, Marcin Slusarz a écrit :
> > >
> > > Just run piglit. Even "quick" tests can cause ~5 lockups (it eventually 
> > > messes
> > > up DDX channel, but this patchset can't fix this case).
> > > You can run fs-discard-exit-2 test first - for me it causes instant GPU 
> > > lockup.
> > >
> > > Marcin
> > Great, Thanks.
> > 
> > Did you have a look at 
> > https://bugs.freedesktop.org/show_bug.cgi?id=40886 and 
> > http://xorg.freedesktop.org/wiki/SummerOfCodeIdeas ?
> 
> Yeah, I've seen them some time ago.
> 
> > The Ubuntu xorg devs were looking for something like this, but they also 
> > wanted a lockup report. Are you also interested on working on it ?
As I argued at XDC last year, I really question the usefulness of
something like this.  We have stupidly HUGE amounts of state that could
be relevant, and the situations where we even need something like this
are RARE.

I don't want this useless crap in our kernel module just because some
random distro thinks it's so useful, when it's not.  On the very very
rare (I can think of one situation where we've wanted these register
dumps, and they weren't useful even then) occasions we need this info,
we can ask people to install envytools and grab it..

We have a GPU with *very* good error reporting, and we log this to
dmesg.  This is good enough.  Any random errorless lockups are much
harder, and unless you dump *all* the card state right from the memory
controllers, to the clocks, to PFIFO to the particular engine that's
involved.. It's going to be useless.  The problem could be anything.

> 
> Yes, when this patchset will be applied, I'm going to work on improving
> error reporting.
Assuming you're not talking about a register-dump style lockup report
like above, this could be good.  Particularly, fleshing out and
improving/completing each engine's IRQ handlers (which will probably
have the nice side-effect of surviving a few more errors without locking
up) :)

Cheers,
Ben.

> 
> Marcin
> ___
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 6/6] gma500: Set the mapping mask

2012-04-24 Thread Alan Cox
From: Alan Cox 

Some boards such as the Intel D2700MUD allow you to have over 4GB of RAM.
The GTT on the PVR based devices is 32bit however. Hugh Dickins points out
that we should therefore be setting the mapping gfp mask.

This is not the whole fix for the problem. Some further shmem patches will
be needed to deal with the corner cases.

Signed-off-by: Alan Cox 
---

 drivers/gpu/drm/gma500/gem.c |2 ++
 drivers/gpu/drm/gma500/gtt.c |4 
 2 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/drivers/gpu/drm/gma500/gem.c b/drivers/gpu/drm/gma500/gem.c
index 9fbb868..fc7d144 100644
--- a/drivers/gpu/drm/gma500/gem.c
+++ b/drivers/gpu/drm/gma500/gem.c
@@ -124,6 +124,8 @@ static int psb_gem_create(struct drm_file *file,
dev_err(dev->dev, "GEM init failed for %lld\n", size);
return -ENOMEM;
}
+   /* Limit the object to 32bit mappings */
+   mapping_set_gfp_mask(r->gem.filp->f_mapping, GFP_KERNEL | __GFP_DMA32);
/* Give the object a handle so we can carry it more easily */
ret = drm_gem_handle_create(file, &r->gem, &handle);
if (ret) {
diff --git a/drivers/gpu/drm/gma500/gtt.c b/drivers/gpu/drm/gma500/gtt.c
index db2e823..54e5c9e 100644
--- a/drivers/gpu/drm/gma500/gtt.c
+++ b/drivers/gpu/drm/gma500/gtt.c
@@ -39,6 +39,10 @@ static inline uint32_t psb_gtt_mask_pte(uint32_t pfn, int 
type)
 {
uint32_t mask = PSB_PTE_VALID;

+   /* Ensure we explode rather than put an invalid low mapping of
+  a high mapping page into the gtt */
+   BUG_ON(pfn & ~(0x >> PAGE_SHIFT));
+
if (type & PSB_MMU_CACHED_MEMORY)
mask |= PSB_PTE_CACHED;
if (type & PSB_MMU_RO_MEMORY)



[PATCH 5/6] gma500: Add ops for hotplug support.

2012-04-24 Thread Alan Cox
From: Alan Cox 

This provides the needed callback hooks to add hotplug display support to
the GMA36x0 devices. 

[The actual enabling device part will follow once I've figured out why it
 breaks suspend/resume on some netbooks]

Signed-off-by: Alan Cox 
---

 drivers/gpu/drm/gma500/psb_drv.h |3 +++
 drivers/gpu/drm/gma500/psb_irq.c |   36 +++-
 2 files changed, 30 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/gma500/psb_drv.h b/drivers/gpu/drm/gma500/psb_drv.h
index 6235499..ab483c3 100644
--- a/drivers/gpu/drm/gma500/psb_drv.h
+++ b/drivers/gpu/drm/gma500/psb_drv.h
@@ -130,6 +130,7 @@ enum {
 #define _PSB_VSYNC_PIPEA_FLAG(1<<7)
 #define _MDFLD_MIPIA_FLAG(1<<16)
 #define _MDFLD_MIPIC_FLAG(1<<17)
+#define _PSB_IRQ_DISP_HOTSYNC(1<<17)
 #define _PSB_IRQ_SGX_FLAG(1<<18)
 #define _PSB_IRQ_MSVDX_FLAG  (1<<19)
 #define _LNC_IRQ_TOPAZ_FLAG  (1<<20)
@@ -703,6 +704,8 @@ struct psb_ops {

/* Display management hooks */
int (*output_init)(struct drm_device *dev);
+   int (*hotplug)(struct drm_device *dev);
+   void (*hotplug_enable)(struct drm_device *dev, bool on);
/* Power management hooks */
void (*init_pm)(struct drm_device *dev);
int (*save_regs)(struct drm_device *dev);
diff --git a/drivers/gpu/drm/gma500/psb_irq.c b/drivers/gpu/drm/gma500/psb_irq.c
index 1869586..4f31312 100644
--- a/drivers/gpu/drm/gma500/psb_irq.c
+++ b/drivers/gpu/drm/gma500/psb_irq.c
@@ -199,11 +199,9 @@ static void psb_vdc_interrupt(struct drm_device *dev, 
uint32_t vdc_stat)

 irqreturn_t psb_irq_handler(DRM_IRQ_ARGS)
 {
-   struct drm_device *dev = (struct drm_device *) arg;
-   struct drm_psb_private *dev_priv =
-   (struct drm_psb_private *) dev->dev_private;
-
-   uint32_t vdc_stat, dsp_int = 0, sgx_int = 0;
+   struct drm_device *dev = arg;
+   struct drm_psb_private *dev_priv = dev->dev_private;
+   uint32_t vdc_stat, dsp_int = 0, sgx_int = 0, hotplug_int = 0;
int handled = 0;

spin_lock(&dev_priv->irqmask_lock);
@@ -220,6 +218,8 @@ irqreturn_t psb_irq_handler(DRM_IRQ_ARGS)

if (vdc_stat & _PSB_IRQ_SGX_FLAG)
sgx_int = 1;
+   if (vdc_stat & _PSB_IRQ_DISP_HOTSYNC)
+   hotplug_int = 1;

vdc_stat &= dev_priv->vdc_irq_mask;
spin_unlock(&dev_priv->irqmask_lock);
@@ -241,6 +241,13 @@ irqreturn_t psb_irq_handler(DRM_IRQ_ARGS)
handled = 1;
}

+   /* Note: this bit has other meanings on some devices, so we will
+  need to address that later if it ever matters */
+   if (hotplug_int && dev_priv->ops->hotplug) {
+   handled = dev_priv->ops->hotplug(dev);
+   REG_WRITE(PORT_HOTPLUG_STAT, REG_READ(PORT_HOTPLUG_STAT));
+   }
+
PSB_WVDC32(vdc_stat, PSB_INT_IDENTITY_R);
(void) PSB_RVDC32(PSB_INT_IDENTITY_R);
DRM_READMEMORYBARRIER();
@@ -273,6 +280,10 @@ void psb_irq_preinstall(struct drm_device *dev)
dev_priv->vdc_irq_mask |= _MDFLD_PIPEC_EVENT_FLAG;
*/

+   /* Revisit this area - want per device masks ? */
+   if (dev_priv->ops->hotplug)
+   dev_priv->vdc_irq_mask |= _PSB_IRQ_DISP_HOTSYNC;
+
/* This register is safe even if display island is off */
PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R);
spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);
@@ -305,18 +316,25 @@ int psb_irq_postinstall(struct drm_device *dev)
else
psb_disable_pipestat(dev_priv, 2, PIPE_VBLANK_INTERRUPT_ENABLE);

+   if (dev_priv->ops->hotplug_enable)
+   dev_priv->ops->hotplug_enable(dev, true);
+
spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);
return 0;
 }

 void psb_irq_uninstall(struct drm_device *dev)
 {
-   struct drm_psb_private *dev_priv =
-   (struct drm_psb_private *) dev->dev_private;
+   struct drm_psb_private *dev_priv = dev->dev_private;
unsigned long irqflags;

spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);

+   if (dev_priv->ops->hotplug_enable) {
+   dev_priv->ops->hotplug_enable(dev, false);
+   dev_priv->vdc_irq_mask &= ~_PSB_IRQ_DISP_HOTSYNC;
+   }
+
PSB_WVDC32(0x, PSB_HWSTAM);

if (dev->vblank_enabled[0])
@@ -328,9 +346,9 @@ void psb_irq_uninstall(struct drm_device *dev)
if (dev->vblank_enabled[2])
psb_disable_pipestat(dev_priv, 2, PIPE_VBLANK_INTERRUPT_ENABLE);

-   dev_priv->vdc_irq_mask &= _PSB_IRQ_SGX_FLAG |
+   dev_priv->vdc_irq_mask &= ~(_PSB_IRQ_SGX_FLAG |
  _PSB_IRQ_MSVDX_FLAG |
- _LNC_IRQ_TOPAZ_FLAG;
+ _LNC_IRQ_TOPAZ_FLAG);

/* These two registers are safe even if display island is off */
PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R);

[PATCH 4/6] gma500: implement backlight functionality for Cedartrail devices

2012-04-24 Thread Alan Cox
From: Alan Cox 

Basically a straight cut/paste from the reference driver code then
cleaned up a spot.

Signed-off-by: Alan Cox 
---

 drivers/gpu/drm/gma500/cdv_device.c |  113 ---
 1 files changed, 51 insertions(+), 62 deletions(-)

diff --git a/drivers/gpu/drm/gma500/cdv_device.c 
b/drivers/gpu/drm/gma500/cdv_device.c
index 5cc06a8..292bcec 100644
--- a/drivers/gpu/drm/gma500/cdv_device.c
+++ b/drivers/gpu/drm/gma500/cdv_device.c
@@ -57,8 +57,7 @@ static int cdv_output_init(struct drm_device *dev)
cdv_intel_crt_init(dev, &dev_priv->mode_dev);
cdv_intel_lvds_init(dev, &dev_priv->mode_dev);

-   /* These bits indicate HDMI not SDVO on CDV, but we don't yet support
-  the HDMI interface */
+   /* These bits indicate HDMI not SDVO on CDV */
if (REG_READ(SDVOB) & SDVO_DETECTED)
cdv_hdmi_init(dev, &dev_priv->mode_dev, SDVOB);
if (REG_READ(SDVOC) & SDVO_DETECTED)
@@ -69,76 +68,71 @@ static int cdv_output_init(struct drm_device *dev)
 #ifdef CONFIG_BACKLIGHT_CLASS_DEVICE

 /*
- * Poulsbo Backlight Interfaces
+ * Cedartrail Backlght Interfaces
  */

-#define BLC_PWM_PRECISION_FACTOR 100   /* 1000 */
-#define BLC_PWM_FREQ_CALC_CONSTANT 32
-#define MHz 100
-
-#define PSB_BLC_PWM_PRECISION_FACTOR10
-#define PSB_BLC_MAX_PWM_REG_FREQ0xFFFE
-#define PSB_BLC_MIN_PWM_REG_FREQ0x2
-
-#define PSB_BACKLIGHT_PWM_POLARITY_BIT_CLEAR (0xFFFE)
-#define PSB_BACKLIGHT_PWM_CTL_SHIFT(16)
-
-static int cdv_brightness;
 static struct backlight_device *cdv_backlight_device;

-static int cdv_get_brightness(struct backlight_device *bd)
+static int cdv_backlight_combination_mode(struct drm_device *dev)
 {
-   /* return locally cached var instead of HW read (due to DPST etc.) */
-   /* FIXME: ideally return actual value in case firmware fiddled with
-  it */
-   return cdv_brightness;
+   return REG_READ(BLC_PWM_CTL2) & PWM_LEGACY_MODE;
 }

-
-static int cdv_backlight_setup(struct drm_device *dev)
+static int cdv_get_brightness(struct backlight_device *bd)
 {
-   struct drm_psb_private *dev_priv = dev->dev_private;
-   unsigned long core_clock;
-   /* u32 bl_max_freq; */
-   /* unsigned long value; */
-   u16 bl_max_freq;
-   uint32_t value;
-   uint32_t blc_pwm_precision_factor;
-
-   /* get bl_max_freq and pol from dev_priv*/
-   if (!dev_priv->lvds_bl) {
-   dev_err(dev->dev, "Has no valid LVDS backlight info\n");
-   return -ENOENT;
-   }
-   bl_max_freq = dev_priv->lvds_bl->freq;
-   blc_pwm_precision_factor = PSB_BLC_PWM_PRECISION_FACTOR;
+   struct drm_device *dev = bl_get_data(bd);
+   u32 val = REG_READ(BLC_PWM_CTL) & BACKLIGHT_DUTY_CYCLE_MASK;

-   core_clock = dev_priv->core_freq;
+   if (cdv_backlight_combination_mode(dev)) {
+   u8 lbpc;

-   value = (core_clock * MHz) / BLC_PWM_FREQ_CALC_CONSTANT;
-   value *= blc_pwm_precision_factor;
-   value /= bl_max_freq;
-   value /= blc_pwm_precision_factor;
+   val &= ~1;
+   pci_read_config_byte(dev->pdev, 0xF4, &lbpc);
+   val *= lbpc;
+   }
+   return val;
+}

-   if (value > (unsigned long long)PSB_BLC_MAX_PWM_REG_FREQ ||
-value < (unsigned long long)PSB_BLC_MIN_PWM_REG_FREQ)
-   return -ERANGE;
-   else {
-   /* FIXME */
+static u32 cdv_get_max_backlight(struct drm_device *dev)
+{
+   u32 max = REG_READ(BLC_PWM_CTL);
+
+   if (max == 0) {
+   DRM_DEBUG_KMS("LVDS Panel PWM value is 0!\n");
+   /* i915 does this, I believe which means that we should not
+* smash PWM control as firmware will take control of it. */
+   return 1;
}
-   return 0;
+
+   max >>= 16;
+   if (cdv_backlight_combination_mode(dev))
+   max *= 0xff;
+   return max;
 }

 static int cdv_set_brightness(struct backlight_device *bd)
 {
+   struct drm_device *dev = bl_get_data(bd);
int level = bd->props.brightness;
+   u32 blc_pwm_ctl;

/* Percentage 1-100% being valid */
if (level < 1)
level = 1;

-   /*cdv_intel_lvds_set_brightness(dev, level); FIXME */
-   cdv_brightness = level;
+   if (cdv_backlight_combination_mode(dev)) {
+   u32 max = cdv_get_max_backlight(dev);
+   u8 lbpc;
+
+   lbpc = level * 0xfe / max + 1;
+   level /= lbpc;
+
+   pci_write_config_byte(dev->pdev, 0xF4, lbpc);
+   }
+
+   blc_pwm_ctl = REG_READ(BLC_PWM_CTL) & ~BACKLIGHT_DUTY_CYCLE_MASK;
+   REG_WRITE(BLC_PWM_CTL, (blc_pwm_ctl |
+   (level << BACKLIGHT_DUTY_CYCLE_SHIFT)));
return 0;
 }

@@ -150,7 +144,6 @@ static const struct backlight_ops cdv_ops = {
 static int cdv_backlight_init(struct drm_device *d

[PATCH 3/6] cdv: continue synching up with updated reference code

2012-04-24 Thread Alan Cox
From: Alan Cox 

In particular clean up the errata handling and correct the crtc masks. We do
this a bit differently using our device abstraction for neatness.

This doesn't address the ACPI opregion and hotplug plumbing, nor the IRQ related
changes that will need. It touches on backlight init but the full backlight
support is not in this change set.

Signed-off-by: Alan Cox 
---

 drivers/gpu/drm/gma500/cdv_device.c|   20 +
 drivers/gpu/drm/gma500/cdv_intel_crt.c |   20 +++--
 drivers/gpu/drm/gma500/cdv_intel_display.c |   61 
 drivers/gpu/drm/gma500/cdv_intel_lvds.c|   17 
 drivers/gpu/drm/gma500/framebuffer.c   |   13 ++
 drivers/gpu/drm/gma500/mdfld_device.c  |2 +
 drivers/gpu/drm/gma500/oaktrail_device.c   |2 +
 drivers/gpu/drm/gma500/psb_device.c|2 +
 drivers/gpu/drm/gma500/psb_drv.h   |4 ++
 drivers/gpu/drm/gma500/psb_intel_reg.h |4 ++
 10 files changed, 89 insertions(+), 56 deletions(-)

diff --git a/drivers/gpu/drm/gma500/cdv_device.c 
b/drivers/gpu/drm/gma500/cdv_device.c
index a54cc73..5cc06a8 100644
--- a/drivers/gpu/drm/gma500/cdv_device.c
+++ b/drivers/gpu/drm/gma500/cdv_device.c
@@ -49,6 +49,9 @@ static void cdv_disable_vga(struct drm_device *dev)
 static int cdv_output_init(struct drm_device *dev)
 {
struct drm_psb_private *dev_priv = dev->dev_private;
+
+   drm_mode_create_scaling_mode_property(dev);
+
cdv_disable_vga(dev);

cdv_intel_crt_init(dev, &dev_priv->mode_dev);
@@ -238,6 +241,18 @@ static void cdv_init_pm(struct drm_device *dev)
dev_err(dev->dev, "GPU: power management timed out.\n");
 }

+static void cdv_errata(struct drm_device *dev)
+{
+   /* Disable bonus launch.
+*  CPU and GPU competes for memory and display misses updates and 
flickers.
+*  Worst with dual core, dual displays.
+*
+*  Fixes were done to Win 7 gfx driver to disable a feature called 
Bonus
+*  Launch to work around the issue, by degrading performance.
+*/
+CDV_MSG_WRITE32(3, 0x30, 0x08027108);
+}
+
 /**
  * cdv_save_display_registers  -   save registers lost on suspend
  * @dev: our DRM device
@@ -355,7 +370,7 @@ static int cdv_restore_display_registers(struct drm_device 
*dev)
REG_WRITE(PSB_INT_MASK_R, regs->cdv.saveIMR);

/* Fix arbitration bug */
-   CDV_MSG_WRITE32(3, 0x30, 0x08027108);
+   cdv_errata(dev);

drm_mode_config_reset(dev);

@@ -464,8 +479,11 @@ const struct psb_ops cdv_chip_ops = {
.accel_2d = 0,
.pipes = 2,
.crtcs = 2,
+   .hdmi_mask = (1 << 0) | (1 << 1),
+   .lvds_mask = (1 << 1),
.sgx_offset = MRST_SGX_OFFSET,
.chip_setup = cdv_chip_setup,
+   .errata = cdv_errata,

.crtc_helper = &cdv_intel_helper_funcs,
.crtc_funcs = &cdv_intel_crtc_funcs,
diff --git a/drivers/gpu/drm/gma500/cdv_intel_crt.c 
b/drivers/gpu/drm/gma500/cdv_intel_crt.c
index 1a82843..1874220 100644
--- a/drivers/gpu/drm/gma500/cdv_intel_crt.c
+++ b/drivers/gpu/drm/gma500/cdv_intel_crt.c
@@ -78,9 +78,6 @@ static int cdv_intel_crt_mode_valid(struct drm_connector 
*connector,
if (mode->clock > 355000)
return MODE_CLOCK_HIGH;

-   if (mode->hdisplay > 1680 || mode->vdisplay > 1050)
-   return MODE_PANEL;
-
return MODE_OK;
 }

@@ -148,13 +145,7 @@ static bool cdv_intel_crt_detect_hotplug(struct 
drm_connector *connector,
struct drm_device *dev = connector->dev;
u32 hotplug_en;
int i, tries = 0, ret = false;
-   u32 adpa_orig;
-
-   /* disable the DAC when doing the hotplug detection */
-
-   adpa_orig = REG_READ(ADPA);
-
-   REG_WRITE(ADPA, adpa_orig & ~(ADPA_DAC_ENABLE));
+   u32 orig;

/*
 * On a CDV thep, CRT detect sequence need to be done twice
@@ -162,7 +153,7 @@ static bool cdv_intel_crt_detect_hotplug(struct 
drm_connector *connector,
 */
tries = 2;

-   hotplug_en = REG_READ(PORT_HOTPLUG_EN);
+   orig = hotplug_en = REG_READ(PORT_HOTPLUG_EN);
hotplug_en &= ~(CRT_HOTPLUG_DETECT_MASK);
hotplug_en |= CRT_HOTPLUG_FORCE_DETECT;

@@ -187,8 +178,11 @@ static bool cdv_intel_crt_detect_hotplug(struct 
drm_connector *connector,
CRT_HOTPLUG_MONITOR_NONE)
ret = true;

-   /* Restore the saved ADPA */
-   REG_WRITE(ADPA, adpa_orig);
+/* clear the interrupt we just generated, if any */
+   REG_WRITE(PORT_HOTPLUG_STAT, CRT_HOTPLUG_INT_STATUS);
+
+   /* and put the bits back */
+   REG_WRITE(PORT_HOTPLUG_EN, orig);
return ret;
 }

diff --git a/drivers/gpu/drm/gma500/cdv_intel_display.c 
b/drivers/gpu/drm/gma500/cdv_intel_display.c
index 07b37f5..2fab778 100644
--- a/drivers/gpu/drm/gma500/cdv_intel_display.c
+++ b/drivers/gpu/drm/gma500/cdv_intel_display.c
@@ -226,13 +226,13 @@ cdv_dpll_set_

[PATCH 2/6] gma500: Clean up weirdness in the cdv mode test code

2012-04-24 Thread Alan Cox
From: Alan Cox 

Signed-off-by: Alan Cox 
---

 drivers/gpu/drm/gma500/cdv_intel_crt.c |4 +---
 1 files changed, 1 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/gma500/cdv_intel_crt.c 
b/drivers/gpu/drm/gma500/cdv_intel_crt.c
index 1de27c7..1a82843 100644
--- a/drivers/gpu/drm/gma500/cdv_intel_crt.c
+++ b/drivers/gpu/drm/gma500/cdv_intel_crt.c
@@ -67,7 +67,6 @@ static void cdv_intel_crt_dpms(struct drm_encoder *encoder, 
int mode)
 static int cdv_intel_crt_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode)
 {
-   int max_clock = 0;
if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
return MODE_NO_DBLESCAN;

@@ -76,8 +75,7 @@ static int cdv_intel_crt_mode_valid(struct drm_connector 
*connector,
return MODE_CLOCK_LOW;

/* The max clock for CDV is 355 instead of 400 */
-   max_clock = 355000;
-   if (mode->clock > max_clock)
+   if (mode->clock > 355000)
return MODE_CLOCK_HIGH;

if (mode->hdisplay > 1680 || mode->vdisplay > 1050)



[PATCH 1/6] gma500: support 1080p

2012-04-24 Thread Alan Cox
From: Alan Cox 

The problem in console mode is lack of linear memory. We can solve that by
dropping to 16bpp. The mode setting X server will allocate its own GEM
framebuffer in 32bpp and all will be well.

We could just do 16bpp anyway but that would be a regression on the lower
modes as many distributions don't yet ship the generic mode setting KMS
drivers.

Signed-off-by: Alan Cox 
---

 drivers/gpu/drm/gma500/cdv_intel_crt.c  |6 --
 drivers/gpu/drm/gma500/cdv_intel_hdmi.c |7 ---
 drivers/gpu/drm/gma500/framebuffer.c|   16 
 drivers/gpu/drm/gma500/oaktrail_hdmi.c  |6 --
 drivers/gpu/drm/gma500/psb_intel_sdvo.c |6 --
 5 files changed, 16 insertions(+), 25 deletions(-)

diff --git a/drivers/gpu/drm/gma500/cdv_intel_crt.c 
b/drivers/gpu/drm/gma500/cdv_intel_crt.c
index a71a6cd..1de27c7 100644
--- a/drivers/gpu/drm/gma500/cdv_intel_crt.c
+++ b/drivers/gpu/drm/gma500/cdv_intel_crt.c
@@ -67,7 +67,6 @@ static void cdv_intel_crt_dpms(struct drm_encoder *encoder, 
int mode)
 static int cdv_intel_crt_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode)
 {
-   struct drm_psb_private *dev_priv = connector->dev->dev_private;
int max_clock = 0;
if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
return MODE_NO_DBLESCAN;
@@ -84,11 +83,6 @@ static int cdv_intel_crt_mode_valid(struct drm_connector 
*connector,
if (mode->hdisplay > 1680 || mode->vdisplay > 1050)
return MODE_PANEL;

-   /* We assume worst case scenario of 32 bpp here, since we don't know */
-   if ((ALIGN(mode->hdisplay * 4, 64) * mode->vdisplay) >
-   dev_priv->vram_stolen_size)
-   return MODE_MEM;
-
return MODE_OK;
 }

diff --git a/drivers/gpu/drm/gma500/cdv_intel_hdmi.c 
b/drivers/gpu/drm/gma500/cdv_intel_hdmi.c
index 8d52695..88b59d4 100644
--- a/drivers/gpu/drm/gma500/cdv_intel_hdmi.c
+++ b/drivers/gpu/drm/gma500/cdv_intel_hdmi.c
@@ -242,8 +242,6 @@ static int cdv_hdmi_get_modes(struct drm_connector 
*connector)
 static int cdv_hdmi_mode_valid(struct drm_connector *connector,
 struct drm_display_mode *mode)
 {
-   struct drm_psb_private *dev_priv = connector->dev->dev_private;
-
if (mode->clock > 165000)
return MODE_CLOCK_HIGH;
if (mode->clock < 2)
@@ -257,11 +255,6 @@ static int cdv_hdmi_mode_valid(struct drm_connector 
*connector,
if (mode->flags & DRM_MODE_FLAG_INTERLACE)
return MODE_NO_INTERLACE;

-   /* We assume worst case scenario of 32 bpp here, since we don't know */
-   if ((ALIGN(mode->hdisplay * 4, 64) * mode->vdisplay) >
-   dev_priv->vram_stolen_size)
-   return MODE_MEM;
-
return MODE_OK;
 }

diff --git a/drivers/gpu/drm/gma500/framebuffer.c 
b/drivers/gpu/drm/gma500/framebuffer.c
index 8ea202f..c2cf6bf 100644
--- a/drivers/gpu/drm/gma500/framebuffer.c
+++ b/drivers/gpu/drm/gma500/framebuffer.c
@@ -543,9 +543,25 @@ static int psbfb_probe(struct drm_fb_helper *helper,
struct drm_fb_helper_surface_size *sizes)
 {
struct psb_fbdev *psb_fbdev = (struct psb_fbdev *)helper;
+   struct drm_device *dev = psb_fbdev->psb_fb_helper.dev;
+   struct drm_psb_private *dev_priv = dev->dev_private;
int new_fb = 0;
+   int bytespp;
int ret;

+   bytespp = sizes->surface_bpp / 8;
+   if (bytespp == 3)   /* no 24bit packed */
+   bytespp = 4;
+
+   /* If the mode will not fit in 32bit then switch to 16bit to get
+  a console on full resolution. The X mode setting server will
+  allocate its own 32bit GEM framebuffer */
+   if (ALIGN(sizes->fb_width * bytespp, 64) * sizes->fb_height >
+   dev_priv->vram_stolen_size) {
+sizes->surface_bpp = 16;
+sizes->surface_depth = 16;
+}
+
if (!helper->fb) {
ret = psbfb_create(psb_fbdev, sizes);
if (ret)
diff --git a/drivers/gpu/drm/gma500/oaktrail_hdmi.c 
b/drivers/gpu/drm/gma500/oaktrail_hdmi.c
index f8b367b..2595660 100644
--- a/drivers/gpu/drm/gma500/oaktrail_hdmi.c
+++ b/drivers/gpu/drm/gma500/oaktrail_hdmi.c
@@ -179,7 +179,6 @@ static void oaktrail_hdmi_dpms(struct drm_encoder *encoder, 
int mode)
 static int oaktrail_hdmi_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode)
 {
-   struct drm_psb_private *dev_priv = connector->dev->dev_private;
if (mode->clock > 165000)
return MODE_CLOCK_HIGH;
if (mode->clock < 2)
@@ -188,11 +187,6 @@ static int oaktrail_hdmi_mode_valid(struct drm_connector 
*connector,
if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
return MODE_NO_DBLESCAN;

-   /* We assume worst case scenario of 32 bpp here, since we don't know */
-   if ((ALIGN(mo

[PATCH 3/3] gma500: don't register the ACPI video bus

2012-04-24 Thread Alan Cox
From: Alan Cox 

We are not yet ready for this and it makes a mess on some devices.

Signed-off-by: Alan Cox 
---

 drivers/gpu/drm/gma500/psb_drv.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/gpu/drm/gma500/psb_drv.c b/drivers/gpu/drm/gma500/psb_drv.c
index d5a6eab..45bd0c7 100644
--- a/drivers/gpu/drm/gma500/psb_drv.c
+++ b/drivers/gpu/drm/gma500/psb_drv.c
@@ -350,7 +350,7 @@ static int psb_driver_load(struct drm_device *dev, unsigned 
long chipset)
PSB_WSGX32(0x3000, PSB_CR_BIF_3D_REQ_BASE);

 /* igd_opregion_init(&dev_priv->opregion_dev); */
-   acpi_video_register();
+/* acpi_video_register(); */
if (dev_priv->lid_state)
psb_lid_timer_init(dev_priv);




[PATCH 2/3] acpi_video: Intel video is not always i915

2012-04-24 Thread Alan Cox
From: Alan Cox 

Handle the GMA500/600/36x0 cases. Also stop it poking at random registers on
the i740 cards that may be out there still.

This should also allow the legacy gma500 stub driver to go away as the ACPI
video layer will now do the right thing rather than assume all the world is
Gen graphics and need the gma500 stub as a workaround.

Signed-off-by: Alan Cox 
---

 drivers/acpi/video.c |   54 +++---
 1 files changed, 46 insertions(+), 8 deletions(-)

diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index 66e8f73..b2ae7aa 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -1743,25 +1743,63 @@ static int acpi_video_bus_remove(struct acpi_device 
*device, int type)
return 0;
 }

+static int __init is_gma_pvr(struct pci_dev *dev)
+{
+   /* Medfield */
+   if ((dev->device & 0xFFF8) == 0x0130)
+   return 1;
+   /* GMA36x0 */
+   if ((dev->device & 0xFFF8) == 0x0be0)
+   return 1;
+   /* GMA600 */
+   if ((dev->device & 0xFFF8) == 0x4100)
+   return 1;
+   /* GMA500 */
+   if ((dev->device & 0xFFFE) == 0x8108)
+   return 1;
+   /* E620 */
+   if (dev->device == 0x4108)
+   return 1;
+   return 0;
+}
+
+static int __init is_i740(struct pci_dev *dev)
+{
+   if (dev->device == 0x00D1)
+   return 1;
+   if (dev->device == 0x7000)
+   return 1;
+   return 0;
+}
+
 static int __init intel_opregion_present(void)
 {
-   int i915 = 0;
-#if defined(CONFIG_DRM_I915) || defined(CONFIG_DRM_I915_MODULE)
+   int opregion = 0;
struct pci_dev *dev = NULL;
-   u32 address;

for_each_pci_dev(dev) {
if ((dev->class >> 8) != PCI_CLASS_DISPLAY_VGA)
continue;
if (dev->vendor != PCI_VENDOR_ID_INTEL)
continue;
-   pci_read_config_dword(dev, 0xfc, &address);
-   if (!address)
+   /* We don't want to poke around undefined i740 registers */
+   if (is_i740(dev))
continue;
-   i915 = 1;
-   }
+#if defined(CONFIG_DRM_GMA500) || defined(CONFIG_DRM_GMA500_MODULE)
+   if (is_gma_pvr(dev))
+   opregion = 1;
 #endif
-   return i915;
+#if defined(CONFIG_DRM_I915) || defined(CONFIG_DRM_I915_MODULE)
+   if (!is_gma_pvr(dev)) {
+   u32 address;
+   pci_read_config_dword(dev, 0xfc, &address);
+   if (!address)
+   continue;
+   opregion = 1;
+   }
+#endif
+   }
+   return opregion;
 }

 int acpi_video_register(void)



[PATCH 1/3] acpi_video: fix leaking PCI references

2012-04-24 Thread Alan Cox
From: Alan Cox 

Otherwise we keep a bogus pci reference to the GPU

Signed-off-by: Alan Cox 
---

 drivers/acpi/video.c |5 +++--
 1 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index 9577b6f..66e8f73 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -1745,6 +1745,7 @@ static int acpi_video_bus_remove(struct acpi_device 
*device, int type)

 static int __init intel_opregion_present(void)
 {
+   int i915 = 0;
 #if defined(CONFIG_DRM_I915) || defined(CONFIG_DRM_I915_MODULE)
struct pci_dev *dev = NULL;
u32 address;
@@ -1757,10 +1758,10 @@ static int __init intel_opregion_present(void)
pci_read_config_dword(dev, 0xfc, &address);
if (!address)
continue;
-   return 1;
+   i915 = 1;
}
 #endif
-   return 0;
+   return i915;
 }

 int acpi_video_register(void)



[PATCH 6/6] gma500: panel presence check

2012-04-24 Thread Alan Cox
From: Alan Cox 

Introduce a panel presence check for Cedartrail. Non netbook devices don't
necessarily have a panel attached.

Signed-off-by: Alan Cox 
---

 drivers/gpu/drm/gma500/cdv_intel_lvds.c |   57 +++
 1 files changed, 57 insertions(+), 0 deletions(-)

diff --git a/drivers/gpu/drm/gma500/cdv_intel_lvds.c 
b/drivers/gpu/drm/gma500/cdv_intel_lvds.c
index 8359c1a..c87b179 100644
--- a/drivers/gpu/drm/gma500/cdv_intel_lvds.c
+++ b/drivers/gpu/drm/gma500/cdv_intel_lvds.c
@@ -556,6 +556,56 @@ const struct drm_encoder_funcs cdv_intel_lvds_enc_funcs = {
.destroy = cdv_intel_lvds_enc_destroy,
 };

+/*
+ * Enumerate the child dev array parsed from VBT to check whether
+ * the LVDS is present.
+ * If it is present, return 1.
+ * If it is not present, return false.
+ * If no child dev is parsed from VBT, it assumes that the LVDS is present.
+ */
+static bool lvds_is_present_in_vbt(struct drm_device *dev,
+  u8 *i2c_pin)
+{
+   struct drm_psb_private *dev_priv = dev->dev_private;
+   int i;
+
+   if (!dev_priv->child_dev_num)
+   return true;
+
+   for (i = 0; i < dev_priv->child_dev_num; i++) {
+   struct child_device_config *child = dev_priv->child_dev + i;
+
+   /* If the device type is not LFP, continue.
+* We have to check both the new identifiers as well as the
+* old for compatibility with some BIOSes.
+*/
+   if (child->device_type != DEVICE_TYPE_INT_LFP &&
+   child->device_type != DEVICE_TYPE_LFP)
+   continue;
+
+   if (child->i2c_pin)
+   *i2c_pin = child->i2c_pin;
+
+   /* However, we cannot trust the BIOS writers to populate
+* the VBT correctly.  Since LVDS requires additional
+* information from AIM blocks, a non-zero addin offset is
+* a good indicator that the LVDS is actually present.
+*/
+   if (child->addin_offset)
+   return true;
+
+   /* But even then some BIOS writers perform some black magic
+* and instantiate the device without reference to any
+* additional data.  Trust that if the VBT was written into
+* the OpRegion then they have validated the LVDS's existence.
+*/
+   if (dev_priv->opregion.vbt)
+   return true;
+   }
+
+   return false;
+}
+
 /**
  * cdv_intel_lvds_init - setup LVDS connectors on this device
  * @dev: drm device
@@ -576,6 +626,13 @@ void cdv_intel_lvds_init(struct drm_device *dev,
struct drm_psb_private *dev_priv = dev->dev_private;
u32 lvds;
int pipe;
+   u8 pin;
+
+   pin = GMBUS_PORT_PANEL;
+   if (!lvds_is_present_in_vbt(dev, &pin)) {
+   DRM_DEBUG_KMS("LVDS is not present in VBT\n");
+   return;
+   }

psb_intel_encoder = kzalloc(sizeof(struct psb_intel_encoder),
GFP_KERNEL);



[PATCH 5/6] gma500: intel_bios updates

2012-04-24 Thread Alan Cox
From: Alan Cox 

Pull in various i915 bits that we will need to begin tackling the LVDS detect
and ACPI events. We try and drift towards the i915 version of the code with
the long term goal that at least some of it can one day be unified.

Signed-off-by: Alan Cox 
---

 drivers/gpu/drm/gma500/intel_bios.c |  232 ---
 drivers/gpu/drm/gma500/intel_bios.h |  122 +++-
 drivers/gpu/drm/gma500/intel_opregion.c |  117 ++--
 drivers/gpu/drm/gma500/psb_drv.h|4 +
 4 files changed, 438 insertions(+), 37 deletions(-)

diff --git a/drivers/gpu/drm/gma500/intel_bios.c 
b/drivers/gpu/drm/gma500/intel_bios.c
index 51ea6df..479e449 100644
--- a/drivers/gpu/drm/gma500/intel_bios.c
+++ b/drivers/gpu/drm/gma500/intel_bios.c
@@ -26,6 +26,8 @@
 #include "psb_intel_reg.h"
 #include "intel_bios.h"

+#defineSLAVE_ADDR1 0x70
+#defineSLAVE_ADDR2 0x72

 static void *find_section(struct bdb_header *bdb, int section_id)
 {
@@ -52,6 +54,16 @@ static void *find_section(struct bdb_header *bdb, int 
section_id)
return NULL;
 }

+static u16
+get_blocksize(void *p)
+{
+   u16 *block_ptr, block_size;
+
+   block_ptr = (u16 *)((char *)p - 2);
+   block_size = *block_ptr;
+   return block_size;
+}
+
 static void fill_detail_timing_data(struct drm_display_mode *panel_fixed_mode,
struct lvds_dvo_timing *dvo_timing)
 {
@@ -75,6 +87,16 @@ static void fill_detail_timing_data(struct drm_display_mode 
*panel_fixed_mode,
panel_fixed_mode->clock = dvo_timing->clock * 10;
panel_fixed_mode->type = DRM_MODE_TYPE_PREFERRED;

+   if (dvo_timing->hsync_positive)
+   panel_fixed_mode->flags |= DRM_MODE_FLAG_PHSYNC;
+   else
+   panel_fixed_mode->flags |= DRM_MODE_FLAG_NHSYNC;
+
+   if (dvo_timing->vsync_positive)
+   panel_fixed_mode->flags |= DRM_MODE_FLAG_PVSYNC;
+   else
+   panel_fixed_mode->flags |= DRM_MODE_FLAG_NVSYNC;
+
/* Some VBTs have bogus h/vtotal values */
if (panel_fixed_mode->hsync_end > panel_fixed_mode->htotal)
panel_fixed_mode->htotal = panel_fixed_mode->hsync_end + 1;
@@ -218,6 +240,97 @@ static void parse_general_features(struct drm_psb_private 
*dev_priv,
 }

 static void
+parse_sdvo_device_mapping(struct drm_psb_private *dev_priv,
+ struct bdb_header *bdb)
+{
+   struct sdvo_device_mapping *p_mapping;
+   struct bdb_general_definitions *p_defs;
+   struct child_device_config *p_child;
+   int i, child_device_num, count;
+   u16 block_size;
+
+   p_defs = find_section(bdb, BDB_GENERAL_DEFINITIONS);
+   if (!p_defs) {
+   DRM_DEBUG_KMS("No general definition block is found, unable to 
construct sdvo mapping.\n");
+   return;
+   }
+   /* judge whether the size of child device meets the requirements.
+* If the child device size obtained from general definition block
+* is different with sizeof(struct child_device_config), skip the
+* parsing of sdvo device info
+*/
+   if (p_defs->child_dev_size != sizeof(*p_child)) {
+   /* different child dev size . Ignore it */
+   DRM_DEBUG_KMS("different child size is found. Invalid.\n");
+   return;
+   }
+   /* get the block size of general definitions */
+   block_size = get_blocksize(p_defs);
+   /* get the number of child device */
+   child_device_num = (block_size - sizeof(*p_defs)) /
+   sizeof(*p_child);
+   count = 0;
+   for (i = 0; i < child_device_num; i++) {
+   p_child = &(p_defs->devices[i]);
+   if (!p_child->device_type) {
+   /* skip the device block if device type is invalid */
+   continue;
+   }
+   if (p_child->slave_addr != SLAVE_ADDR1 &&
+   p_child->slave_addr != SLAVE_ADDR2) {
+   /*
+* If the slave address is neither 0x70 nor 0x72,
+* it is not a SDVO device. Skip it.
+*/
+   continue;
+   }
+   if (p_child->dvo_port != DEVICE_PORT_DVOB &&
+   p_child->dvo_port != DEVICE_PORT_DVOC) {
+   /* skip the incorrect SDVO port */
+   DRM_DEBUG_KMS("Incorrect SDVO port. Skip it\n");
+   continue;
+   }
+   DRM_DEBUG_KMS("the SDVO device with slave addr %2x is found on"
+   " %s port\n",
+   p_child->slave_addr,
+   (p_child->dvo_port == DEVICE_PORT_DVOB) ?
+   "SDVOB" : "SDVOC");
+   p_mapping = &(dev_priv->sdvo_mappings[p_child->dvo_port - 1]);
+   

[PATCH 4/6] gma500: cache GEM framebuffer pages wc not uc

2012-04-24 Thread Alan Cox
From: Alan Cox 

Fixes the case where the modesetting driver is slower than /dev/fb.

Signed-off-by: Alan Cox 
Cc: stable at kernel.org



---

 drivers/gpu/drm/gma500/gtt.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/gpu/drm/gma500/gtt.c b/drivers/gpu/drm/gma500/gtt.c
index c6465b4..db2e823 100644
--- a/drivers/gpu/drm/gma500/gtt.c
+++ b/drivers/gpu/drm/gma500/gtt.c
@@ -93,7 +93,7 @@ static int psb_gtt_insert(struct drm_device *dev, struct 
gtt_range *r)
pages = r->pages;

/* Make sure changes are visible to the GPU */
-   set_pages_array_uc(pages, r->npage);
+   set_pages_array_wc(pages, r->npage);

/* Write our page entries into the GTT itself */
for (i = r->roll; i < r->npage; i++) {



[PATCH 3/6] gma500: Update the Cedarview clock handling

2012-04-24 Thread Alan Cox
From: Alan Cox 


---

 drivers/gpu/drm/gma500/cdv_intel_display.c |  331 +++-
 drivers/gpu/drm/gma500/psb_intel_drv.h |3 
 drivers/gpu/drm/gma500/psb_intel_reg.h |   25 ++
 3 files changed, 294 insertions(+), 65 deletions(-)

diff --git a/drivers/gpu/drm/gma500/cdv_intel_display.c 
b/drivers/gpu/drm/gma500/cdv_intel_display.c
index be84559..07b37f5 100644
--- a/drivers/gpu/drm/gma500/cdv_intel_display.c
+++ b/drivers/gpu/drm/gma500/cdv_intel_display.c
@@ -216,7 +216,7 @@ static void cdv_sb_reset(struct drm_device *dev)
  */
 static int
 cdv_dpll_set_clock_cdv(struct drm_device *dev, struct drm_crtc *crtc,
-  struct cdv_intel_clock_t *clock)
+  struct cdv_intel_clock_t *clock, bool is_lvds)
 {
struct psb_intel_crtc *psb_crtc =
to_psb_intel_crtc(crtc);
@@ -224,6 +224,7 @@ cdv_dpll_set_clock_cdv(struct drm_device *dev, struct 
drm_crtc *crtc,
u32 m, n_vco, p;
int ret = 0;
int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B;
+   int ref_sfr = (pipe == 0) ? SB_REF_DPLLA : SB_REF_DPLLB;
u32 ref_value;

cdv_sb_reset(dev);
@@ -241,6 +242,35 @@ cdv_dpll_set_clock_cdv(struct drm_device *dev, struct 
drm_crtc *crtc,
/* We don't know what the other fields of these regs are, so
 * leave them in place.
 */
+   /* 
+* The BIT 14:13 of 0x8010/0x8030 is used to select the ref clk
+* for the pipe A/B. Display spec 1.06 has wrong definition.
+* Correct definition is like below:
+*
+* refclka mean use clock from same PLL
+*
+* if DPLLA sets 01 and DPLLB sets 01, they use clock from their pll
+*
+* if DPLLA sets 01 and DPLLB sets 02, both use clk from DPLLA
+*
+*/  
+   ret = cdv_sb_read(dev, ref_sfr, &ref_value);
+   if (ret)
+   return ret;
+   ref_value &= ~(REF_CLK_MASK);
+
+   /* use DPLL_A for pipeB on CRT/HDMI */
+   if (pipe == 1 && !is_lvds) {
+   DRM_DEBUG_KMS("use DPLLA for pipe B\n");
+   ref_value |= REF_CLK_DPLLA;
+   } else {
+   DRM_DEBUG_KMS("use their DPLL for pipe A/B\n");
+   ref_value |= REF_CLK_DPLL;
+   }
+   ret = cdv_sb_write(dev, ref_sfr, ref_value);
+   if (ret)
+   return ret;
+
ret = cdv_sb_read(dev, SB_M(pipe), &m);
if (ret)
return ret;
@@ -308,7 +338,7 @@ cdv_dpll_set_clock_cdv(struct drm_device *dev, struct 
drm_crtc *crtc,
return ret;

/* always Program the Lane Register for the Pipe A*/
-   if (pipe == 0) {
+/* if (pipe == 0) */ {
/* Program the Lane0/1 for HDMI B */
u32 lane_reg, lane_value;

@@ -553,6 +583,200 @@ psb_intel_pipe_set_base_exit:
return ret;
 }

+#defineFIFO_PIPEA  (1 << 0)
+#defineFIFO_PIPEB  (1 << 1)
+
+static bool cdv_intel_pipe_enabled(struct drm_device *dev, int pipe)
+{
+   struct drm_crtc *crtc;
+   struct drm_psb_private *dev_priv = dev->dev_private;
+   struct psb_intel_crtc *psb_intel_crtc = NULL;
+
+   crtc = dev_priv->pipe_to_crtc_mapping[pipe];
+   psb_intel_crtc = to_psb_intel_crtc(crtc);
+
+   if (crtc->fb == NULL || !psb_intel_crtc->active)
+   return false;
+   return true;
+}
+
+static bool cdv_intel_single_pipe_active (struct drm_device *dev)
+{
+   uint32_t pipe_enabled = 0;
+
+   if (cdv_intel_pipe_enabled(dev, 0))
+   pipe_enabled |= FIFO_PIPEA;
+
+   if (cdv_intel_pipe_enabled(dev, 1))
+   pipe_enabled |= FIFO_PIPEB;
+
+
+   DRM_DEBUG_KMS("pipe enabled %x\n", pipe_enabled);
+
+   if (pipe_enabled == FIFO_PIPEA || pipe_enabled == FIFO_PIPEB)
+   return true;
+   else
+   return false;
+}
+
+static bool is_pipeb_lvds(struct drm_device *dev, struct drm_crtc *crtc)
+{
+   struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
+   struct drm_mode_config *mode_config = &dev->mode_config;
+   struct drm_connector *connector;
+
+   if (psb_intel_crtc->pipe != 1)
+   return false;
+
+   list_for_each_entry(connector, &mode_config->connector_list, head) {
+   struct psb_intel_encoder *psb_intel_encoder =
+   psb_intel_attached_encoder(connector);
+
+   if (!connector->encoder
+   || connector->encoder->crtc != crtc)
+   continue;
+
+   if (psb_intel_encoder->type == INTEL_OUTPUT_LVDS)
+   return true;
+   }
+
+   return false;
+}
+
+static void cdv_intel_disable_self_refresh (struct drm_device *dev)
+{
+   if (REG_READ(FW_BLC_SELF) & FW_BLC_SELF_EN) {
+
+   /* Disable self-refresh before adjust WM */
+   REG_WR

[PATCH 2/6] gma500: read the PLL bits

2012-04-24 Thread Alan Cox
From: Alan Cox 

We need to pull more stuff from the VBT in order to configure the clocking
correctly in all cases. Add the relevant bits from the other CDV driver work.

Signed-off-by: Alan Cox 
---

 drivers/gpu/drm/gma500/intel_bios.c |   18 
 drivers/gpu/drm/gma500/intel_bios.h |   39 +++
 drivers/gpu/drm/gma500/psb_drv.h|2 ++
 3 files changed, 59 insertions(+), 0 deletions(-)

diff --git a/drivers/gpu/drm/gma500/intel_bios.c 
b/drivers/gpu/drm/gma500/intel_bios.c
index d4d0c5b..51ea6df 100644
--- a/drivers/gpu/drm/gma500/intel_bios.c
+++ b/drivers/gpu/drm/gma500/intel_bios.c
@@ -217,6 +217,23 @@ static void parse_general_features(struct drm_psb_private 
*dev_priv,
}
 }

+static void
+parse_driver_features(struct drm_psb_private *dev_priv,
+ struct bdb_header *bdb)
+{
+   struct bdb_driver_features *driver;
+
+   driver = find_section(bdb, BDB_DRIVER_FEATURES);
+   if (!driver)
+   return;
+
+   /* This bit means to use 96Mhz for DPLL_A or not */
+   if (driver->primary_lfp_id)
+   dev_priv->dplla_96mhz = true;
+   else
+   dev_priv->dplla_96mhz = false;
+}
+
 /**
  * psb_intel_init_bios - initialize VBIOS settings & find VBT
  * @dev: DRM device
@@ -263,6 +280,7 @@ bool psb_intel_init_bios(struct drm_device *dev)

/* Grab useful general definitions */
parse_general_features(dev_priv, bdb);
+   parse_driver_features(dev_priv, bdb);
parse_lfp_panel_data(dev_priv, bdb);
parse_sdvo_panel_data(dev_priv, bdb);
parse_backlight_data(dev_priv, bdb);
diff --git a/drivers/gpu/drm/gma500/intel_bios.h 
b/drivers/gpu/drm/gma500/intel_bios.h
index 70f1bf0..c67979e 100644
--- a/drivers/gpu/drm/gma500/intel_bios.h
+++ b/drivers/gpu/drm/gma500/intel_bios.h
@@ -302,6 +302,45 @@ struct bdb_sdvo_lvds_options {
u8 panel_misc_bits_4;
 } __attribute__((packed));

+struct bdb_driver_features {
+   u8 boot_dev_algorithm:1;
+   u8 block_display_switch:1;
+   u8 allow_display_switch:1;
+   u8 hotplug_dvo:1;
+   u8 dual_view_zoom:1;
+   u8 int15h_hook:1;
+   u8 sprite_in_clone:1;
+   u8 primary_lfp_id:1;
+
+   u16 boot_mode_x;
+   u16 boot_mode_y;
+   u8 boot_mode_bpp;
+   u8 boot_mode_refresh;
+
+   u16 enable_lfp_primary:1;
+   u16 selective_mode_pruning:1;
+   u16 dual_frequency:1;
+   u16 render_clock_freq:1; /* 0: high freq; 1: low freq */
+   u16 nt_clone_support:1;
+   u16 power_scheme_ui:1; /* 0: CUI; 1: 3rd party */
+   u16 sprite_display_assign:1; /* 0: secondary; 1: primary */
+   u16 cui_aspect_scaling:1;
+   u16 preserve_aspect_ratio:1;
+   u16 sdvo_device_power_down:1;
+   u16 crt_hotplug:1;
+   u16 lvds_config:2;
+   u16 tv_hotplug:1;
+   u16 hdmi_config:2;
+
+   u8 static_display:1;
+   u8 reserved2:7;
+   u16 legacy_crt_max_x;
+   u16 legacy_crt_max_y;
+   u8 legacy_crt_max_refresh;
+
+   u8 hdmi_termination;
+   u8 custom_vbt_version;
+} __attribute__((packed));

 extern bool psb_intel_init_bios(struct drm_device *dev);
 extern void psb_intel_destroy_bios(struct drm_device *dev);
diff --git a/drivers/gpu/drm/gma500/psb_drv.h b/drivers/gpu/drm/gma500/psb_drv.h
index 40ce2c9..4c50969 100644
--- a/drivers/gpu/drm/gma500/psb_drv.h
+++ b/drivers/gpu/drm/gma500/psb_drv.h
@@ -669,6 +669,8 @@ struct drm_psb_private {
u32 dspcntr[3];

int mdfld_panel_id;
+
+   bool dplla_96mhz;   /* DPLL data from the VBT */
 };





[PATCH 1/6] gma500: Fix leak of uncached page

2012-04-24 Thread Alan Cox
From: Alan Cox 

This was reported a long time ago (and I apologize to whoever it was that
reported it as I've lost the original report).

Signed-off-by: Alan Cox 
---

 drivers/gpu/drm/gma500/psb_drv.c |1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/drivers/gpu/drm/gma500/psb_drv.c b/drivers/gpu/drm/gma500/psb_drv.c
index c34adf9..d5a6eab 100644
--- a/drivers/gpu/drm/gma500/psb_drv.c
+++ b/drivers/gpu/drm/gma500/psb_drv.c
@@ -246,6 +246,7 @@ static int psb_driver_unload(struct drm_device *dev)
}
psb_gtt_takedown(dev);
if (dev_priv->scratch_page) {
+   set_pages_wb(dev_priv->scratch_page, 1);
__free_page(dev_priv->scratch_page);
dev_priv->scratch_page = NULL;
}



[PATCH v2] scatterlist: add sg_alloc_table_from_pages function

2012-04-24 Thread Daniel Vetter
On Tue, Apr 24, 2012 at 02:58:56PM +0200, Tomasz Stanislawski wrote:
> This patch adds a new constructor for an sg table. The table is constructed
> from an array of struct pages. All contiguous chunks of the pages are merged
> into a single sg nodes. A user may provide an offset and a size of a buffer if
> the buffer is not page-aligned.
> 
> The function is dedicated for DMABUF exporters which often perform conversion
> from an page array to a scatterlist. Moreover the scatterlist should be
> squashed in order to save memory and to speed-up the process of DMA mapping
> using dma_map_sg.
> 
> The code is based on the patch 'v4l: vb2-dma-contig: add support for
> scatterlist in userptr mode' and hints from Laurent Pinchart.
> 
> Signed-off-by: Tomasz Stanislawski 
> Signed-off-by: Kyungmin Park 

I like this and we could replace the drm helper function in drm prime with
this one. One comment below.
-Daniel

> ---
>  include/linux/scatterlist.h |4 +++
>  lib/scatterlist.c   |   63 
> +++
>  2 files changed, 67 insertions(+), 0 deletions(-)
> 
> diff --git a/include/linux/scatterlist.h b/include/linux/scatterlist.h
> index ac9586d..7b600da 100644
> --- a/include/linux/scatterlist.h
> +++ b/include/linux/scatterlist.h
> @@ -214,6 +214,10 @@ void sg_free_table(struct sg_table *);
>  int __sg_alloc_table(struct sg_table *, unsigned int, unsigned int, gfp_t,
>sg_alloc_fn *);
>  int sg_alloc_table(struct sg_table *, unsigned int, gfp_t);
> +int sg_alloc_table_from_pages(struct sg_table *sgt,
> + struct page **pages, unsigned int n_pages,
> + unsigned long offset, unsigned long size,
> + gfp_t gfp_mask);
> 
>  size_t sg_copy_from_buffer(struct scatterlist *sgl, unsigned int nents,
>  void *buf, size_t buflen);
> diff --git a/lib/scatterlist.c b/lib/scatterlist.c
> index 6096e89..90f9265 100644
> --- a/lib/scatterlist.c
> +++ b/lib/scatterlist.c
> @@ -319,6 +319,69 @@ int sg_alloc_table(struct sg_table *table, unsigned int 
> nents, gfp_t gfp_mask)
>  EXPORT_SYMBOL(sg_alloc_table);
> 
>  /**
> + * sg_alloc_table_from_pages - Allocate and initialize an sg table from
> + *  an array of pages
> + * @sgt: The sg table header to use
> + * @pages:   Pointer to an array of page pointers
> + * @n_pages: Number of pages in the pages array
> + * @offset: Offset from a start of the first page to a start of a buffer
> + * @size:   Number of valid bytes in the buffer (after offset)
> + * @gfp_mask:GFP allocation mask
> + *
> + *  Description:
> + *Allocate and initialize an sg table from a list of pages. Continuous
> + *ranges of the pages are squashed into a single scatterlist node. A user
> + *may provide an offset at a start and a size of valid data in a buffer
> + *specified by the page array. The returned sg table is released by
> + *sg_free_table.
> + *
> + * Returns:
> + *   0 on success, negative error on failure
> + **/
> +int sg_alloc_table_from_pages(struct sg_table *sgt,
> + struct page **pages, unsigned int n_pages,
> + unsigned long offset, unsigned long size,
> + gfp_t gfp_mask)
> +{
> + unsigned int chunks;
> + unsigned int i;
> + unsigned int cur_page;
> + int ret;
> + struct scatterlist *s;
> +
> + /* compute number of contiguous chunks */
> + chunks = 1;
> + for (i = 1; i < n_pages; ++i)
> + if (pages[i] != pages[i - 1] + 1)
> + ++chunks;

I'm not aware of the details (and didn't bother to do a full audit), but
I guess this could blow up on funky discontig-mem setups. Imo would be
safer to compare the pfn or phys address. And also slightly more readable.
Imo sg table creation is not a fastpath, the exporter should cache these
anyway, so we can waste some cpu cycles here.

> + ret = sg_alloc_table(sgt, chunks, gfp_mask);
> + if (unlikely(ret))
> + return ret;
> +
> + /* merging chunks and putting them into the scatterlist */
> + cur_page = 0;
> + for_each_sg(sgt->sgl, s, sgt->orig_nents, i) {
> + unsigned long chunk_size;
> + unsigned int j;
> +
> + /* looking for the end of the current chunk */
> + for (j = cur_page + 1; j < n_pages; ++j)
> + if (pages[j] != pages[j - 1] + 1)
> + break;
> +
> + chunk_size = ((j - cur_page) << PAGE_SHIFT) - offset;
> + sg_set_page(s, pages[cur_page], min(size, chunk_size), offset);
> + size -= chunk_size;
> + offset = 0;
> + cur_page = j;
> + }
> +
> + return 0;
> +}
> +EXPORT_SYMBOL(sg_alloc_table_from_pages);
> +
> +/**
>   * sg_miter_start - start mapping iteration over a sg list
>   * @miter: sg mapping iter to be started
>   * @sgl: sg list to iterate over
> -- 
> 1.7.5.4
> 
> ___
> dri-devel 

[PATCH] drm: Initial KMS driver for AST (ASpeed Technologies) 2000 series

2012-04-24 Thread Michel Dänzer
On Mon, 2012-04-23 at 14:30 +0100, Alan Cox wrote:
> 
> > fbdev objects once exposed to userspace or to fbcon, thanks to some 
> > wonderful
> > API design way back, the mmaps on the fbdev device are direct to the VRAM
> > physical pages. Can't tear them down and move them into system RAM pages
> > at all easily.
> 
> Thats not strictly true. They can move mapping if the locking is right
> and the helpers handle it because you can invalidate the pages in the
> userspace mappings and they will get faulted back with the new ones.

fbdev userspace mappings is the easy part, TTM has supported that for
years. The problem is fbcon, which can access the framebuffer from
basically any context for printk. 


> > Because I'm not 100% sure nothing will get written to it, and if
> 
> Fair point.
> 
> > something gets written
> > to it I'd rather not have to complicate the oops printing to have to
> > page in memory
> > from disk, when it might be the disk that caused the oops.
> 
> If the box was horked that way then you are going to fail to migrate the
> graphical frame buffer out in order to go into text mode to print the
> oops. Probably safest any oops hits the current visible object ?

It's not always that simple either, e.g. this wouldn't work when
scanning out a tiled buffer on Radeon HDs.


-- 
Earthling Michel D?nzer   |   http://www.amd.com
Libre software enthusiast |  Debian, X and DRI developer


[PATCH 12/13] drm/radeon: fix a bug with the ring syncing code

2012-04-24 Thread Christian König
On 24.04.2012 16:04, Dave Airlie wrote:
> 2012/4/19 Christian K?nig:
>> Rings need to lock in order, otherwise
>> the ring subsystem can deadlock.
> No sure if its the commit or not but I was profiling on an r700 and
> saw it create a semaphore for ring syncing.
>
> surely the r700 would have no need?
>
In theory the first hardware with more than a gfx ring was some r6xx 
(but of course we haven't released any code/documentation for that yet), 
so it's ok that the code generally checks for inter ring synchronization 
needs on r7xx cards.

But with the current mainline it should just boil down to an not taken 
"if" branch, witch it currently doesn't (*crap*). Just tested with my 
RV710 and I can confirm that it unnecessarily allocates a semaphore. 
Another bug on my todo list for this patchset, going to send out an v2 
soon, but going to test it through first.

Thanks for the comment,
Christian.


[Bug 49110] AMDILCFGStructurizer.cpp:1751:3: error: 'isCurrentDebugType' was not declared in this scope

2012-04-24 Thread bugzilla-daemon
https://bugs.freedesktop.org/show_bug.cgi?id=49110

--- Comment #1 from Tom Stellard  2012-04-24 16:04:18 PDT 
---
I think this happens when you build Mesa with debugging enabled and LLVM
without it enabled.  It's still a bug though.  For now, you could try building
a debug version of both Mesa and LLVM.  I think that will fix it.

-- 
Configure bugmail: https://bugs.freedesktop.org/userprefs.cgi?tab=email
--- You are receiving this mail because: ---
You are the assignee for the bug.
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH 2/3] acpi_video: Intel video is not always i915

2012-04-24 Thread Matthew Garrett
On Tue, Apr 24, 2012 at 11:31:17PM +0100, Alan Cox wrote:
> On Tue, 24 Apr 2012 22:02:18 +0100
> Matthew Garrett  wrote:
> > The PowerVR Intels I'd seen had the opregion address in the 0xfc 
> > register as well. Is this no longer true on the latest?
> 
> PowerVR does - i740 never did.
> 
> The PowerVR 0xfc poking also doesn't currently work once the driver takes
> over because it isn't yet implementing the driver end of the weird ACPI
> messaging/event stuff.
> 
> Once it does the GMA500 will be able to do an ACPI video register, but we
> will still need the check to get the ifdeffery right for what drivers are
> compiled for the kernel.

Right now you seem to set opregion unconditionally on PVR, which seems 
to be equivalent to the 0xfc check that was there before - I can 
understand excluding i740, but the PVR check could be left with the gen 
hardware one?

-- 
Matthew Garrett | mj...@srcf.ucam.org
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH 2/3] acpi_video: Intel video is not always i915

2012-04-24 Thread Alan Cox
On Tue, 24 Apr 2012 22:02:18 +0100
Matthew Garrett  wrote:

> On Tue, Apr 24, 2012 at 04:45:01PM +0100, Alan Cox wrote:
> > From: Alan Cox 
> > 
> > Handle the GMA500/600/36x0 cases. Also stop it poking at random registers on
> > the i740 cards that may be out there still.
> 
> The PowerVR Intels I'd seen had the opregion address in the 0xfc 
> register as well. Is this no longer true on the latest?

PowerVR does - i740 never did.

The PowerVR 0xfc poking also doesn't currently work once the driver takes
over because it isn't yet implementing the driver end of the weird ACPI
messaging/event stuff.

Once it does the GMA500 will be able to do an ACPI video register, but we
will still need the check to get the ifdeffery right for what drivers are
compiled for the kernel.

Alan
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH] drm/edid: Try harder to fix up base EDID blocks

2012-04-24 Thread Alex Deucher
On Tue, Apr 24, 2012 at 2:56 PM, Adam Jackson  wrote:
> On 4/16/12 10:40 AM, Adam Jackson wrote:
>>
>> Requiring the first byte of the EDID base block header to be 0 means we
>> don't fix up as many transfer errors as we could. ?Instead have the
>> callers specify whether it's meant to be block 0 or not, and
>> conditionally run header fixup based on that.
>
>
> Anybody? ?This appears to be a pretty common form of EDID corruption.

Seems reasonable to me.

Reviewed-by: Alex Deucher 

>
> - ajax
>
>
> ___
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 12/13] drm/radeon: fix a bug with the ring syncing code

2012-04-24 Thread Dave Airlie
2012/4/19 Christian K?nig :
> Rings need to lock in order, otherwise
> the ring subsystem can deadlock.

No sure if its the commit or not but I was profiling on an r700 and
saw it create a semaphore for ring syncing.

surely the r700 would have no need?

Dave.


[PATCH v2] scatterlist: add sg_alloc_table_from_pages function

2012-04-24 Thread Tomasz Stanislawski
This patch adds a new constructor for an sg table. The table is constructed
from an array of struct pages. All contiguous chunks of the pages are merged
into a single sg nodes. A user may provide an offset and a size of a buffer if
the buffer is not page-aligned.

The function is dedicated for DMABUF exporters which often perform conversion
from an page array to a scatterlist. Moreover the scatterlist should be
squashed in order to save memory and to speed-up the process of DMA mapping
using dma_map_sg.

The code is based on the patch 'v4l: vb2-dma-contig: add support for
scatterlist in userptr mode' and hints from Laurent Pinchart.

Signed-off-by: Tomasz Stanislawski 
Signed-off-by: Kyungmin Park 
---
 include/linux/scatterlist.h |4 +++
 lib/scatterlist.c   |   63 +++
 2 files changed, 67 insertions(+), 0 deletions(-)

diff --git a/include/linux/scatterlist.h b/include/linux/scatterlist.h
index ac9586d..7b600da 100644
--- a/include/linux/scatterlist.h
+++ b/include/linux/scatterlist.h
@@ -214,6 +214,10 @@ void sg_free_table(struct sg_table *);
 int __sg_alloc_table(struct sg_table *, unsigned int, unsigned int, gfp_t,
 sg_alloc_fn *);
 int sg_alloc_table(struct sg_table *, unsigned int, gfp_t);
+int sg_alloc_table_from_pages(struct sg_table *sgt,
+   struct page **pages, unsigned int n_pages,
+   unsigned long offset, unsigned long size,
+   gfp_t gfp_mask);

 size_t sg_copy_from_buffer(struct scatterlist *sgl, unsigned int nents,
   void *buf, size_t buflen);
diff --git a/lib/scatterlist.c b/lib/scatterlist.c
index 6096e89..90f9265 100644
--- a/lib/scatterlist.c
+++ b/lib/scatterlist.c
@@ -319,6 +319,69 @@ int sg_alloc_table(struct sg_table *table, unsigned int 
nents, gfp_t gfp_mask)
 EXPORT_SYMBOL(sg_alloc_table);

 /**
+ * sg_alloc_table_from_pages - Allocate and initialize an sg table from
+ *an array of pages
+ * @sgt:   The sg table header to use
+ * @pages: Pointer to an array of page pointers
+ * @n_pages:   Number of pages in the pages array
+ * @offset: Offset from a start of the first page to a start of a buffer
+ * @size:   Number of valid bytes in the buffer (after offset)
+ * @gfp_mask:  GFP allocation mask
+ *
+ *  Description:
+ *Allocate and initialize an sg table from a list of pages. Continuous
+ *ranges of the pages are squashed into a single scatterlist node. A user
+ *may provide an offset at a start and a size of valid data in a buffer
+ *specified by the page array. The returned sg table is released by
+ *sg_free_table.
+ *
+ * Returns:
+ *   0 on success, negative error on failure
+ **/
+int sg_alloc_table_from_pages(struct sg_table *sgt,
+   struct page **pages, unsigned int n_pages,
+   unsigned long offset, unsigned long size,
+   gfp_t gfp_mask)
+{
+   unsigned int chunks;
+   unsigned int i;
+   unsigned int cur_page;
+   int ret;
+   struct scatterlist *s;
+
+   /* compute number of contiguous chunks */
+   chunks = 1;
+   for (i = 1; i < n_pages; ++i)
+   if (pages[i] != pages[i - 1] + 1)
+   ++chunks;
+
+   ret = sg_alloc_table(sgt, chunks, gfp_mask);
+   if (unlikely(ret))
+   return ret;
+
+   /* merging chunks and putting them into the scatterlist */
+   cur_page = 0;
+   for_each_sg(sgt->sgl, s, sgt->orig_nents, i) {
+   unsigned long chunk_size;
+   unsigned int j;
+
+   /* looking for the end of the current chunk */
+   for (j = cur_page + 1; j < n_pages; ++j)
+   if (pages[j] != pages[j - 1] + 1)
+   break;
+
+   chunk_size = ((j - cur_page) << PAGE_SHIFT) - offset;
+   sg_set_page(s, pages[cur_page], min(size, chunk_size), offset);
+   size -= chunk_size;
+   offset = 0;
+   cur_page = j;
+   }
+
+   return 0;
+}
+EXPORT_SYMBOL(sg_alloc_table_from_pages);
+
+/**
  * sg_miter_start - start mapping iteration over a sg list
  * @miter: sg mapping iter to be started
  * @sgl: sg list to iterate over
-- 
1.7.5.4



[PATCH] drm/edid: Try harder to fix up base EDID blocks

2012-04-24 Thread Adam Jackson
On 4/16/12 10:40 AM, Adam Jackson wrote:
> Requiring the first byte of the EDID base block header to be 0 means we
> don't fix up as many transfer errors as we could.  Instead have the
> callers specify whether it's meant to be block 0 or not, and
> conditionally run header fixup based on that.

Anybody?  This appears to be a pretty common form of EDID corruption.

- ajax



Re: [PATCH 2/3] acpi_video: Intel video is not always i915

2012-04-24 Thread Matthew Garrett
On Tue, Apr 24, 2012 at 04:45:01PM +0100, Alan Cox wrote:
> From: Alan Cox 
> 
> Handle the GMA500/600/36x0 cases. Also stop it poking at random registers on
> the i740 cards that may be out there still.

The PowerVR Intels I'd seen had the opregion address in the 0xfc 
register as well. Is this no longer true on the latest?

-- 
Matthew Garrett | mj...@srcf.ucam.org
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v2 3/4] drm/exynos: added userptr feature.

2012-04-24 Thread Inki Dae
this feature could be used to use memory region allocated by malloc() in user
mode and mmaped memory region allocated by other memory allocators. userptr
interface can identify memory type through vm_flags value and would get
pages or page frame numbers to user space appropriately.

changelog v2:
the memory region mmaped with VM_PFNMAP type is physically continuous and
start address of the memory region should be set into buf->dma_addr but
previous patch had a problem that end address is set into buf->dma_addr
so v2 fixes that problem.

Signed-off-by: Inki Dae 
Signed-off-by: Kyungmin Park 
---
 drivers/gpu/drm/exynos/exynos_drm_drv.c |2 +
 drivers/gpu/drm/exynos/exynos_drm_gem.c |  265 +++
 drivers/gpu/drm/exynos/exynos_drm_gem.h |   13 ++-
 include/drm/exynos_drm.h|   25 +++-
 4 files changed, 303 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c 
b/drivers/gpu/drm/exynos/exynos_drm_drv.c
index f58a487..5bb0361 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c
@@ -211,6 +211,8 @@ static struct drm_ioctl_desc exynos_ioctls[] = {
DRM_AUTH),
DRM_IOCTL_DEF_DRV(EXYNOS_GEM_MMAP,
exynos_drm_gem_mmap_ioctl, DRM_UNLOCKED | DRM_AUTH),
+   DRM_IOCTL_DEF_DRV(EXYNOS_GEM_USERPTR,
+   exynos_drm_gem_userptr_ioctl, DRM_UNLOCKED),
DRM_IOCTL_DEF_DRV(EXYNOS_PLANE_SET_ZPOS, exynos_plane_set_zpos_ioctl,
DRM_UNLOCKED | DRM_AUTH),
DRM_IOCTL_DEF_DRV(EXYNOS_VIDI_CONNECTION,
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c 
b/drivers/gpu/drm/exynos/exynos_drm_gem.c
index afd0cd4..1ee5383 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c
@@ -66,6 +66,43 @@ static int check_gem_flags(unsigned int flags)
return 0;
 }

+static struct vm_area_struct *get_vma(struct vm_area_struct *vma)
+{
+   struct vm_area_struct *vma_copy;
+
+   vma_copy = kmalloc(sizeof(*vma_copy), GFP_KERNEL);
+   if (!vma_copy)
+   return NULL;
+
+   if (vma->vm_ops && vma->vm_ops->open)
+   vma->vm_ops->open(vma);
+
+   if (vma->vm_file)
+   get_file(vma->vm_file);
+
+   memcpy(vma_copy, vma, sizeof(*vma));
+
+   vma_copy->vm_mm = NULL;
+   vma_copy->vm_next = NULL;
+   vma_copy->vm_prev = NULL;
+
+   return vma_copy;
+}
+
+static void put_vma(struct vm_area_struct *vma)
+{
+   if (!vma)
+   return;
+
+   if (vma->vm_ops && vma->vm_ops->close)
+   vma->vm_ops->close(vma);
+
+   if (vma->vm_file)
+   fput(vma->vm_file);
+
+   kfree(vma);
+}
+
 static void update_vm_cache_attr(struct exynos_drm_gem_obj *obj,
struct vm_area_struct *vma)
 {
@@ -254,6 +291,41 @@ static void exynos_drm_gem_put_pages(struct drm_gem_object 
*obj)
/* add some codes for UNCACHED type here. TODO */
 }

+static void exynos_drm_put_userptr(struct drm_gem_object *obj)
+{
+   struct exynos_drm_gem_obj *exynos_gem_obj;
+   struct exynos_drm_gem_buf *buf;
+   struct vm_area_struct *vma;
+   int npages;
+
+   exynos_gem_obj = to_exynos_gem_obj(obj);
+   buf = exynos_gem_obj->buffer;
+   vma = exynos_gem_obj->vma;
+
+   if (vma && (vma->vm_flags & VM_PFNMAP) && (vma->vm_pgoff)) {
+   put_vma(exynos_gem_obj->vma);
+   goto out;
+   }
+
+   npages = buf->size >> PAGE_SHIFT;
+
+   npages--;
+   while (npages >= 0) {
+   if (buf->write)
+   set_page_dirty_lock(buf->pages[npages]);
+
+   put_page(buf->pages[npages]);
+   npages--;
+   }
+
+out:
+   kfree(buf->pages);
+   buf->pages = NULL;
+
+   kfree(buf->sgt);
+   buf->sgt = NULL;
+}
+
 static int exynos_drm_gem_handle_create(struct drm_gem_object *obj,
struct drm_file *file_priv,
unsigned int *handle)
@@ -293,6 +365,8 @@ void exynos_drm_gem_destroy(struct exynos_drm_gem_obj 
*exynos_gem_obj)

if (exynos_gem_obj->flags & EXYNOS_BO_NONCONTIG)
exynos_drm_gem_put_pages(obj);
+   else if (exynos_gem_obj->flags & EXYNOS_BO_USERPTR)
+   exynos_drm_put_userptr(obj);
else
exynos_drm_free_buf(obj->dev, exynos_gem_obj->flags, buf);

@@ -606,6 +680,197 @@ int exynos_drm_gem_mmap_ioctl(struct drm_device *dev, 
void *data,
return 0;
 }

+static int exynos_drm_get_userptr(struct drm_device *dev,
+   struct exynos_drm_gem_obj *obj,
+   unsigned long userptr,
+   unsigned int write)
+{
+   unsigned int get_npages;
+   unsigned long npages = 0;
+   struct vm_area_struct *vma;
+   struct exynos_dr

[Bug 49110] New: AMDILCFGStructurizer.cpp:1751:3: error: 'isCurrentDebugType' was not declared in this scope

2012-04-24 Thread bugzilla-dae...@freedesktop.org
https://bugs.freedesktop.org/show_bug.cgi?id=49110

 Bug #: 49110
   Summary: AMDILCFGStructurizer.cpp:1751:3: error:
'isCurrentDebugType' was not declared in this scope
Classification: Unclassified
   Product: Mesa
   Version: git
  Platform: x86 (IA32)
OS/Version: Linux (All)
Status: NEW
  Severity: normal
  Priority: medium
 Component: Drivers/Gallium/r600
AssignedTo: dri-devel at lists.freedesktop.org
ReportedBy: fabio.ped at libero.it


I get this compile error when building the new LLVM compiler:

AMDILCFGStructurizer.cpp:1751:3: error: 'isCurrentDebugType' was not declared
in this scope

Full log is available here:
https://launchpadlibrarian.net/102973365/buildlog_ubuntu-precise-amd64.mesa_8.1~git1204241446.587c22~gd~p_FAILEDTOBUILD.txt.gz

-- 
Configure bugmail: https://bugs.freedesktop.org/userprefs.cgi?tab=email
--- You are receiving this mail because: ---
You are the assignee for the bug.


Enhancing EDID quirk functionality

2012-04-24 Thread Ian Pilcher
On 04/24/2012 04:07 AM, Lars-Peter Clausen wrote:
> I just had a similar issue with a different driver and remembered your post
>
> If the S bits in the infoframe are 0 the display may under- or overscan the
> the image (Although the spec says it should behave the same if no infoframe
> is present). If it is set to 2 the display should underscan the image, so
> I'd be interested to see if the following patch changes the displays
> behavior for you.
>
>
> --- a/drivers/gpu/drm/nouveau/nouveau_hdmi.c
> +++ b/drivers/gpu/drm/nouveau/nouveau_hdmi.c
> @@ -147,7 +147,7 @@ static void
>   nouveau_hdmi_video_infoframe(struct drm_encoder *encoder,
>struct drm_display_mode *mode)
>   {
> - const u8 Y = 0, A = 0, B = 0, S = 0, C = 0, M = 0, R = 0;
> + const u8 Y = 0, A = 0, B = 0, S = 2, C = 0, M = 0, R = 0;
>   const u8 ITC = 0, EC = 0, Q = 0, SC = 0, VIC = 0, PR = 0;
>   const u8 bar_top = 0, bar_bottom = 0, bar_left = 0, bar_right = 0;
>   u8 frame[20];

No change.

BTW, I've been grinding ahead with the EDID quirk infrastructure
changes that I discussed in my previous note.  I'd prefer not to waste
huge amounts of my less-than-copious free time, so please speak up if
you have any objections.

(The preceding paragraph is not specifically directed at Lars-Peter.)



[Bug 43138] Radeon HD5450 fails to load cedar firmware ?

2012-04-24 Thread bugzilla-dae...@bugzilla.kernel.org
https://bugzilla.kernel.org/show_bug.cgi?id=43138





--- Comment #11 from Michel D?nzer   2012-04-24 13:42:41 
---
(In reply to comment #10)
> ...nope, as Debian considers that particular firmware to be "nonfree" it is 
> not
> included in the initrd at all,

That the firmware is in the firmware-linux-nonfree package merely means it's
not installed on the system by default, it doesn't directly prevent the
firmware from getting included in the initrd.

> so it boils down to a somewhat misleading "bogus length" instead of a more
> appropriate "file not found" error for all cases above.

The lengths in the original error messages are the amounts of firmware data
written by the /lib/udev/firmware.agent helper. If the firmware was missing
altogether, how could the helper guess their sizes?

Anyway, glad it's working for you now.

-- 
Configure bugmail: https://bugzilla.kernel.org/userprefs.cgi?tab=email
--- You are receiving this mail because: ---
You are watching the assignee of the bug.


[Nouveau] [PATCH 2/5] drm/nouveau: base fence timeout on time of emission

2012-04-24 Thread Ben Skeggs
On Mon, 2012-04-23 at 00:18 +0200, Marcin Slusarz wrote:
> Wait loop can be interrupted by signal, so if signals are raised
> periodically (e.g. SIGALRM) this loop may never finish. Use
> emission time as a base for fence timeout.
Ah, thanks for tackling this issue.  It's been long on my list of things
to do, but never quite made it to the top.

Rather than hardcoding the timeout in fence_wait(), I think perhaps
storing "fence->timeout = jiffies + (whatever * HZ);" is a better plan.
I can forsee us wanting longer timeouts for certain operations
(particularly long compute operations) in the future.

Ben.

> 
> Signed-off-by: Marcin Slusarz 
> ---
>  drivers/gpu/drm/nouveau/nouveau_fence.c |5 -
>  1 files changed, 4 insertions(+), 1 deletions(-)
> 
> diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.c 
> b/drivers/gpu/drm/nouveau/nouveau_fence.c
> index a22b9ad..59f92e9 100644
> --- a/drivers/gpu/drm/nouveau/nouveau_fence.c
> +++ b/drivers/gpu/drm/nouveau/nouveau_fence.c
> @@ -44,6 +44,7 @@ struct nouveau_fence {
>  
>   uint32_t sequence;
>   bool signalled;
> + unsigned long emitted_at;
>  
>   void (*work)(void *priv, bool signalled);
>   void *priv;
> @@ -172,6 +173,7 @@ nouveau_fence_emit(struct nouveau_fence *fence)
>   }
>   OUT_RING (chan, fence->sequence);
>   FIRE_RING(chan);
> + fence->emitted_at = jiffies;
>  
>   return 0;
>  }
> @@ -230,7 +232,8 @@ __nouveau_fence_signalled(void *sync_obj, void *sync_arg)
>  int
>  __nouveau_fence_wait(void *sync_obj, void *sync_arg, bool lazy, bool intr)
>  {
> - unsigned long timeout = jiffies + (3 * DRM_HZ);
> + struct nouveau_fence *fence = nouveau_fence(sync_obj);
> + unsigned long timeout = fence->emitted_at + 3 * DRM_HZ;
>   unsigned long sleep_time = NSEC_PER_MSEC / 1000;
>   ktime_t t;
>   int ret = 0;




Re: [RFC PATCH 5/5] drm/nouveau: gpu lockup recovery

2012-04-24 Thread Marcin Slusarz
On Mon, Apr 23, 2012 at 06:56:44PM +0200, Martin Peres wrote:
> Le 23/04/2012 18:32, Marcin Slusarz a écrit :
> >
> > Just run piglit. Even "quick" tests can cause ~5 lockups (it eventually 
> > messes
> > up DDX channel, but this patchset can't fix this case).
> > You can run fs-discard-exit-2 test first - for me it causes instant GPU 
> > lockup.
> >
> > Marcin
> Great, Thanks.
> 
> Did you have a look at 
> https://bugs.freedesktop.org/show_bug.cgi?id=40886 and 
> http://xorg.freedesktop.org/wiki/SummerOfCodeIdeas ?

Yeah, I've seen them some time ago.

> The Ubuntu xorg devs were looking for something like this, but they also 
> wanted a lockup report. Are you also interested on working on it ?

Yes, when this patchset will be applied, I'm going to work on improving
error reporting.

Marcin
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH] drm/edid: Try harder to fix up base EDID blocks

2012-04-24 Thread Chris Wilson
On Mon, 16 Apr 2012 10:40:08 -0400, Adam Jackson  wrote:
> Requiring the first byte of the EDID base block header to be 0 means we
> don't fix up as many transfer errors as we could.  Instead have the
> callers specify whether it's meant to be block 0 or not, and
> conditionally run header fixup based on that.
> 
> Bugzilla: https://bugzilla.redhat.com/812890
> Signed-off-by: Adam Jackson 

The patch does watch it says on the tin. I don't pretend to know how
frequent this corruption is, but as it stands the current code fails to
be as effective as it could be.

Reviewed-by: Chris Wilson 
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH 1/5] drm: add optional per device rwsem for all ioctls

2012-04-24 Thread Marcin Slusarz
On Mon, Apr 23, 2012 at 09:51:48AM +0200, Daniel Vetter wrote:
> On Mon, Apr 23, 2012 at 12:18:28AM +0200, Marcin Slusarz wrote:
> > Nouveau, in normal circumstances, does not need device lock for every ioctl,
> > but incoming "gpu reset" code needs exclusive access to the device.
> > This commit adds drm_driver flag which turns on read lock ioctl 
> > encapsulation.
> > 
> > Signed-off-by: Marcin Slusarz 
> 
> Why can't we just move this down to nouveau driver code?

Ok, I think it's easily possible by wrapping drm_ioctl.

> So why can't nouveau do the same? Also, if this is indeed necessary and we
> add this as some mandatory core infrastructure, it's not good enough: In
> i915 we go to great lengths to ensure that all processes waiting for gpu
> reset are still interruptible, in case the gpu reset dies unexpectedly
> (which happens), so this would need to be improved.

I came up with a scheme where down_read can be made interruptible.

I'll post both changes in a few days.

(Unfortunately adding proper down_read_interruptible / down_write_interruptible
require a bit of unfunny work - 8 architectures have their own code for rwsems)

Marcin
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH] drm/edid: Try harder to fix up base EDID blocks

2012-04-24 Thread Alex Deucher
On Tue, Apr 24, 2012 at 2:56 PM, Adam Jackson  wrote:
> On 4/16/12 10:40 AM, Adam Jackson wrote:
>>
>> Requiring the first byte of the EDID base block header to be 0 means we
>> don't fix up as many transfer errors as we could.  Instead have the
>> callers specify whether it's meant to be block 0 or not, and
>> conditionally run header fixup based on that.
>
>
> Anybody?  This appears to be a pretty common form of EDID corruption.

Seems reasonable to me.

Reviewed-by: Alex Deucher 

>
> - ajax
>
>
> ___
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: Enhancing EDID quirk functionality

2012-04-24 Thread Ian Pilcher

On 04/24/2012 04:07 AM, Lars-Peter Clausen wrote:

I just had a similar issue with a different driver and remembered your post

If the S bits in the infoframe are 0 the display may under- or overscan the
the image (Although the spec says it should behave the same if no infoframe
is present). If it is set to 2 the display should underscan the image, so
I'd be interested to see if the following patch changes the displays
behavior for you.


--- a/drivers/gpu/drm/nouveau/nouveau_hdmi.c
+++ b/drivers/gpu/drm/nouveau/nouveau_hdmi.c
@@ -147,7 +147,7 @@ static void
  nouveau_hdmi_video_infoframe(struct drm_encoder *encoder,
 struct drm_display_mode *mode)
  {
-   const u8 Y = 0, A = 0, B = 0, S = 0, C = 0, M = 0, R = 0;
+   const u8 Y = 0, A = 0, B = 0, S = 2, C = 0, M = 0, R = 0;
const u8 ITC = 0, EC = 0, Q = 0, SC = 0, VIC = 0, PR = 0;
const u8 bar_top = 0, bar_bottom = 0, bar_left = 0, bar_right = 0;
u8 frame[20];


No change.

BTW, I've been grinding ahead with the EDID quirk infrastructure
changes that I discussed in my previous note.  I'd prefer not to waste
huge amounts of my less-than-copious free time, so please speak up if
you have any objections.

(The preceding paragraph is not specifically directed at Lars-Peter.)

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH] drm/edid: Try harder to fix up base EDID blocks

2012-04-24 Thread Adam Jackson

On 4/16/12 10:40 AM, Adam Jackson wrote:

Requiring the first byte of the EDID base block header to be 0 means we
don't fix up as many transfer errors as we could.  Instead have the
callers specify whether it's meant to be block 0 or not, and
conditionally run header fixup based on that.


Anybody?  This appears to be a pretty common form of EDID corruption.

- ajax

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [Nouveau] [PATCH 2/5] drm/nouveau: base fence timeout on time of emission

2012-04-24 Thread Marcin Slusarz
On Tue, Apr 24, 2012 at 12:37:34PM +1000, Ben Skeggs wrote:
> On Mon, 2012-04-23 at 00:18 +0200, Marcin Slusarz wrote:
> > Wait loop can be interrupted by signal, so if signals are raised
> > periodically (e.g. SIGALRM) this loop may never finish. Use
> > emission time as a base for fence timeout.
> Ah, thanks for tackling this issue.  It's been long on my list of things
> to do, but never quite made it to the top.
> 
> Rather than hardcoding the timeout in fence_wait(), I think perhaps
> storing "fence->timeout = jiffies + (whatever * HZ);" is a better plan.
> I can forsee us wanting longer timeouts for certain operations
> (particularly long compute operations) in the future.

Yeah, good idea. Later, we will probably need to add code which will keep 
extending
this timeout as long as gpu is progressing.

Marcin
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


Linux 3.4-rc4

2012-04-24 Thread Konrad Rzeszutek Wilk
On Mon, Apr 23, 2012 at 09:03:45PM -0400, Nick Bowler wrote:
> On 2012-04-22 22:45 -0400, Konrad Rzeszutek Wilk wrote:
> > On Sun, Apr 22, 2012 at 08:05:54PM -0400, Nick Bowler wrote:
> > > Following up on the above, the commit which introduces the panics during
> > > boot is this one:
> > >
> > > commit 8e7e70522d760c4ccd4cd370ebfa0ba69e006c6e
> > > Author: Jerome Glisse 
> > > Date:   Wed Nov 9 17:15:26 2011 -0500
> > > 
> > > drm/ttm: isolate dma data from ttm_tt V4
> > 
> > I think
> > 
> > dea7e0a ttm: fix agp since ttm tt rework
> > 
> > fixed that.
> 
> Yes, I just tested this commit and the one immediately before it.  The
> one before crashes in the usual way, and dea7e0a boots (with the VGA
> output black as in the original report).  So this fixed the crash.
> 
> Now, returning to the original bisection, I marked that commit as "bad"
> and dropped all the earlier "skip" markings.  Git asks me to test commit
> 2a44e4997c5f ("drm/nouveau/disp: introduce proper init/fini, separate
> from create/destroy").  I cherry picked the aforementioned ttm fix:
> 
>   git cherry-pick -n dea7e0a
> 
> which succeeded.  Howevew, the resulting kernel still crashes early,
> although now in a different way.  I just can't win :(

Perhaps there is a better way. You could do this:

git log --oneline -r v3.2..v3.3 drivers/gpu/drm/nouveau

to get an idea of the set of patches that went in. And use that, so

git bisect start -- drivers/gpu/drm/nouveau [this should only do the bisection 
on those patches]

git bisect good v3.2
git bisect bad v3.3

And keep in mind the dea7e0a might need to be stuck on some of these.

This _should_ limit the bisection to just the nouveau changes, I hope.


[PATCH] dma-buf: mmap support

2012-04-24 Thread Daniel Vetter
Compared to Rob Clark's RFC I've ditched the prepare/finish hooks
and corresponding ioctls on the dma_buf file. The major reason for
that is that many people seem to be under the impression that this is
also for synchronization with outstanding asynchronous processsing.
I'm pretty massively opposed to this because:

- It boils down reinventing a new rather general-purpose userspace
  synchronization interface. If we look at things like futexes, this
  is hard to get right.
- Furthermore a lot of kernel code has to interact with this
  synchronization primitive. This smells a look like the dri1 hw_lock,
  a horror show I prefer not to reinvent.
- Even more fun is that multiple different subsystems would interact
  here, so we have plenty of opportunities to create funny deadlock
  scenarios.

I think synchronization is a wholesale different problem from data
sharing and should be tackled as an orthogonal problem.

Now we could demand that prepare/finish may only ensure cache
coherency (as Rob intended), but that runs up into the next problem:
We not only need mmap support to facilitate sw-only processing nodes
in a pipeline (without jumping through hoops by importing the dma_buf
into some sw-access only importer), which allows for a nicer
ION->dma-buf upgrade path for existing Android userspace. We also need
mmap support for existing importing subsystems to support existing
userspace libraries. And a loot of these subsystems are expected to
export coherent userspace mappings.

So prepare/finish can only ever be optional and the exporter /needs/
to support coherent mappings. Given that mmap access is always
somewhat fallback-y in nature I've decided to drop this optimization,
instead of just making it optional. If we demonstrate a clear need for
this, supported by benchmark results, we can always add it in again
later as an optional extension.

Other differences compared to Rob's RFC is the above mentioned support
for mapping a dma-buf through facilities provided by the importer.
Which results in mmap support no longer being optional.

Note that this dma-buf mmap patch does _not_ support every possible
insanity an existing subsystem could pull of with mmap: Because it
does not allow to intercept pagefaults and shoot down ptes importing
subsystems can't add some magic of their own at these points (e.g. to
automatically synchronize with outstanding rendering or set up some
special resources). I've done a cursory read through a few mmap
implementions of various subsytems and I'm hopeful that we can avoid
this (and the complexity it'd bring with it).

Additonally I've extended the documentation a bit to explain the hows
and whys of this mmap extension.

In case we ever want to add support for explicitly cache maneged
userspace mmap with a prepare/finish ioctl pair, we could specify that
userspace needs to mmap a different part of the dma_buf, e.g. the
range starting at dma_buf->size up to dma_buf->size*2. This works
because the size of a dma_buf is invariant over it's lifetime. The
exporter would obviously need to fall back to coherent mappings for
both ranges if a legacy clients maps the coherent range and the
architecture cannot suppor conflicting caching policies. Also, this
would obviously be optional and userspace needs to be able to fall
back to coherent mappings.

v2:
- Spelling fixes from Rob Clark.
- Compile fix for !DMA_BUF from Rob Clark.
- Extend commit message to explain how explicitly cache managed mmap
  support could be added later.
- Extend the documentation with implementations notes for exporters
  that need to manually fake coherency.

v3:
- dma_buf pointer initialization goof-up noticed by Rebecca Schultz
  Zavin.

Cc: Rob Clark 
Cc: Rebecca Schultz Zavin 
Signed-Off-by: Daniel Vetter 
---
 Documentation/dma-buf-sharing.txt |   98 ++---
 drivers/base/dma-buf.c|   64 +++-
 include/linux/dma-buf.h   |   16 ++
 3 files changed, 170 insertions(+), 8 deletions(-)

diff --git a/Documentation/dma-buf-sharing.txt 
b/Documentation/dma-buf-sharing.txt
index 3bbd5c5..5ff4d2b 100644
--- a/Documentation/dma-buf-sharing.txt
+++ b/Documentation/dma-buf-sharing.txt
@@ -29,13 +29,6 @@ The buffer-user
in memory, mapped into its own address space, so it can access the same area
of memory.

-*IMPORTANT*: [see https://lkml.org/lkml/2011/12/20/211 for more details]
-For this first version, A buffer shared using the dma_buf sharing API:
-- *may* be exported to user space using "mmap" *ONLY* by exporter, outside of
-  this framework.
-- with this new iteration of the dma-buf api cpu access from the kernel has 
been
-  enable, see below for the details.
-
 dma-buf operations for device dma only
 --

@@ -313,6 +306,83 @@ Access to a dma_buf from the kernel context involves three 
steps:
  enum dma_data_direction dir);


+Direct Userspace Access/mmap Support
+-

Enhancing EDID quirk functionality

2012-04-24 Thread Lars-Peter Clausen
On 04/19/2012 09:16 PM, Ian Pilcher wrote:
> Greetings all!
> 
> I recently discovered that my nice 1900x1200 display is horribly
> confused by the InfoFrame functionality that was added to the nouveau
> driver in Linux 3.3.  Additional testing has shown that it has the same
> problem with the i915 driver and NVIDIA's proprietary driver.
> 

I just had a similar issue with a different driver and remembered your post

If the S bits in the infoframe are 0 the display may under- or overscan the
the image (Although the spec says it should behave the same if no infoframe
is present). If it is set to 2 the display should underscan the image, so
I'd be interested to see if the following patch changes the displays
behavior for you.


--- a/drivers/gpu/drm/nouveau/nouveau_hdmi.c
+++ b/drivers/gpu/drm/nouveau/nouveau_hdmi.c
@@ -147,7 +147,7 @@ static void
 nouveau_hdmi_video_infoframe(struct drm_encoder *encoder,
 struct drm_display_mode *mode)
 {
-   const u8 Y = 0, A = 0, B = 0, S = 0, C = 0, M = 0, R = 0;
+   const u8 Y = 0, A = 0, B = 0, S = 2, C = 0, M = 0, R = 0;
const u8 ITC = 0, EC = 0, Q = 0, SC = 0, VIC = 0, PR = 0;
const u8 bar_top = 0, bar_bottom = 0, bar_left = 0, bar_right = 0;
u8 frame[20];


[Patch 3/3] edid override: make edid writable in sysfs

2012-04-24 Thread Thorsten Schoel
From: Thorsten Schoel 

Makes class/drm/[CONNECTOR]/edid writable for adding edid overrides.

Signed-off-by: Thorsten Schoel 
---
diff -Nurp infra/drivers/gpu/drm/drm_sysfs.c sysfs/drivers/gpu/drm/drm_sysfs.c
--- infra/drivers/gpu/drm/drm_sysfs.c   2012-01-12 20:42:45.0 +0100
+++ sysfs/drivers/gpu/drm/drm_sysfs.c   2012-01-25 22:13:08.0 +0100
@@ -21,6 +21,8 @@
 #include "drm_sysfs.h"
 #include "drm_core.h"
 #include "drmP.h"
+#include "drm_edid.h"
+#include "drm_crtc.h"

 #define to_drm_minor(d) container_of(d, struct drm_minor, kdev)
 #define to_drm_connector(d) container_of(d, struct drm_connector, kdev)
@@ -228,6 +230,44 @@ static ssize_t edid_show(struct file *fi
return count;
 }

+static ssize_t edid_override(struct file *filp, struct kobject *kobj,
+struct bin_attribute *attr, char *buf, loff_t off,
+size_t count)
+{
+   struct device *connector_dev = container_of(kobj, struct device, kobj);
+   struct drm_connector *connector = to_drm_connector(connector_dev);
+   char *connector_name;
+   unsigned char *edid_new;
+
+   connector_name = drm_get_connector_name(connector);
+   
+   if (!count) {
+   drm_edid_override_remove(connector_name);
+   return 0;
+   }
+   
+   /* Only support writing the whole EDID in one piece */
+   if (off)
+   return 0;
+
+   if (count < EDID_LENGTH)
+   return 0;
+   if (count != (buf[0x7e] + 1) * EDID_LENGTH)
+   return 0;
+   
+   edid_new = kmalloc(count, GFP_KERNEL);
+   if (!edid_new)
+   return 0;
+   
+   memcpy(edid_new,  buf, count);
+
+   if (drm_edid_override_set(connector_name, (struct edid *)edid_new) < 0)
+   count = 0;
+   
+   kfree(edid_new);
+   return count;
+}
+
 static ssize_t modes_show(struct device *device,
   struct device_attribute *attr,
   char *buf)
@@ -341,9 +381,10 @@ static struct device_attribute connector

 static struct bin_attribute edid_attr = {
.attr.name = "edid",
-   .attr.mode = 0444,
+   .attr.mode = 0644,
.size = 0,
.read = edid_show,
+   .write = edid_override,
 };

 /**
---




[Patch 2/3] edid override: module parameter

2012-04-24 Thread Thorsten Schoel
From: Thorsten Schoel 

Allows for setting edid overrides through new parameter edid_override
for module drm.

Signed-off-by: Thorsten Schoel 
---
diff -Nurp infra/drivers/gpu/drm/drm_edid.c param/drivers/gpu/drm/drm_edid.c
--- infra/drivers/gpu/drm/drm_edid.c2012-01-25 22:12:59.0 +0100
+++ param/drivers/gpu/drm/drm_edid.c2012-01-25 22:14:51.0 +0100
@@ -32,6 +32,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 #include 
 #include "drmP.h"
 #include "drm_edid.h"
@@ -232,11 +234,37 @@ struct drm_edid_override {
struct list_head list;

char *connector;
+   char *param;
struct edid *edid;
unsigned num_blocks;
 };
 LIST_HEAD(drm_edid_override_list);

+
+static int drm_edid_override_ops__get(char *buffer, const struct kernel_param 
*kp);
+static int drm_edid_override_ops__set(const char *val, const struct 
kernel_param *kp);
+static void drm_edid_override_ops__free(void *arg);
+
+
+struct kernel_param_ops drm_edid_override_ops = {
+   .get = drm_edid_override_ops__get,
+   .set = drm_edid_override_ops__set,
+   .free = drm_edid_override_ops__free
+};
+
+MODULE_PARM_DESC(edid_override, "Override the EDID data of a monitor. "
+   "This should be a comma separated list of entries of the format "
+   "[connector name]:[data]. data is either raw EDID data encoded in "
+   "hexadecimal format, or, if it cannot be parsed as such, the name "
+   "of a file containing the EDID data to be loaded through "
+   "request_firmware. Examples:\nVGA-1:syncmaster913n.edid\n"
+   "DVI-I-1:00?");
+module_param_cb(edid_override,
+   &drm_edid_override_ops,
+   &drm_edid_override_list,
+   0600);
+
+
 /*
  * Free the memory associated with an EDID override.
  */
@@ -246,6 +273,7 @@ drm_edid_override_delete(struct drm_edid
if (entry->edid)
kfree(entry->edid);
kfree(entry->connector);
+   /* param is generated from the same piece of memory through strsep */
kfree(entry);
 }

@@ -270,7 +299,7 @@ drm_edid_override_remove(const char *con
 EXPORT_SYMBOL(drm_edid_override_remove);

 static int
-drm_edid_override_do_set(char *connector, struct edid *edid, unsigned 
num_blocks)
+drm_edid_override_do_set(char *connector, struct edid *edid, unsigned 
num_blocks, char *param)
 {
struct drm_edid_override *entry = NULL;
int found = 0;
@@ -300,6 +329,7 @@ drm_edid_override_do_set(char *connector
entry->connector = connector;
entry->edid = edid;
entry->num_blocks = num_blocks;
+   entry->param = param;

if (!found)
list_add_tail(&entry->list, &drm_edid_override_list);
@@ -308,6 +338,25 @@ drm_edid_override_do_set(char *connector
return 0;
 }

+/*
+ * Helper function for setter of module parameter.
+ */
+static int
+drm_edid_override_set_from_param(char *val)
+{
+   char *connector = NULL, *param = NULL;
+   
+   connector = strsep(&val, ":");
+   param = strlen(val) ? val : NULL;
+   
+   if (param)
+   return drm_edid_override_do_set(connector, NULL, 0, param);
+   else
+   drm_edid_override_remove(connector);
+   
+   return 0;
+}
+
 /**
  * Add a new override for connector if none has been set yet or replace the
  * current one.
@@ -336,10 +385,179 @@ drm_edid_override_set(const char *connec
}
memcpy(edid_dup, edid, edid_size);

-   return drm_edid_override_do_set(connector_dup, edid_dup, num_blocks);
+   return drm_edid_override_do_set(connector_dup, edid_dup, num_blocks, 
NULL);
 }
 EXPORT_SYMBOL(drm_edid_override_set);

+/*
+ * Setter for module parameter.
+ */
+static int
+drm_edid_override_ops__set(const char *val, const struct kernel_param *kp)
+{
+   const char *master = val;
+   char *substr = NULL;
+   int result = 0;
+   
+   do {
+   const char *new_master = strchr(master, ',');
+   int substr_len = 0;
+   
+   if (new_master)
+   substr_len = new_master - master;
+   else
+   substr_len = strlen(master);
+
+   substr = kstrndup(master, substr_len, GFP_KERNEL);
+   if (!substr)
+   return -ENOMEM;
+
+   result = drm_edid_override_set_from_param(substr);
+   if (result)
+   return result;
+   
+   master = new_master;
+   } while (master);
+   
+   return 0;
+}
+
+/* moduleparam.h claims this is "4k" */
+#define OPT_GET__BUFFER_LENGTH 4096
+/*
+ * Getter for module parameter. Will produce a comma separated list of
+ * all connectors an override has been set for.
+ */
+static int
+drm_edid_override_ops__get(char *buffer, const struct kernel_param *kp)
+{
+   struct drm_edid_override *entry = NULL;
+   int remaining_buf = OPT_GET_

[Patch 1/3] edid override: infrastructure

2012-04-24 Thread Thorsten Schoel
From: Thorsten Schoel 

Provides infrastructure for overriding edid information of individual
monitors.

Signed-off-by: Thorsten Schoel 
---
diff -Nurp vanilla/drivers/gpu/drm/drm_edid.c infra/drivers/gpu/drm/drm_edid.c
--- vanilla/drivers/gpu/drm/drm_edid.c  2012-01-25 22:29:25.0 +0100
+++ infra/drivers/gpu/drm/drm_edid.c2012-01-25 22:12:59.0 +0100
@@ -30,6 +30,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 #include 
 #include "drmP.h"
 #include "drm_edid.h"
@@ -226,6 +228,158 @@ bool drm_edid_is_valid(struct edid *edid
 }
 EXPORT_SYMBOL(drm_edid_is_valid);

+struct drm_edid_override {
+   struct list_head list;
+   
+   char *connector;
+   struct edid *edid;
+   unsigned num_blocks;
+};
+LIST_HEAD(drm_edid_override_list);
+
+/*
+ * Free the memory associated with an EDID override.
+ */
+static void
+drm_edid_override_delete(struct drm_edid_override *entry)
+{
+   if (entry->edid)
+   kfree(entry->edid);
+   kfree(entry->connector);
+   kfree(entry);
+}
+
+/**
+ * Remove an existing override.
+ *
+ * \param connector : name of a drm_connector
+ */
+void
+drm_edid_override_remove(const char *connector)
+{
+   struct drm_edid_override *entry = NULL;
+   
+   list_for_each_entry (entry, &drm_edid_override_list, list) {
+   if (strcmp(entry->connector, connector))
+   continue;
+   list_del(&entry->list);
+   drm_edid_override_delete(entry);
+   break;
+   }
+}
+EXPORT_SYMBOL(drm_edid_override_remove);
+
+static int
+drm_edid_override_do_set(char *connector, struct edid *edid, unsigned 
num_blocks)
+{
+   struct drm_edid_override *entry = NULL;
+   int found = 0;
+   
+   /* replace previous entry if present */
+   list_for_each_entry (entry, &drm_edid_override_list, list) {
+   if (strcmp(connector, entry->connector))
+   continue;
+   found = 1;
+   break;
+   }
+
+   if (!found) {
+   entry = kmalloc(sizeof(struct drm_edid_override), GFP_KERNEL);
+   if (!entry) {
+   kfree(connector);
+   kfree(edid);
+   return -ENOMEM;
+   }
+   INIT_LIST_HEAD(&entry->list);
+   } else {
+   kfree(entry->connector);
+   if (entry->edid)
+   kfree(entry->edid);
+   }
+   
+   entry->connector = connector;
+   entry->edid = edid;
+   entry->num_blocks = num_blocks;
+   
+   if (!found)
+   list_add_tail(&entry->list, &drm_edid_override_list);
+   DRM_INFO("Set new EDID override for connector %s", connector);
+   
+   return 0;
+}
+
+/**
+ * Add a new override for connector if none has been set yet or replace the
+ * current one.
+ *
+ * \param connector : name of a drm_connector as retrieved through 
drm_get_connector_name
+ * \param edid  : binary EDID data
+ */
+int
+drm_edid_override_set(const char *connector, const struct edid *edid)
+{
+   char *connector_dup = NULL;
+   struct edid *edid_dup = NULL;
+   int num_blocks = 0;
+   unsigned edid_size = 0;
+   
+   connector_dup = kstrdup(connector, GFP_KERNEL);
+   if (!connector_dup)
+   return -ENOMEM;
+   
+   num_blocks = edid->extensions + 1;
+   edid_size = num_blocks * EDID_LENGTH;
+   edid_dup = kmalloc(edid_size, GFP_KERNEL);
+   if (!edid_dup) {
+   kfree(connector_dup);
+   return -ENOMEM;
+   }
+   memcpy(edid_dup, edid, edid_size);
+   
+   return drm_edid_override_do_set(connector_dup, edid_dup, num_blocks);
+}
+EXPORT_SYMBOL(drm_edid_override_set);
+
+/**
+ * Get EDID information from overrides list if available.
+ *
+ * \param connector : DRM connector to get EDID for
+ * \return a newly allocated edid structure filled with the EDID data from the
+ *override or NULL if no override for @connector could be found.
+ */
+static struct edid *
+drm_edid_override_get (struct drm_connector *connector)
+{
+   struct list_head *pos = NULL;
+   struct drm_edid_override *entry = NULL;
+   char *connector_name = NULL;
+   struct edid *result = NULL;
+
+   connector_name = drm_get_connector_name(connector);
+
+   list_for_each(pos, &drm_edid_override_list) {
+   entry = (struct drm_edid_override *)
+   list_entry(pos, struct drm_edid_override, list);
+   if(!strcmp(entry->connector, connector_name))
+   break;
+   else
+   entry = NULL;
+   }
+   
+   if (!entry)
+   return NULL;
+   
+   if (!entry->edid) {
+   DRM_ERROR("EDID override without EDID data for connector %s", 
connector_name);
+   return NULL;
+   }
+   
+   if

[Patch 0/3] Add ability to override a monitor's EDID information

2012-04-24 Thread Thorsten Schoel
Hello everybody,

having a monitor provide wrong or invalid EDID information ? or none at
all ? seems to be a problem quite a number of people are facing. A few
of the non-KMS X-drivers provide individual mechanisms for overriding
such an EDID with user provided data. To my knowledge at least the
kernel currently falls short of providing such a mechanism. This set of
patches attempts to provide one.

It has a number of potential shortcoming to which I was not yet able to
find any solution. These are:

1. It uses drm_get_connector_name to identify a connector. I am not
entirely sure though if these names are guaranteed to be unique (the
names used in /sys/class/drm seem to suggest they are not). Since they
are good enough for the kernel's video parameter, though, I figured they
should be good enough for the present purpose as well.

2. One of the patches introduces a new kernel parameter (edid_override).
This parameter takes either the raw edid-data encoded as a hex-string or
the name of a firmware file from which to load the data. I am a bit
unhappy with both solutions since the first puts raw data on the command
line and makes it rather long and the second? well edid-data is not
exactly firmware in the strict sense. It may be firm, but it is probably
not ware.

3. I thought about making the sysfs code more sophisticated so that
individual bytes could be written at any position within the data. Yet,
there seems to be no way to truncate a file in sysfs which would be
important when changing the number of 128 byte blocks the data is made
up of. In addition, I cannot see what good such a behaviour would be or
how the obscure use probably is somewhere out there could justify the
additional complexity. I therefore opted for the approach of only
allowing writes of complete edid-blobs in one pass.

The patches I submit were tested on an x64 with radeon graphics and on
an x86 with i915. They were made for 3.4.

 drivers/gpu/drm/drm_edid.c  |  399 +++-
 drivers/gpu/drm/drm_sysfs.c |   43 
 include/drm/drm_crtc.h  |2 
 3 files changed, 435 insertions(+), 9 deletions(-)




PCI resources above 4GB

2012-04-24 Thread Steven Newbury
-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1

On 16/04/12 18:29, Yinghai Lu wrote:
> On Sun, Apr 15, 2012 at 11:54 PM, Yinghai Lu 
> wrote:
>> On Sun, Apr 15, 2012 at 1:06 PM, Yinghai Lu 
>> wrote:
 3. use pci_bus_allocate_resource in drm/radeon driver ...
 ===> but that could fail. so could hack it like a. disable
 bar 0x10 and steal BAR address, then set 0x30 to that address
 then copy ROM to ram. after that, disable rom again and set
 back address to 0x10. You try to update radeon_get_bios() to
 achieve that.
>> 
>> patches for solution 3: map_rom.patch will try to borrow mem or
>> mem pref bar for ROM copying
>> 
>> and You still need to use pci=norom
> 
> map_rom.patch missed one !
> 
> Please check map_rom_v2.patch
> 
Hopefully, I'm going to have time to look into this again later today,
depending how well other tasks go...
-BEGIN PGP SIGNATURE-
Version: GnuPG v2.0.19 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAk+WdwwACgkQGcb56gMuC62DgQCglk+MxOIxWxbLChNWNlAOdbSp
tysAnA83Mfa6tZ6TC97xHIqpFqtPJ5Wc
=Vd8+
-END PGP SIGNATURE-


[Bug 43138] Radeon HD5450 fails to load cedar firmware ?

2012-04-24 Thread bugzilla-dae...@bugzilla.kernel.org
https://bugzilla.kernel.org/show_bug.cgi?id=43138


bugtraq at hobbit.in-berlin.de changed:

   What|Removed |Added

 Resolution|CODE_FIX|INVALID




-- 
Configure bugmail: https://bugzilla.kernel.org/userprefs.cgi?tab=email
--- You are receiving this mail because: ---
You are watching the assignee of the bug.


[Bug 43138] Radeon HD5450 fails to load cedar firmware ?

2012-04-24 Thread bugzilla-dae...@bugzilla.kernel.org
https://bugzilla.kernel.org/show_bug.cgi?id=43138


bugtraq at hobbit.in-berlin.de changed:

   What|Removed |Added

 Status|NEW |RESOLVED
 Resolution||CODE_FIX




--- Comment #10 from bugtraq at hobbit.in-berlin.de  2012-04-24 10:17:27 ---
stupid me should've checked this beforehand,
very sorry for having wasted your time & thanks for your patience...

...nope, as Debian considers that particular firmware to be "nonfree" it is not
included in the initrd at all, so it boils down to a somewhat misleading "bogus
length" instead of a more appropriate "file not found" error for all cases
above.

issue solved.

-- 
Configure bugmail: https://bugzilla.kernel.org/userprefs.cgi?tab=email
--- You are receiving this mail because: ---
You are watching the assignee of the bug.


Re: [PATCH] dma-buf: mmap support

2012-04-24 Thread Daniel Vetter
On Wed, Apr 25, 2012 at 01:37:51AM +0900, InKi Dae wrote:
> Hi,
> 
> >
> > +static int dma_buf_mmap_internal(struct file *file, struct vm_area_struct 
> > *vma)
> > +{
> > +       struct dma_buf *dmabuf;
> > +
> > +       if (!is_dma_buf_file(file))
> > +               return -EINVAL;
> > +
> > +       dmabuf = file->private_data;
> > +
> > +       /* check for overflowing the buffer's size */
> > +       if (vma->vm_pgoff + ((vma->vm_end - vma->vm_start) >> PAGE_SHIFT) >
> > +           dmabuf->size >> PAGE_SHIFT)
> 
> is this condition right? your intention is for checking buffer's size
> is valid or not. by the way why is vma->vm_pgoff added to vm region
> size?

This check here is to ensure that userspace cannot mmap beyong the end of
the dma_buf object. vm_pgoff is the offset userspace passed in at mmap
time and hence needs to be added. Note that vm_end and vm_start are in
bytes, wheres vm_pgoff is in pages.

> > +               return -EINVAL;
> > +
> > +       return dmabuf->ops->mmap(dmabuf, vma);
> > +}
> > +
> >  static const struct file_operations dma_buf_fops = {
> >        .release        = dma_buf_release,
> > +       .mmap           = dma_buf_mmap_internal,
> >  };
> >
> >  /*
> > @@ -82,7 +100,8 @@ struct dma_buf *dma_buf_export(void *priv, const struct 
> > dma_buf_ops *ops,
> >                          || !ops->unmap_dma_buf
> >                          || !ops->release
> >                          || !ops->kmap_atomic
> > -                         || !ops->kmap)) {
> > +                         || !ops->kmap
> > +                         || !ops->mmap)) {
> >                return ERR_PTR(-EINVAL);
> >        }
> >
> > @@ -406,3 +425,46 @@ void dma_buf_kunmap(struct dma_buf *dmabuf, unsigned 
> > long page_num,
> >                dmabuf->ops->kunmap(dmabuf, page_num, vaddr);
> >  }
> >  EXPORT_SYMBOL_GPL(dma_buf_kunmap);
> > +
> > +
> > +/**
> > + * dma_buf_mmap - Setup up a userspace mmap with the given vma
> > + * @dma_buf:   [in]    buffer that should back the vma
> > + * @vma:       [in]    vma for the mmap
> > + * @pgoff:     [in]    offset in pages where this mmap should start within 
> > the
> > + *                     dma-buf buffer.
> > + *
> > + * This function adjusts the passed in vma so that it points at the file 
> > of the
> > + * dma_buf operation. It alsog adjusts the starting pgoff and does bounds
> > + * checking on the size of the vma. Then it calls the exporters mmap 
> > function to
> > + * set up the mapping.
> > + *
> > + * Can return negative error values, returns 0 on success.
> > + */
> > +int dma_buf_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma,
> > +                unsigned long pgoff)
> > +{
> > +       if (WARN_ON(!dmabuf || !vma))
> > +               return -EINVAL;
> > +
> > +       /* check for offset overflow */
> > +       if (pgoff + ((vma->vm_end - vma->vm_start) >> PAGE_SHIFT) < pgoff)
> 
> ditto. isn't it checked whether page offset to be mmaped is placed
> within vm region or not with the condition, if ((vma->vm_end -
> vma->vm_start) >> PAGE_SHIFT) < pgoff)?

Nope, this check only checks for overflow. The pgoff is the offset within
the dma_buf object. E.g. a drm driver splits up it mmap space into pieces,
which map to individual buffers. If userspace just mmaps parts of such a
buffer, the importer can pass the offset in pgoff. But I expect this to be
0 for almost all cases.

Note that we don't need this overflow check in the internal mmap function
because do_mmap will do it for us. But here the importer potentially sets
a completely different pgoff, so we need to do it. dma_buf documentation
also mentions this (and that importers do not have to do these checks).

Yours, Daniel

> 
> > +               return -EOVERFLOW;
> > +
> > +       /* check for overflowing the buffer's size */
> > +       if (pgoff + ((vma->vm_end - vma->vm_start) >> PAGE_SHIFT) >
> > +           dmabuf->size >> PAGE_SHIFT)
> > +               return -EINVAL;
> > +
> > +       /* readjust the vma */
> > +       if (vma->vm_file)
> > +               fput(vma->vm_file);
> > +
> > +       vma->vm_file = dmabuf->file;
> > +       get_file(vma->vm_file);
> > +
> > +       vma->vm_pgoff = pgoff;
> > +
> > +       return dmabuf->ops->mmap(dmabuf, vma);
> > +}
> > +EXPORT_SYMBOL_GPL(dma_buf_mmap);
> > diff --git a/include/linux/dma-buf.h b/include/linux/dma-buf.h
> > index 3efbfc2..1f78d15 100644
> > --- a/include/linux/dma-buf.h
> > +++ b/include/linux/dma-buf.h
> > @@ -61,6 +61,10 @@ struct dma_buf_attachment;
> >  *                This Callback must not sleep.
> >  * @kmap: maps a page from the buffer into kernel address space.
> >  * @kunmap: [optional] unmaps a page from the buffer.
> > + * @mmap: used to expose the backing storage to userspace. Note that the
> > + *       mapping needs to be coherent - if the exporter doesn't directly
> > + *       support this, it needs to fake coherency by shooting down any ptes
> > + *       when transitioning away from the cpu d

state of drm next

2012-04-24 Thread Dave Airlie
On Fri, Apr 20, 2012 at 10:10 PM, Alex Deucher  wrote:
> On Fri, Apr 20, 2012 at 8:27 AM, Dave Airlie  wrote:
>> Hi,
>>
>> So I've spent today trawling and most likely missing patches on the
>> list for -next.
>>
>> -next before today had:
>> an intel -next from Daniel
>> radeon - copy optimisation, pci bus master race fix.
>> two agp patches
>>
>> I've merged today into drm-core-next
>> Ville's framebuffer creation sanity check series
>> Paulo's CEA/EDID patches that touch core (I think there are two i915
>> patches that can come via Daniel).
>> Lars-Peter Clausen: CEA/EDID patches
>> Ajax's: DMT modes adding patches
>>
>> I've also got in -next:
>> mjg59's work on multiple gpu with EFI interactions, I'll push to
>> -core-next once it stops breaking builds on misc arches!
>>
>> So feel free to point me at anything I've missed or haven't commented
>> on, and everyone keep reviewing everyone else's stuff as a path to
>> success, as I'm busy!!
>
> Can you pick the following patches?
> http://lists.freedesktop.org/archives/dri-devel/2012-March/020577.html
> http://lists.freedesktop.org/archives/dri-devel/2012-March/020717.html
> http://lists.freedesktop.org/archives/dri-devel/2012-March/020855.html

I've merged these 3 to drm-core-next.

Dave.


[Bug 27563] [810] Xorg freezes sometimes when playing Crack-Attack (races in drivers/char/drm/drm.ko?)

2012-04-24 Thread bugzilla-dae...@freedesktop.org
https://bugs.freedesktop.org/show_bug.cgi?id=27563

Daniel Vetter  changed:

   What|Removed |Added

 Status|NEW |RESOLVED
 Resolution||WONTFIX

--- Comment #6 from Daniel Vetter  2012-04-24 02:56:15 PDT 
---
I've looked a few times into the i810 drm kernel driver to clean up various
things all accross drm, and the code in there is horrible. It is so horrible
that you stop caring about race conditions you noticed after reading just a few
functions of code ... :(

Given that, I think the only way to fix this disaster is to rewrite the i810
support as a new, clean kernel modeset driver. That needs a volunteer with too
much time. Hence I'll close this as wontfix. Sorry.

-- 
Configure bugmail: https://bugs.freedesktop.org/userprefs.cgi?tab=email
--- You are receiving this mail because: ---
You are the assignee for the bug.


Re: [PATCH] dma-buf: mmap support

2012-04-24 Thread InKi Dae
Hi,

>
> +static int dma_buf_mmap_internal(struct file *file, struct vm_area_struct 
> *vma)
> +{
> +       struct dma_buf *dmabuf;
> +
> +       if (!is_dma_buf_file(file))
> +               return -EINVAL;
> +
> +       dmabuf = file->private_data;
> +
> +       /* check for overflowing the buffer's size */
> +       if (vma->vm_pgoff + ((vma->vm_end - vma->vm_start) >> PAGE_SHIFT) >
> +           dmabuf->size >> PAGE_SHIFT)

is this condition right? your intention is for checking buffer's size
is valid or not. by the way why is vma->vm_pgoff added to vm region
size?

> +               return -EINVAL;
> +
> +       return dmabuf->ops->mmap(dmabuf, vma);
> +}
> +
>  static const struct file_operations dma_buf_fops = {
>        .release        = dma_buf_release,
> +       .mmap           = dma_buf_mmap_internal,
>  };
>
>  /*
> @@ -82,7 +100,8 @@ struct dma_buf *dma_buf_export(void *priv, const struct 
> dma_buf_ops *ops,
>                          || !ops->unmap_dma_buf
>                          || !ops->release
>                          || !ops->kmap_atomic
> -                         || !ops->kmap)) {
> +                         || !ops->kmap
> +                         || !ops->mmap)) {
>                return ERR_PTR(-EINVAL);
>        }
>
> @@ -406,3 +425,46 @@ void dma_buf_kunmap(struct dma_buf *dmabuf, unsigned 
> long page_num,
>                dmabuf->ops->kunmap(dmabuf, page_num, vaddr);
>  }
>  EXPORT_SYMBOL_GPL(dma_buf_kunmap);
> +
> +
> +/**
> + * dma_buf_mmap - Setup up a userspace mmap with the given vma
> + * @dma_buf:   [in]    buffer that should back the vma
> + * @vma:       [in]    vma for the mmap
> + * @pgoff:     [in]    offset in pages where this mmap should start within 
> the
> + *                     dma-buf buffer.
> + *
> + * This function adjusts the passed in vma so that it points at the file of 
> the
> + * dma_buf operation. It alsog adjusts the starting pgoff and does bounds
> + * checking on the size of the vma. Then it calls the exporters mmap 
> function to
> + * set up the mapping.
> + *
> + * Can return negative error values, returns 0 on success.
> + */
> +int dma_buf_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma,
> +                unsigned long pgoff)
> +{
> +       if (WARN_ON(!dmabuf || !vma))
> +               return -EINVAL;
> +
> +       /* check for offset overflow */
> +       if (pgoff + ((vma->vm_end - vma->vm_start) >> PAGE_SHIFT) < pgoff)

ditto. isn't it checked whether page offset to be mmaped is placed
within vm region or not with the condition, if ((vma->vm_end -
vma->vm_start) >> PAGE_SHIFT) < pgoff)?

> +               return -EOVERFLOW;
> +
> +       /* check for overflowing the buffer's size */
> +       if (pgoff + ((vma->vm_end - vma->vm_start) >> PAGE_SHIFT) >
> +           dmabuf->size >> PAGE_SHIFT)
> +               return -EINVAL;
> +
> +       /* readjust the vma */
> +       if (vma->vm_file)
> +               fput(vma->vm_file);
> +
> +       vma->vm_file = dmabuf->file;
> +       get_file(vma->vm_file);
> +
> +       vma->vm_pgoff = pgoff;
> +
> +       return dmabuf->ops->mmap(dmabuf, vma);
> +}
> +EXPORT_SYMBOL_GPL(dma_buf_mmap);
> diff --git a/include/linux/dma-buf.h b/include/linux/dma-buf.h
> index 3efbfc2..1f78d15 100644
> --- a/include/linux/dma-buf.h
> +++ b/include/linux/dma-buf.h
> @@ -61,6 +61,10 @@ struct dma_buf_attachment;
>  *                This Callback must not sleep.
>  * @kmap: maps a page from the buffer into kernel address space.
>  * @kunmap: [optional] unmaps a page from the buffer.
> + * @mmap: used to expose the backing storage to userspace. Note that the
> + *       mapping needs to be coherent - if the exporter doesn't directly
> + *       support this, it needs to fake coherency by shooting down any ptes
> + *       when transitioning away from the cpu domain.
>  */
>  struct dma_buf_ops {
>        int (*attach)(struct dma_buf *, struct device *,
> @@ -92,6 +96,8 @@ struct dma_buf_ops {
>        void (*kunmap_atomic)(struct dma_buf *, unsigned long, void *);
>        void *(*kmap)(struct dma_buf *, unsigned long);
>        void (*kunmap)(struct dma_buf *, unsigned long, void *);
> +
> +       int (*mmap)(struct dma_buf *, struct vm_area_struct *vma);
>  };
>
>  /**
> @@ -167,6 +173,9 @@ void *dma_buf_kmap_atomic(struct dma_buf *, unsigned 
> long);
>  void dma_buf_kunmap_atomic(struct dma_buf *, unsigned long, void *);
>  void *dma_buf_kmap(struct dma_buf *, unsigned long);
>  void dma_buf_kunmap(struct dma_buf *, unsigned long, void *);
> +
> +int dma_buf_mmap(struct dma_buf *, struct vm_area_struct *,
> +                unsigned long);
>  #else
>
>  static inline struct dma_buf_attachment *dma_buf_attach(struct dma_buf 
> *dmabuf,
> @@ -248,6 +257,13 @@ static inline void dma_buf_kunmap(struct dma_buf *dmabuf,
>                                  unsigned long pnum, void *vaddr)
>  {
>  }
> +
> +static inline int dma_buf_mmap(struct dma_buf *dmabuf,
> +                              struct vm_ar

[Bug 30654] [855] flickers when vblank_mode is enabled

2012-04-24 Thread bugzilla-dae...@freedesktop.org
https://bugs.freedesktop.org/show_bug.cgi?id=30654

Chris Wilson  changed:

   What|Removed |Added

 Status|REOPENED|RESOLVED
 Resolution||FIXED

--- Comment #17 from Chris Wilson  2012-04-24 
02:11:18 PDT ---
I believe this will be fixed with:

commit 8fa2a569d3fb6ea78b83c6062b2f3aec528cc9e5
Author: Chris Wilson 
Date:   Sun Apr 22 21:13:57 2012 +0100

drm/i915: i8xx interrupt handler

gen2 hardware has some significant differences from the other interrupt
routines that were glossed over and then forgotten about in the
transition to KMS. Such as

- 16bit IIR
- PendingFlip status bit

This patch reintroduces a handler specifically for gen2 for the purpose
of handling pageflips correctly, simplifying code in the process.

v2: Also fixup ring get/put irq to only access 16bit registers (Daniel)

Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=24202
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=41793
Signed-off-by: Chris Wilson 
Signed-off-by: Daniel Vetter 

-- 
Configure bugmail: https://bugs.freedesktop.org/userprefs.cgi?tab=email
--- You are receiving this mail because: ---
You are the assignee for the bug.


[PATCH 6/6] gma500: Set the mapping mask

2012-04-24 Thread Alan Cox
From: Alan Cox 

Some boards such as the Intel D2700MUD allow you to have over 4GB of RAM.
The GTT on the PVR based devices is 32bit however. Hugh Dickins points out
that we should therefore be setting the mapping gfp mask.

This is not the whole fix for the problem. Some further shmem patches will
be needed to deal with the corner cases.

Signed-off-by: Alan Cox 
---

 drivers/gpu/drm/gma500/gem.c |2 ++
 drivers/gpu/drm/gma500/gtt.c |4 
 2 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/drivers/gpu/drm/gma500/gem.c b/drivers/gpu/drm/gma500/gem.c
index 9fbb868..fc7d144 100644
--- a/drivers/gpu/drm/gma500/gem.c
+++ b/drivers/gpu/drm/gma500/gem.c
@@ -124,6 +124,8 @@ static int psb_gem_create(struct drm_file *file,
dev_err(dev->dev, "GEM init failed for %lld\n", size);
return -ENOMEM;
}
+   /* Limit the object to 32bit mappings */
+   mapping_set_gfp_mask(r->gem.filp->f_mapping, GFP_KERNEL | __GFP_DMA32);
/* Give the object a handle so we can carry it more easily */
ret = drm_gem_handle_create(file, &r->gem, &handle);
if (ret) {
diff --git a/drivers/gpu/drm/gma500/gtt.c b/drivers/gpu/drm/gma500/gtt.c
index db2e823..54e5c9e 100644
--- a/drivers/gpu/drm/gma500/gtt.c
+++ b/drivers/gpu/drm/gma500/gtt.c
@@ -39,6 +39,10 @@ static inline uint32_t psb_gtt_mask_pte(uint32_t pfn, int 
type)
 {
uint32_t mask = PSB_PTE_VALID;
 
+   /* Ensure we explode rather than put an invalid low mapping of
+  a high mapping page into the gtt */
+   BUG_ON(pfn & ~(0x >> PAGE_SHIFT));
+
if (type & PSB_MMU_CACHED_MEMORY)
mask |= PSB_PTE_CACHED;
if (type & PSB_MMU_RO_MEMORY)

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 5/6] gma500: Add ops for hotplug support.

2012-04-24 Thread Alan Cox
From: Alan Cox 

This provides the needed callback hooks to add hotplug display support to
the GMA36x0 devices. 

[The actual enabling device part will follow once I've figured out why it
 breaks suspend/resume on some netbooks]

Signed-off-by: Alan Cox 
---

 drivers/gpu/drm/gma500/psb_drv.h |3 +++
 drivers/gpu/drm/gma500/psb_irq.c |   36 +++-
 2 files changed, 30 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/gma500/psb_drv.h b/drivers/gpu/drm/gma500/psb_drv.h
index 6235499..ab483c3 100644
--- a/drivers/gpu/drm/gma500/psb_drv.h
+++ b/drivers/gpu/drm/gma500/psb_drv.h
@@ -130,6 +130,7 @@ enum {
 #define _PSB_VSYNC_PIPEA_FLAG(1<<7)
 #define _MDFLD_MIPIA_FLAG(1<<16)
 #define _MDFLD_MIPIC_FLAG(1<<17)
+#define _PSB_IRQ_DISP_HOTSYNC(1<<17)
 #define _PSB_IRQ_SGX_FLAG(1<<18)
 #define _PSB_IRQ_MSVDX_FLAG  (1<<19)
 #define _LNC_IRQ_TOPAZ_FLAG  (1<<20)
@@ -703,6 +704,8 @@ struct psb_ops {
 
/* Display management hooks */
int (*output_init)(struct drm_device *dev);
+   int (*hotplug)(struct drm_device *dev);
+   void (*hotplug_enable)(struct drm_device *dev, bool on);
/* Power management hooks */
void (*init_pm)(struct drm_device *dev);
int (*save_regs)(struct drm_device *dev);
diff --git a/drivers/gpu/drm/gma500/psb_irq.c b/drivers/gpu/drm/gma500/psb_irq.c
index 1869586..4f31312 100644
--- a/drivers/gpu/drm/gma500/psb_irq.c
+++ b/drivers/gpu/drm/gma500/psb_irq.c
@@ -199,11 +199,9 @@ static void psb_vdc_interrupt(struct drm_device *dev, 
uint32_t vdc_stat)
 
 irqreturn_t psb_irq_handler(DRM_IRQ_ARGS)
 {
-   struct drm_device *dev = (struct drm_device *) arg;
-   struct drm_psb_private *dev_priv =
-   (struct drm_psb_private *) dev->dev_private;
-
-   uint32_t vdc_stat, dsp_int = 0, sgx_int = 0;
+   struct drm_device *dev = arg;
+   struct drm_psb_private *dev_priv = dev->dev_private;
+   uint32_t vdc_stat, dsp_int = 0, sgx_int = 0, hotplug_int = 0;
int handled = 0;
 
spin_lock(&dev_priv->irqmask_lock);
@@ -220,6 +218,8 @@ irqreturn_t psb_irq_handler(DRM_IRQ_ARGS)
 
if (vdc_stat & _PSB_IRQ_SGX_FLAG)
sgx_int = 1;
+   if (vdc_stat & _PSB_IRQ_DISP_HOTSYNC)
+   hotplug_int = 1;
 
vdc_stat &= dev_priv->vdc_irq_mask;
spin_unlock(&dev_priv->irqmask_lock);
@@ -241,6 +241,13 @@ irqreturn_t psb_irq_handler(DRM_IRQ_ARGS)
handled = 1;
}
 
+   /* Note: this bit has other meanings on some devices, so we will
+  need to address that later if it ever matters */
+   if (hotplug_int && dev_priv->ops->hotplug) {
+   handled = dev_priv->ops->hotplug(dev);
+   REG_WRITE(PORT_HOTPLUG_STAT, REG_READ(PORT_HOTPLUG_STAT));
+   }
+
PSB_WVDC32(vdc_stat, PSB_INT_IDENTITY_R);
(void) PSB_RVDC32(PSB_INT_IDENTITY_R);
DRM_READMEMORYBARRIER();
@@ -273,6 +280,10 @@ void psb_irq_preinstall(struct drm_device *dev)
dev_priv->vdc_irq_mask |= _MDFLD_PIPEC_EVENT_FLAG;
*/
 
+   /* Revisit this area - want per device masks ? */
+   if (dev_priv->ops->hotplug)
+   dev_priv->vdc_irq_mask |= _PSB_IRQ_DISP_HOTSYNC;
+
/* This register is safe even if display island is off */
PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R);
spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);
@@ -305,18 +316,25 @@ int psb_irq_postinstall(struct drm_device *dev)
else
psb_disable_pipestat(dev_priv, 2, PIPE_VBLANK_INTERRUPT_ENABLE);
 
+   if (dev_priv->ops->hotplug_enable)
+   dev_priv->ops->hotplug_enable(dev, true);
+
spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);
return 0;
 }
 
 void psb_irq_uninstall(struct drm_device *dev)
 {
-   struct drm_psb_private *dev_priv =
-   (struct drm_psb_private *) dev->dev_private;
+   struct drm_psb_private *dev_priv = dev->dev_private;
unsigned long irqflags;
 
spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);
 
+   if (dev_priv->ops->hotplug_enable) {
+   dev_priv->ops->hotplug_enable(dev, false);
+   dev_priv->vdc_irq_mask &= ~_PSB_IRQ_DISP_HOTSYNC;
+   }
+
PSB_WVDC32(0x, PSB_HWSTAM);
 
if (dev->vblank_enabled[0])
@@ -328,9 +346,9 @@ void psb_irq_uninstall(struct drm_device *dev)
if (dev->vblank_enabled[2])
psb_disable_pipestat(dev_priv, 2, PIPE_VBLANK_INTERRUPT_ENABLE);
 
-   dev_priv->vdc_irq_mask &= _PSB_IRQ_SGX_FLAG |
+   dev_priv->vdc_irq_mask &= ~(_PSB_IRQ_SGX_FLAG |
  _PSB_IRQ_MSVDX_FLAG |
- _LNC_IRQ_TOPAZ_FLAG;
+ _LNC_IRQ_TOPAZ_FLAG);
 
/* These two registers are safe even if display island is off */
PSB_WVDC32(~dev_priv->vdc_irq_mask, PS

[PATCH 4/6] gma500: implement backlight functionality for Cedartrail devices

2012-04-24 Thread Alan Cox
From: Alan Cox 

Basically a straight cut/paste from the reference driver code then
cleaned up a spot.

Signed-off-by: Alan Cox 
---

 drivers/gpu/drm/gma500/cdv_device.c |  113 ---
 1 files changed, 51 insertions(+), 62 deletions(-)

diff --git a/drivers/gpu/drm/gma500/cdv_device.c 
b/drivers/gpu/drm/gma500/cdv_device.c
index 5cc06a8..292bcec 100644
--- a/drivers/gpu/drm/gma500/cdv_device.c
+++ b/drivers/gpu/drm/gma500/cdv_device.c
@@ -57,8 +57,7 @@ static int cdv_output_init(struct drm_device *dev)
cdv_intel_crt_init(dev, &dev_priv->mode_dev);
cdv_intel_lvds_init(dev, &dev_priv->mode_dev);
 
-   /* These bits indicate HDMI not SDVO on CDV, but we don't yet support
-  the HDMI interface */
+   /* These bits indicate HDMI not SDVO on CDV */
if (REG_READ(SDVOB) & SDVO_DETECTED)
cdv_hdmi_init(dev, &dev_priv->mode_dev, SDVOB);
if (REG_READ(SDVOC) & SDVO_DETECTED)
@@ -69,76 +68,71 @@ static int cdv_output_init(struct drm_device *dev)
 #ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
 
 /*
- * Poulsbo Backlight Interfaces
+ * Cedartrail Backlght Interfaces
  */
 
-#define BLC_PWM_PRECISION_FACTOR 100   /* 1000 */
-#define BLC_PWM_FREQ_CALC_CONSTANT 32
-#define MHz 100
-
-#define PSB_BLC_PWM_PRECISION_FACTOR10
-#define PSB_BLC_MAX_PWM_REG_FREQ0xFFFE
-#define PSB_BLC_MIN_PWM_REG_FREQ0x2
-
-#define PSB_BACKLIGHT_PWM_POLARITY_BIT_CLEAR (0xFFFE)
-#define PSB_BACKLIGHT_PWM_CTL_SHIFT(16)
-
-static int cdv_brightness;
 static struct backlight_device *cdv_backlight_device;
 
-static int cdv_get_brightness(struct backlight_device *bd)
+static int cdv_backlight_combination_mode(struct drm_device *dev)
 {
-   /* return locally cached var instead of HW read (due to DPST etc.) */
-   /* FIXME: ideally return actual value in case firmware fiddled with
-  it */
-   return cdv_brightness;
+   return REG_READ(BLC_PWM_CTL2) & PWM_LEGACY_MODE;
 }
 
-
-static int cdv_backlight_setup(struct drm_device *dev)
+static int cdv_get_brightness(struct backlight_device *bd)
 {
-   struct drm_psb_private *dev_priv = dev->dev_private;
-   unsigned long core_clock;
-   /* u32 bl_max_freq; */
-   /* unsigned long value; */
-   u16 bl_max_freq;
-   uint32_t value;
-   uint32_t blc_pwm_precision_factor;
-
-   /* get bl_max_freq and pol from dev_priv*/
-   if (!dev_priv->lvds_bl) {
-   dev_err(dev->dev, "Has no valid LVDS backlight info\n");
-   return -ENOENT;
-   }
-   bl_max_freq = dev_priv->lvds_bl->freq;
-   blc_pwm_precision_factor = PSB_BLC_PWM_PRECISION_FACTOR;
+   struct drm_device *dev = bl_get_data(bd);
+   u32 val = REG_READ(BLC_PWM_CTL) & BACKLIGHT_DUTY_CYCLE_MASK;
 
-   core_clock = dev_priv->core_freq;
+   if (cdv_backlight_combination_mode(dev)) {
+   u8 lbpc;
 
-   value = (core_clock * MHz) / BLC_PWM_FREQ_CALC_CONSTANT;
-   value *= blc_pwm_precision_factor;
-   value /= bl_max_freq;
-   value /= blc_pwm_precision_factor;
+   val &= ~1;
+   pci_read_config_byte(dev->pdev, 0xF4, &lbpc);
+   val *= lbpc;
+   }
+   return val;
+}
 
-   if (value > (unsigned long long)PSB_BLC_MAX_PWM_REG_FREQ ||
-value < (unsigned long long)PSB_BLC_MIN_PWM_REG_FREQ)
-   return -ERANGE;
-   else {
-   /* FIXME */
+static u32 cdv_get_max_backlight(struct drm_device *dev)
+{
+   u32 max = REG_READ(BLC_PWM_CTL);
+
+   if (max == 0) {
+   DRM_DEBUG_KMS("LVDS Panel PWM value is 0!\n");
+   /* i915 does this, I believe which means that we should not
+* smash PWM control as firmware will take control of it. */
+   return 1;
}
-   return 0;
+
+   max >>= 16;
+   if (cdv_backlight_combination_mode(dev))
+   max *= 0xff;
+   return max;
 }
 
 static int cdv_set_brightness(struct backlight_device *bd)
 {
+   struct drm_device *dev = bl_get_data(bd);
int level = bd->props.brightness;
+   u32 blc_pwm_ctl;
 
/* Percentage 1-100% being valid */
if (level < 1)
level = 1;
 
-   /*cdv_intel_lvds_set_brightness(dev, level); FIXME */
-   cdv_brightness = level;
+   if (cdv_backlight_combination_mode(dev)) {
+   u32 max = cdv_get_max_backlight(dev);
+   u8 lbpc;
+
+   lbpc = level * 0xfe / max + 1;
+   level /= lbpc;
+
+   pci_write_config_byte(dev->pdev, 0xF4, lbpc);
+   }
+
+   blc_pwm_ctl = REG_READ(BLC_PWM_CTL) & ~BACKLIGHT_DUTY_CYCLE_MASK;
+   REG_WRITE(BLC_PWM_CTL, (blc_pwm_ctl |
+   (level << BACKLIGHT_DUTY_CYCLE_SHIFT)));
return 0;
 }
 
@@ -150,7 +144,6 @@ static const struct backlight_ops cdv_ops = {
 static int cdv_backlight_init(struct d

[PATCH 3/6] cdv: continue synching up with updated reference code

2012-04-24 Thread Alan Cox
From: Alan Cox 

In particular clean up the errata handling and correct the crtc masks. We do
this a bit differently using our device abstraction for neatness.

This doesn't address the ACPI opregion and hotplug plumbing, nor the IRQ related
changes that will need. It touches on backlight init but the full backlight
support is not in this change set.

Signed-off-by: Alan Cox 
---

 drivers/gpu/drm/gma500/cdv_device.c|   20 +
 drivers/gpu/drm/gma500/cdv_intel_crt.c |   20 +++--
 drivers/gpu/drm/gma500/cdv_intel_display.c |   61 
 drivers/gpu/drm/gma500/cdv_intel_lvds.c|   17 
 drivers/gpu/drm/gma500/framebuffer.c   |   13 ++
 drivers/gpu/drm/gma500/mdfld_device.c  |2 +
 drivers/gpu/drm/gma500/oaktrail_device.c   |2 +
 drivers/gpu/drm/gma500/psb_device.c|2 +
 drivers/gpu/drm/gma500/psb_drv.h   |4 ++
 drivers/gpu/drm/gma500/psb_intel_reg.h |4 ++
 10 files changed, 89 insertions(+), 56 deletions(-)

diff --git a/drivers/gpu/drm/gma500/cdv_device.c 
b/drivers/gpu/drm/gma500/cdv_device.c
index a54cc73..5cc06a8 100644
--- a/drivers/gpu/drm/gma500/cdv_device.c
+++ b/drivers/gpu/drm/gma500/cdv_device.c
@@ -49,6 +49,9 @@ static void cdv_disable_vga(struct drm_device *dev)
 static int cdv_output_init(struct drm_device *dev)
 {
struct drm_psb_private *dev_priv = dev->dev_private;
+
+   drm_mode_create_scaling_mode_property(dev);
+
cdv_disable_vga(dev);
 
cdv_intel_crt_init(dev, &dev_priv->mode_dev);
@@ -238,6 +241,18 @@ static void cdv_init_pm(struct drm_device *dev)
dev_err(dev->dev, "GPU: power management timed out.\n");
 }
 
+static void cdv_errata(struct drm_device *dev)
+{
+   /* Disable bonus launch.
+*  CPU and GPU competes for memory and display misses updates and 
flickers.
+*  Worst with dual core, dual displays.
+*
+*  Fixes were done to Win 7 gfx driver to disable a feature called 
Bonus
+*  Launch to work around the issue, by degrading performance.
+*/
+CDV_MSG_WRITE32(3, 0x30, 0x08027108);
+}
+
 /**
  * cdv_save_display_registers  -   save registers lost on suspend
  * @dev: our DRM device
@@ -355,7 +370,7 @@ static int cdv_restore_display_registers(struct drm_device 
*dev)
REG_WRITE(PSB_INT_MASK_R, regs->cdv.saveIMR);
 
/* Fix arbitration bug */
-   CDV_MSG_WRITE32(3, 0x30, 0x08027108);
+   cdv_errata(dev);
 
drm_mode_config_reset(dev);
 
@@ -464,8 +479,11 @@ const struct psb_ops cdv_chip_ops = {
.accel_2d = 0,
.pipes = 2,
.crtcs = 2,
+   .hdmi_mask = (1 << 0) | (1 << 1),
+   .lvds_mask = (1 << 1),
.sgx_offset = MRST_SGX_OFFSET,
.chip_setup = cdv_chip_setup,
+   .errata = cdv_errata,
 
.crtc_helper = &cdv_intel_helper_funcs,
.crtc_funcs = &cdv_intel_crtc_funcs,
diff --git a/drivers/gpu/drm/gma500/cdv_intel_crt.c 
b/drivers/gpu/drm/gma500/cdv_intel_crt.c
index 1a82843..1874220 100644
--- a/drivers/gpu/drm/gma500/cdv_intel_crt.c
+++ b/drivers/gpu/drm/gma500/cdv_intel_crt.c
@@ -78,9 +78,6 @@ static int cdv_intel_crt_mode_valid(struct drm_connector 
*connector,
if (mode->clock > 355000)
return MODE_CLOCK_HIGH;
 
-   if (mode->hdisplay > 1680 || mode->vdisplay > 1050)
-   return MODE_PANEL;
-
return MODE_OK;
 }
 
@@ -148,13 +145,7 @@ static bool cdv_intel_crt_detect_hotplug(struct 
drm_connector *connector,
struct drm_device *dev = connector->dev;
u32 hotplug_en;
int i, tries = 0, ret = false;
-   u32 adpa_orig;
-
-   /* disable the DAC when doing the hotplug detection */
-
-   adpa_orig = REG_READ(ADPA);
-
-   REG_WRITE(ADPA, adpa_orig & ~(ADPA_DAC_ENABLE));
+   u32 orig;
 
/*
 * On a CDV thep, CRT detect sequence need to be done twice
@@ -162,7 +153,7 @@ static bool cdv_intel_crt_detect_hotplug(struct 
drm_connector *connector,
 */
tries = 2;
 
-   hotplug_en = REG_READ(PORT_HOTPLUG_EN);
+   orig = hotplug_en = REG_READ(PORT_HOTPLUG_EN);
hotplug_en &= ~(CRT_HOTPLUG_DETECT_MASK);
hotplug_en |= CRT_HOTPLUG_FORCE_DETECT;
 
@@ -187,8 +178,11 @@ static bool cdv_intel_crt_detect_hotplug(struct 
drm_connector *connector,
CRT_HOTPLUG_MONITOR_NONE)
ret = true;
 
-   /* Restore the saved ADPA */
-   REG_WRITE(ADPA, adpa_orig);
+/* clear the interrupt we just generated, if any */
+   REG_WRITE(PORT_HOTPLUG_STAT, CRT_HOTPLUG_INT_STATUS);
+
+   /* and put the bits back */
+   REG_WRITE(PORT_HOTPLUG_EN, orig);
return ret;
 }
 
diff --git a/drivers/gpu/drm/gma500/cdv_intel_display.c 
b/drivers/gpu/drm/gma500/cdv_intel_display.c
index 07b37f5..2fab778 100644
--- a/drivers/gpu/drm/gma500/cdv_intel_display.c
+++ b/drivers/gpu/drm/gma500/cdv_intel_display.c
@@ -226,13 +226,13 @@ 

[PATCH 2/6] gma500: Clean up weirdness in the cdv mode test code

2012-04-24 Thread Alan Cox
From: Alan Cox 

Signed-off-by: Alan Cox 
---

 drivers/gpu/drm/gma500/cdv_intel_crt.c |4 +---
 1 files changed, 1 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/gma500/cdv_intel_crt.c 
b/drivers/gpu/drm/gma500/cdv_intel_crt.c
index 1de27c7..1a82843 100644
--- a/drivers/gpu/drm/gma500/cdv_intel_crt.c
+++ b/drivers/gpu/drm/gma500/cdv_intel_crt.c
@@ -67,7 +67,6 @@ static void cdv_intel_crt_dpms(struct drm_encoder *encoder, 
int mode)
 static int cdv_intel_crt_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode)
 {
-   int max_clock = 0;
if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
return MODE_NO_DBLESCAN;
 
@@ -76,8 +75,7 @@ static int cdv_intel_crt_mode_valid(struct drm_connector 
*connector,
return MODE_CLOCK_LOW;
 
/* The max clock for CDV is 355 instead of 400 */
-   max_clock = 355000;
-   if (mode->clock > max_clock)
+   if (mode->clock > 355000)
return MODE_CLOCK_HIGH;
 
if (mode->hdisplay > 1680 || mode->vdisplay > 1050)

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 1/6] gma500: support 1080p

2012-04-24 Thread Alan Cox
From: Alan Cox 

The problem in console mode is lack of linear memory. We can solve that by
dropping to 16bpp. The mode setting X server will allocate its own GEM
framebuffer in 32bpp and all will be well.

We could just do 16bpp anyway but that would be a regression on the lower
modes as many distributions don't yet ship the generic mode setting KMS
drivers.

Signed-off-by: Alan Cox 
---

 drivers/gpu/drm/gma500/cdv_intel_crt.c  |6 --
 drivers/gpu/drm/gma500/cdv_intel_hdmi.c |7 ---
 drivers/gpu/drm/gma500/framebuffer.c|   16 
 drivers/gpu/drm/gma500/oaktrail_hdmi.c  |6 --
 drivers/gpu/drm/gma500/psb_intel_sdvo.c |6 --
 5 files changed, 16 insertions(+), 25 deletions(-)

diff --git a/drivers/gpu/drm/gma500/cdv_intel_crt.c 
b/drivers/gpu/drm/gma500/cdv_intel_crt.c
index a71a6cd..1de27c7 100644
--- a/drivers/gpu/drm/gma500/cdv_intel_crt.c
+++ b/drivers/gpu/drm/gma500/cdv_intel_crt.c
@@ -67,7 +67,6 @@ static void cdv_intel_crt_dpms(struct drm_encoder *encoder, 
int mode)
 static int cdv_intel_crt_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode)
 {
-   struct drm_psb_private *dev_priv = connector->dev->dev_private;
int max_clock = 0;
if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
return MODE_NO_DBLESCAN;
@@ -84,11 +83,6 @@ static int cdv_intel_crt_mode_valid(struct drm_connector 
*connector,
if (mode->hdisplay > 1680 || mode->vdisplay > 1050)
return MODE_PANEL;
 
-   /* We assume worst case scenario of 32 bpp here, since we don't know */
-   if ((ALIGN(mode->hdisplay * 4, 64) * mode->vdisplay) >
-   dev_priv->vram_stolen_size)
-   return MODE_MEM;
-
return MODE_OK;
 }
 
diff --git a/drivers/gpu/drm/gma500/cdv_intel_hdmi.c 
b/drivers/gpu/drm/gma500/cdv_intel_hdmi.c
index 8d52695..88b59d4 100644
--- a/drivers/gpu/drm/gma500/cdv_intel_hdmi.c
+++ b/drivers/gpu/drm/gma500/cdv_intel_hdmi.c
@@ -242,8 +242,6 @@ static int cdv_hdmi_get_modes(struct drm_connector 
*connector)
 static int cdv_hdmi_mode_valid(struct drm_connector *connector,
 struct drm_display_mode *mode)
 {
-   struct drm_psb_private *dev_priv = connector->dev->dev_private;
-
if (mode->clock > 165000)
return MODE_CLOCK_HIGH;
if (mode->clock < 2)
@@ -257,11 +255,6 @@ static int cdv_hdmi_mode_valid(struct drm_connector 
*connector,
if (mode->flags & DRM_MODE_FLAG_INTERLACE)
return MODE_NO_INTERLACE;
 
-   /* We assume worst case scenario of 32 bpp here, since we don't know */
-   if ((ALIGN(mode->hdisplay * 4, 64) * mode->vdisplay) >
-   dev_priv->vram_stolen_size)
-   return MODE_MEM;
-
return MODE_OK;
 }
 
diff --git a/drivers/gpu/drm/gma500/framebuffer.c 
b/drivers/gpu/drm/gma500/framebuffer.c
index 8ea202f..c2cf6bf 100644
--- a/drivers/gpu/drm/gma500/framebuffer.c
+++ b/drivers/gpu/drm/gma500/framebuffer.c
@@ -543,9 +543,25 @@ static int psbfb_probe(struct drm_fb_helper *helper,
struct drm_fb_helper_surface_size *sizes)
 {
struct psb_fbdev *psb_fbdev = (struct psb_fbdev *)helper;
+   struct drm_device *dev = psb_fbdev->psb_fb_helper.dev;
+   struct drm_psb_private *dev_priv = dev->dev_private;
int new_fb = 0;
+   int bytespp;
int ret;
 
+   bytespp = sizes->surface_bpp / 8;
+   if (bytespp == 3)   /* no 24bit packed */
+   bytespp = 4;
+
+   /* If the mode will not fit in 32bit then switch to 16bit to get
+  a console on full resolution. The X mode setting server will
+  allocate its own 32bit GEM framebuffer */
+   if (ALIGN(sizes->fb_width * bytespp, 64) * sizes->fb_height >
+   dev_priv->vram_stolen_size) {
+sizes->surface_bpp = 16;
+sizes->surface_depth = 16;
+}
+
if (!helper->fb) {
ret = psbfb_create(psb_fbdev, sizes);
if (ret)
diff --git a/drivers/gpu/drm/gma500/oaktrail_hdmi.c 
b/drivers/gpu/drm/gma500/oaktrail_hdmi.c
index f8b367b..2595660 100644
--- a/drivers/gpu/drm/gma500/oaktrail_hdmi.c
+++ b/drivers/gpu/drm/gma500/oaktrail_hdmi.c
@@ -179,7 +179,6 @@ static void oaktrail_hdmi_dpms(struct drm_encoder *encoder, 
int mode)
 static int oaktrail_hdmi_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode)
 {
-   struct drm_psb_private *dev_priv = connector->dev->dev_private;
if (mode->clock > 165000)
return MODE_CLOCK_HIGH;
if (mode->clock < 2)
@@ -188,11 +187,6 @@ static int oaktrail_hdmi_mode_valid(struct drm_connector 
*connector,
if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
return MODE_NO_DBLESCAN;
 
-   /* We assume worst case scenario of 32 bpp here, since we don't know */
-   if ((AL

[PATCH 3/3] gma500: don't register the ACPI video bus

2012-04-24 Thread Alan Cox
From: Alan Cox 

We are not yet ready for this and it makes a mess on some devices.

Signed-off-by: Alan Cox 
---

 drivers/gpu/drm/gma500/psb_drv.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/gpu/drm/gma500/psb_drv.c b/drivers/gpu/drm/gma500/psb_drv.c
index d5a6eab..45bd0c7 100644
--- a/drivers/gpu/drm/gma500/psb_drv.c
+++ b/drivers/gpu/drm/gma500/psb_drv.c
@@ -350,7 +350,7 @@ static int psb_driver_load(struct drm_device *dev, unsigned 
long chipset)
PSB_WSGX32(0x3000, PSB_CR_BIF_3D_REQ_BASE);
 
 /* igd_opregion_init(&dev_priv->opregion_dev); */
-   acpi_video_register();
+/* acpi_video_register(); */
if (dev_priv->lid_state)
psb_lid_timer_init(dev_priv);
 

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 2/3] acpi_video: Intel video is not always i915

2012-04-24 Thread Alan Cox
From: Alan Cox 

Handle the GMA500/600/36x0 cases. Also stop it poking at random registers on
the i740 cards that may be out there still.

This should also allow the legacy gma500 stub driver to go away as the ACPI
video layer will now do the right thing rather than assume all the world is
Gen graphics and need the gma500 stub as a workaround.

Signed-off-by: Alan Cox 
---

 drivers/acpi/video.c |   54 +++---
 1 files changed, 46 insertions(+), 8 deletions(-)

diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index 66e8f73..b2ae7aa 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -1743,25 +1743,63 @@ static int acpi_video_bus_remove(struct acpi_device 
*device, int type)
return 0;
 }
 
+static int __init is_gma_pvr(struct pci_dev *dev)
+{
+   /* Medfield */
+   if ((dev->device & 0xFFF8) == 0x0130)
+   return 1;
+   /* GMA36x0 */
+   if ((dev->device & 0xFFF8) == 0x0be0)
+   return 1;
+   /* GMA600 */
+   if ((dev->device & 0xFFF8) == 0x4100)
+   return 1;
+   /* GMA500 */
+   if ((dev->device & 0xFFFE) == 0x8108)
+   return 1;
+   /* E620 */
+   if (dev->device == 0x4108)
+   return 1;
+   return 0;
+}
+
+static int __init is_i740(struct pci_dev *dev)
+{
+   if (dev->device == 0x00D1)
+   return 1;
+   if (dev->device == 0x7000)
+   return 1;
+   return 0;
+}
+
 static int __init intel_opregion_present(void)
 {
-   int i915 = 0;
-#if defined(CONFIG_DRM_I915) || defined(CONFIG_DRM_I915_MODULE)
+   int opregion = 0;
struct pci_dev *dev = NULL;
-   u32 address;
 
for_each_pci_dev(dev) {
if ((dev->class >> 8) != PCI_CLASS_DISPLAY_VGA)
continue;
if (dev->vendor != PCI_VENDOR_ID_INTEL)
continue;
-   pci_read_config_dword(dev, 0xfc, &address);
-   if (!address)
+   /* We don't want to poke around undefined i740 registers */
+   if (is_i740(dev))
continue;
-   i915 = 1;
-   }
+#if defined(CONFIG_DRM_GMA500) || defined(CONFIG_DRM_GMA500_MODULE)
+   if (is_gma_pvr(dev))
+   opregion = 1;
 #endif
-   return i915;
+#if defined(CONFIG_DRM_I915) || defined(CONFIG_DRM_I915_MODULE)
+   if (!is_gma_pvr(dev)) {
+   u32 address;
+   pci_read_config_dword(dev, 0xfc, &address);
+   if (!address)
+   continue;
+   opregion = 1;
+   }
+#endif
+   }
+   return opregion;
 }
 
 int acpi_video_register(void)

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 1/3] acpi_video: fix leaking PCI references

2012-04-24 Thread Alan Cox
From: Alan Cox 

Otherwise we keep a bogus pci reference to the GPU

Signed-off-by: Alan Cox 
---

 drivers/acpi/video.c |5 +++--
 1 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index 9577b6f..66e8f73 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -1745,6 +1745,7 @@ static int acpi_video_bus_remove(struct acpi_device 
*device, int type)
 
 static int __init intel_opregion_present(void)
 {
+   int i915 = 0;
 #if defined(CONFIG_DRM_I915) || defined(CONFIG_DRM_I915_MODULE)
struct pci_dev *dev = NULL;
u32 address;
@@ -1757,10 +1758,10 @@ static int __init intel_opregion_present(void)
pci_read_config_dword(dev, 0xfc, &address);
if (!address)
continue;
-   return 1;
+   i915 = 1;
}
 #endif
-   return 0;
+   return i915;
 }
 
 int acpi_video_register(void)

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 6/6] gma500: panel presence check

2012-04-24 Thread Alan Cox
From: Alan Cox 

Introduce a panel presence check for Cedartrail. Non netbook devices don't
necessarily have a panel attached.

Signed-off-by: Alan Cox 
---

 drivers/gpu/drm/gma500/cdv_intel_lvds.c |   57 +++
 1 files changed, 57 insertions(+), 0 deletions(-)

diff --git a/drivers/gpu/drm/gma500/cdv_intel_lvds.c 
b/drivers/gpu/drm/gma500/cdv_intel_lvds.c
index 8359c1a..c87b179 100644
--- a/drivers/gpu/drm/gma500/cdv_intel_lvds.c
+++ b/drivers/gpu/drm/gma500/cdv_intel_lvds.c
@@ -556,6 +556,56 @@ const struct drm_encoder_funcs cdv_intel_lvds_enc_funcs = {
.destroy = cdv_intel_lvds_enc_destroy,
 };
 
+/*
+ * Enumerate the child dev array parsed from VBT to check whether
+ * the LVDS is present.
+ * If it is present, return 1.
+ * If it is not present, return false.
+ * If no child dev is parsed from VBT, it assumes that the LVDS is present.
+ */
+static bool lvds_is_present_in_vbt(struct drm_device *dev,
+  u8 *i2c_pin)
+{
+   struct drm_psb_private *dev_priv = dev->dev_private;
+   int i;
+
+   if (!dev_priv->child_dev_num)
+   return true;
+
+   for (i = 0; i < dev_priv->child_dev_num; i++) {
+   struct child_device_config *child = dev_priv->child_dev + i;
+
+   /* If the device type is not LFP, continue.
+* We have to check both the new identifiers as well as the
+* old for compatibility with some BIOSes.
+*/
+   if (child->device_type != DEVICE_TYPE_INT_LFP &&
+   child->device_type != DEVICE_TYPE_LFP)
+   continue;
+
+   if (child->i2c_pin)
+   *i2c_pin = child->i2c_pin;
+
+   /* However, we cannot trust the BIOS writers to populate
+* the VBT correctly.  Since LVDS requires additional
+* information from AIM blocks, a non-zero addin offset is
+* a good indicator that the LVDS is actually present.
+*/
+   if (child->addin_offset)
+   return true;
+
+   /* But even then some BIOS writers perform some black magic
+* and instantiate the device without reference to any
+* additional data.  Trust that if the VBT was written into
+* the OpRegion then they have validated the LVDS's existence.
+*/
+   if (dev_priv->opregion.vbt)
+   return true;
+   }
+
+   return false;
+}
+
 /**
  * cdv_intel_lvds_init - setup LVDS connectors on this device
  * @dev: drm device
@@ -576,6 +626,13 @@ void cdv_intel_lvds_init(struct drm_device *dev,
struct drm_psb_private *dev_priv = dev->dev_private;
u32 lvds;
int pipe;
+   u8 pin;
+
+   pin = GMBUS_PORT_PANEL;
+   if (!lvds_is_present_in_vbt(dev, &pin)) {
+   DRM_DEBUG_KMS("LVDS is not present in VBT\n");
+   return;
+   }
 
psb_intel_encoder = kzalloc(sizeof(struct psb_intel_encoder),
GFP_KERNEL);

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 5/6] gma500: intel_bios updates

2012-04-24 Thread Alan Cox
From: Alan Cox 

Pull in various i915 bits that we will need to begin tackling the LVDS detect
and ACPI events. We try and drift towards the i915 version of the code with
the long term goal that at least some of it can one day be unified.

Signed-off-by: Alan Cox 
---

 drivers/gpu/drm/gma500/intel_bios.c |  232 ---
 drivers/gpu/drm/gma500/intel_bios.h |  122 +++-
 drivers/gpu/drm/gma500/intel_opregion.c |  117 ++--
 drivers/gpu/drm/gma500/psb_drv.h|4 +
 4 files changed, 438 insertions(+), 37 deletions(-)

diff --git a/drivers/gpu/drm/gma500/intel_bios.c 
b/drivers/gpu/drm/gma500/intel_bios.c
index 51ea6df..479e449 100644
--- a/drivers/gpu/drm/gma500/intel_bios.c
+++ b/drivers/gpu/drm/gma500/intel_bios.c
@@ -26,6 +26,8 @@
 #include "psb_intel_reg.h"
 #include "intel_bios.h"
 
+#defineSLAVE_ADDR1 0x70
+#defineSLAVE_ADDR2 0x72
 
 static void *find_section(struct bdb_header *bdb, int section_id)
 {
@@ -52,6 +54,16 @@ static void *find_section(struct bdb_header *bdb, int 
section_id)
return NULL;
 }
 
+static u16
+get_blocksize(void *p)
+{
+   u16 *block_ptr, block_size;
+
+   block_ptr = (u16 *)((char *)p - 2);
+   block_size = *block_ptr;
+   return block_size;
+}
+
 static void fill_detail_timing_data(struct drm_display_mode *panel_fixed_mode,
struct lvds_dvo_timing *dvo_timing)
 {
@@ -75,6 +87,16 @@ static void fill_detail_timing_data(struct drm_display_mode 
*panel_fixed_mode,
panel_fixed_mode->clock = dvo_timing->clock * 10;
panel_fixed_mode->type = DRM_MODE_TYPE_PREFERRED;
 
+   if (dvo_timing->hsync_positive)
+   panel_fixed_mode->flags |= DRM_MODE_FLAG_PHSYNC;
+   else
+   panel_fixed_mode->flags |= DRM_MODE_FLAG_NHSYNC;
+
+   if (dvo_timing->vsync_positive)
+   panel_fixed_mode->flags |= DRM_MODE_FLAG_PVSYNC;
+   else
+   panel_fixed_mode->flags |= DRM_MODE_FLAG_NVSYNC;
+
/* Some VBTs have bogus h/vtotal values */
if (panel_fixed_mode->hsync_end > panel_fixed_mode->htotal)
panel_fixed_mode->htotal = panel_fixed_mode->hsync_end + 1;
@@ -218,6 +240,97 @@ static void parse_general_features(struct drm_psb_private 
*dev_priv,
 }
 
 static void
+parse_sdvo_device_mapping(struct drm_psb_private *dev_priv,
+ struct bdb_header *bdb)
+{
+   struct sdvo_device_mapping *p_mapping;
+   struct bdb_general_definitions *p_defs;
+   struct child_device_config *p_child;
+   int i, child_device_num, count;
+   u16 block_size;
+
+   p_defs = find_section(bdb, BDB_GENERAL_DEFINITIONS);
+   if (!p_defs) {
+   DRM_DEBUG_KMS("No general definition block is found, unable to 
construct sdvo mapping.\n");
+   return;
+   }
+   /* judge whether the size of child device meets the requirements.
+* If the child device size obtained from general definition block
+* is different with sizeof(struct child_device_config), skip the
+* parsing of sdvo device info
+*/
+   if (p_defs->child_dev_size != sizeof(*p_child)) {
+   /* different child dev size . Ignore it */
+   DRM_DEBUG_KMS("different child size is found. Invalid.\n");
+   return;
+   }
+   /* get the block size of general definitions */
+   block_size = get_blocksize(p_defs);
+   /* get the number of child device */
+   child_device_num = (block_size - sizeof(*p_defs)) /
+   sizeof(*p_child);
+   count = 0;
+   for (i = 0; i < child_device_num; i++) {
+   p_child = &(p_defs->devices[i]);
+   if (!p_child->device_type) {
+   /* skip the device block if device type is invalid */
+   continue;
+   }
+   if (p_child->slave_addr != SLAVE_ADDR1 &&
+   p_child->slave_addr != SLAVE_ADDR2) {
+   /*
+* If the slave address is neither 0x70 nor 0x72,
+* it is not a SDVO device. Skip it.
+*/
+   continue;
+   }
+   if (p_child->dvo_port != DEVICE_PORT_DVOB &&
+   p_child->dvo_port != DEVICE_PORT_DVOC) {
+   /* skip the incorrect SDVO port */
+   DRM_DEBUG_KMS("Incorrect SDVO port. Skip it\n");
+   continue;
+   }
+   DRM_DEBUG_KMS("the SDVO device with slave addr %2x is found on"
+   " %s port\n",
+   p_child->slave_addr,
+   (p_child->dvo_port == DEVICE_PORT_DVOB) ?
+   "SDVOB" : "SDVOC");
+   p_mapping = &(dev_priv->sdvo_mappings[p_child->dvo_port - 1]);

[PATCH 4/6] gma500: cache GEM framebuffer pages wc not uc

2012-04-24 Thread Alan Cox
From: Alan Cox 

Fixes the case where the modesetting driver is slower than /dev/fb.

Signed-off-by: Alan Cox 
Cc: sta...@kernel.org



---

 drivers/gpu/drm/gma500/gtt.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/gpu/drm/gma500/gtt.c b/drivers/gpu/drm/gma500/gtt.c
index c6465b4..db2e823 100644
--- a/drivers/gpu/drm/gma500/gtt.c
+++ b/drivers/gpu/drm/gma500/gtt.c
@@ -93,7 +93,7 @@ static int psb_gtt_insert(struct drm_device *dev, struct 
gtt_range *r)
pages = r->pages;
 
/* Make sure changes are visible to the GPU */
-   set_pages_array_uc(pages, r->npage);
+   set_pages_array_wc(pages, r->npage);
 
/* Write our page entries into the GTT itself */
for (i = r->roll; i < r->npage; i++) {

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 3/6] gma500: Update the Cedarview clock handling

2012-04-24 Thread Alan Cox
From: Alan Cox 


---

 drivers/gpu/drm/gma500/cdv_intel_display.c |  331 +++-
 drivers/gpu/drm/gma500/psb_intel_drv.h |3 
 drivers/gpu/drm/gma500/psb_intel_reg.h |   25 ++
 3 files changed, 294 insertions(+), 65 deletions(-)

diff --git a/drivers/gpu/drm/gma500/cdv_intel_display.c 
b/drivers/gpu/drm/gma500/cdv_intel_display.c
index be84559..07b37f5 100644
--- a/drivers/gpu/drm/gma500/cdv_intel_display.c
+++ b/drivers/gpu/drm/gma500/cdv_intel_display.c
@@ -216,7 +216,7 @@ static void cdv_sb_reset(struct drm_device *dev)
  */
 static int
 cdv_dpll_set_clock_cdv(struct drm_device *dev, struct drm_crtc *crtc,
-  struct cdv_intel_clock_t *clock)
+  struct cdv_intel_clock_t *clock, bool is_lvds)
 {
struct psb_intel_crtc *psb_crtc =
to_psb_intel_crtc(crtc);
@@ -224,6 +224,7 @@ cdv_dpll_set_clock_cdv(struct drm_device *dev, struct 
drm_crtc *crtc,
u32 m, n_vco, p;
int ret = 0;
int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B;
+   int ref_sfr = (pipe == 0) ? SB_REF_DPLLA : SB_REF_DPLLB;
u32 ref_value;
 
cdv_sb_reset(dev);
@@ -241,6 +242,35 @@ cdv_dpll_set_clock_cdv(struct drm_device *dev, struct 
drm_crtc *crtc,
/* We don't know what the other fields of these regs are, so
 * leave them in place.
 */
+   /* 
+* The BIT 14:13 of 0x8010/0x8030 is used to select the ref clk
+* for the pipe A/B. Display spec 1.06 has wrong definition.
+* Correct definition is like below:
+*
+* refclka mean use clock from same PLL
+*
+* if DPLLA sets 01 and DPLLB sets 01, they use clock from their pll
+*
+* if DPLLA sets 01 and DPLLB sets 02, both use clk from DPLLA
+*
+*/  
+   ret = cdv_sb_read(dev, ref_sfr, &ref_value);
+   if (ret)
+   return ret;
+   ref_value &= ~(REF_CLK_MASK);
+
+   /* use DPLL_A for pipeB on CRT/HDMI */
+   if (pipe == 1 && !is_lvds) {
+   DRM_DEBUG_KMS("use DPLLA for pipe B\n");
+   ref_value |= REF_CLK_DPLLA;
+   } else {
+   DRM_DEBUG_KMS("use their DPLL for pipe A/B\n");
+   ref_value |= REF_CLK_DPLL;
+   }
+   ret = cdv_sb_write(dev, ref_sfr, ref_value);
+   if (ret)
+   return ret;
+
ret = cdv_sb_read(dev, SB_M(pipe), &m);
if (ret)
return ret;
@@ -308,7 +338,7 @@ cdv_dpll_set_clock_cdv(struct drm_device *dev, struct 
drm_crtc *crtc,
return ret;
 
/* always Program the Lane Register for the Pipe A*/
-   if (pipe == 0) {
+/* if (pipe == 0) */ {
/* Program the Lane0/1 for HDMI B */
u32 lane_reg, lane_value;
 
@@ -553,6 +583,200 @@ psb_intel_pipe_set_base_exit:
return ret;
 }
 
+#defineFIFO_PIPEA  (1 << 0)
+#defineFIFO_PIPEB  (1 << 1)
+
+static bool cdv_intel_pipe_enabled(struct drm_device *dev, int pipe)
+{
+   struct drm_crtc *crtc;
+   struct drm_psb_private *dev_priv = dev->dev_private;
+   struct psb_intel_crtc *psb_intel_crtc = NULL;
+
+   crtc = dev_priv->pipe_to_crtc_mapping[pipe];
+   psb_intel_crtc = to_psb_intel_crtc(crtc);
+
+   if (crtc->fb == NULL || !psb_intel_crtc->active)
+   return false;
+   return true;
+}
+
+static bool cdv_intel_single_pipe_active (struct drm_device *dev)
+{
+   uint32_t pipe_enabled = 0;
+
+   if (cdv_intel_pipe_enabled(dev, 0))
+   pipe_enabled |= FIFO_PIPEA;
+
+   if (cdv_intel_pipe_enabled(dev, 1))
+   pipe_enabled |= FIFO_PIPEB;
+
+
+   DRM_DEBUG_KMS("pipe enabled %x\n", pipe_enabled);
+
+   if (pipe_enabled == FIFO_PIPEA || pipe_enabled == FIFO_PIPEB)
+   return true;
+   else
+   return false;
+}
+
+static bool is_pipeb_lvds(struct drm_device *dev, struct drm_crtc *crtc)
+{
+   struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
+   struct drm_mode_config *mode_config = &dev->mode_config;
+   struct drm_connector *connector;
+
+   if (psb_intel_crtc->pipe != 1)
+   return false;
+
+   list_for_each_entry(connector, &mode_config->connector_list, head) {
+   struct psb_intel_encoder *psb_intel_encoder =
+   psb_intel_attached_encoder(connector);
+
+   if (!connector->encoder
+   || connector->encoder->crtc != crtc)
+   continue;
+
+   if (psb_intel_encoder->type == INTEL_OUTPUT_LVDS)
+   return true;
+   }
+
+   return false;
+}
+
+static void cdv_intel_disable_self_refresh (struct drm_device *dev)
+{
+   if (REG_READ(FW_BLC_SELF) & FW_BLC_SELF_EN) {
+
+   /* Disable self-refresh before adjust WM */
+   RE

[PATCH 2/6] gma500: read the PLL bits

2012-04-24 Thread Alan Cox
From: Alan Cox 

We need to pull more stuff from the VBT in order to configure the clocking
correctly in all cases. Add the relevant bits from the other CDV driver work.

Signed-off-by: Alan Cox 
---

 drivers/gpu/drm/gma500/intel_bios.c |   18 
 drivers/gpu/drm/gma500/intel_bios.h |   39 +++
 drivers/gpu/drm/gma500/psb_drv.h|2 ++
 3 files changed, 59 insertions(+), 0 deletions(-)

diff --git a/drivers/gpu/drm/gma500/intel_bios.c 
b/drivers/gpu/drm/gma500/intel_bios.c
index d4d0c5b..51ea6df 100644
--- a/drivers/gpu/drm/gma500/intel_bios.c
+++ b/drivers/gpu/drm/gma500/intel_bios.c
@@ -217,6 +217,23 @@ static void parse_general_features(struct drm_psb_private 
*dev_priv,
}
 }
 
+static void
+parse_driver_features(struct drm_psb_private *dev_priv,
+ struct bdb_header *bdb)
+{
+   struct bdb_driver_features *driver;
+
+   driver = find_section(bdb, BDB_DRIVER_FEATURES);
+   if (!driver)
+   return;
+
+   /* This bit means to use 96Mhz for DPLL_A or not */
+   if (driver->primary_lfp_id)
+   dev_priv->dplla_96mhz = true;
+   else
+   dev_priv->dplla_96mhz = false;
+}
+
 /**
  * psb_intel_init_bios - initialize VBIOS settings & find VBT
  * @dev: DRM device
@@ -263,6 +280,7 @@ bool psb_intel_init_bios(struct drm_device *dev)
 
/* Grab useful general definitions */
parse_general_features(dev_priv, bdb);
+   parse_driver_features(dev_priv, bdb);
parse_lfp_panel_data(dev_priv, bdb);
parse_sdvo_panel_data(dev_priv, bdb);
parse_backlight_data(dev_priv, bdb);
diff --git a/drivers/gpu/drm/gma500/intel_bios.h 
b/drivers/gpu/drm/gma500/intel_bios.h
index 70f1bf0..c67979e 100644
--- a/drivers/gpu/drm/gma500/intel_bios.h
+++ b/drivers/gpu/drm/gma500/intel_bios.h
@@ -302,6 +302,45 @@ struct bdb_sdvo_lvds_options {
u8 panel_misc_bits_4;
 } __attribute__((packed));
 
+struct bdb_driver_features {
+   u8 boot_dev_algorithm:1;
+   u8 block_display_switch:1;
+   u8 allow_display_switch:1;
+   u8 hotplug_dvo:1;
+   u8 dual_view_zoom:1;
+   u8 int15h_hook:1;
+   u8 sprite_in_clone:1;
+   u8 primary_lfp_id:1;
+
+   u16 boot_mode_x;
+   u16 boot_mode_y;
+   u8 boot_mode_bpp;
+   u8 boot_mode_refresh;
+
+   u16 enable_lfp_primary:1;
+   u16 selective_mode_pruning:1;
+   u16 dual_frequency:1;
+   u16 render_clock_freq:1; /* 0: high freq; 1: low freq */
+   u16 nt_clone_support:1;
+   u16 power_scheme_ui:1; /* 0: CUI; 1: 3rd party */
+   u16 sprite_display_assign:1; /* 0: secondary; 1: primary */
+   u16 cui_aspect_scaling:1;
+   u16 preserve_aspect_ratio:1;
+   u16 sdvo_device_power_down:1;
+   u16 crt_hotplug:1;
+   u16 lvds_config:2;
+   u16 tv_hotplug:1;
+   u16 hdmi_config:2;
+
+   u8 static_display:1;
+   u8 reserved2:7;
+   u16 legacy_crt_max_x;
+   u16 legacy_crt_max_y;
+   u8 legacy_crt_max_refresh;
+
+   u8 hdmi_termination;
+   u8 custom_vbt_version;
+} __attribute__((packed));
 
 extern bool psb_intel_init_bios(struct drm_device *dev);
 extern void psb_intel_destroy_bios(struct drm_device *dev);
diff --git a/drivers/gpu/drm/gma500/psb_drv.h b/drivers/gpu/drm/gma500/psb_drv.h
index 40ce2c9..4c50969 100644
--- a/drivers/gpu/drm/gma500/psb_drv.h
+++ b/drivers/gpu/drm/gma500/psb_drv.h
@@ -669,6 +669,8 @@ struct drm_psb_private {
u32 dspcntr[3];
 
int mdfld_panel_id;
+
+   bool dplla_96mhz;   /* DPLL data from the VBT */
 };
 
 

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 1/6] gma500: Fix leak of uncached page

2012-04-24 Thread Alan Cox
From: Alan Cox 

This was reported a long time ago (and I apologize to whoever it was that
reported it as I've lost the original report).

Signed-off-by: Alan Cox 
---

 drivers/gpu/drm/gma500/psb_drv.c |1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/drivers/gpu/drm/gma500/psb_drv.c b/drivers/gpu/drm/gma500/psb_drv.c
index c34adf9..d5a6eab 100644
--- a/drivers/gpu/drm/gma500/psb_drv.c
+++ b/drivers/gpu/drm/gma500/psb_drv.c
@@ -246,6 +246,7 @@ static int psb_driver_unload(struct drm_device *dev)
}
psb_gtt_takedown(dev);
if (dev_priv->scratch_page) {
+   set_pages_wb(dev_priv->scratch_page, 1);
__free_page(dev_priv->scratch_page);
dev_priv->scratch_page = NULL;
}

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[Bug 41668] Screen locks up at random points when using a 3D compositing wm (gnome-shell) on an rv515 (radeon mobility x1300)

2012-04-24 Thread bugzilla-dae...@freedesktop.org
https://bugs.freedesktop.org/show_bug.cgi?id=41668

--- Comment #26 from Michel D?nzer  2012-04-24 01:37:57 
PDT ---
Current kernels disable MSI by default for RV515. Does that resolve this
report?

-- 
Configure bugmail: https://bugs.freedesktop.org/userprefs.cgi?tab=email
--- You are receiving this mail because: ---
You are the assignee for the bug.


[Bug 43138] Radeon HD5450 fails to load cedar firmware ?

2012-04-24 Thread bugzilla-dae...@bugzilla.kernel.org
https://bugzilla.kernel.org/show_bug.cgi?id=43138





--- Comment #9 from Michel D?nzer   2012-04-24 08:24:23 
---
(In reply to comment #7)
> that leaves the pretty unlikely bug in the loader and/or some weird local
> hardware problem - no idea how much different the cards in the cedar family
> really are from each other?

It's got nothing to do with the hardware. request_firmware() reports sizes of
the files in question which do not match the sizes of the files on your system
(which match the expected sizes). So something goes wrong between your
filesystem and request_firmware(). The most likely explanation seeming a
problem when copying the files into the initrd, or maybe
/lib/udev/firmware.agent in the initrd doing something wrong or something like
that.

What does

 gunzip -c /boot/initrd.img-$(uname -r) | cpio -tv | grep CEDAR

say?

(In reply to comment #8)
> Boot with "radeon.modeset=0 3"

The '3' won't have any visible effect on a Debian system, you'd need 'single'
for single user mode.

> If it works it means debian initrd doesn't include the firmware.

It does include something (otherwise the failure would be different), but
possibly not the correct files.

-- 
Configure bugmail: https://bugzilla.kernel.org/userprefs.cgi?tab=email
--- You are receiving this mail because: ---
You are watching the assignee of the bug.


[Patch 3/3] edid override: make edid writable in sysfs

2012-04-24 Thread Thorsten Schoel
From: Thorsten Schoel 

Makes class/drm/[CONNECTOR]/edid writable for adding edid overrides.

Signed-off-by: Thorsten Schoel 
---
diff -Nurp infra/drivers/gpu/drm/drm_sysfs.c sysfs/drivers/gpu/drm/drm_sysfs.c
--- infra/drivers/gpu/drm/drm_sysfs.c   2012-01-12 20:42:45.0 +0100
+++ sysfs/drivers/gpu/drm/drm_sysfs.c   2012-01-25 22:13:08.0 +0100
@@ -21,6 +21,8 @@
 #include "drm_sysfs.h"
 #include "drm_core.h"
 #include "drmP.h"
+#include "drm_edid.h"
+#include "drm_crtc.h"
 
 #define to_drm_minor(d) container_of(d, struct drm_minor, kdev)
 #define to_drm_connector(d) container_of(d, struct drm_connector, kdev)
@@ -228,6 +230,44 @@ static ssize_t edid_show(struct file *fi
return count;
 }
 
+static ssize_t edid_override(struct file *filp, struct kobject *kobj,
+struct bin_attribute *attr, char *buf, loff_t off,
+size_t count)
+{
+   struct device *connector_dev = container_of(kobj, struct device, kobj);
+   struct drm_connector *connector = to_drm_connector(connector_dev);
+   char *connector_name;
+   unsigned char *edid_new;
+
+   connector_name = drm_get_connector_name(connector);
+   
+   if (!count) {
+   drm_edid_override_remove(connector_name);
+   return 0;
+   }
+   
+   /* Only support writing the whole EDID in one piece */
+   if (off)
+   return 0;
+
+   if (count < EDID_LENGTH)
+   return 0;
+   if (count != (buf[0x7e] + 1) * EDID_LENGTH)
+   return 0;
+   
+   edid_new = kmalloc(count, GFP_KERNEL);
+   if (!edid_new)
+   return 0;
+   
+   memcpy(edid_new,  buf, count);
+
+   if (drm_edid_override_set(connector_name, (struct edid *)edid_new) < 0)
+   count = 0;
+   
+   kfree(edid_new);
+   return count;
+}
+
 static ssize_t modes_show(struct device *device,
   struct device_attribute *attr,
   char *buf)
@@ -341,9 +381,10 @@ static struct device_attribute connector
 
 static struct bin_attribute edid_attr = {
.attr.name = "edid",
-   .attr.mode = 0444,
+   .attr.mode = 0644,
.size = 0,
.read = edid_show,
+   .write = edid_override,
 };
 
 /**
---


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[Patch 2/3] edid override: module parameter

2012-04-24 Thread Thorsten Schoel
From: Thorsten Schoel 

Allows for setting edid overrides through new parameter edid_override
for module drm.

Signed-off-by: Thorsten Schoel 
---
diff -Nurp infra/drivers/gpu/drm/drm_edid.c param/drivers/gpu/drm/drm_edid.c
--- infra/drivers/gpu/drm/drm_edid.c2012-01-25 22:12:59.0 +0100
+++ param/drivers/gpu/drm/drm_edid.c2012-01-25 22:14:51.0 +0100
@@ -32,6 +32,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 #include 
 #include "drmP.h"
 #include "drm_edid.h"
@@ -232,11 +234,37 @@ struct drm_edid_override {
struct list_head list;

char *connector;
+   char *param;
struct edid *edid;
unsigned num_blocks;
 };
 LIST_HEAD(drm_edid_override_list);
 
+
+static int drm_edid_override_ops__get(char *buffer, const struct kernel_param 
*kp);
+static int drm_edid_override_ops__set(const char *val, const struct 
kernel_param *kp);
+static void drm_edid_override_ops__free(void *arg);
+
+
+struct kernel_param_ops drm_edid_override_ops = {
+   .get = drm_edid_override_ops__get,
+   .set = drm_edid_override_ops__set,
+   .free = drm_edid_override_ops__free
+};
+
+MODULE_PARM_DESC(edid_override, "Override the EDID data of a monitor. "
+   "This should be a comma separated list of entries of the format "
+   "[connector name]:[data]. data is either raw EDID data encoded in "
+   "hexadecimal format, or, if it cannot be parsed as such, the name "
+   "of a file containing the EDID data to be loaded through "
+   "request_firmware. Examples:\nVGA-1:syncmaster913n.edid\n"
+   "DVI-I-1:00…");
+module_param_cb(edid_override,
+   &drm_edid_override_ops,
+   &drm_edid_override_list,
+   0600);
+
+
 /*
  * Free the memory associated with an EDID override.
  */
@@ -246,6 +273,7 @@ drm_edid_override_delete(struct drm_edid
if (entry->edid)
kfree(entry->edid);
kfree(entry->connector);
+   /* param is generated from the same piece of memory through strsep */
kfree(entry);
 }
 
@@ -270,7 +299,7 @@ drm_edid_override_remove(const char *con
 EXPORT_SYMBOL(drm_edid_override_remove);
 
 static int
-drm_edid_override_do_set(char *connector, struct edid *edid, unsigned 
num_blocks)
+drm_edid_override_do_set(char *connector, struct edid *edid, unsigned 
num_blocks, char *param)
 {
struct drm_edid_override *entry = NULL;
int found = 0;
@@ -300,6 +329,7 @@ drm_edid_override_do_set(char *connector
entry->connector = connector;
entry->edid = edid;
entry->num_blocks = num_blocks;
+   entry->param = param;

if (!found)
list_add_tail(&entry->list, &drm_edid_override_list);
@@ -308,6 +338,25 @@ drm_edid_override_do_set(char *connector
return 0;
 }
 
+/*
+ * Helper function for setter of module parameter.
+ */
+static int
+drm_edid_override_set_from_param(char *val)
+{
+   char *connector = NULL, *param = NULL;
+   
+   connector = strsep(&val, ":");
+   param = strlen(val) ? val : NULL;
+   
+   if (param)
+   return drm_edid_override_do_set(connector, NULL, 0, param);
+   else
+   drm_edid_override_remove(connector);
+   
+   return 0;
+}
+
 /**
  * Add a new override for connector if none has been set yet or replace the
  * current one.
@@ -336,10 +385,179 @@ drm_edid_override_set(const char *connec
}
memcpy(edid_dup, edid, edid_size);

-   return drm_edid_override_do_set(connector_dup, edid_dup, num_blocks);
+   return drm_edid_override_do_set(connector_dup, edid_dup, num_blocks, 
NULL);
 }
 EXPORT_SYMBOL(drm_edid_override_set);
 
+/*
+ * Setter for module parameter.
+ */
+static int
+drm_edid_override_ops__set(const char *val, const struct kernel_param *kp)
+{
+   const char *master = val;
+   char *substr = NULL;
+   int result = 0;
+   
+   do {
+   const char *new_master = strchr(master, ',');
+   int substr_len = 0;
+   
+   if (new_master)
+   substr_len = new_master - master;
+   else
+   substr_len = strlen(master);
+
+   substr = kstrndup(master, substr_len, GFP_KERNEL);
+   if (!substr)
+   return -ENOMEM;
+
+   result = drm_edid_override_set_from_param(substr);
+   if (result)
+   return result;
+   
+   master = new_master;
+   } while (master);
+   
+   return 0;
+}
+
+/* moduleparam.h claims this is "4k" */
+#define OPT_GET__BUFFER_LENGTH 4096
+/*
+ * Getter for module parameter. Will produce a comma separated list of
+ * all connectors an override has been set for.
+ */
+static int
+drm_edid_override_ops__get(char *buffer, const struct kernel_param *kp)
+{
+   struct drm_edid_override *entry = NULL;
+  

[Patch 0/3] Add ability to override a monitor's EDID information

2012-04-24 Thread Thorsten Schoel
Hello everybody,

having a monitor provide wrong or invalid EDID information – or none at
all – seems to be a problem quite a number of people are facing. A few
of the non-KMS X-drivers provide individual mechanisms for overriding
such an EDID with user provided data. To my knowledge at least the
kernel currently falls short of providing such a mechanism. This set of
patches attempts to provide one.

It has a number of potential shortcoming to which I was not yet able to
find any solution. These are:

1. It uses drm_get_connector_name to identify a connector. I am not
entirely sure though if these names are guaranteed to be unique (the
names used in /sys/class/drm seem to suggest they are not). Since they
are good enough for the kernel's video parameter, though, I figured they
should be good enough for the present purpose as well.

2. One of the patches introduces a new kernel parameter (edid_override).
This parameter takes either the raw edid-data encoded as a hex-string or
the name of a firmware file from which to load the data. I am a bit
unhappy with both solutions since the first puts raw data on the command
line and makes it rather long and the second… well edid-data is not
exactly firmware in the strict sense. It may be firm, but it is probably
not ware.

3. I thought about making the sysfs code more sophisticated so that
individual bytes could be written at any position within the data. Yet,
there seems to be no way to truncate a file in sysfs which would be
important when changing the number of 128 byte blocks the data is made
up of. In addition, I cannot see what good such a behaviour would be or
how the obscure use probably is somewhere out there could justify the
additional complexity. I therefore opted for the approach of only
allowing writes of complete edid-blobs in one pass.

The patches I submit were tested on an x64 with radeon graphics and on
an x86 with i915. They were made for 3.4.

 drivers/gpu/drm/drm_edid.c  |  399 +++-
 drivers/gpu/drm/drm_sysfs.c |   43 
 include/drm/drm_crtc.h  |2 
 3 files changed, 435 insertions(+), 9 deletions(-)


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[Patch 1/3] edid override: infrastructure

2012-04-24 Thread Thorsten Schoel
From: Thorsten Schoel 

Provides infrastructure for overriding edid information of individual
monitors.

Signed-off-by: Thorsten Schoel 
---
diff -Nurp vanilla/drivers/gpu/drm/drm_edid.c infra/drivers/gpu/drm/drm_edid.c
--- vanilla/drivers/gpu/drm/drm_edid.c  2012-01-25 22:29:25.0 +0100
+++ infra/drivers/gpu/drm/drm_edid.c2012-01-25 22:12:59.0 +0100
@@ -30,6 +30,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 #include 
 #include "drmP.h"
 #include "drm_edid.h"
@@ -226,6 +228,158 @@ bool drm_edid_is_valid(struct edid *edid
 }
 EXPORT_SYMBOL(drm_edid_is_valid);
 
+struct drm_edid_override {
+   struct list_head list;
+   
+   char *connector;
+   struct edid *edid;
+   unsigned num_blocks;
+};
+LIST_HEAD(drm_edid_override_list);
+
+/*
+ * Free the memory associated with an EDID override.
+ */
+static void
+drm_edid_override_delete(struct drm_edid_override *entry)
+{
+   if (entry->edid)
+   kfree(entry->edid);
+   kfree(entry->connector);
+   kfree(entry);
+}
+
+/**
+ * Remove an existing override.
+ *
+ * \param connector : name of a drm_connector
+ */
+void
+drm_edid_override_remove(const char *connector)
+{
+   struct drm_edid_override *entry = NULL;
+   
+   list_for_each_entry (entry, &drm_edid_override_list, list) {
+   if (strcmp(entry->connector, connector))
+   continue;
+   list_del(&entry->list);
+   drm_edid_override_delete(entry);
+   break;
+   }
+}
+EXPORT_SYMBOL(drm_edid_override_remove);
+
+static int
+drm_edid_override_do_set(char *connector, struct edid *edid, unsigned 
num_blocks)
+{
+   struct drm_edid_override *entry = NULL;
+   int found = 0;
+   
+   /* replace previous entry if present */
+   list_for_each_entry (entry, &drm_edid_override_list, list) {
+   if (strcmp(connector, entry->connector))
+   continue;
+   found = 1;
+   break;
+   }
+
+   if (!found) {
+   entry = kmalloc(sizeof(struct drm_edid_override), GFP_KERNEL);
+   if (!entry) {
+   kfree(connector);
+   kfree(edid);
+   return -ENOMEM;
+   }
+   INIT_LIST_HEAD(&entry->list);
+   } else {
+   kfree(entry->connector);
+   if (entry->edid)
+   kfree(entry->edid);
+   }
+   
+   entry->connector = connector;
+   entry->edid = edid;
+   entry->num_blocks = num_blocks;
+   
+   if (!found)
+   list_add_tail(&entry->list, &drm_edid_override_list);
+   DRM_INFO("Set new EDID override for connector %s", connector);
+   
+   return 0;
+}
+
+/**
+ * Add a new override for connector if none has been set yet or replace the
+ * current one.
+ *
+ * \param connector : name of a drm_connector as retrieved through 
drm_get_connector_name
+ * \param edid  : binary EDID data
+ */
+int
+drm_edid_override_set(const char *connector, const struct edid *edid)
+{
+   char *connector_dup = NULL;
+   struct edid *edid_dup = NULL;
+   int num_blocks = 0;
+   unsigned edid_size = 0;
+   
+   connector_dup = kstrdup(connector, GFP_KERNEL);
+   if (!connector_dup)
+   return -ENOMEM;
+   
+   num_blocks = edid->extensions + 1;
+   edid_size = num_blocks * EDID_LENGTH;
+   edid_dup = kmalloc(edid_size, GFP_KERNEL);
+   if (!edid_dup) {
+   kfree(connector_dup);
+   return -ENOMEM;
+   }
+   memcpy(edid_dup, edid, edid_size);
+   
+   return drm_edid_override_do_set(connector_dup, edid_dup, num_blocks);
+}
+EXPORT_SYMBOL(drm_edid_override_set);
+
+/**
+ * Get EDID information from overrides list if available.
+ *
+ * \param connector : DRM connector to get EDID for
+ * \return a newly allocated edid structure filled with the EDID data from the
+ *override or NULL if no override for @connector could be found.
+ */
+static struct edid *
+drm_edid_override_get (struct drm_connector *connector)
+{
+   struct list_head *pos = NULL;
+   struct drm_edid_override *entry = NULL;
+   char *connector_name = NULL;
+   struct edid *result = NULL;
+
+   connector_name = drm_get_connector_name(connector);
+
+   list_for_each(pos, &drm_edid_override_list) {
+   entry = (struct drm_edid_override *)
+   list_entry(pos, struct drm_edid_override, list);
+   if(!strcmp(entry->connector, connector_name))
+   break;
+   else
+   entry = NULL;
+   }
+   
+   if (!entry)
+   return NULL;
+   
+   if (!entry->edid) {
+   DRM_ERROR("EDID override without EDID data for connector %s", 
connector_name);
+   return NULL;
+   }
+   
+   i

Re: Linux 3.4-rc4

2012-04-24 Thread Konrad Rzeszutek Wilk
On Mon, Apr 23, 2012 at 09:03:45PM -0400, Nick Bowler wrote:
> On 2012-04-22 22:45 -0400, Konrad Rzeszutek Wilk wrote:
> > On Sun, Apr 22, 2012 at 08:05:54PM -0400, Nick Bowler wrote:
> > > Following up on the above, the commit which introduces the panics during
> > > boot is this one:
> > >
> > > commit 8e7e70522d760c4ccd4cd370ebfa0ba69e006c6e
> > > Author: Jerome Glisse 
> > > Date:   Wed Nov 9 17:15:26 2011 -0500
> > > 
> > > drm/ttm: isolate dma data from ttm_tt V4
> > 
> > I think
> > 
> > dea7e0a ttm: fix agp since ttm tt rework
> > 
> > fixed that.
> 
> Yes, I just tested this commit and the one immediately before it.  The
> one before crashes in the usual way, and dea7e0a boots (with the VGA
> output black as in the original report).  So this fixed the crash.
> 
> Now, returning to the original bisection, I marked that commit as "bad"
> and dropped all the earlier "skip" markings.  Git asks me to test commit
> 2a44e4997c5f ("drm/nouveau/disp: introduce proper init/fini, separate
> from create/destroy").  I cherry picked the aforementioned ttm fix:
> 
>   git cherry-pick -n dea7e0a
> 
> which succeeded.  Howevew, the resulting kernel still crashes early,
> although now in a different way.  I just can't win :(

Perhaps there is a better way. You could do this:

git log --oneline -r v3.2..v3.3 drivers/gpu/drm/nouveau

to get an idea of the set of patches that went in. And use that, so

git bisect start -- drivers/gpu/drm/nouveau [this should only do the bisection 
on those patches]

git bisect good v3.2
git bisect bad v3.3

And keep in mind the dea7e0a might need to be stuck on some of these.

This _should_ limit the bisection to just the nouveau changes, I hope.
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[Bug 49083] Crashing when open gnome-control-center 3.4.1

2012-04-24 Thread bugzilla-dae...@freedesktop.org
https://bugs.freedesktop.org/show_bug.cgi?id=49083

Michel D?nzer  changed:

   What|Removed |Added

  Attachment #60490|text/x-log  |text/plain
  mime type||

-- 
Configure bugmail: https://bugs.freedesktop.org/userprefs.cgi?tab=email
--- You are receiving this mail because: ---
You are the assignee for the bug.


Re: [PATCH v2] scatterlist: add sg_alloc_table_from_pages function

2012-04-24 Thread Daniel Vetter
On Tue, Apr 24, 2012 at 02:58:56PM +0200, Tomasz Stanislawski wrote:
> This patch adds a new constructor for an sg table. The table is constructed
> from an array of struct pages. All contiguous chunks of the pages are merged
> into a single sg nodes. A user may provide an offset and a size of a buffer if
> the buffer is not page-aligned.
> 
> The function is dedicated for DMABUF exporters which often perform conversion
> from an page array to a scatterlist. Moreover the scatterlist should be
> squashed in order to save memory and to speed-up the process of DMA mapping
> using dma_map_sg.
> 
> The code is based on the patch 'v4l: vb2-dma-contig: add support for
> scatterlist in userptr mode' and hints from Laurent Pinchart.
> 
> Signed-off-by: Tomasz Stanislawski 
> Signed-off-by: Kyungmin Park 

I like this and we could replace the drm helper function in drm prime with
this one. One comment below.
-Daniel

> ---
>  include/linux/scatterlist.h |4 +++
>  lib/scatterlist.c   |   63 
> +++
>  2 files changed, 67 insertions(+), 0 deletions(-)
> 
> diff --git a/include/linux/scatterlist.h b/include/linux/scatterlist.h
> index ac9586d..7b600da 100644
> --- a/include/linux/scatterlist.h
> +++ b/include/linux/scatterlist.h
> @@ -214,6 +214,10 @@ void sg_free_table(struct sg_table *);
>  int __sg_alloc_table(struct sg_table *, unsigned int, unsigned int, gfp_t,
>sg_alloc_fn *);
>  int sg_alloc_table(struct sg_table *, unsigned int, gfp_t);
> +int sg_alloc_table_from_pages(struct sg_table *sgt,
> + struct page **pages, unsigned int n_pages,
> + unsigned long offset, unsigned long size,
> + gfp_t gfp_mask);
> 
>  size_t sg_copy_from_buffer(struct scatterlist *sgl, unsigned int nents,
>  void *buf, size_t buflen);
> diff --git a/lib/scatterlist.c b/lib/scatterlist.c
> index 6096e89..90f9265 100644
> --- a/lib/scatterlist.c
> +++ b/lib/scatterlist.c
> @@ -319,6 +319,69 @@ int sg_alloc_table(struct sg_table *table, unsigned int 
> nents, gfp_t gfp_mask)
>  EXPORT_SYMBOL(sg_alloc_table);
> 
>  /**
> + * sg_alloc_table_from_pages - Allocate and initialize an sg table from
> + *  an array of pages
> + * @sgt: The sg table header to use
> + * @pages:   Pointer to an array of page pointers
> + * @n_pages: Number of pages in the pages array
> + * @offset: Offset from a start of the first page to a start of a buffer
> + * @size:   Number of valid bytes in the buffer (after offset)
> + * @gfp_mask:GFP allocation mask
> + *
> + *  Description:
> + *Allocate and initialize an sg table from a list of pages. Continuous
> + *ranges of the pages are squashed into a single scatterlist node. A user
> + *may provide an offset at a start and a size of valid data in a buffer
> + *specified by the page array. The returned sg table is released by
> + *sg_free_table.
> + *
> + * Returns:
> + *   0 on success, negative error on failure
> + **/
> +int sg_alloc_table_from_pages(struct sg_table *sgt,
> + struct page **pages, unsigned int n_pages,
> + unsigned long offset, unsigned long size,
> + gfp_t gfp_mask)
> +{
> + unsigned int chunks;
> + unsigned int i;
> + unsigned int cur_page;
> + int ret;
> + struct scatterlist *s;
> +
> + /* compute number of contiguous chunks */
> + chunks = 1;
> + for (i = 1; i < n_pages; ++i)
> + if (pages[i] != pages[i - 1] + 1)
> + ++chunks;

I'm not aware of the details (and didn't bother to do a full audit), but
I guess this could blow up on funky discontig-mem setups. Imo would be
safer to compare the pfn or phys address. And also slightly more readable.
Imo sg table creation is not a fastpath, the exporter should cache these
anyway, so we can waste some cpu cycles here.

> + ret = sg_alloc_table(sgt, chunks, gfp_mask);
> + if (unlikely(ret))
> + return ret;
> +
> + /* merging chunks and putting them into the scatterlist */
> + cur_page = 0;
> + for_each_sg(sgt->sgl, s, sgt->orig_nents, i) {
> + unsigned long chunk_size;
> + unsigned int j;
> +
> + /* looking for the end of the current chunk */
> + for (j = cur_page + 1; j < n_pages; ++j)
> + if (pages[j] != pages[j - 1] + 1)
> + break;
> +
> + chunk_size = ((j - cur_page) << PAGE_SHIFT) - offset;
> + sg_set_page(s, pages[cur_page], min(size, chunk_size), offset);
> + size -= chunk_size;
> + offset = 0;
> + cur_page = j;
> + }
> +
> + return 0;
> +}
> +EXPORT_SYMBOL(sg_alloc_table_from_pages);
> +
> +/**
>   * sg_miter_start - start mapping iteration over a sg list
>   * @miter: sg mapping iter to be started
>   * @sgl: sg list to iterate over
> -- 
> 1.7.5.4
> 
> ___
> dri-devel 

Re: [PATCH] drm: Initial KMS driver for AST (ASpeed Technologies) 2000 series

2012-04-24 Thread Michel Dänzer
On Mon, 2012-04-23 at 14:30 +0100, Alan Cox wrote:
> 
> > fbdev objects once exposed to userspace or to fbcon, thanks to some 
> > wonderful
> > API design way back, the mmaps on the fbdev device are direct to the VRAM
> > physical pages. Can't tear them down and move them into system RAM pages
> > at all easily.
> 
> Thats not strictly true. They can move mapping if the locking is right
> and the helpers handle it because you can invalidate the pages in the
> userspace mappings and they will get faulted back with the new ones.

fbdev userspace mappings is the easy part, TTM has supported that for
years. The problem is fbcon, which can access the framebuffer from
basically any context for printk. 


> > Because I'm not 100% sure nothing will get written to it, and if
> 
> Fair point.
> 
> > something gets written
> > to it I'd rather not have to complicate the oops printing to have to
> > page in memory
> > from disk, when it might be the disk that caused the oops.
> 
> If the box was horked that way then you are going to fail to migrate the
> graphical frame buffer out in order to go into text mode to print the
> oops. Probably safest any oops hits the current visible object ?

It's not always that simple either, e.g. this wouldn't work when
scanning out a tiled buffer on Radeon HDs.


-- 
Earthling Michel Dänzer   |   http://www.amd.com
Libre software enthusiast |  Debian, X and DRI developer
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


  1   2   >