* [PATCH 2/7] aty: remove mode restriction
From: Mikulas Patocka @ 2012-08-20 18:06 UTC (permalink / raw)
To: linux-fbdev
aty: remove mode restriction
The mach64 video card works fine in 1920x1080 resolution,
there's no need to limit it.
Signed-off-by: Mikulas Patocka <mpatocka@artax.karlin.mff.cuni.cz>
---
drivers/video/aty/atyfb_base.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
Index: linux-3.6-rc2-fast/drivers/video/aty/atyfb_base.c
=================================--- linux-3.6-rc2-fast.orig/drivers/video/aty/atyfb_base.c 2012-08-18 04:07:55.000000000 +0200
+++ linux-3.6-rc2-fast/drivers/video/aty/atyfb_base.c 2012-08-18 04:09:09.000000000 +0200
@@ -861,8 +861,8 @@ static int aty_var_to_crtc(const struct
h_sync_pol = sync & FB_SYNC_HOR_HIGH_ACT ? 0 : 1;
v_sync_pol = sync & FB_SYNC_VERT_HIGH_ACT ? 0 : 1;
- if ((xres > 1600) || (yres > 1200)) {
- FAIL("MACH64 chips are designed for max 1600x1200\n"
+ if ((xres > 1920) || (yres > 1200)) {
+ FAIL("MACH64 chips are designed for max 1920x1200\n"
"select another resolution.");
}
h_sync_strt = h_disp + var->right_margin;
^ permalink raw reply
* [PATCH 3/7] mach64: fix unaligned access on sparc64
From: Mikulas Patocka @ 2012-08-20 18:07 UTC (permalink / raw)
To: linux-fbdev
mach64: use unaligned access
This patch fixes mach64 to use unaligned access to the font bitmap.
This fixes unaligned access warning on sparc64 when 14x8 font is loaded.
On x86(64), unaligned access is handled on hardware, so both functions
le32_to_cpup and get_unaligned_le32 perform the same operation.
On RISC machines, unaligned access is not handled in hardware, so we
better use get_unaligned_le32 to avoid the unaligned trap and warning.
Signed-off-by: Mikulas Patocka <mikulas@artax.karlin.mff.cuni.cz>
Cc: stable@kernel.org
---
drivers/video/aty/mach64_accel.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
Index: linux-3.4.3-fast/drivers/video/aty/mach64_accel.c
=================================--- linux-3.4.3-fast.orig/drivers/video/aty/mach64_accel.c 2012-07-02 00:10:56.000000000 +0200
+++ linux-3.4.3-fast/drivers/video/aty/mach64_accel.c 2012-07-02 00:13:29.000000000 +0200
@@ -4,6 +4,7 @@
*/
#include <linux/delay.h>
+#include <asm/unaligned.h>
#include <linux/fb.h>
#include <video/mach64.h>
#include "atyfb.h"
@@ -419,7 +420,7 @@ void atyfb_imageblit(struct fb_info *inf
u32 *pbitmap, dwords = (src_bytes + 3) / 4;
for (pbitmap = (u32*)(image->data); dwords; dwords--, pbitmap++) {
wait_for_fifo(1, par);
- aty_st_le32(HOST_DATA0, le32_to_cpup(pbitmap), par);
+ aty_st_le32(HOST_DATA0, get_unaligned_le32(pbitmap), par);
}
}
^ permalink raw reply
* [PATCH 4/7] mach64: fix cursor when character width is not a multiple of 8 pixels
From: Mikulas Patocka @ 2012-08-20 18:08 UTC (permalink / raw)
To: linux-fbdev
mach64: fix cursor when character width is not a multiple of 8 pixels
This patch fixes hardware cursor on mach64 when font width is not a
multiple of 8 pixels.
If you load such a font, the cursor is expanded to the next 8-byte
boundary and a part of the next character after the cursor is not
visible.
For example, when you load a font with 12-pixel width, the cursor width
is 16 pixels and when the cursor is displayed, 4 pixels of the next
character are not visible.
The reason is this: atyfb_cursor is called with proper parameters to
load an image that is 12-pixel wide. However, the number is aligned on
the next 8-pixel boundary on the line
"unsigned int width = (cursor->image.width + 7) >> 3;" and the whole
function acts as it is was loading a 16-pixel image.
This patch fixes it so that the value written to the framebuffer is
padded with 0xaaaa (the transparent pattern) when the image size it not
a multiple of 8 pixels.
Signed-off-by: Mikulas Patocka <mikulas@artax.karlin.mff.cuni.cz>
Cc: stable@kernel.org
---
drivers/video/aty/mach64_cursor.c | 22 ++++++++++++++++------
1 file changed, 16 insertions(+), 6 deletions(-)
Index: linux-3.4.3-fast/drivers/video/aty/mach64_cursor.c
=================================--- linux-3.4.3-fast.orig/drivers/video/aty/mach64_cursor.c 2012-07-02 01:15:38.000000000 +0200
+++ linux-3.4.3-fast/drivers/video/aty/mach64_cursor.c 2012-07-02 01:54:10.000000000 +0200
@@ -5,6 +5,7 @@
#include <linux/fb.h>
#include <linux/init.h>
#include <linux/string.h>
+#include "../fb_draw.h"
#include <asm/io.h>
@@ -157,24 +158,33 @@ static int atyfb_cursor(struct fb_info *
for (i = 0; i < height; i++) {
for (j = 0; j < width; j++) {
+ u16 l = 0xaaaa;
b = *src++;
m = *msk++;
switch (cursor->rop) {
case ROP_XOR:
// Upper 4 bits of mask data
- fb_writeb(cursor_bits_lookup[(b ^ m) >> 4], dst++);
+ l = cursor_bits_lookup[(b ^ m) >> 4] |
// Lower 4 bits of mask
- fb_writeb(cursor_bits_lookup[(b ^ m) & 0x0f],
- dst++);
+ (cursor_bits_lookup[(b ^ m) & 0x0f] << 8);
break;
case ROP_COPY:
// Upper 4 bits of mask data
- fb_writeb(cursor_bits_lookup[(b & m) >> 4], dst++);
+ l = cursor_bits_lookup[(b & m) >> 4] |
// Lower 4 bits of mask
- fb_writeb(cursor_bits_lookup[(b & m) & 0x0f],
- dst++);
+ (cursor_bits_lookup[(b & m) & 0x0f] << 8);
break;
}
+ /*
+ * If cursor size is not a multiple of 8 characters
+ * we must pad it with transparent pattern (0xaaaa).
+ */
+ if ((j + 1) * 8 > cursor->image.width) {
+ l = comp(l, 0xaaaa,
+ (1 << ((cursor->image.width & 7) * 2)) - 1);
+ }
+ fb_writeb(l & 0xff, dst++);
+ fb_writeb(l >> 8, dst++);
}
dst += offset;
}
^ permalink raw reply
* [PATCH 5/7] tgafb: fix mode setting with fbset
From: Mikulas Patocka @ 2012-08-20 18:09 UTC (permalink / raw)
To: linux-fbdev
tgafb: fix mode setting with fbset
Mode setting in the TGA driver is broken for these reasons:
- info->fix.line_length is set just once in tgafb_init_fix function. If
we change videomode, info->fix.line_length is not recalculated - so
the video mode is changed but screen is corrupted because of wrong
info->fix.line_length
- info->fix.smem_len is set in tgafb_init_fix to the size of the default
video mode (640x480). If we set a higher resolution,
info->fix.smem_len is smaller than the current screen size, preventing
the userspace program from mapping the framebuffer.
This patch fixes it:
- info->fix.line_length initialization is moved to tgafb_set_par so that
it is recalculated with each mode change.
- info->fix.smem_len is set to a fixed value representing the real
amount of video ram (the values are taken from xfree86 driver).
- add a check to tgafb_check_var to prevent us from setting a videomode
that doesn't fit into videoram.
- in tgafb_register, tgafb_init_fix is moved upwards, to be called
before fb_find_mode (because fb_find_mode already needs the videoram
size set in tgafb_init_fix).
Signed-off-by: Mikulas Patocka <mikulas@artax.karlin.mff.cuni.cz>
Cc: stable@kernel.org
---
drivers/video/tgafb.c | 15 ++++++++++++---
1 file changed, 12 insertions(+), 3 deletions(-)
Index: linux-3.4.4-fast/drivers/video/tgafb.c
=================================--- linux-3.4.4-fast.orig/drivers/video/tgafb.c 2012-07-02 02:15:43.000000000 +0200
+++ linux-3.4.4-fast/drivers/video/tgafb.c 2012-07-02 02:16:48.000000000 +0200
@@ -192,6 +192,8 @@ tgafb_check_var(struct fb_var_screeninfo
if (var->xres_virtual != var->xres || var->yres_virtual != var->yres)
return -EINVAL;
+ if (var->xres * var->yres * (var->bits_per_pixel >> 3) > info->fix.smem_len)
+ return -EINVAL;
if (var->nonstd)
return -EINVAL;
if (1000000000 / var->pixclock > TGA_PLL_MAX_FREQ)
@@ -272,6 +274,7 @@ tgafb_set_par(struct fb_info *info)
par->yres = info->var.yres;
par->pll_freq = pll_freq = 1000000000 / info->var.pixclock;
par->bits_per_pixel = info->var.bits_per_pixel;
+ info->fix.line_length = par->xres * (par->bits_per_pixel >> 3);
tga_type = par->tga_type;
@@ -1480,6 +1483,7 @@ tgafb_init_fix(struct fb_info *info)
int tga_bus_tc = TGA_BUS_TC(par->dev);
u8 tga_type = par->tga_type;
const char *tga_type_name = NULL;
+ unsigned memory_size;
switch (tga_type) {
case TGA_TYPE_8PLANE:
@@ -1487,21 +1491,25 @@ tgafb_init_fix(struct fb_info *info)
tga_type_name = "Digital ZLXp-E1";
if (tga_bus_tc)
tga_type_name = "Digital ZLX-E1";
+ memory_size = 2097152;
break;
case TGA_TYPE_24PLANE:
if (tga_bus_pci)
tga_type_name = "Digital ZLXp-E2";
if (tga_bus_tc)
tga_type_name = "Digital ZLX-E2";
+ memory_size = 8388608;
break;
case TGA_TYPE_24PLUSZ:
if (tga_bus_pci)
tga_type_name = "Digital ZLXp-E3";
if (tga_bus_tc)
tga_type_name = "Digital ZLX-E3";
+ memory_size = 16777216;
break;
default:
tga_type_name = "Unknown";
+ memory_size = 16777216;
break;
}
@@ -1513,9 +1521,8 @@ tgafb_init_fix(struct fb_info *info)
? FB_VISUAL_PSEUDOCOLOR
: FB_VISUAL_DIRECTCOLOR);
- info->fix.line_length = par->xres * (par->bits_per_pixel >> 3);
info->fix.smem_start = (size_t) par->tga_fb_base;
- info->fix.smem_len = info->fix.line_length * par->yres;
+ info->fix.smem_len = memory_size;
info->fix.mmio_start = (size_t) par->tga_regs_base;
info->fix.mmio_len = 512;
@@ -1640,6 +1647,9 @@ tgafb_register(struct device *dev)
modedb_tga = &modedb_tc;
modedbsize_tga = 1;
}
+
+ tgafb_init_fix(info);
+
ret = fb_find_mode(&info->var, info,
mode_option ? mode_option : mode_option_tga,
modedb_tga, modedbsize_tga, NULL,
@@ -1657,7 +1667,6 @@ tgafb_register(struct device *dev)
}
tgafb_set_par(info);
- tgafb_init_fix(info);
if (register_framebuffer(info) < 0) {
printk(KERN_ERR "tgafb: Could not register framebuffer\n");
^ permalink raw reply
* [PATCH 6/7] tgafb: fix data copying
From: Mikulas Patocka @ 2012-08-20 18:10 UTC (permalink / raw)
To: linux-fbdev
tgafb: fix data copying
The functions for data copying copyarea_foreward_8bpp and
copyarea_backward_8bpp are buggy, they produce screen corruption.
This patch fixes the functions and moves the logic to one function
"copyarea_8bpp". For simplicity, the function only handles copying that
is aligned on 8 pixes. If we copy an unaligned area, generic function
cfb_copyarea is used.
Signed-off-by: Mikulas Patocka <mikulas@artax.karlin.mff.cuni.cz>
Cc: stable@kernel.org
---
drivers/video/tgafb.c | 266 +++++++++-----------------------------------------
1 file changed, 52 insertions(+), 214 deletions(-)
Index: linux-3.4.4-fast/drivers/video/tgafb.c
=================================--- linux-3.4.4-fast.orig/drivers/video/tgafb.c 2012-07-03 22:58:32.000000000 +0200
+++ linux-3.4.4-fast/drivers/video/tgafb.c 2012-07-04 02:32:47.000000000 +0200
@@ -1149,222 +1149,57 @@ copyarea_line_32bpp(struct fb_info *info
__raw_writel(TGA_MODE_SBM_24BPP|TGA_MODE_SIMPLE, tga_regs+TGA_MODE_REG);
}
-/* The general case of forward copy in 8bpp mode. */
+/* The (almost) general case of backward copy in 8bpp mode. */
static inline void
-copyarea_foreward_8bpp(struct fb_info *info, u32 dx, u32 dy, u32 sx, u32 sy,
- u32 height, u32 width, u32 line_length)
+copyarea_8bpp(struct fb_info *info, u32 dx, u32 dy, u32 sx, u32 sy,
+ u32 height, u32 width, u32 line_length,
+ const struct fb_copyarea *area)
{
struct tga_par *par = (struct tga_par *) info->par;
- unsigned long i, copied, left;
- unsigned long dpos, spos, dalign, salign, yincr;
- u32 smask_first, dmask_first, dmask_last;
- int pixel_shift, need_prime, need_second;
- unsigned long n64, n32, xincr_first;
+ unsigned i, yincr;
+ int depos, sepos, backward, last_step, step;
+ u32 mask_last;
+ unsigned n32;
void __iomem *tga_regs;
void __iomem *tga_fb;
- yincr = line_length;
- if (dy > sy) {
- dy += height - 1;
- sy += height - 1;
- yincr = -yincr;
- }
-
- /* Compute the offsets and alignments in the frame buffer.
- More than anything else, these control how we do copies. */
- dpos = dy * line_length + dx;
- spos = sy * line_length + sx;
- dalign = dpos & 7;
- salign = spos & 7;
- dpos &= -8;
- spos &= -8;
-
- /* Compute the value for the PIXELSHIFT register. This controls
- both non-co-aligned source and destination and copy direction. */
- if (dalign >= salign)
- pixel_shift = dalign - salign;
- else
- pixel_shift = 8 - (salign - dalign);
-
- /* Figure out if we need an additional priming step for the
- residue register. */
- need_prime = (salign > dalign);
- if (need_prime)
- dpos -= 8;
-
- /* Begin by copying the leading unaligned destination. Copy enough
- to make the next destination address 32-byte aligned. */
- copied = 32 - (dalign + (dpos & 31));
- if (copied = 32)
- copied = 0;
- xincr_first = (copied + 7) & -8;
- smask_first = dmask_first = (1ul << copied) - 1;
- smask_first <<= salign;
- dmask_first <<= dalign + need_prime*8;
- if (need_prime && copied > 24)
- copied -= 8;
- left = width - copied;
-
- /* Care for small copies. */
- if (copied > width) {
- u32 t;
- t = (1ul << width) - 1;
- t <<= dalign + need_prime*8;
- dmask_first &= t;
- left = 0;
- }
-
- /* Attempt to use 64-byte copies. This is only possible if the
- source and destination are co-aligned at 64 bytes. */
- n64 = need_second = 0;
- if ((dpos & 63) = (spos & 63)
- && (height = 1 || line_length % 64 = 0)) {
- /* We may need a 32-byte copy to ensure 64 byte alignment. */
- need_second = (dpos + xincr_first) & 63;
- if ((need_second & 32) != need_second)
- printk(KERN_ERR "tgafb: need_second wrong\n");
- if (left >= need_second + 64) {
- left -= need_second;
- n64 = left / 64;
- left %= 64;
- } else
- need_second = 0;
- }
-
- /* Copy trailing full 32-byte sections. This will be the main
- loop if the 64 byte loop can't be used. */
- n32 = left / 32;
- left %= 32;
-
- /* Copy the trailing unaligned destination. */
- dmask_last = (1ul << left) - 1;
-
- tga_regs = par->tga_regs_base;
- tga_fb = par->tga_fb_base;
-
- /* Set up the MODE and PIXELSHIFT registers. */
- __raw_writel(TGA_MODE_SBM_8BPP|TGA_MODE_COPY, tga_regs+TGA_MODE_REG);
- __raw_writel(pixel_shift, tga_regs+TGA_PIXELSHIFT_REG);
- wmb();
-
- for (i = 0; i < height; ++i) {
- unsigned long j;
- void __iomem *sfb;
- void __iomem *dfb;
-
- sfb = tga_fb + spos;
- dfb = tga_fb + dpos;
- if (dmask_first) {
- __raw_writel(smask_first, sfb);
- wmb();
- __raw_writel(dmask_first, dfb);
- wmb();
- sfb += xincr_first;
- dfb += xincr_first;
- }
-
- if (need_second) {
- __raw_writel(0xffffffff, sfb);
- wmb();
- __raw_writel(0xffffffff, dfb);
- wmb();
- sfb += 32;
- dfb += 32;
- }
-
- if (n64 && (((unsigned long)sfb | (unsigned long)dfb) & 63))
- printk(KERN_ERR
- "tgafb: misaligned copy64 (s:%p, d:%p)\n",
- sfb, dfb);
-
- for (j = 0; j < n64; ++j) {
- __raw_writel(sfb - tga_fb, tga_regs+TGA_COPY64_SRC);
- wmb();
- __raw_writel(dfb - tga_fb, tga_regs+TGA_COPY64_DST);
- wmb();
- sfb += 64;
- dfb += 64;
- }
-
- for (j = 0; j < n32; ++j) {
- __raw_writel(0xffffffff, sfb);
- wmb();
- __raw_writel(0xffffffff, dfb);
- wmb();
- sfb += 32;
- dfb += 32;
- }
-
- if (dmask_last) {
- __raw_writel(0xffffffff, sfb);
- wmb();
- __raw_writel(dmask_last, dfb);
- wmb();
- }
-
- spos += yincr;
- dpos += yincr;
+ /* Do acceleration only if we are aligned on 8 pixels */
+ if ((dx | sx | width) & 7) {
+ cfb_copyarea(info, area);
+ return;
}
- /* Reset the MODE register to normal. */
- __raw_writel(TGA_MODE_SBM_8BPP|TGA_MODE_SIMPLE, tga_regs+TGA_MODE_REG);
-}
-
-/* The (almost) general case of backward copy in 8bpp mode. */
-static inline void
-copyarea_backward_8bpp(struct fb_info *info, u32 dx, u32 dy, u32 sx, u32 sy,
- u32 height, u32 width, u32 line_length,
- const struct fb_copyarea *area)
-{
- struct tga_par *par = (struct tga_par *) info->par;
- unsigned long i, left, yincr;
- unsigned long depos, sepos, dealign, sealign;
- u32 mask_first, mask_last;
- unsigned long n32;
- void __iomem *tga_regs;
- void __iomem *tga_fb;
-
yincr = line_length;
if (dy > sy) {
dy += height - 1;
sy += height - 1;
yincr = -yincr;
}
+ backward = dy = sy && dx > sx && dx < sx + width;
/* Compute the offsets and alignments in the frame buffer.
More than anything else, these control how we do copies. */
- depos = dy * line_length + dx + width;
- sepos = sy * line_length + sx + width;
- dealign = depos & 7;
- sealign = sepos & 7;
-
- /* ??? The documentation appears to be incorrect (or very
- misleading) wrt how pixel shifting works in backward copy
- mode, i.e. when PIXELSHIFT is negative. I give up for now.
- Do handle the common case of co-aligned backward copies,
- but frob everything else back on generic code. */
- if (dealign != sealign) {
- cfb_copyarea(info, area);
- return;
- }
-
- /* We begin the copy with the trailing pixels of the
- unaligned destination. */
- mask_first = (1ul << dealign) - 1;
- left = width - dealign;
-
- /* Care for small copies. */
- if (dealign > width) {
- mask_first ^= (1ul << (dealign - width)) - 1;
- left = 0;
- }
+ depos = dy * line_length + dx;
+ sepos = sy * line_length + sx;
+ if (backward)
+ depos += width, sepos += width;
/* Next copy full words at a time. */
- n32 = left / 32;
- left %= 32;
+ n32 = width / 32;
+ last_step = width % 32;
/* Finally copy the unaligned head of the span. */
- mask_last = -1 << (32 - left);
+ mask_last = (1ul << last_step) - 1;
+
+ if (!backward) {
+ step = 32;
+ last_step = 32;
+ } else {
+ step = -32;
+ last_step = -last_step;
+ sepos -= 32;
+ depos -= 32;
+ }
tga_regs = par->tga_regs_base;
tga_fb = par->tga_fb_base;
@@ -1381,25 +1216,33 @@ copyarea_backward_8bpp(struct fb_info *i
sfb = tga_fb + sepos;
dfb = tga_fb + depos;
- if (mask_first) {
- __raw_writel(mask_first, sfb);
- wmb();
- __raw_writel(mask_first, dfb);
- wmb();
- }
- for (j = 0; j < n32; ++j) {
- sfb -= 32;
- dfb -= 32;
+ for (j = 0; j < n32; j++) {
+ if (j < 2 && j + 1 < n32 && !backward &&
+ !(((unsigned long)sfb | (unsigned long)dfb) & 63)) {
+ do {
+ __raw_writel(sfb - tga_fb, tga_regs+TGA_COPY64_SRC);
+ wmb();
+ __raw_writel(dfb - tga_fb, tga_regs+TGA_COPY64_DST);
+ wmb();
+ sfb += 64;
+ dfb += 64;
+ j += 2;
+ } while (j + 1 < n32);
+ j--;
+ continue;
+ }
__raw_writel(0xffffffff, sfb);
wmb();
__raw_writel(0xffffffff, dfb);
wmb();
+ sfb += step;
+ dfb += step;
}
if (mask_last) {
- sfb -= 32;
- dfb -= 32;
+ sfb += last_step - step;
+ dfb += last_step - step;
__raw_writel(mask_last, sfb);
wmb();
__raw_writel(mask_last, dfb);
@@ -1460,14 +1303,9 @@ tgafb_copyarea(struct fb_info *info, con
else if (bpp = 32)
cfb_copyarea(info, area);
- /* Detect overlapping source and destination that requires
- a backward copy. */
- else if (dy = sy && dx > sx && dx < sx + width)
- copyarea_backward_8bpp(info, dx, dy, sx, sy, height,
- width, line_length, area);
else
- copyarea_foreward_8bpp(info, dx, dy, sx, sy, height,
- width, line_length);
+ copyarea_8bpp(info, dx, dy, sx, sy, height,
+ width, line_length, area);
}
^ permalink raw reply
* [PATCH 7/7] tgafb: avoid restriction on modes with line length not a multiple of 64
From: Mikulas Patocka @ 2012-08-20 18:12 UTC (permalink / raw)
To: linux-fbdev
tgafb: avoid restriction on modes with line length not a multiple of 64
In tgafb there is a restriction that prevents the user from setting a
videomode with line length not a multiple of 64 bytes (for example
800x600 is not allowed).
The reason for this restriction it that functions copyarea_line_8bpp and
copyarea_line_32bpp can not handle a line length that is not a multiple
of 64 bytes.
This patch removes this restriction on mode setting and makes sure that
the functions copyarea_line_8bpp and copyarea_line_32bpp are called only
if line length is a multiple of 64 bytes. If we set a mode 800x600,
the functions copyarea_line_8bpp and copyarea_line_32bpp are not used,
generic functions for copying are used instead and it works just fine.
Signed-off-by: Mikulas Patocka <mikulas@artax.karlin.mff.cuni.cz>
---
drivers/video/tgafb.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
Index: linux-3.6-rc2-fast/drivers/video/tgafb.c
=================================--- linux-3.6-rc2-fast.orig/drivers/video/tgafb.c 2012-08-20 19:40:02.000000000 +0200
+++ linux-3.6-rc2-fast/drivers/video/tgafb.c 2012-08-20 19:40:33.000000000 +0200
@@ -202,8 +202,8 @@ tgafb_check_var(struct fb_var_screeninfo
return -EINVAL;
/* Some of the acceleration routines assume the line width is
- a multiple of 64 bytes. */
- if (var->xres * (par->tga_type = TGA_TYPE_8PLANE ? 1 : 4) % 64)
+ a multiple of 8 bytes. */
+ if (var->xres % 8)
return -EINVAL;
return 0;
@@ -1290,7 +1290,7 @@ tgafb_copyarea(struct fb_info *info, con
bpp = info->var.bits_per_pixel;
/* Detect copies of the entire line. */
- if (width * (bpp >> 3) = line_length) {
+ if (!(line_length & 63) && width * (bpp >> 3) = line_length) {
if (bpp = 8)
copyarea_line_8bpp(info, dy, sy, height, width);
else
^ permalink raw reply
* [PATCH] video: hpfb: Fix error handling
From: Emil Goode @ 2012-08-20 18:32 UTC (permalink / raw)
To: FlorianSchandinat; +Cc: linux-fbdev, linux-kernel, kernel-janitors, Emil Goode
This patch solves problems with the error handling by
introducing labels for proper error paths and it also
frees resources that where missed.
Signed-off-by: Emil Goode <emilgoode@gmail.com>
---
drivers/video/hpfb.c | 28 +++++++++++++++++++++-------
1 file changed, 21 insertions(+), 7 deletions(-)
diff --git a/drivers/video/hpfb.c b/drivers/video/hpfb.c
index ebf8495..7324865 100644
--- a/drivers/video/hpfb.c
+++ b/drivers/video/hpfb.c
@@ -210,6 +210,7 @@ static int __devinit hpfb_init_one(unsigned long phys_base,
unsigned long virt_base)
{
unsigned long fboff, fb_width, fb_height, fb_start;
+ int ret;
fb_regs = virt_base;
fboff = (in_8(fb_regs + HPFB_FBOMSB) << 8) | in_8(fb_regs + HPFB_FBOLSB);
@@ -290,19 +291,29 @@ static int __devinit hpfb_init_one(unsigned long phys_base,
fb_info.var = hpfb_defined;
fb_info.screen_base = (char *)fb_start;
- fb_alloc_cmap(&fb_info.cmap, 1 << hpfb_defined.bits_per_pixel, 0);
+ ret = fb_alloc_cmap(&fb_info.cmap, 1 << hpfb_defined.bits_per_pixel, 0);
+ if (ret < 0)
+ goto unmap_screen_base;
- if (register_framebuffer(&fb_info) < 0) {
- fb_dealloc_cmap(&fb_info.cmap);
- iounmap(fb_info.screen_base);
- fb_info.screen_base = NULL;
- return 1;
- }
+ ret = register_framebuffer(&fb_info);
+ if (ret < 0)
+ goto dealloc_cmap;
printk(KERN_INFO "fb%d: %s frame buffer device\n",
fb_info.node, fb_info.fix.id);
return 0;
+
+dealloc_cmap:
+ fb_dealloc_cmap(&fb_info.cmap);
+
+unmap_screen_base:
+ if (fb_info.screen_base) {
+ iounmap(fb_info.screen_base);
+ fb_info.screen_base = NULL;
+ }
+
+ return ret;
}
/*
@@ -345,6 +356,9 @@ static void __devexit hpfb_remove_one(struct dio_dev *d)
if (d->scode >= DIOII_SCBASE)
iounmap((void *)fb_regs);
release_mem_region(d->resource.start, resource_size(&d->resource));
+ fb_dealloc_cmap(&fb_info.cmap);
+ if (fb_info.screen_base)
+ iounmap(fb_info.screen_base);
}
static struct dio_device_id hpfb_dio_tbl[] = {
--
1.7.10.4
^ permalink raw reply related
* Re: [RFC 0/5] Generic panel framework
From: Laurent Pinchart @ 2012-08-20 23:29 UTC (permalink / raw)
To: Tomi Valkeinen
Cc: linux-fbdev, Marcus Lorentzon, dri-devel, Kyungmin Park,
Richard Purdie, Sebastien Guiriec, Bryan Wu, linux-leds,
linux-media
In-Reply-To: <1345462770.2684.23.camel@deskari>
Hi Tomi,
On Monday 20 August 2012 14:39:30 Tomi Valkeinen wrote:
> On Sat, 2012-08-18 at 03:16 +0200, Laurent Pinchart wrote:
> > Hi Tomi,
> >
> > mipi-dbi-bus might not belong to include/video/panel/ though, as it can be
> > used for non-panel devices (at least in theory). The future mipi-dsi-bus
> > certainly will.
>
> They are both display busses. So while they could be used for anything,
> I find it quite unlikely as there are much better alternatives for
> generic bus needs.
My point is that they could be used for display devices other than panels.
This is especially true for DSI, as there are DSI to HDMI converters.
Technically speaking that's also true for DBI, as DBI chips convert from DBI
to DPI, but we can group both the DBI-to-DPI chip and the panel in a single
panel object.
> > Would you be able to send incremental patches on top of v2 to implement
> > the solution you have in mind ? It would be neat if you could also
> > implement mipi- dsi-bus for the OMAP DSS and test the code with a real
> > device :-)
>
> Yes, I'd like to try this out on OMAP, both DBI and DSI. However, I fear
> it'll be quite complex due to the dependencies all around we have in the
> current driver. We're working on simplifying things so that it'll be
> easier to try thing like the panel framework, though, so we're going in
> the right direction.
If you want the panel framework to support your use cases I'm afraid you will
need to work on that ;-)
> > > Generally about locks, if we define that panel ops may only be called
> > > exclusively, does it simplify things? I think we can make such
> > > requirements, as there should be only one display framework that handles
> > > the panel. Then we don't need locking for things like enable/disable.
> >
> > Pushing locking to callers would indeed simplify panel drivers, but we
> > need to make sure we won't need to expose a panel to several callers in
> > the future.
>
> I have a feeling that would be a bad idea.
>
> Display related stuff are quite sensitive to any delays, so any extra
> transactions over, say, DSI bus could cause a noticeable glitch on the
> screen. I'm not sure what are all the possible ops that a panel can
> offer, but I think all that affect the display or could cause delays
> should be handled by one controlling entity (drm or such). The
> controlling entity needs to handle locking anyway, so in that sense I
> don't think it's an extra burden for it.
>
> The things that come to my mind that could possibly cause calls to the
> panel outside drm: debugfs, sysfs, audio, backlight. Of those, I think
> backlight should go through drm. Audio, no idea. debugfs and sysfs
> locking needs to be handled by the panel driver, and they are a bit
> problematic as I guess having them requires full locking.
--
Regards,
Laurent Pinchart
^ permalink raw reply
* Re: [RFC 0/5] Generic panel framework
From: Tomi Valkeinen @ 2012-08-21 5:49 UTC (permalink / raw)
To: Laurent Pinchart
Cc: linux-fbdev, dri-devel, linux-leds, linux-media, Bryan Wu,
Richard Purdie, Marcus Lorentzon, Sumit Semwal, Archit Taneja,
Sebastien Guiriec, Inki Dae, Kyungmin Park
In-Reply-To: <3937256.gcqPRVoNWN@avalon>
[-- Attachment #1: Type: text/plain, Size: 1828 bytes --]
On Tue, 2012-08-21 at 01:29 +0200, Laurent Pinchart wrote:
> Hi Tomi,
>
> On Monday 20 August 2012 14:39:30 Tomi Valkeinen wrote:
> > On Sat, 2012-08-18 at 03:16 +0200, Laurent Pinchart wrote:
> > > Hi Tomi,
> > >
> > > mipi-dbi-bus might not belong to include/video/panel/ though, as it can be
> > > used for non-panel devices (at least in theory). The future mipi-dsi-bus
> > > certainly will.
> >
> > They are both display busses. So while they could be used for anything,
> > I find it quite unlikely as there are much better alternatives for
> > generic bus needs.
>
> My point is that they could be used for display devices other than panels.
> This is especially true for DSI, as there are DSI to HDMI converters.
> Technically speaking that's also true for DBI, as DBI chips convert from DBI
> to DPI, but we can group both the DBI-to-DPI chip and the panel in a single
> panel object.
Ah, ok. I thought "panels" would include these buffer/converter chips.
I think we should have one driver for one indivisible hardware entity.
So if you've got a panel module that contains DBI receiver, buffer
memory and a DPI panel, let's just have one "DBI panel" driver for it.
If we get lots of different panel modules containing the same DBI RX IP,
we could have the DBI IP part as a common library, but still have one
panel driver per panel module.
But how do you see the case for separate converter/buffer chips? Are
they part of the generic panel framework? I guess they kinda have to be.
On one side they use the "panel" API control the bus they are connected
to, and on the other they offer an API for the connected panel to use
the bus they provide.
Did you just mean we should have a separate directory for them, while
still part of the same framework, or...?
Tomi
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply
* RE: [PATCH v3] da8xx-fb: allow frame to complete after disabling LCDC
From: Manjunathappa, Prakash @ 2012-08-21 5:52 UTC (permalink / raw)
To: linux-fbdev
In-Reply-To: <1344950605-18945-1-git-send-email-prakash.pm@ti.com>
SGkgU2VraGFyLA0KDQpPbiBGcmksIEF1ZyAxNywgMjAxMiBhdCAxMjoxNTowMSwgTm9yaSwgU2Vr
aGFyIHdyb3RlOg0KPiBIaSBQcmFrYXNoLA0KPiANCj4gT24gOC8xNC8yMDEyIDY6NTMgUE0sIE1h
bmp1bmF0aGFwcGEsIFByYWthc2ggd3JvdGU6DQo+ID4gV2FpdCBmb3IgYWN0aXZlIGZyYW1lIHRy
YW5zZmVyIHRvIGNvbXBsZXRlIGFmdGVyIGRpc2FibGluZyBMQ0RDLg0KPiA+IEF0IHRoZSBzYW1l
IHRoaXMgd2FpdCBpcyBub3QgYmUgcmVxdWlyZWQgd2hlbiB0aGVyZSBhcmUgc3luYyBhbmQNCj4g
PiB1bmRlcmZsb3cgZXJyb3JzLg0KPiA+IE1vcmUgaW5mb3JtYXRpb24gb24gZGlzYWJsZSBhbmQg
cmVzZXQgc2VxdWVuY2UgY2FuIGJlIGZvdW5kIGluDQo+ID4gc2VjdGlvbiAxMy40LjYgb2YgQU0z
MzV4IFRSTSBAd3d3LnRpLmNvbS9hbTMzNXguDQo+ID4gDQo+ID4gU2lnbmVkLW9mZi1ieTogTWFu
anVuYXRoYXBwYSwgUHJha2FzaCA8cHJha2FzaC5wbUB0aS5jb20+DQo+ID4gLS0tDQo+ID4gQXBw
bGllcyBvbiB0b3Agb2YgZmJkZXYtbmV4dCBvZiBGbG9yaWFuIFRvYmlhcyBTY2hhbmRpbmF0J3Mg
dHJlZS4NCj4gPiBTaW5jZSB2MjoNCj4gPiBPcHRpbWl6ZWQgdGhlIGxjZF9kaXNhYmxlX3Jhc3Rl
ciBmdW5jdGlvbi4NCj4gPiBTaW5jZSB2MToNCj4gPiBDaGFuZ2VkIHRoZSBjb21taXQgbWVzc2Fn
ZSwgYWxzbyBhZGRlZCBsaW5rIHRvIGhhcmR3YXJlIHNwZWNpZmljYXRpb24uDQo+ID4gDQo+ID4g
IGRyaXZlcnMvdmlkZW8vZGE4eHgtZmIuYyB8ICAgNDkgKysrKysrKysrKysrKysrKysrKysrKysr
KysrKysrKysrKysrLS0tLS0tLS0tDQo+ID4gIDEgZmlsZXMgY2hhbmdlZCwgMzkgaW5zZXJ0aW9u
cygrKSwgMTAgZGVsZXRpb25zKC0pDQo+ID4gDQo+ID4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvdmlk
ZW8vZGE4eHgtZmIuYyBiL2RyaXZlcnMvdmlkZW8vZGE4eHgtZmIuYw0KPiA+IGluZGV4IDdhZTlk
NTMuLmNiNjk2ZmYgMTAwNjQ0DQo+ID4gLS0tIGEvZHJpdmVycy92aWRlby9kYTh4eC1mYi5jDQo+
ID4gKysrIGIvZHJpdmVycy92aWRlby9kYTh4eC1mYi5jDQo+ID4gQEAgLTQ4LDYgKzQ4LDcgQEAN
Cj4gPiAgI2RlZmluZSBMQ0RfUExfTE9BRF9ET05FCQlCSVQoNikNCj4gPiAgI2RlZmluZSBMQ0Rf
RklGT19VTkRFUkZMT1cJCUJJVCg1KQ0KPiA+ICAjZGVmaW5lIExDRF9TWU5DX0xPU1QJCQlCSVQo
MikNCj4gPiArI2RlZmluZSBMQ0RfRlJBTUVfRE9ORQkJCUJJVCgwKQ0KPiA+ICANCj4gPiAgLyog
TENEIERNQSBDb250cm9sIFJlZ2lzdGVyICovDQo+ID4gICNkZWZpbmUgTENEX0RNQV9CVVJTVF9T
SVpFKHgpCQkoKHgpIDw8IDQpDQo+ID4gQEAgLTI4OCwxMyArMjg5LDQxIEBAIHN0YXRpYyBpbmxp
bmUgdm9pZCBsY2RfZW5hYmxlX3Jhc3Rlcih2b2lkKQ0KPiA+ICB9DQo+ID4gIA0KPiA+ICAvKiBE
aXNhYmxlIHRoZSBSYXN0ZXIgRW5naW5lIG9mIHRoZSBMQ0QgQ29udHJvbGxlciAqLw0KPiA+IC1z
dGF0aWMgaW5saW5lIHZvaWQgbGNkX2Rpc2FibGVfcmFzdGVyKHZvaWQpDQo+ID4gK3N0YXRpYyBp
bmxpbmUgdm9pZCBsY2RfZGlzYWJsZV9yYXN0ZXIoYm9vbCB3YWl0X2Zvcl9mcmFtZV9kb25lKQ0K
PiA+ICB7DQo+ID4gIAl1MzIgcmVnOw0KPiA+ICsJdTMyIHN0YXRfcmVnID0gTENEX1NUQVRfUkVH
Ow0KPiA+ICsJdTMyIGxvb3BfY250ID0gMDsNCj4gPiAgDQo+ID4gIAlyZWcgPSBsY2RjX3JlYWQo
TENEX1JBU1RFUl9DVFJMX1JFRyk7DQo+ID4gIAlpZiAocmVnICYgTENEX1JBU1RFUl9FTkFCTEUp
DQo+ID4gIAkJbGNkY193cml0ZShyZWcgJiB+TENEX1JBU1RFUl9FTkFCTEUsIExDRF9SQVNURVJf
Q1RSTF9SRUcpOw0KPiA+ICsNCj4gPiArCWlmIChsY2RfcmV2aXNpb24gPT0gTENEX1ZFUlNJT05f
MikNCj4gPiArCQlzdGF0X3JlZyA9IExDRF9SQVdfU1RBVF9SRUc7DQo+ID4gKw0KPiA+ICsJaWYg
KHdhaXRfZm9yX2ZyYW1lX2RvbmUpIHsNCj4gPiArCQkvKg0KPiA+ICsJCSAqIDUwIG1pbGxpIHNl
Y29uZHMgc2hvdWxkIGJlIHN1ZmZpY2llbnQgZm9yIGEgZnJhbWUgdG8NCj4gPiArCQkgKiBjb21w
bGV0ZQ0KPiA+ICsJCSAqLw0KPiA+ICsJCWxvb3BfY250ID0gNTA7DQo+ID4gKwkJd2hpbGUgKCEo
bGNkY19yZWFkKHN0YXRfcmVnKSAmIExDRF9GUkFNRV9ET05FKSkgew0KPiA+ICsJCQkvKiBIYW5k
bGUgdGltZW91dCAqLw0KPiA+ICsJCQlpZiAodW5saWtlbHkoMCA9PSAtLWxvb3BfY250KSkgew0K
PiA+ICsJCQkJcHJfZXJyKCJMQ0QgQ29udHJvbGxlciB0aW1lZCBvdXRcbiIpOw0KPiA+ICsJCQkJ
YnJlYWs7DQo+ID4gKwkJCX0NCj4gPiArCQkJbWRlbGF5KDEpOw0KPiA+ICsJCX0NCj4gPiArCX0N
Cj4gDQo+IFRoZSBUUk0geW91IHJlZmVyZW5jZWQgaW4gdGhlIHBhdGNoIGRlc2NyaXB0aW9uIHN1
Z2dlc3RzIHdhaXRpbmcgZm9yDQo+IGZyYW1lIGRvbmUgaW50ZXJydXB0LiBDYW4gd2UgYWN0dWFs
bHkgd2FpdCBmb3IgdGhlIGludGVycnVwdCBoZXJlDQo+IGluc3RlYWQgb2YgYnVzeSBsb29waW5n
Pw0KPiANCg0KSSBhZ3JlZSwgd2lsbCBzdWJtaXQgbmV4dCB2ZXJzaW9uIG9mIHBhdGNoIGNvbnNp
ZGVyaW5nIGFib3ZlLg0KDQpUaGFua3MsDQpQcmFrYXNoDQoNCj4gVGhhbmtzLA0KPiBTZWtoYXIN
Cj4gDQoNCg=
^ permalink raw reply
* [PATCH 0/2] OMAPDSS: fixes for -rc
From: Tomi Valkeinen @ 2012-08-21 6:09 UTC (permalink / raw)
To: Florian Tobias Schandinat; +Cc: linux-fbdev, linux-omap, Tomi Valkeinen
Hi Florian,
Here are two small fixes for omapfb and omapdss. The first one fixes an old bug
that causes colors to be wrong on fb console. The other fixes SDI output that
got broken in the previous merge window.
Tomi
Grazvydas Ignotas (1):
OMAPFB: fix framebuffer console colors
Tomi Valkeinen (1):
OMAPDSS: Fix SDI PLL locking
drivers/video/omap2/dss/sdi.c | 14 ++++++++++++++
drivers/video/omap2/omapfb/omapfb-main.c | 2 +-
2 files changed, 15 insertions(+), 1 deletion(-)
--
1.7.9.5
^ permalink raw reply
* [PATCH 1/2] OMAPDSS: Fix SDI PLL locking
From: Tomi Valkeinen @ 2012-08-21 6:09 UTC (permalink / raw)
To: Florian Tobias Schandinat; +Cc: linux-fbdev, linux-omap, Tomi Valkeinen
In-Reply-To: <1345529388-3509-1-git-send-email-tomi.valkeinen@ti.com>
Commit f476ae9dab3234532d41d36beb4ba7be838fa786 (OMAPDSS: APPLY: Remove
DISPC writes to manager's lcd parameters in interface) broke the SDI
output, as it causes the SDI PLL locking to fail.
LCLK and PCLK divisors are located in shadow registers, and we normally
write them to DISPC registers when enabling the output. However, SDI
uses pck-free as source clock for its PLL, and pck-free is affected by
the divisors. And as we need the PLL before enabling the output, we need
to write the divisors early.
It seems just writing to the DISPC register is enough, and we don't need
to care about the shadow register mechanism for pck-free. The exact
reason for this is unknown.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Reported-by: Aaro Koskinen <aaro.koskinen@iki.fi>
---
drivers/video/omap2/dss/sdi.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/omap2/dss/sdi.c
index 5d31699..f43bfe1 100644
--- a/drivers/video/omap2/dss/sdi.c
+++ b/drivers/video/omap2/dss/sdi.c
@@ -105,6 +105,20 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
sdi_config_lcd_manager(dssdev);
+ /*
+ * LCLK and PCLK divisors are located in shadow registers, and we
+ * normally write them to DISPC registers when enabling the output.
+ * However, SDI uses pck-free as source clock for its PLL, and pck-free
+ * is affected by the divisors. And as we need the PLL before enabling
+ * the output, we need to write the divisors early.
+ *
+ * It seems just writing to the DISPC register is enough, and we don't
+ * need to care about the shadow register mechanism for pck-free. The
+ * exact reason for this is unknown.
+ */
+ dispc_mgr_set_clock_div(dssdev->manager->id,
+ &sdi.mgr_config.clock_info);
+
dss_sdi_init(dssdev->phy.sdi.datapairs);
r = dss_sdi_enable();
if (r)
--
1.7.9.5
^ permalink raw reply related
* [PATCH 2/2] OMAPFB: fix framebuffer console colors
From: Tomi Valkeinen @ 2012-08-21 6:09 UTC (permalink / raw)
To: Florian Tobias Schandinat
Cc: linux-fbdev, linux-omap, Grazvydas Ignotas, Tomi Valkeinen
In-Reply-To: <1345529388-3509-1-git-send-email-tomi.valkeinen@ti.com>
From: Grazvydas Ignotas <notasas@gmail.com>
omapfb does not currently set pseudo palette correctly for color depths
above 16bpp, making red text invisible, command like
echo -e '\e[0;31mRED' > /dev/tty1
will display nothing on framebuffer console in 24bpp mode.
This is because temporary variable is declared incorrectly, fix it.
Signed-off-by: Grazvydas Ignotas <notasas@gmail.com>
Cc: stable@vger.kernel.org # v3.x
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/omapfb/omapfb-main.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c
index 08ec1a7..fc671d3 100644
--- a/drivers/video/omap2/omapfb/omapfb-main.c
+++ b/drivers/video/omap2/omapfb/omapfb-main.c
@@ -1192,7 +1192,7 @@ static int _setcolreg(struct fb_info *fbi, u_int regno, u_int red, u_int green,
break;
if (regno < 16) {
- u16 pal;
+ u32 pal;
pal = ((red >> (16 - var->red.length)) <<
var->red.offset) |
((green >> (16 - var->green.length)) <<
--
1.7.9.5
^ permalink raw reply related
* [PATCH 00/23] OMAPDSS: Create output entities
From: Archit Taneja @ 2012-08-21 6:10 UTC (permalink / raw)
To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, rob, sumit.semwal, Archit Taneja
Create a new entity in OMAPDSS called outputs. These represent the
interfaces/outputs like DSI, HDMI etc. that a panel connects to. An output
sits in between an overlay manager and a panel. More details about outputs
are explained in the first patch of the series.
This series adds omap_dss_output as an entity along with omap_overlay,
omap_overlay_manager and omap_dss_device. It changes the code to establish
links between managers and outputs, and outputs and devices. The rest of the
patches replace omap_dss_device with omap_dss_output as the argument exposed
by interface driver functions(DSI, HDMI etc) for panel drivers.
Reference tree:
git://gitorious.org/~boddob/linux-omap-dss2/archit-dss2-clone.git 2-add-outputs
Archit Taneja (23):
OMAPDSS: outputs: Create a new entity called outputs
OMAPDSS: outputs: Create and initialize output instances
OMAPDSS: output: Add set/unset device ops for omap_dss_output
OMAPDSS: APPLY: Add manager set/unset output ops for
omap_overlay_manager
OMAPDSS: Remove manager->device references
OMAP_VOUT: Remove manager->device references
OMAPFB: remove manager->device references
OMAPDRM: Remove manager->device references
OMAPDSS: Create links between managers, outputs and devices
OMAPDSS: DPI: Pass outputs from panel driver to DPI interface driver
OMAPDSS: DSI: Remove dsi_pdev_map global struct
OMAPDSS: DSI: Pass outputs from panel driver to DSI interface driver
OMAPDSS: SDI: Pass outputs from panel driver to SDI interface driver
OMAPDSS: RFBI: Pass outputs from panel driver to RFBI interface
driver
OMAPDSS: RFBI: Add output pointers as arguments to all exported
functions
OMAPDSS: VENC: Pass outputs from panel driver to VENC interface
driver
OMAPDSS: HDMI: Pass outputs from panel driver to HDMI interface
driver
OMAPDSS: HDMI: Add output pointers as arguments to all functions used
by hdmi panel driver
OMAPDSS/OMAPFB: Change dssdev->manager references
OMAPDSS: MANAGER: Update display sysfs store
OMAPDSS: MANAGER: Get device via output
OMAPDSS: APPLY: Remove omap_dss_device references from
dss_ovl_enable/disable
OMAPDSS: Remove old way of setting manager and device links
drivers/media/video/omap/omap_vout.c | 81 ++++--
drivers/staging/omapdrm/omap_drv.c | 5 +-
drivers/video/omap2/displays/panel-acx565akm.c | 22 +-
drivers/video/omap2/displays/panel-generic-dpi.c | 27 +-
.../omap2/displays/panel-lgphilips-lb035q02.c | 16 +-
drivers/video/omap2/displays/panel-n8x0.c | 114 +++++---
.../omap2/displays/panel-nec-nl8048hl11-01b.c | 15 +-
drivers/video/omap2/displays/panel-picodlp.c | 15 +-
.../video/omap2/displays/panel-sharp-ls037v7dw01.c | 16 +-
drivers/video/omap2/displays/panel-taal.c | 201 ++++++++-----
drivers/video/omap2/displays/panel-tfp410.c | 17 +-
.../video/omap2/displays/panel-tpo-td043mtea1.c | 29 +-
drivers/video/omap2/dss/Makefile | 2 +-
drivers/video/omap2/dss/apply.c | 52 ++--
drivers/video/omap2/dss/core.c | 1 +
drivers/video/omap2/dss/dispc.c | 10 +-
drivers/video/omap2/dss/display.c | 11 +-
drivers/video/omap2/dss/dpi.c | 84 ++++--
drivers/video/omap2/dss/dsi.c | 307 +++++++++++---------
drivers/video/omap2/dss/dss.h | 50 ++--
drivers/video/omap2/dss/dss_features.c | 52 ++++
drivers/video/omap2/dss/dss_features.h | 1 +
drivers/video/omap2/dss/hdmi.c | 84 ++++--
drivers/video/omap2/dss/hdmi_panel.c | 85 ++++--
drivers/video/omap2/dss/manager.c | 48 ++-
drivers/video/omap2/dss/output.c | 125 ++++++++
drivers/video/omap2/dss/overlay.c | 96 +++---
drivers/video/omap2/dss/rfbi.c | 77 +++--
drivers/video/omap2/dss/sdi.c | 54 ++--
drivers/video/omap2/dss/venc.c | 78 +++--
drivers/video/omap2/dss/venc_panel.c | 53 +++-
drivers/video/omap2/omapfb/omapfb-ioctl.c | 4 +-
drivers/video/omap2/omapfb/omapfb-main.c | 7 +-
drivers/video/omap2/omapfb/omapfb.h | 5 +-
include/video/omapdss.h | 172 ++++++-----
35 files changed, 1350 insertions(+), 666 deletions(-)
create mode 100644 drivers/video/omap2/dss/output.c
--
1.7.9.5
^ permalink raw reply
* [PATCH 01/23] OMAPDSS: outputs: Create a new entity called outputs
From: Archit Taneja @ 2012-08-21 6:10 UTC (permalink / raw)
To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, rob, sumit.semwal, Archit Taneja
In-Reply-To: <1345528711-27801-1-git-send-email-archit@ti.com>
The current OMAPDSS design contains 3 software entities: Overlays, Managers and
Devices. These map to pipelines, overlay managers and the panels respectively in
hardware. One or more overlays connect to a manager to represent a composition,
the manager connects to a device(generally a display) to display the content.
The part of DSS hardware which isn't represented by any of the above entities
are interfaces/outputs that connect to an overlay manager, i.e blocks like DSI,
HDMI, VENC and so on. Currently, an overlay manager directly connects to the
display, and the output to which it is actually connected is ignored. The panel
driver of the display is responsible of calling output specific functions to
configure the output.
Adding outputs as a new software entity gives us the following benefits:
- Have exact information on the possible connections between managers and
outputs: A manager can't connect to each and every output, there only limited
hardware links between a manager's video port and some of the outputs.
- Remove hacks related to connecting managers and devices: Currently, default
links between managers and devices are set in a not so clean way. Matching is
done via comparing the device type, and the display types supported by the
manager. This isn't sufficient to establish all the possible links between
managers, outputs and devices in hardware.
- Make panel drivers more generic: The DSS panel drivers currently call
interface/output specific functions to configure the hardware IP. When making
these calls, the driver isn't actually aware of the underlying output. The
output driver extracts information from the panel's omap_dss_device pointer
to figure out which interface it is connected to, and then configures the
corresponding output block. An example of this is when a DSI panel calls
dsi functions, the dsi driver figures out whether the panel is connected
to DSI1 or DSI2. This isn't correct, and having output as entities will
give the panel driver the exact information on which output to configure.
Having outputs also gives the opportunity to make panel drivers generic
across different platforms/SoCs, this is achieved as omap specific output
calls can be replaced by ops of a particular output type.
- Have more complex connections between managers, outputs and devices: OMAPDSS
currently doesn't support use cases like 2 outputs connect to a single
device. This can be achieved by extending properties of outputs to connect to
more managers or devices.
- Represent writeback as an output: The writeback pipeline fits well in OMAPDSS
as compared to overlays, managers or devices.
Add a new struct to represent outputs. An output struct holds pointers to the
manager and device structs to which it is connected. Add functions which can
add an output, or look for one. Create an enum which represent each output
instance.
Signed-off-by: Archit Taneja <archit@ti.com>
---
drivers/video/omap2/dss/Makefile | 2 +-
drivers/video/omap2/dss/core.c | 1 +
drivers/video/omap2/dss/dss.h | 4 +++
drivers/video/omap2/dss/output.c | 58 ++++++++++++++++++++++++++++++++++++++
include/video/omapdss.h | 30 ++++++++++++++++++++
5 files changed, 94 insertions(+), 1 deletion(-)
create mode 100644 drivers/video/omap2/dss/output.c
diff --git a/drivers/video/omap2/dss/Makefile b/drivers/video/omap2/dss/Makefile
index 30a48fb..645f8c3 100644
--- a/drivers/video/omap2/dss/Makefile
+++ b/drivers/video/omap2/dss/Makefile
@@ -1,6 +1,6 @@
obj-$(CONFIG_OMAP2_DSS) += omapdss.o
omapdss-y := core.o dss.o dss_features.o dispc.o dispc_coefs.o display.o \
- manager.o overlay.o apply.o
+ manager.o overlay.o output.o apply.o
omapdss-$(CONFIG_OMAP2_DSS_DPI) += dpi.o
omapdss-$(CONFIG_OMAP2_DSS_RFBI) += rfbi.o
omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o venc_panel.o
diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/omap2/dss/core.c
index c35a248..2eccd74 100644
--- a/drivers/video/omap2/dss/core.c
+++ b/drivers/video/omap2/dss/core.c
@@ -239,6 +239,7 @@ static int __init omap_dss_probe(struct platform_device *pdev)
dss_init_overlay_managers(pdev);
dss_init_overlays(pdev);
+ dss_init_outputs();
r = dss_initialize_debugfs();
if (r)
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 41c00dc..8a7c94c 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -222,6 +222,10 @@ int dss_ovl_set_manager(struct omap_overlay *ovl,
struct omap_overlay_manager *mgr);
int dss_ovl_unset_manager(struct omap_overlay *ovl);
+/* output */
+struct omap_dss_output *dss_create_output(struct platform_device *pdev);
+void dss_init_outputs(void);
+
/* display */
int dss_suspend_all_devices(void);
int dss_resume_all_devices(void);
diff --git a/drivers/video/omap2/dss/output.c b/drivers/video/omap2/dss/output.c
new file mode 100644
index 0000000..034ebbe
--- /dev/null
+++ b/drivers/video/omap2/dss/output.c
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2012 Texas Instruments Ltd
+ * Author: Archit Taneja <archit@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#include <video/omapdss.h>
+
+#include "dss.h"
+
+static struct list_head output_list;
+
+struct omap_dss_output *dss_create_output(struct platform_device *pdev)
+{
+ struct omap_dss_output *out;
+
+ out = kzalloc(sizeof(struct omap_dss_output *), GFP_KERNEL);
+ if (!out)
+ return NULL;
+
+ out->pdev = pdev;
+
+ list_add_tail(&out->list, &output_list);
+
+ return out;
+}
+
+struct omap_dss_output *omap_dss_get_output(enum omap_dss_output_id id)
+{
+ struct omap_dss_output *out;
+
+ list_for_each_entry(out, &output_list, list) {
+ if (out->id = id)
+ return out;
+ }
+
+ return NULL;
+}
+
+void dss_init_outputs(void)
+{
+ INIT_LIST_HEAD(&output_list);
+}
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index b868123..0ba613f 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -207,6 +207,16 @@ enum omap_hdmi_flags {
OMAP_HDMI_SDA_SCL_EXTERNAL_PULLUP = 1 << 0,
};
+enum omap_dss_output_id {
+ OMAP_DSS_OUTPUT_DPI = 1 << 0,
+ OMAP_DSS_OUTPUT_DBI = 1 << 1,
+ OMAP_DSS_OUTPUT_SDI = 1 << 2,
+ OMAP_DSS_OUTPUT_DSI1 = 1 << 3,
+ OMAP_DSS_OUTPUT_VENC = 1 << 4,
+ OMAP_DSS_OUTPUT_DSI2 = 1 << 5,
+ OMAP_DSS_OUTPUT_HDMI = 1 << 6,
+};
+
/* RFBI */
struct rfbi_timings {
@@ -492,6 +502,24 @@ struct omap_dsi_pin_config {
int pins[OMAP_DSS_MAX_DSI_PINS];
};
+struct omap_dss_output {
+ struct list_head list;
+
+ /* display type supported by the output */
+ enum omap_display_type type;
+
+ /* output instance */
+ enum omap_dss_output_id id;
+
+ /* output's platform device pointer */
+ struct platform_device *pdev;
+
+ /* dynamic fields */
+ struct omap_overlay_manager *manager;
+
+ struct omap_dss_device *device;
+};
+
struct omap_dss_device {
struct device dev;
@@ -699,6 +727,8 @@ struct omap_overlay_manager *omap_dss_get_overlay_manager(int num);
int omap_dss_get_num_overlays(void);
struct omap_overlay *omap_dss_get_overlay(int num);
+struct omap_dss_output *omap_dss_get_output(enum omap_dss_output_id id);
+
void omapdss_default_get_resolution(struct omap_dss_device *dssdev,
u16 *xres, u16 *yres);
int omapdss_default_get_recommended_bpp(struct omap_dss_device *dssdev);
--
1.7.9.5
^ permalink raw reply related
* [PATCH 02/23] OMAPDSS: outputs: Create and initialize output instances
From: Archit Taneja @ 2012-08-21 6:10 UTC (permalink / raw)
To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, rob, sumit.semwal, Archit Taneja
In-Reply-To: <1345528711-27801-1-git-send-email-archit@ti.com>
Create output instances by having an init function in the probes of the platform
device drivers for different interfaces. Create a small function for each
interface to initialize the output entity's fields type and id.
In the probe of each interface driver, the output entities are created before
the *_probe_pdata() functions intentionally. This is done to ensure that the
output entity is prepared before the panels connected to the output are
registered. We need the output entities to be ready because OMAPDSS will try
to make connections between overlays, managers, outputs and devices during the
panel's probe.
Signed-off-by: Archit Taneja <archit@ti.com>
---
drivers/video/omap2/dss/dpi.c | 20 ++++++++++++++++++++
drivers/video/omap2/dss/dsi.c | 26 ++++++++++++++++++++++++--
drivers/video/omap2/dss/hdmi.c | 18 ++++++++++++++++++
drivers/video/omap2/dss/rfbi.c | 19 +++++++++++++++++++
drivers/video/omap2/dss/sdi.c | 20 ++++++++++++++++++++
drivers/video/omap2/dss/venc.c | 20 ++++++++++++++++++++
6 files changed, 121 insertions(+), 2 deletions(-)
diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c
index f260343..4eca2e7 100644
--- a/drivers/video/omap2/dss/dpi.c
+++ b/drivers/video/omap2/dss/dpi.c
@@ -408,10 +408,30 @@ static void __init dpi_probe_pdata(struct platform_device *pdev)
}
}
+static int __init dpi_init_output(struct platform_device *pdev)
+{
+ struct omap_dss_output *out;
+
+ out = dss_create_output(pdev);
+ if (!out)
+ return -ENOMEM;
+
+ out->id = OMAP_DSS_OUTPUT_DPI;
+ out->type = OMAP_DISPLAY_TYPE_DPI;
+
+ return 0;
+}
+
static int __init omap_dpi_probe(struct platform_device *pdev)
{
+ int r;
+
mutex_init(&dpi.lock);
+ r = dpi_init_output(pdev);
+ if (r)
+ return r;
+
dpi_probe_pdata(pdev);
return 0;
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index 659b6cd..22e0873 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -4903,6 +4903,23 @@ static void __init dsi_probe_pdata(struct platform_device *dsidev)
}
}
+static int __init dsi_init_output(struct platform_device *dsidev,
+ struct dsi_data *dsi)
+{
+ struct omap_dss_output *out;
+
+ out = dss_create_output(dsidev);
+ if (!out)
+ return -ENOMEM;
+
+ out->id = dsi->module_id = 0 ?
+ OMAP_DSS_OUTPUT_DSI1 : OMAP_DSS_OUTPUT_DSI2;
+
+ out->type = OMAP_DISPLAY_TYPE_DSI;
+
+ return 0;
+}
+
/* DSI1 HW IP initialisation */
static int __init omap_dsihw_probe(struct platform_device *dsidev)
{
@@ -4997,10 +5014,14 @@ static int __init omap_dsihw_probe(struct platform_device *dsidev)
else
dsi->num_lanes_supported = 3;
- dsi_probe_pdata(dsidev);
-
dsi_runtime_put(dsidev);
+ r = dsi_init_output(dsidev, dsi);
+ if (r)
+ goto err_init_output;
+
+ dsi_probe_pdata(dsidev);
+
if (dsi->module_id = 0)
dss_debugfs_create_file("dsi1_regs", dsi1_dump_regs);
else if (dsi->module_id = 1)
@@ -5014,6 +5035,7 @@ static int __init omap_dsihw_probe(struct platform_device *dsidev)
#endif
return 0;
+err_init_output:
err_runtime_get:
pm_runtime_disable(&dsidev->dev);
dsi_put_clocks(dsidev);
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
index 0cdf246..d32dbc3 100644
--- a/drivers/video/omap2/dss/hdmi.c
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -890,6 +890,20 @@ static void __init hdmi_probe_pdata(struct platform_device *pdev)
}
}
+static int __init hdmi_init_output(struct platform_device *pdev)
+{
+ struct omap_dss_output *out;
+
+ out = dss_create_output(pdev);
+ if (!out)
+ return -ENOMEM;
+
+ out->id = OMAP_DSS_OUTPUT_HDMI;
+ out->type = OMAP_DISPLAY_TYPE_HDMI;
+
+ return 0;
+}
+
/* HDMI HW IP initialisation */
static int __init omapdss_hdmihw_probe(struct platform_device *pdev)
{
@@ -933,6 +947,10 @@ static int __init omapdss_hdmihw_probe(struct platform_device *pdev)
dss_debugfs_create_file("hdmi", hdmi_dump_regs);
+ r = hdmi_init_output(pdev);
+ if (r)
+ return r;
+
hdmi_probe_pdata(pdev);
return 0;
diff --git a/drivers/video/omap2/dss/rfbi.c b/drivers/video/omap2/dss/rfbi.c
index 5a9c0e9..9d9244c 100644
--- a/drivers/video/omap2/dss/rfbi.c
+++ b/drivers/video/omap2/dss/rfbi.c
@@ -967,6 +967,20 @@ static void __init rfbi_probe_pdata(struct platform_device *pdev)
}
}
+static int __init rfbi_init_output(struct platform_device *pdev)
+{
+ struct omap_dss_output *out;
+
+ out = dss_create_output(pdev);
+ if (!out)
+ return -ENOMEM;
+
+ out->id = OMAP_DSS_OUTPUT_DBI;
+ out->type = OMAP_DISPLAY_TYPE_DBI;
+
+ return 0;
+}
+
/* RFBI HW IP initialisation */
static int __init omap_rfbihw_probe(struct platform_device *pdev)
{
@@ -1018,10 +1032,15 @@ static int __init omap_rfbihw_probe(struct platform_device *pdev)
dss_debugfs_create_file("rfbi", rfbi_dump_regs);
+ r = rfbi_init_output(pdev);
+ if (r)
+ goto err_init_output;
+
rfbi_probe_pdata(pdev);
return 0;
+err_init_output:
err_runtime_get:
pm_runtime_disable(&pdev->dev);
return r;
diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/omap2/dss/sdi.c
index 3bf1bfe..a5632d0 100644
--- a/drivers/video/omap2/dss/sdi.c
+++ b/drivers/video/omap2/dss/sdi.c
@@ -216,8 +216,28 @@ static void __init sdi_probe_pdata(struct platform_device *pdev)
}
}
+static int __init sdi_init_output(struct platform_device *pdev)
+{
+ struct omap_dss_output *out;
+
+ out = dss_create_output(pdev);
+ if (!out)
+ return -ENOMEM;
+
+ out->id = OMAP_DSS_OUTPUT_SDI;
+ out->type = OMAP_DISPLAY_TYPE_SDI;
+
+ return 0;
+}
+
static int __init omap_sdi_probe(struct platform_device *pdev)
{
+ int r;
+
+ r = sdi_init_output(pdev);
+ if (r)
+ return r;
+
sdi_probe_pdata(pdev);
return 0;
diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c
index 7d3eef8..264c5ec 100644
--- a/drivers/video/omap2/dss/venc.c
+++ b/drivers/video/omap2/dss/venc.c
@@ -778,6 +778,20 @@ static void __init venc_probe_pdata(struct platform_device *pdev)
}
}
+static int __init venc_init_output(struct platform_device *pdev)
+{
+ struct omap_dss_output *out;
+
+ out = dss_create_output(pdev);
+ if (!out)
+ return -ENOMEM;
+
+ out->id = OMAP_DSS_OUTPUT_VENC;
+ out->type = OMAP_DISPLAY_TYPE_VENC;
+
+ return 0;
+}
+
/* VENC HW IP initialisation */
static int __init omap_venchw_probe(struct platform_device *pdev)
{
@@ -825,10 +839,16 @@ static int __init omap_venchw_probe(struct platform_device *pdev)
dss_debugfs_create_file("venc", venc_dump_regs);
+ r = venc_init_output(pdev);
+ if (r)
+ goto err_init_output;
+
venc_probe_pdata(pdev);
return 0;
+err_init_output:
+ venc_panel_exit();
err_panel_init:
err_runtime_get:
pm_runtime_disable(&pdev->dev);
--
1.7.9.5
^ permalink raw reply related
* [PATCH 03/23] OMAPDSS: output: Add set/unset device ops for omap_dss_output
From: Archit Taneja @ 2012-08-21 6:10 UTC (permalink / raw)
To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, rob, sumit.semwal, Archit Taneja
In-Reply-To: <1345528711-27801-1-git-send-email-archit@ti.com>
An output entity represented by the struct omap_dss_output connects to a
omap_dss_device entity. Add functions to set or unset an output's device. This
is similar to how managers and devices were connected previously. An output can
connect to a device without being connected to a manager. However, the output
needs to eventually connect to a manager so that the connected panel can be
enabled.
Keep the omap_overlay_manager pointer in omap_dss_device for now to prevent
breaking things. This will be removed later when outputs are supported
completely.
Signed-off-by: Archit Taneja <archit@ti.com>
---
drivers/video/omap2/dss/output.c | 67 ++++++++++++++++++++++++++++++++++++++
include/video/omapdss.h | 5 +++
2 files changed, 72 insertions(+)
diff --git a/drivers/video/omap2/dss/output.c b/drivers/video/omap2/dss/output.c
index 034ebbe..ac57b19 100644
--- a/drivers/video/omap2/dss/output.c
+++ b/drivers/video/omap2/dss/output.c
@@ -24,6 +24,70 @@
#include "dss.h"
static struct list_head output_list;
+static DEFINE_MUTEX(output_lock);
+
+static int dss_output_set_device(struct omap_dss_output *out,
+ struct omap_dss_device *dssdev)
+{
+ int r;
+
+ mutex_lock(&output_lock);
+
+ if (out->device) {
+ DSSERR("output already has device %s connected to it\n",
+ out->device->name);
+ r = -EINVAL;
+ goto err;
+ }
+
+ if (out->type != dssdev->type) {
+ DSSERR("output type and display type don't match\n");
+ r = -EINVAL;
+ goto err;
+ }
+
+ out->device = dssdev;
+ dssdev->output = out;
+
+ mutex_unlock(&output_lock);
+
+ return 0;
+err:
+ mutex_unlock(&output_lock);
+
+ return r;
+}
+
+static int dss_output_unset_device(struct omap_dss_output *out)
+{
+ int r;
+
+ mutex_lock(&output_lock);
+
+ if (!out->device) {
+ DSSERR("output doesn't have a device connected to it\n");
+ r = -EINVAL;
+ goto err;
+ }
+
+ if (out->device->state != OMAP_DSS_DISPLAY_DISABLED) {
+ DSSERR("device %s is not disabled, cannot unset device\n",
+ out->device->name);
+ r = -EINVAL;
+ goto err;
+ }
+
+ out->device->output = NULL;
+ out->device = NULL;
+
+ mutex_unlock(&output_lock);
+
+ return 0;
+err:
+ mutex_unlock(&output_lock);
+
+ return r;
+}
struct omap_dss_output *dss_create_output(struct platform_device *pdev)
{
@@ -35,6 +99,9 @@ struct omap_dss_output *dss_create_output(struct platform_device *pdev)
out->pdev = pdev;
+ out->set_device = &dss_output_set_device;
+ out->unset_device = &dss_output_unset_device;
+
list_add_tail(&out->list, &output_list);
return out;
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index 0ba613f..2e40f27 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -518,6 +518,10 @@ struct omap_dss_output {
struct omap_overlay_manager *manager;
struct omap_dss_device *device;
+
+ int (*set_device) (struct omap_dss_output *out,
+ struct omap_dss_device *dssdev);
+ int (*unset_device) (struct omap_dss_output *out);
};
struct omap_dss_device {
@@ -619,6 +623,7 @@ struct omap_dss_device {
enum omap_display_caps caps;
struct omap_overlay_manager *manager;
+ struct omap_dss_output *output;
enum omap_dss_display_state state;
--
1.7.9.5
^ permalink raw reply related
* [PATCH 04/23] OMAPDSS: APPLY: Add manager set/unset output ops for omap_overlay_manager
From: Archit Taneja @ 2012-08-21 6:10 UTC (permalink / raw)
To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, rob, sumit.semwal, Archit Taneja
In-Reply-To: <1345528711-27801-1-git-send-email-archit@ti.com>
Add set_output/unset_output ops for overlay managers, these form links between
managers and outputs. Create a function in dss features which tell all the
output instances that connect to a manager, use it when a manager tries to set
an output. Add a constraint of not unsetting an output when the manager is
enabled.
Keep the omap_dss_device pointer and set/unset_device ops in overlay_manager for
now to not break things. Keep the dss feature function get_supported_displays
as it's used in some places. These will be removed later.
Signed-off-by: Archit Taneja <archit@ti.com>
---
drivers/video/omap2/dss/apply.c | 70 ++++++++++++++++++++++++++++++++
drivers/video/omap2/dss/dss.h | 3 ++
drivers/video/omap2/dss/dss_features.c | 52 ++++++++++++++++++++++++
drivers/video/omap2/dss/dss_features.h | 1 +
drivers/video/omap2/dss/manager.c | 4 ++
include/video/omapdss.h | 5 +++
6 files changed, 135 insertions(+)
diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
index 74f1a58..d241407 100644
--- a/drivers/video/omap2/dss/apply.c
+++ b/drivers/video/omap2/dss/apply.c
@@ -1311,6 +1311,76 @@ err:
return r;
}
+int dss_mgr_set_output(struct omap_overlay_manager *mgr,
+ struct omap_dss_output *output)
+{
+ int r;
+
+ mutex_lock(&apply_lock);
+
+ if (mgr->output) {
+ DSSERR("manager %s is already connected to an output\n",
+ mgr->name);
+ r = -EINVAL;
+ goto err;
+ }
+
+ if ((mgr->supported_outputs & output->id) = 0) {
+ DSSERR("output does not support manager %s\n",
+ mgr->name);
+ r = -EINVAL;
+ goto err;
+ }
+
+ output->manager = mgr;
+ mgr->output = output;
+
+ mutex_unlock(&apply_lock);
+
+ return 0;
+err:
+ mutex_unlock(&apply_lock);
+ return r;
+}
+
+int dss_mgr_unset_output(struct omap_overlay_manager *mgr)
+{
+ int r;
+ struct mgr_priv_data *mp = get_mgr_priv(mgr);
+ unsigned long flags;
+
+ mutex_lock(&apply_lock);
+
+ if (!mgr->output) {
+ DSSERR("failed to unset output, output not set\n");
+ r = -EINVAL;
+ goto err;
+ }
+
+ spin_lock_irqsave(&data_lock, flags);
+
+ if (mp->enabled) {
+ DSSERR("output can't be unset when manager is enabled\n");
+ r = -EINVAL;
+ goto err1;
+ }
+
+ spin_unlock_irqrestore(&data_lock, flags);
+
+ mgr->output->manager = NULL;
+ mgr->output = NULL;
+
+ mutex_unlock(&apply_lock);
+
+ return 0;
+err1:
+ spin_unlock_irqrestore(&data_lock, flags);
+err:
+ mutex_unlock(&apply_lock);
+
+ return r;
+}
+
static void dss_apply_mgr_timings(struct omap_overlay_manager *mgr,
const struct omap_video_timings *timings)
{
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 8a7c94c..a119506 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -205,6 +205,9 @@ void dss_mgr_get_info(struct omap_overlay_manager *mgr,
int dss_mgr_set_device(struct omap_overlay_manager *mgr,
struct omap_dss_device *dssdev);
int dss_mgr_unset_device(struct omap_overlay_manager *mgr);
+int dss_mgr_set_output(struct omap_overlay_manager *mgr,
+ struct omap_dss_output *output);
+int dss_mgr_unset_output(struct omap_overlay_manager *mgr);
void dss_mgr_set_timings(struct omap_overlay_manager *mgr,
const struct omap_video_timings *timings);
void dss_mgr_set_lcd_config(struct omap_overlay_manager *mgr,
diff --git a/drivers/video/omap2/dss/dss_features.c b/drivers/video/omap2/dss/dss_features.c
index 9387097..43f8491 100644
--- a/drivers/video/omap2/dss/dss_features.c
+++ b/drivers/video/omap2/dss/dss_features.c
@@ -47,6 +47,7 @@ struct omap_dss_features {
const int num_mgrs;
const int num_ovls;
const enum omap_display_type *supported_displays;
+ const enum omap_dss_output_id *supported_outputs;
const enum omap_color_mode *supported_color_modes;
const enum omap_overlay_caps *overlay_caps;
const char * const *clksrc_names;
@@ -144,6 +145,46 @@ static const enum omap_display_type omap4_dss_supported_displays[] = {
OMAP_DISPLAY_TYPE_DSI,
};
+static const enum omap_dss_output_id omap2_dss_supported_outputs[] = {
+ /* OMAP_DSS_CHANNEL_LCD */
+ OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI,
+
+ /* OMAP_DSS_CHANNEL_DIGIT */
+ OMAP_DSS_OUTPUT_VENC,
+};
+
+static const enum omap_dss_output_id omap3430_dss_supported_outputs[] = {
+ /* OMAP_DSS_CHANNEL_LCD */
+ OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI |
+ OMAP_DSS_OUTPUT_SDI | OMAP_DSS_OUTPUT_DSI1,
+
+ /* OMAP_DSS_CHANNEL_DIGIT */
+ OMAP_DSS_OUTPUT_VENC,
+};
+
+static const enum omap_dss_output_id omap3630_dss_supported_outputs[] = {
+ /* OMAP_DSS_CHANNEL_LCD */
+ OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI |
+ OMAP_DSS_OUTPUT_DSI1,
+
+ /* OMAP_DSS_CHANNEL_DIGIT */
+ OMAP_DSS_OUTPUT_VENC,
+};
+
+static const enum omap_dss_output_id omap4_dss_supported_outputs[] = {
+ /* OMAP_DSS_CHANNEL_LCD */
+ OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI |
+ OMAP_DSS_OUTPUT_DSI1,
+
+ /* OMAP_DSS_CHANNEL_DIGIT */
+ OMAP_DSS_OUTPUT_VENC | OMAP_DSS_OUTPUT_HDMI |
+ OMAP_DSS_OUTPUT_DPI,
+
+ /* OMAP_DSS_CHANNEL_LCD2 */
+ OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI |
+ OMAP_DSS_OUTPUT_DSI2,
+};
+
static const enum omap_color_mode omap2_dss_supported_color_modes[] = {
/* OMAP_DSS_GFX */
OMAP_DSS_COLOR_CLUT1 | OMAP_DSS_COLOR_CLUT2 |
@@ -458,6 +499,7 @@ static const struct omap_dss_features omap2_dss_features = {
.num_mgrs = 2,
.num_ovls = 3,
.supported_displays = omap2_dss_supported_displays,
+ .supported_outputs = omap2_dss_supported_outputs,
.supported_color_modes = omap2_dss_supported_color_modes,
.overlay_caps = omap2_dss_overlay_caps,
.clksrc_names = omap2_dss_clk_source_names,
@@ -478,6 +520,7 @@ static const struct omap_dss_features omap3430_dss_features = {
.num_mgrs = 2,
.num_ovls = 3,
.supported_displays = omap3430_dss_supported_displays,
+ .supported_outputs = omap3430_dss_supported_outputs,
.supported_color_modes = omap3_dss_supported_color_modes,
.overlay_caps = omap3430_dss_overlay_caps,
.clksrc_names = omap3_dss_clk_source_names,
@@ -497,6 +540,7 @@ static const struct omap_dss_features omap3630_dss_features = {
.num_mgrs = 2,
.num_ovls = 3,
.supported_displays = omap3630_dss_supported_displays,
+ .supported_outputs = omap3630_dss_supported_outputs,
.supported_color_modes = omap3_dss_supported_color_modes,
.overlay_caps = omap3630_dss_overlay_caps,
.clksrc_names = omap3_dss_clk_source_names,
@@ -518,6 +562,7 @@ static const struct omap_dss_features omap4430_es1_0_dss_features = {
.num_mgrs = 3,
.num_ovls = 4,
.supported_displays = omap4_dss_supported_displays,
+ .supported_outputs = omap4_dss_supported_outputs,
.supported_color_modes = omap4_dss_supported_color_modes,
.overlay_caps = omap4_dss_overlay_caps,
.clksrc_names = omap4_dss_clk_source_names,
@@ -538,6 +583,7 @@ static const struct omap_dss_features omap4430_es2_0_1_2_dss_features = {
.num_mgrs = 3,
.num_ovls = 4,
.supported_displays = omap4_dss_supported_displays,
+ .supported_outputs = omap4_dss_supported_outputs,
.supported_color_modes = omap4_dss_supported_color_modes,
.overlay_caps = omap4_dss_overlay_caps,
.clksrc_names = omap4_dss_clk_source_names,
@@ -558,6 +604,7 @@ static const struct omap_dss_features omap4_dss_features = {
.num_mgrs = 3,
.num_ovls = 4,
.supported_displays = omap4_dss_supported_displays,
+ .supported_outputs = omap4_dss_supported_outputs,
.supported_color_modes = omap4_dss_supported_color_modes,
.overlay_caps = omap4_dss_overlay_caps,
.clksrc_names = omap4_dss_clk_source_names,
@@ -627,6 +674,11 @@ enum omap_display_type dss_feat_get_supported_displays(enum omap_channel channel
return omap_current_dss_features->supported_displays[channel];
}
+enum omap_dss_output_id dss_feat_get_supported_outputs(enum omap_channel channel)
+{
+ return omap_current_dss_features->supported_outputs[channel];
+}
+
enum omap_color_mode dss_feat_get_supported_color_modes(enum omap_plane plane)
{
return omap_current_dss_features->supported_color_modes[plane];
diff --git a/drivers/video/omap2/dss/dss_features.h b/drivers/video/omap2/dss/dss_features.h
index 996ffcb..89a71d1 100644
--- a/drivers/video/omap2/dss/dss_features.h
+++ b/drivers/video/omap2/dss/dss_features.h
@@ -103,6 +103,7 @@ int dss_feat_get_num_ovls(void);
unsigned long dss_feat_get_param_min(enum dss_range_param param);
unsigned long dss_feat_get_param_max(enum dss_range_param param);
enum omap_display_type dss_feat_get_supported_displays(enum omap_channel channel);
+enum omap_dss_output_id dss_feat_get_supported_outputs(enum omap_channel channel);
enum omap_color_mode dss_feat_get_supported_color_modes(enum omap_plane plane);
enum omap_overlay_caps dss_feat_get_overlay_caps(enum omap_plane plane);
bool dss_feat_color_mode_supported(enum omap_plane plane,
diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c
index 53710fa..e15fa5f 100644
--- a/drivers/video/omap2/dss/manager.c
+++ b/drivers/video/omap2/dss/manager.c
@@ -549,6 +549,8 @@ int dss_init_overlay_managers(struct platform_device *pdev)
mgr->set_device = &dss_mgr_set_device;
mgr->unset_device = &dss_mgr_unset_device;
+ mgr->set_output = &dss_mgr_set_output;
+ mgr->unset_output = &dss_mgr_unset_output;
mgr->apply = &omap_dss_mgr_apply;
mgr->set_manager_info = &dss_mgr_set_info;
mgr->get_manager_info = &dss_mgr_get_info;
@@ -558,6 +560,8 @@ int dss_init_overlay_managers(struct platform_device *pdev)
mgr->caps = 0;
mgr->supported_displays dss_feat_get_supported_displays(mgr->id);
+ mgr->supported_outputs + dss_feat_get_supported_outputs(mgr->id);
INIT_LIST_HEAD(&mgr->overlays);
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index 2e40f27..813672b 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -458,9 +458,11 @@ struct omap_overlay_manager {
enum omap_overlay_manager_caps caps;
struct list_head overlays;
enum omap_display_type supported_displays;
+ enum omap_dss_output_id supported_outputs;
/* dynamic fields */
struct omap_dss_device *device;
+ struct omap_dss_output *output;
/*
* The following functions do not block:
@@ -476,6 +478,9 @@ struct omap_overlay_manager {
int (*set_device)(struct omap_overlay_manager *mgr,
struct omap_dss_device *dssdev);
int (*unset_device)(struct omap_overlay_manager *mgr);
+ int (*set_output)(struct omap_overlay_manager *mgr,
+ struct omap_dss_output *output);
+ int (*unset_output)(struct omap_overlay_manager *mgr);
int (*set_manager_info)(struct omap_overlay_manager *mgr,
struct omap_overlay_manager_info *info);
--
1.7.9.5
^ permalink raw reply related
* [PATCH 05/23] OMAPDSS: Remove manager->device references
From: Archit Taneja @ 2012-08-21 6:10 UTC (permalink / raw)
To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, rob, sumit.semwal, Archit Taneja
In-Reply-To: <1345528711-27801-1-git-send-email-archit@ti.com>
With the introduction of output entities, managers will now connect to outputs.
Create a helper op for managers named get_device. This will abstract away the
information on how to get the device from an overlay manager. The get_device
op currently retrieves the output via a manager->device reference. This will
be later replaced by a manager->output->device reference.
Signed-off-by: Archit Taneja <archit@ti.com>
---
drivers/video/omap2/dss/apply.c | 6 ++++--
drivers/video/omap2/dss/dispc.c | 10 +++++++---
drivers/video/omap2/dss/manager.c | 19 ++++++++++++++-----
include/video/omapdss.h | 2 ++
4 files changed, 27 insertions(+), 10 deletions(-)
diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
index d241407..8a05cbc 100644
--- a/drivers/video/omap2/dss/apply.c
+++ b/drivers/video/omap2/dss/apply.c
@@ -1607,7 +1607,8 @@ int dss_ovl_enable(struct omap_overlay *ovl)
goto err1;
}
- if (ovl->manager = NULL || ovl->manager->device = NULL) {
+ if (ovl->manager = NULL ||
+ ovl->manager->get_device(ovl->manager) = NULL) {
r = -EINVAL;
goto err1;
}
@@ -1676,7 +1677,8 @@ int dss_ovl_disable(struct omap_overlay *ovl)
goto err;
}
- if (ovl->manager = NULL || ovl->manager->device = NULL) {
+ if (ovl->manager = NULL ||
+ ovl->manager->get_device(ovl->manager) = NULL) {
r = -EINVAL;
goto err;
}
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index ff52702..33061f5 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -3503,7 +3503,7 @@ static void dispc_error_worker(struct work_struct *work)
bit = mgr_desc[i].sync_lost_irq;
if (bit & errors) {
- struct omap_dss_device *dssdev = mgr->device;
+ struct omap_dss_device *dssdev = mgr->get_device(mgr);
bool enable;
DSSERR("SYNC_LOST on channel %s, restarting the output "
@@ -3534,9 +3534,13 @@ static void dispc_error_worker(struct work_struct *work)
DSSERR("OCP_ERR\n");
for (i = 0; i < omap_dss_get_num_overlay_managers(); ++i) {
struct omap_overlay_manager *mgr;
+ struct omap_dss_device *dssdev;
+
mgr = omap_dss_get_overlay_manager(i);
- if (mgr->device && mgr->device->driver)
- mgr->device->driver->disable(mgr->device);
+ dssdev = mgr->get_device(mgr);
+
+ if (dssdev && dssdev->driver)
+ dssdev->driver->disable(dssdev);
}
}
diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c
index e15fa5f..fd39f66 100644
--- a/drivers/video/omap2/dss/manager.c
+++ b/drivers/video/omap2/dss/manager.c
@@ -43,8 +43,10 @@ static ssize_t manager_name_show(struct omap_overlay_manager *mgr, char *buf)
static ssize_t manager_display_show(struct omap_overlay_manager *mgr, char *buf)
{
- return snprintf(buf, PAGE_SIZE, "%s\n",
- mgr->device ? mgr->device->name : "<none>");
+ struct omap_dss_device *dssdev = mgr->get_device(mgr);
+
+ return snprintf(buf, PAGE_SIZE, "%s\n", dssdev ?
+ dssdev->name : "<none>");
}
static ssize_t manager_display_store(struct omap_overlay_manager *mgr,
@@ -72,7 +74,7 @@ static ssize_t manager_display_store(struct omap_overlay_manager *mgr,
if (dssdev)
DSSDBG("display %s found\n", dssdev->name);
- if (mgr->device) {
+ if (mgr->get_device(mgr)) {
r = mgr->unset_device(mgr);
if (r) {
DSSERR("failed to unset display\n");
@@ -490,9 +492,15 @@ static struct kobj_type manager_ktype = {
.default_attrs = manager_sysfs_attrs,
};
+static inline struct omap_dss_device *dss_mgr_get_device(struct omap_overlay_manager *mgr)
+{
+ return mgr->device;
+}
+
static int dss_mgr_wait_for_vsync(struct omap_overlay_manager *mgr)
{
unsigned long timeout = msecs_to_jiffies(500);
+ struct omap_dss_device *dssdev = mgr->get_device(mgr);
u32 irq;
int r;
@@ -500,9 +508,9 @@ static int dss_mgr_wait_for_vsync(struct omap_overlay_manager *mgr)
if (r)
return r;
- if (mgr->device->type = OMAP_DISPLAY_TYPE_VENC)
+ if (dssdev->type = OMAP_DISPLAY_TYPE_VENC)
irq = DISPC_IRQ_EVSYNC_ODD;
- else if (mgr->device->type = OMAP_DISPLAY_TYPE_HDMI)
+ else if (dssdev->type = OMAP_DISPLAY_TYPE_HDMI)
irq = DISPC_IRQ_EVSYNC_EVEN;
else
irq = dispc_mgr_get_vsync_irq(mgr->id);
@@ -556,6 +564,7 @@ int dss_init_overlay_managers(struct platform_device *pdev)
mgr->get_manager_info = &dss_mgr_get_info;
mgr->wait_for_go = &dss_mgr_wait_for_go;
mgr->wait_for_vsync = &dss_mgr_wait_for_vsync;
+ mgr->get_device = &dss_mgr_get_device;
mgr->caps = 0;
mgr->supported_displays diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index 813672b..361d41e 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -490,6 +490,8 @@ struct omap_overlay_manager {
int (*apply)(struct omap_overlay_manager *mgr);
int (*wait_for_go)(struct omap_overlay_manager *mgr);
int (*wait_for_vsync)(struct omap_overlay_manager *mgr);
+
+ struct omap_dss_device *(*get_device)(struct omap_overlay_manager *mgr);
};
/* 22 pins means 1 clk lane and 10 data lanes */
--
1.7.9.5
^ permalink raw reply related
* [PATCH 06/23] OMAP_VOUT: Remove manager->device references
From: Archit Taneja @ 2012-08-21 6:10 UTC (permalink / raw)
To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, rob, sumit.semwal, Archit Taneja
In-Reply-To: <1345528711-27801-1-git-send-email-archit@ti.com>
With the introduction of output entities, managers will now connect to outputs.
Use the helper op for managers named get_device. This will abstract away the
information on how to get the device from an overlay manager.
Using the helper function will reduce the number of pointer dereferences a user
of OMAPDSS needs to do and reduce risk of a NULL dereference.
Signed-off-by: Archit Taneja <archit@ti.com>
---
drivers/media/video/omap/omap_vout.c | 81 ++++++++++++++++++++++++----------
1 file changed, 57 insertions(+), 24 deletions(-)
diff --git a/drivers/media/video/omap/omap_vout.c b/drivers/media/video/omap/omap_vout.c
index 88cf9d9..0ebf87e 100644
--- a/drivers/media/video/omap/omap_vout.c
+++ b/drivers/media/video/omap/omap_vout.c
@@ -454,11 +454,16 @@ static int omapvid_init(struct omap_vout_device *vout, u32 addr)
win = &vout->win;
for (i = 0; i < ovid->num_overlays; i++) {
+ struct omap_dss_device *dssdev;
+
ovl = ovid->overlays[i];
- if (!ovl->manager || !ovl->manager->device)
+ dssdev = ovl->manager ?
+ ovl->manager->get_device(ovl->manager) : NULL;
+
+ if (!dssdev)
return -EINVAL;
- timing = &ovl->manager->device->panel.timings;
+ timing = &dssdev->panel.timings;
outw = win->w.width;
outh = win->w.height;
@@ -515,8 +520,12 @@ static int omapvid_apply_changes(struct omap_vout_device *vout)
struct omapvideo_info *ovid = &vout->vid_info;
for (i = 0; i < ovid->num_overlays; i++) {
+ struct omap_dss_device *dssdev;
+
ovl = ovid->overlays[i];
- if (!ovl->manager || !ovl->manager->device)
+ dssdev = ovl->manager ?
+ ovl->manager->get_device(ovl->manager) : NULL;
+ if (!dssdev)
return -EINVAL;
ovl->manager->apply(ovl->manager);
}
@@ -579,12 +588,15 @@ static void omap_vout_isr(void *arg, unsigned int irqstatus)
ovid = &vout->vid_info;
ovl = ovid->overlays[0];
- /* get the display device attached to the overlay */
- if (!ovl->manager || !ovl->manager->device)
- return;
mgr_id = ovl->manager->id;
- cur_display = ovl->manager->device;
+
+ /* get the display device attached to the overlay */
+ cur_display = ovl->manager ?
+ ovl->manager->get_device(ovl->manager) : NULL;
+
+ if (!cur_display)
+ return;
spin_lock(&vout->vbq_lock);
do_gettimeofday(&timevalue);
@@ -948,7 +960,10 @@ static int omap_vout_release(struct file *file)
/* Disable all the overlay managers connected with this interface */
for (i = 0; i < ovid->num_overlays; i++) {
struct omap_overlay *ovl = ovid->overlays[i];
- if (ovl->manager && ovl->manager->device)
+ struct omap_dss_device *dssdev = ovl->manager ?
+ ovl->manager->get_device(ovl->manager) : NULL;
+
+ if (dssdev)
ovl->disable(ovl);
}
/* Turn off the pipeline */
@@ -1081,14 +1096,17 @@ static int vidioc_try_fmt_vid_out(struct file *file, void *fh,
struct omapvideo_info *ovid;
struct omap_video_timings *timing;
struct omap_vout_device *vout = fh;
+ struct omap_dss_device *dssdev;
ovid = &vout->vid_info;
ovl = ovid->overlays[0];
+ /* get the display device attached to the overlay */
+ dssdev = ovl->manager ? ovl->manager->get_device(ovl->manager) : NULL;
- if (!ovl->manager || !ovl->manager->device)
+ if (!dssdev)
return -EINVAL;
- /* get the display device attached to the overlay */
- timing = &ovl->manager->device->panel.timings;
+
+ timing = &dssdev->panel.timings;
vout->fbuf.fmt.height = timing->y_res;
vout->fbuf.fmt.width = timing->x_res;
@@ -1105,6 +1123,7 @@ static int vidioc_s_fmt_vid_out(struct file *file, void *fh,
struct omapvideo_info *ovid;
struct omap_video_timings *timing;
struct omap_vout_device *vout = fh;
+ struct omap_dss_device *dssdev;
if (vout->streaming)
return -EBUSY;
@@ -1113,13 +1132,14 @@ static int vidioc_s_fmt_vid_out(struct file *file, void *fh,
ovid = &vout->vid_info;
ovl = ovid->overlays[0];
+ dssdev = ovl->manager ? ovl->manager->get_device(ovl->manager) : NULL;
/* get the display device attached to the overlay */
- if (!ovl->manager || !ovl->manager->device) {
+ if (!dssdev) {
ret = -EINVAL;
goto s_fmt_vid_out_exit;
}
- timing = &ovl->manager->device->panel.timings;
+ timing = &dssdev->panel.timings;
/* We dont support RGB24-packed mode if vrfb rotation
* is enabled*/
@@ -1298,6 +1318,7 @@ static int vidioc_s_crop(struct file *file, void *fh, struct v4l2_crop *crop)
struct omapvideo_info *ovid;
struct omap_overlay *ovl;
struct omap_video_timings *timing;
+ struct omap_dss_device *dssdev;
if (vout->streaming)
return -EBUSY;
@@ -1305,13 +1326,15 @@ static int vidioc_s_crop(struct file *file, void *fh, struct v4l2_crop *crop)
mutex_lock(&vout->lock);
ovid = &vout->vid_info;
ovl = ovid->overlays[0];
+ /* get the display device attached to the overlay */
+ dssdev = ovl->manager ? ovl->manager->get_device(ovl->manager) : NULL;
- if (!ovl->manager || !ovl->manager->device) {
+ if (!dssdev) {
ret = -EINVAL;
goto s_crop_err;
}
- /* get the display device attached to the overlay */
- timing = &ovl->manager->device->panel.timings;
+
+ timing = &dssdev->panel.timings;
if (is_rotation_90_or_270(vout)) {
vout->fbuf.fmt.height = timing->x_res;
@@ -1666,8 +1689,9 @@ static int vidioc_streamon(struct file *file, void *fh, enum v4l2_buf_type i)
for (j = 0; j < ovid->num_overlays; j++) {
struct omap_overlay *ovl = ovid->overlays[j];
+ struct omap_overlay_manager *mgr = ovl->manager;
- if (ovl->manager && ovl->manager->device) {
+ if (mgr && mgr->get_device(mgr)) {
struct omap_overlay_info info;
ovl->get_overlay_info(ovl, &info);
info.paddr = addr;
@@ -1690,8 +1714,10 @@ static int vidioc_streamon(struct file *file, void *fh, enum v4l2_buf_type i)
for (j = 0; j < ovid->num_overlays; j++) {
struct omap_overlay *ovl = ovid->overlays[j];
+ struct omap_dss_device *dssdev = ovl->manager ?
+ ovl->manager->get_device(ovl->manager) : NULL;
- if (ovl->manager && ovl->manager->device) {
+ if (dssdev) {
ret = ovl->enable(ovl);
if (ret)
goto streamon_err1;
@@ -1726,8 +1752,10 @@ static int vidioc_streamoff(struct file *file, void *fh, enum v4l2_buf_type i)
for (j = 0; j < ovid->num_overlays; j++) {
struct omap_overlay *ovl = ovid->overlays[j];
+ struct omap_dss_device *dssdev = ovl->manager ?
+ ovl->manager->get_device(ovl->manager) : NULL;
- if (ovl->manager && ovl->manager->device)
+ if (dssdev)
ovl->disable(ovl);
}
@@ -1890,8 +1918,9 @@ static int __init omap_vout_setup_video_data(struct omap_vout_device *vout)
struct video_device *vfd;
struct v4l2_pix_format *pix;
struct v4l2_control *control;
+ struct omap_overlay *ovl = vout->vid_info.overlays[0];
struct omap_dss_device *display - vout->vid_info.overlays[0]->manager->device;
+ ovl->manager->get_device(ovl->manager);
/* set the default pix */
pix = &vout->pix;
@@ -2205,8 +2234,10 @@ static int __init omap_vout_probe(struct platform_device *pdev)
*/
for (i = 1; i < vid_dev->num_overlays; i++) {
ovl = omap_dss_get_overlay(i);
- if (ovl->manager && ovl->manager->device) {
- def_display = ovl->manager->device;
+ dssdev = ovl->manager ? ovl->manager->get_device(ovl->manager) :
+ NULL;
+ if (dssdev) {
+ def_display = dssdev;
} else {
dev_warn(&pdev->dev, "cannot find display\n");
def_display = NULL;
@@ -2253,8 +2284,10 @@ probe_err1:
for (i = 1; i < vid_dev->num_overlays; i++) {
def_display = NULL;
ovl = omap_dss_get_overlay(i);
- if (ovl->manager && ovl->manager->device)
- def_display = ovl->manager->device;
+ dssdev = ovl->manager ? ovl->manager->get_device(ovl->manager) :
+ NULL;
+ if (dssdev)
+ def_display = dssdev;
if (def_display && def_display->driver)
def_display->driver->disable(def_display);
--
1.7.9.5
^ permalink raw reply related
* [PATCH 07/23] OMAPFB: remove manager->device references
From: Archit Taneja @ 2012-08-21 6:10 UTC (permalink / raw)
To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, rob, sumit.semwal, Archit Taneja
In-Reply-To: <1345528711-27801-1-git-send-email-archit@ti.com>
With the introduction of output entities, managers will now connect to outputs.
Use the helper op for managers named get_device. This will abstract away the
information on how to get the device from an overlay manager.
Using the helper function will reduce the number of pointer dereferences a user
of OMAPDSS needs to do and reduce risk of a NULL dereference.
Signed-off-by: Archit Taneja <archit@ti.com>
---
drivers/video/omap2/omapfb/omapfb-main.c | 7 +++++--
drivers/video/omap2/omapfb/omapfb.h | 5 +++--
2 files changed, 8 insertions(+), 4 deletions(-)
diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c
index fc671d3..c6992be 100644
--- a/drivers/video/omap2/omapfb/omapfb-main.c
+++ b/drivers/video/omap2/omapfb/omapfb-main.c
@@ -2353,6 +2353,7 @@ static int __init omapfb_probe(struct platform_device *pdev)
struct omap_overlay *ovl;
struct omap_dss_device *def_display;
struct omap_dss_device *dssdev;
+ struct omap_dss_device *mgr_device;
DBG("omapfb_probe\n");
@@ -2426,8 +2427,10 @@ static int __init omapfb_probe(struct platform_device *pdev)
/* gfx overlay should be the default one. find a display
* connected to that, and use it as default display */
ovl = omap_dss_get_overlay(0);
- if (ovl->manager && ovl->manager->device) {
- def_display = ovl->manager->device;
+ mgr_device = ovl->manager ?
+ ovl->manager->get_device(ovl->manager) : NULL;
+ if (mgr_device) {
+ def_display = mgr_device;
} else {
dev_warn(&pdev->dev, "cannot find default display\n");
def_display = NULL;
diff --git a/drivers/video/omap2/omapfb/omapfb.h b/drivers/video/omap2/omapfb/omapfb.h
index 30361a0..2782b1f 100644
--- a/drivers/video/omap2/omapfb/omapfb.h
+++ b/drivers/video/omap2/omapfb/omapfb.h
@@ -148,8 +148,9 @@ static inline struct omap_dss_device *fb2display(struct fb_info *fbi)
/* XXX: returns the display connected to first attached overlay */
for (i = 0; i < ofbi->num_overlays; i++) {
- if (ofbi->overlays[i]->manager)
- return ofbi->overlays[i]->manager->device;
+ struct omap_overlay_manager *mgr = ofbi->overlays[i]->manager;
+ if (mgr)
+ return mgr->get_device(mgr);
}
return NULL;
--
1.7.9.5
^ permalink raw reply related
* [PATCH 08/23] OMAPDRM: Remove manager->device references
From: Archit Taneja @ 2012-08-21 6:10 UTC (permalink / raw)
To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, rob, sumit.semwal, Archit Taneja
In-Reply-To: <1345528711-27801-1-git-send-email-archit@ti.com>
With the introduction of output entities, managers will now connect to outputs.
Use the helper op for managers named get_device. This will abstract away the
information on how to get the device from an overlay manager.
Using the helper function will reduce the number of pointer dereferences a user
of OMAPDSS needs to do and reduce risk of a NULL dereference.
Signed-off-by: Archit Taneja <archit@ti.com>
---
drivers/staging/omapdrm/omap_drv.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/staging/omapdrm/omap_drv.c b/drivers/staging/omapdrm/omap_drv.c
index 4beab94..64a354a 100644
--- a/drivers/staging/omapdrm/omap_drv.c
+++ b/drivers/staging/omapdrm/omap_drv.c
@@ -106,7 +106,8 @@ static void dump_video_chains(void)
for (i = 0; i < omap_dss_get_num_overlays(); i++) {
struct omap_overlay *ovl = omap_dss_get_overlay(i);
struct omap_overlay_manager *mgr = ovl->manager;
- struct omap_dss_device *dssdev = mgr ? mgr->device : NULL;
+ struct omap_dss_device *dssdev = mgr ?
+ mgr->get_device(mgr) : NULL;
if (dssdev) {
DBG("%d: %s -> %s -> %s", i, ovl->name, mgr->name,
dssdev->name);
@@ -185,7 +186,7 @@ static int create_connector(struct drm_device *dev,
for (j = 0; j < priv->num_encoders; j++) {
struct omap_overlay_manager *mgr omap_encoder_get_manager(priv->encoders[j]);
- if (mgr->device = dssdev) {
+ if (mgr->get_device(mgr) = dssdev) {
drm_mode_connector_attach_encoder(connector,
priv->encoders[j]);
}
--
1.7.9.5
^ permalink raw reply related
* [PATCH 09/23] OMAPDSS: Create links between managers, outputs and devices
From: Archit Taneja @ 2012-08-21 6:10 UTC (permalink / raw)
To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, rob, sumit.semwal, Archit Taneja
In-Reply-To: <1345528711-27801-1-git-send-email-archit@ti.com>
Links between DSS entities are made in dss_recheck_connections when a new panel
is probed. Rewrite the code in dss_recheck_connections to link managers to
outputs, and outputs to devices.
The fields in omap_dss_device struct gives information on which output and
manager to connect to. The desired manager and output pointers are retrieved and
prepared(existing outputs/devices unset, if default display)) to form the
desired links. The output is linked to the device, and then the manager to the
output. If a probed device's required manager isn't free, the required output
is still connected to the device so that it's easier to use the panel in the
future.
Signed-off-by: Archit Taneja <archit@ti.com>
---
drivers/video/omap2/dss/overlay.c | 96 +++++++++++++++++++++----------------
1 file changed, 56 insertions(+), 40 deletions(-)
diff --git a/drivers/video/omap2/dss/overlay.c b/drivers/video/omap2/dss/overlay.c
index 952c6fa..07605f1 100644
--- a/drivers/video/omap2/dss/overlay.c
+++ b/drivers/video/omap2/dss/overlay.c
@@ -525,51 +525,67 @@ void dss_init_overlays(struct platform_device *pdev)
void dss_recheck_connections(struct omap_dss_device *dssdev, bool force)
{
int i;
- struct omap_overlay_manager *lcd_mgr;
- struct omap_overlay_manager *tv_mgr;
- struct omap_overlay_manager *lcd2_mgr = NULL;
- struct omap_overlay_manager *lcd3_mgr = NULL;
struct omap_overlay_manager *mgr = NULL;
+ struct omap_dss_output *out = NULL;
+ enum omap_dss_output_id id;
+
+ switch (dssdev->type) {
+ case OMAP_DISPLAY_TYPE_DPI:
+ out = omap_dss_get_output(OMAP_DSS_OUTPUT_DPI);
+ break;
+ case OMAP_DISPLAY_TYPE_DBI:
+ out = omap_dss_get_output(OMAP_DSS_OUTPUT_DBI);
+ break;
+ case OMAP_DISPLAY_TYPE_SDI:
+ out = omap_dss_get_output(OMAP_DSS_OUTPUT_SDI);
+ break;
+ case OMAP_DISPLAY_TYPE_VENC:
+ out = omap_dss_get_output(OMAP_DSS_OUTPUT_VENC);
+ break;
+ case OMAP_DISPLAY_TYPE_HDMI:
+ out = omap_dss_get_output(OMAP_DSS_OUTPUT_HDMI);
+ break;
+ case OMAP_DISPLAY_TYPE_DSI:
+ id = dssdev->phy.dsi.module = 0 ? OMAP_DSS_OUTPUT_DSI1 :
+ OMAP_DSS_OUTPUT_DSI2;
+ out = omap_dss_get_output(id);
+ break;
+ default:
+ break;
+ }
- lcd_mgr = omap_dss_get_overlay_manager(OMAP_DSS_CHANNEL_LCD);
- tv_mgr = omap_dss_get_overlay_manager(OMAP_DSS_CHANNEL_DIGIT);
- if (dss_has_feature(FEAT_MGR_LCD3))
- lcd3_mgr = omap_dss_get_overlay_manager(OMAP_DSS_CHANNEL_LCD3);
- if (dss_has_feature(FEAT_MGR_LCD2))
- lcd2_mgr = omap_dss_get_overlay_manager(OMAP_DSS_CHANNEL_LCD2);
-
- if (dssdev->channel = OMAP_DSS_CHANNEL_LCD3) {
- if (!lcd3_mgr->device || force) {
- if (lcd3_mgr->device)
- lcd3_mgr->unset_device(lcd3_mgr);
- lcd3_mgr->set_device(lcd3_mgr, dssdev);
- mgr = lcd3_mgr;
- }
- } else if (dssdev->channel = OMAP_DSS_CHANNEL_LCD2) {
- if (!lcd2_mgr->device || force) {
- if (lcd2_mgr->device)
- lcd2_mgr->unset_device(lcd2_mgr);
- lcd2_mgr->set_device(lcd2_mgr, dssdev);
- mgr = lcd2_mgr;
- }
- } else if (dssdev->type != OMAP_DISPLAY_TYPE_VENC
- && dssdev->type != OMAP_DISPLAY_TYPE_HDMI) {
- if (!lcd_mgr->device || force) {
- if (lcd_mgr->device)
- lcd_mgr->unset_device(lcd_mgr);
- lcd_mgr->set_device(lcd_mgr, dssdev);
- mgr = lcd_mgr;
- }
+ /*
+ * We don't want to touch board files and mention channel for VENC
+ * devices. Force the channel as DIGIT for HDMI and VENC devices
+ */
+ if (dssdev->type = OMAP_DISPLAY_TYPE_VENC ||
+ dssdev->type = OMAP_DISPLAY_TYPE_HDMI)
+ dssdev->channel = OMAP_DSS_CHANNEL_DIGIT;
+
+ mgr = omap_dss_get_overlay_manager(dssdev->channel);
+
+ if (!mgr || !out) {
+ DSSERR("Incorrect manager or output\n");
+ return;
}
- if (dssdev->type = OMAP_DISPLAY_TYPE_VENC
- || dssdev->type = OMAP_DISPLAY_TYPE_HDMI) {
- if (!tv_mgr->device || force) {
- if (tv_mgr->device)
- tv_mgr->unset_device(tv_mgr);
- tv_mgr->set_device(tv_mgr, dssdev);
- mgr = tv_mgr;
+ if (!mgr->output || force) {
+ struct omap_dss_output *curr_out = mgr->output;
+
+ if (curr_out) {
+ if (curr_out->device)
+ curr_out->unset_device(curr_out);
+ mgr->unset_output(mgr);
}
+ out->set_device(out, dssdev);
+ mgr->set_output(mgr, out);
+ } else {
+ /*
+ * connect a floating output to the device even if the desired
+ * manager is in use
+ */
+ if (!out->manager && !out->device)
+ out->set_device(out, dssdev);
}
if (mgr) {
--
1.7.9.5
^ permalink raw reply related
* [PATCH 10/23] OMAPDSS: DPI: Pass outputs from panel driver to DPI interface driver
From: Archit Taneja @ 2012-08-21 6:10 UTC (permalink / raw)
To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, rob, sumit.semwal, Archit Taneja
In-Reply-To: <1345528711-27801-1-git-send-email-archit@ti.com>
With outputs introduces as new entities, we can now pass output pointer to
functions used to configure the connected interface. These functions currently
pass the omap_dss_device pointer, and extract output information via
omap_dss_device. This is unnecessary, and it doesn't make sense for interface
related functions to get the panel's/device's pointer, it should receive a
pointer related to the connected interface, which in our case is the output
entity.
With the addition of outputs. There is a possibility that an omap_dss_device
isn't connected to an output yet. Ensure that panel drivers call the interface
functions only if outputs are non NULL.
Modify DPI functions to pass omap_dss_output pointer instead of omap_dss_device
pointer. Modify the panel drivers to call the updated functions.
Signed-off-by: Archit Taneja <archit@ti.com>
---
drivers/video/omap2/displays/panel-generic-dpi.c | 27 ++++++---
.../omap2/displays/panel-lgphilips-lb035q02.c | 16 +++--
.../omap2/displays/panel-nec-nl8048hl11-01b.c | 15 +++--
drivers/video/omap2/displays/panel-picodlp.c | 15 +++--
.../video/omap2/displays/panel-sharp-ls037v7dw01.c | 16 +++--
drivers/video/omap2/displays/panel-tfp410.c | 17 ++++--
.../video/omap2/displays/panel-tpo-td043mtea1.c | 29 ++++++---
drivers/video/omap2/dss/dpi.c | 64 ++++++++++----------
include/video/omapdss.h | 12 ++--
9 files changed, 133 insertions(+), 78 deletions(-)
diff --git a/drivers/video/omap2/displays/panel-generic-dpi.c b/drivers/video/omap2/displays/panel-generic-dpi.c
index 88295c5..76ee8df 100644
--- a/drivers/video/omap2/displays/panel-generic-dpi.c
+++ b/drivers/video/omap2/displays/panel-generic-dpi.c
@@ -561,14 +561,18 @@ static int generic_dpi_panel_power_on(struct omap_dss_device *dssdev)
struct panel_generic_dpi_data *panel_data = get_panel_data(dssdev);
struct panel_drv_data *drv_data = dev_get_drvdata(&dssdev->dev);
struct panel_config *panel_config = drv_data->panel_config;
+ struct omap_dss_output *out = dssdev->output;
+
+ if (out = NULL)
+ return -ENODEV;
if (dssdev->state = OMAP_DSS_DISPLAY_ACTIVE)
return 0;
- omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings);
- omapdss_dpi_set_data_lines(dssdev, dssdev->phy.dpi.data_lines);
+ omapdss_dpi_set_timings(out, &dssdev->panel.timings);
+ omapdss_dpi_set_data_lines(out, dssdev->phy.dpi.data_lines);
- r = omapdss_dpi_display_enable(dssdev);
+ r = omapdss_dpi_display_enable(out);
if (r)
goto err0;
@@ -584,7 +588,7 @@ static int generic_dpi_panel_power_on(struct omap_dss_device *dssdev)
return 0;
err1:
- omapdss_dpi_display_disable(dssdev);
+ omapdss_dpi_display_disable(out);
err0:
return r;
}
@@ -594,6 +598,7 @@ static void generic_dpi_panel_power_off(struct omap_dss_device *dssdev)
struct panel_generic_dpi_data *panel_data = get_panel_data(dssdev);
struct panel_drv_data *drv_data = dev_get_drvdata(&dssdev->dev);
struct panel_config *panel_config = drv_data->panel_config;
+ struct omap_dss_output *out = dssdev->output;
if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
return;
@@ -605,7 +610,7 @@ static void generic_dpi_panel_power_off(struct omap_dss_device *dssdev)
if (panel_config->power_off_delay)
msleep(panel_config->power_off_delay);
- omapdss_dpi_display_disable(dssdev);
+ omapdss_dpi_display_disable(out);
}
static int generic_dpi_panel_probe(struct omap_dss_device *dssdev)
@@ -726,10 +731,14 @@ static void generic_dpi_panel_set_timings(struct omap_dss_device *dssdev,
struct omap_video_timings *timings)
{
struct panel_drv_data *drv_data = dev_get_drvdata(&dssdev->dev);
+ struct omap_dss_output *out = dssdev->output;
+
+ if (out = NULL)
+ return;
mutex_lock(&drv_data->lock);
- omapdss_dpi_set_timings(dssdev, timings);
+ omapdss_dpi_set_timings(out, timings);
dssdev->panel.timings = *timings;
@@ -752,11 +761,15 @@ static int generic_dpi_panel_check_timings(struct omap_dss_device *dssdev,
struct omap_video_timings *timings)
{
struct panel_drv_data *drv_data = dev_get_drvdata(&dssdev->dev);
+ struct omap_dss_output *out = dssdev->output;
int r;
+ if (out = NULL)
+ return -ENODEV;
+
mutex_lock(&drv_data->lock);
- r = dpi_check_timings(dssdev, timings);
+ r = dpi_check_timings(out, timings);
mutex_unlock(&drv_data->lock);
diff --git a/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c b/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c
index 90c1cab..2764c32 100644
--- a/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c
+++ b/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c
@@ -50,15 +50,19 @@ static struct omap_video_timings lb035q02_timings = {
static int lb035q02_panel_power_on(struct omap_dss_device *dssdev)
{
+ struct omap_dss_output *out = dssdev->output;
int r;
+ if (out = NULL)
+ return -ENODEV;
+
if (dssdev->state = OMAP_DSS_DISPLAY_ACTIVE)
return 0;
- omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings);
- omapdss_dpi_set_data_lines(dssdev, dssdev->phy.dpi.data_lines);
+ omapdss_dpi_set_timings(out, &dssdev->panel.timings);
+ omapdss_dpi_set_data_lines(out, dssdev->phy.dpi.data_lines);
- r = omapdss_dpi_display_enable(dssdev);
+ r = omapdss_dpi_display_enable(out);
if (r)
goto err0;
@@ -70,20 +74,22 @@ static int lb035q02_panel_power_on(struct omap_dss_device *dssdev)
return 0;
err1:
- omapdss_dpi_display_disable(dssdev);
+ omapdss_dpi_display_disable(out);
err0:
return r;
}
static void lb035q02_panel_power_off(struct omap_dss_device *dssdev)
{
+ struct omap_dss_output *out = dssdev->output;
+
if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
return;
if (dssdev->platform_disable)
dssdev->platform_disable(dssdev);
- omapdss_dpi_display_disable(dssdev);
+ omapdss_dpi_display_disable(out);
}
static int lb035q02_panel_probe(struct omap_dss_device *dssdev)
diff --git a/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c b/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c
index 908fd26..906bc48 100644
--- a/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c
+++ b/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c
@@ -171,14 +171,18 @@ static int nec_8048_panel_power_on(struct omap_dss_device *dssdev)
int r;
struct nec_8048_data *necd = dev_get_drvdata(&dssdev->dev);
struct backlight_device *bl = necd->bl;
+ struct omap_dss_output *out = dssdev->output;
+
+ if (out = NULL)
+ return -ENODEV;
if (dssdev->state = OMAP_DSS_DISPLAY_ACTIVE)
return 0;
- omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings);
- omapdss_dpi_set_data_lines(dssdev, dssdev->phy.dpi.data_lines);
+ omapdss_dpi_set_timings(out, &dssdev->panel.timings);
+ omapdss_dpi_set_data_lines(out, dssdev->phy.dpi.data_lines);
- r = omapdss_dpi_display_enable(dssdev);
+ r = omapdss_dpi_display_enable(out);
if (r)
goto err0;
@@ -194,7 +198,7 @@ static int nec_8048_panel_power_on(struct omap_dss_device *dssdev)
return 0;
err1:
- omapdss_dpi_display_disable(dssdev);
+ omapdss_dpi_display_disable(out);
err0:
return r;
}
@@ -203,6 +207,7 @@ static void nec_8048_panel_power_off(struct omap_dss_device *dssdev)
{
struct nec_8048_data *necd = dev_get_drvdata(&dssdev->dev);
struct backlight_device *bl = necd->bl;
+ struct omap_dss_output *out = dssdev->output;
if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
return;
@@ -213,7 +218,7 @@ static void nec_8048_panel_power_off(struct omap_dss_device *dssdev)
if (dssdev->platform_disable)
dssdev->platform_disable(dssdev);
- omapdss_dpi_display_disable(dssdev);
+ omapdss_dpi_display_disable(out);
}
static int nec_8048_panel_enable(struct omap_dss_device *dssdev)
diff --git a/drivers/video/omap2/displays/panel-picodlp.c b/drivers/video/omap2/displays/panel-picodlp.c
index 9df8764..2bd4f7b 100644
--- a/drivers/video/omap2/displays/panel-picodlp.c
+++ b/drivers/video/omap2/displays/panel-picodlp.c
@@ -352,6 +352,10 @@ static int picodlp_panel_power_on(struct omap_dss_device *dssdev)
int r, trial = 100;
struct picodlp_data *picod = dev_get_drvdata(&dssdev->dev);
struct picodlp_panel_data *picodlp_pdata = get_panel_data(dssdev);
+ struct omap_dss_output *out = dssdev->output;
+
+ if (out = NULL)
+ return -ENODEV;
if (dssdev->platform_enable) {
r = dssdev->platform_enable(dssdev);
@@ -378,10 +382,10 @@ static int picodlp_panel_power_on(struct omap_dss_device *dssdev)
*/
msleep(1000);
- omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings);
- omapdss_dpi_set_data_lines(dssdev, dssdev->phy.dpi.data_lines);
+ omapdss_dpi_set_timings(out, &dssdev->panel.timings);
+ omapdss_dpi_set_data_lines(out, dssdev->phy.dpi.data_lines);
- r = omapdss_dpi_display_enable(dssdev);
+ r = omapdss_dpi_display_enable(out);
if (r) {
dev_err(&dssdev->dev, "failed to enable DPI\n");
goto err1;
@@ -395,7 +399,7 @@ static int picodlp_panel_power_on(struct omap_dss_device *dssdev)
return r;
err:
- omapdss_dpi_display_disable(dssdev);
+ omapdss_dpi_display_disable(out);
err1:
if (dssdev->platform_disable)
dssdev->platform_disable(dssdev);
@@ -406,8 +410,9 @@ err1:
static void picodlp_panel_power_off(struct omap_dss_device *dssdev)
{
struct picodlp_panel_data *picodlp_pdata = get_panel_data(dssdev);
+ struct omap_dss_output *out = dssdev->output;
- omapdss_dpi_display_disable(dssdev);
+ omapdss_dpi_display_disable(out);
gpio_set_value(picodlp_pdata->emu_done_gpio, 0);
gpio_set_value(picodlp_pdata->pwrgood_gpio, 0);
diff --git a/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c b/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c
index 1ec3b27..dffd85a 100644
--- a/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c
+++ b/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c
@@ -137,15 +137,19 @@ static void __exit sharp_ls_panel_remove(struct omap_dss_device *dssdev)
static int sharp_ls_power_on(struct omap_dss_device *dssdev)
{
+ struct omap_dss_output *out = dssdev->output;
int r = 0;
+ if (out = NULL)
+ return -ENODEV;
+
if (dssdev->state = OMAP_DSS_DISPLAY_ACTIVE)
return 0;
- omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings);
- omapdss_dpi_set_data_lines(dssdev, dssdev->phy.dpi.data_lines);
+ omapdss_dpi_set_timings(out, &dssdev->panel.timings);
+ omapdss_dpi_set_data_lines(out, dssdev->phy.dpi.data_lines);
- r = omapdss_dpi_display_enable(dssdev);
+ r = omapdss_dpi_display_enable(out);
if (r)
goto err0;
@@ -160,13 +164,15 @@ static int sharp_ls_power_on(struct omap_dss_device *dssdev)
return 0;
err1:
- omapdss_dpi_display_disable(dssdev);
+ omapdss_dpi_display_disable(out);
err0:
return r;
}
static void sharp_ls_power_off(struct omap_dss_device *dssdev)
{
+ struct omap_dss_output *out = dssdev->output;
+
if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
return;
@@ -177,7 +183,7 @@ static void sharp_ls_power_off(struct omap_dss_device *dssdev)
msleep(100);
- omapdss_dpi_display_disable(dssdev);
+ omapdss_dpi_display_disable(out);
}
static int sharp_ls_panel_enable(struct omap_dss_device *dssdev)
diff --git a/drivers/video/omap2/displays/panel-tfp410.c b/drivers/video/omap2/displays/panel-tfp410.c
index 4be9a59..88a1507 100644
--- a/drivers/video/omap2/displays/panel-tfp410.c
+++ b/drivers/video/omap2/displays/panel-tfp410.c
@@ -60,15 +60,19 @@ struct panel_drv_data {
static int tfp410_power_on(struct omap_dss_device *dssdev)
{
struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev);
+ struct omap_dss_output *out = dssdev->output;
int r;
+ if (out = NULL)
+ return -ENODEV;
+
if (dssdev->state = OMAP_DSS_DISPLAY_ACTIVE)
return 0;
- omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings);
- omapdss_dpi_set_data_lines(dssdev, dssdev->phy.dpi.data_lines);
+ omapdss_dpi_set_timings(out, &dssdev->panel.timings);
+ omapdss_dpi_set_data_lines(out, dssdev->phy.dpi.data_lines);
- r = omapdss_dpi_display_enable(dssdev);
+ r = omapdss_dpi_display_enable(out);
if (r)
goto err0;
@@ -83,6 +87,7 @@ err0:
static void tfp410_power_off(struct omap_dss_device *dssdev)
{
struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev);
+ struct omap_dss_output *out = dssdev->output;
if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
return;
@@ -90,7 +95,7 @@ static void tfp410_power_off(struct omap_dss_device *dssdev)
if (gpio_is_valid(ddata->pd_gpio))
gpio_set_value_cansleep(ddata->pd_gpio, 0);
- omapdss_dpi_display_disable(dssdev);
+ omapdss_dpi_display_disable(out);
}
static int tfp410_probe(struct omap_dss_device *dssdev)
@@ -234,7 +239,7 @@ static void tfp410_set_timings(struct omap_dss_device *dssdev,
struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev);
mutex_lock(&ddata->lock);
- omapdss_dpi_set_timings(dssdev, timings);
+ omapdss_dpi_set_timings(dssdev->output, timings);
dssdev->panel.timings = *timings;
mutex_unlock(&ddata->lock);
}
@@ -256,7 +261,7 @@ static int tfp410_check_timings(struct omap_dss_device *dssdev,
int r;
mutex_lock(&ddata->lock);
- r = dpi_check_timings(dssdev, timings);
+ r = dpi_check_timings(dssdev->output, timings);
mutex_unlock(&ddata->lock);
return r;
diff --git a/drivers/video/omap2/displays/panel-tpo-td043mtea1.c b/drivers/video/omap2/displays/panel-tpo-td043mtea1.c
index b5e6dbc..792e9ff 100644
--- a/drivers/video/omap2/displays/panel-tpo-td043mtea1.c
+++ b/drivers/video/omap2/displays/panel-tpo-td043mtea1.c
@@ -331,16 +331,20 @@ static void tpo_td043_power_off(struct tpo_td043_device *tpo_td043)
static int tpo_td043_enable_dss(struct omap_dss_device *dssdev)
{
+ struct omap_dss_output *out = dssdev->output;
struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&dssdev->dev);
int r;
+ if (out = NULL)
+ return -ENODEV;
+
if (dssdev->state = OMAP_DSS_DISPLAY_ACTIVE)
return 0;
- omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings);
- omapdss_dpi_set_data_lines(dssdev, dssdev->phy.dpi.data_lines);
+ omapdss_dpi_set_timings(out, &dssdev->panel.timings);
+ omapdss_dpi_set_data_lines(out, dssdev->phy.dpi.data_lines);
- r = omapdss_dpi_display_enable(dssdev);
+ r = omapdss_dpi_display_enable(out);
if (r)
goto err0;
@@ -364,7 +368,7 @@ static int tpo_td043_enable_dss(struct omap_dss_device *dssdev)
return 0;
err1:
- omapdss_dpi_display_disable(dssdev);
+ omapdss_dpi_display_disable(out);
err0:
return r;
}
@@ -372,6 +376,7 @@ err0:
static void tpo_td043_disable_dss(struct omap_dss_device *dssdev)
{
struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&dssdev->dev);
+ struct omap_dss_output *out = dssdev->output;
if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
return;
@@ -379,7 +384,7 @@ static void tpo_td043_disable_dss(struct omap_dss_device *dssdev)
if (dssdev->platform_disable)
dssdev->platform_disable(dssdev);
- omapdss_dpi_display_disable(dssdev);
+ omapdss_dpi_display_disable(out);
if (!tpo_td043->spi_suspended)
tpo_td043_power_off(tpo_td043);
@@ -483,7 +488,12 @@ static void tpo_td043_remove(struct omap_dss_device *dssdev)
static void tpo_td043_set_timings(struct omap_dss_device *dssdev,
struct omap_video_timings *timings)
{
- omapdss_dpi_set_timings(dssdev, timings);
+ struct omap_dss_output *out = dssdev->output;
+
+ if (out = NULL)
+ return;
+
+ omapdss_dpi_set_timings(out, timings);
dssdev->panel.timings = *timings;
}
@@ -491,7 +501,12 @@ static void tpo_td043_set_timings(struct omap_dss_device *dssdev,
static int tpo_td043_check_timings(struct omap_dss_device *dssdev,
struct omap_video_timings *timings)
{
- return dpi_check_timings(dssdev, timings);
+ struct omap_dss_output *out = dssdev->output;
+
+ if (out = NULL)
+ return -ENODEV;
+
+ return dpi_check_timings(out, timings);
}
static struct omap_dss_driver tpo_td043_driver = {
diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c
index 4eca2e7..6506e40 100644
--- a/drivers/video/omap2/dss/dpi.c
+++ b/drivers/video/omap2/dss/dpi.c
@@ -70,7 +70,7 @@ static bool dpi_use_dsi_pll(struct omap_dss_device *dssdev)
return false;
}
-static int dpi_set_dsi_clk(struct omap_dss_device *dssdev,
+static int dpi_set_dsi_clk(struct omap_dss_output *out,
unsigned long pck_req, unsigned long *fck, int *lck_div,
int *pck_div)
{
@@ -87,7 +87,7 @@ static int dpi_set_dsi_clk(struct omap_dss_device *dssdev,
if (r)
return r;
- dss_select_dispc_clk_source(dssdev->clocks.dispc.dispc_fclk_src);
+ dss_select_dispc_clk_source(out->device->clocks.dispc.dispc_fclk_src);
dpi.mgr_config.clock_info = dispc_cinfo;
@@ -98,7 +98,7 @@ static int dpi_set_dsi_clk(struct omap_dss_device *dssdev,
return 0;
}
-static int dpi_set_dispc_clk(struct omap_dss_device *dssdev,
+static int dpi_set_dispc_clk(struct omap_dss_output *out,
unsigned long pck_req, unsigned long *fck, int *lck_div,
int *pck_div)
{
@@ -123,7 +123,7 @@ static int dpi_set_dispc_clk(struct omap_dss_device *dssdev,
return 0;
}
-static int dpi_set_mode(struct omap_dss_device *dssdev)
+static int dpi_set_mode(struct omap_dss_output *out)
{
struct omap_video_timings *t = &dpi.timings;
int lck_div = 0, pck_div = 0;
@@ -131,11 +131,11 @@ static int dpi_set_mode(struct omap_dss_device *dssdev)
unsigned long pck;
int r = 0;
- if (dpi_use_dsi_pll(dssdev))
- r = dpi_set_dsi_clk(dssdev, t->pixel_clock * 1000, &fck,
+ if (dpi_use_dsi_pll(out->device))
+ r = dpi_set_dsi_clk(out, t->pixel_clock * 1000, &fck,
&lck_div, &pck_div);
else
- r = dpi_set_dispc_clk(dssdev, t->pixel_clock * 1000, &fck,
+ r = dpi_set_dispc_clk(out, t->pixel_clock * 1000, &fck,
&lck_div, &pck_div);
if (r)
return r;
@@ -150,12 +150,12 @@ static int dpi_set_mode(struct omap_dss_device *dssdev)
t->pixel_clock = pck;
}
- dss_mgr_set_timings(dssdev->manager, t);
+ dss_mgr_set_timings(out->manager, t);
return 0;
}
-static void dpi_config_lcd_manager(struct omap_dss_device *dssdev)
+static void dpi_config_lcd_manager(struct omap_dss_output *out)
{
dpi.mgr_config.io_pad_mode = DSS_IO_PAD_MODE_BYPASS;
@@ -166,10 +166,10 @@ static void dpi_config_lcd_manager(struct omap_dss_device *dssdev)
dpi.mgr_config.lcden_sig_polarity = 0;
- dss_mgr_set_lcd_config(dssdev->manager, &dpi.mgr_config);
+ dss_mgr_set_lcd_config(out->manager, &dpi.mgr_config);
}
-int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
+int omapdss_dpi_display_enable(struct omap_dss_output *out)
{
int r;
@@ -181,13 +181,13 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
goto err_no_reg;
}
- if (dssdev->manager = NULL) {
+ if (out->manager = NULL) {
DSSERR("failed to enable display: no manager\n");
r = -ENODEV;
goto err_no_mgr;
}
- r = omap_dss_start_device(dssdev);
+ r = omap_dss_start_device(out->device);
if (r) {
DSSERR("failed to start device\n");
goto err_start_dev;
@@ -203,7 +203,7 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
if (r)
goto err_get_dispc;
- if (dpi_use_dsi_pll(dssdev)) {
+ if (dpi_use_dsi_pll(out->device)) {
r = dsi_runtime_get(dpi.dsidev);
if (r)
goto err_get_dsi;
@@ -213,15 +213,15 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
goto err_dsi_pll_init;
}
- r = dpi_set_mode(dssdev);
+ r = dpi_set_mode(out);
if (r)
goto err_set_mode;
- dpi_config_lcd_manager(dssdev);
+ dpi_config_lcd_manager(out);
mdelay(2);
- r = dss_mgr_enable(dssdev->manager);
+ r = dss_mgr_enable(out->manager);
if (r)
goto err_mgr_enable;
@@ -231,10 +231,10 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
err_mgr_enable:
err_set_mode:
- if (dpi_use_dsi_pll(dssdev))
+ if (dpi_use_dsi_pll(out->device))
dsi_pll_uninit(dpi.dsidev, true);
err_dsi_pll_init:
- if (dpi_use_dsi_pll(dssdev))
+ if (dpi_use_dsi_pll(out->device))
dsi_runtime_put(dpi.dsidev);
err_get_dsi:
dispc_runtime_put();
@@ -242,7 +242,7 @@ err_get_dispc:
if (cpu_is_omap34xx())
regulator_disable(dpi.vdds_dsi_reg);
err_reg_enable:
- omap_dss_stop_device(dssdev);
+ omap_dss_stop_device(out->device);
err_start_dev:
err_no_mgr:
err_no_reg:
@@ -251,13 +251,13 @@ err_no_reg:
}
EXPORT_SYMBOL(omapdss_dpi_display_enable);
-void omapdss_dpi_display_disable(struct omap_dss_device *dssdev)
+void omapdss_dpi_display_disable(struct omap_dss_output *out)
{
mutex_lock(&dpi.lock);
- dss_mgr_disable(dssdev->manager);
+ dss_mgr_disable(out->manager);
- if (dpi_use_dsi_pll(dssdev)) {
+ if (dpi_use_dsi_pll(out->device)) {
dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK);
dsi_pll_uninit(dpi.dsidev, true);
dsi_runtime_put(dpi.dsidev);
@@ -268,13 +268,13 @@ void omapdss_dpi_display_disable(struct omap_dss_device *dssdev)
if (cpu_is_omap34xx())
regulator_disable(dpi.vdds_dsi_reg);
- omap_dss_stop_device(dssdev);
+ omap_dss_stop_device(out->device);
mutex_unlock(&dpi.lock);
}
EXPORT_SYMBOL(omapdss_dpi_display_disable);
-void omapdss_dpi_set_timings(struct omap_dss_device *dssdev,
+void omapdss_dpi_set_timings(struct omap_dss_output *out,
struct omap_video_timings *timings)
{
int r;
@@ -285,23 +285,23 @@ void omapdss_dpi_set_timings(struct omap_dss_device *dssdev,
dpi.timings = *timings;
- if (dssdev->state = OMAP_DSS_DISPLAY_ACTIVE) {
+ if (out->device->state = OMAP_DSS_DISPLAY_ACTIVE) {
r = dispc_runtime_get();
if (r)
return;
- dpi_set_mode(dssdev);
+ dpi_set_mode(out);
dispc_runtime_put();
} else {
- dss_mgr_set_timings(dssdev->manager, timings);
+ dss_mgr_set_timings(out->manager, timings);
}
mutex_unlock(&dpi.lock);
}
EXPORT_SYMBOL(omapdss_dpi_set_timings);
-int dpi_check_timings(struct omap_dss_device *dssdev,
+int dpi_check_timings(struct omap_dss_output *out,
struct omap_video_timings *timings)
{
int r;
@@ -310,13 +310,13 @@ int dpi_check_timings(struct omap_dss_device *dssdev,
unsigned long pck;
struct dispc_clock_info dispc_cinfo;
- if (dss_mgr_check_timings(dssdev->manager, timings))
+ if (dss_mgr_check_timings(out->manager, timings))
return -EINVAL;
if (timings->pixel_clock = 0)
return -EINVAL;
- if (dpi_use_dsi_pll(dssdev)) {
+ if (dpi_use_dsi_pll(out->device)) {
struct dsi_clock_info dsi_cinfo;
r = dsi_pll_calc_clock_div_pck(dpi.dsidev,
timings->pixel_clock * 1000,
@@ -348,7 +348,7 @@ int dpi_check_timings(struct omap_dss_device *dssdev,
}
EXPORT_SYMBOL(dpi_check_timings);
-void omapdss_dpi_set_data_lines(struct omap_dss_device *dssdev, int data_lines)
+void omapdss_dpi_set_data_lines(struct omap_dss_output *out, int data_lines)
{
mutex_lock(&dpi.lock);
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index 361d41e..da3f070 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -783,13 +783,13 @@ int omapdss_dsi_display_enable(struct omap_dss_device *dssdev);
void omapdss_dsi_display_disable(struct omap_dss_device *dssdev,
bool disconnect_lanes, bool enter_ulps);
-int omapdss_dpi_display_enable(struct omap_dss_device *dssdev);
-void omapdss_dpi_display_disable(struct omap_dss_device *dssdev);
-void omapdss_dpi_set_timings(struct omap_dss_device *dssdev,
+int omapdss_dpi_display_enable(struct omap_dss_output *out);
+void omapdss_dpi_display_disable(struct omap_dss_output *out);
+void omapdss_dpi_set_timings(struct omap_dss_output *out,
struct omap_video_timings *timings);
-int dpi_check_timings(struct omap_dss_device *dssdev,
- struct omap_video_timings *timings);
-void omapdss_dpi_set_data_lines(struct omap_dss_device *dssdev, int data_lines);
+int dpi_check_timings(struct omap_dss_output *out,
+ struct omap_video_timings *timings);
+void omapdss_dpi_set_data_lines(struct omap_dss_output *out, int data_lines);
int omapdss_sdi_display_enable(struct omap_dss_device *dssdev);
void omapdss_sdi_display_disable(struct omap_dss_device *dssdev);
--
1.7.9.5
^ permalink raw reply related
* [PATCH 11/23] OMAPDSS: DSI: Remove dsi_pdev_map global struct
From: Archit Taneja @ 2012-08-21 6:10 UTC (permalink / raw)
To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, rob, sumit.semwal, Archit Taneja
In-Reply-To: <1345528711-27801-1-git-send-email-archit@ti.com>
dsi_pdev_map is a struct visible globally in the DSI driver to get the platform
device pointer of the DSI device corresponding to it's module ID. This was
required because there was no clean way to derive the platform device from
the DSI module instance number or from the connected panel.
With the new output entity, it is possible to retrieve the platform device
pointer if the omap_dss_output pointer is available. Modify the functions
dsi_get_dsidev_from_dssdev() dsi_get_dsidev_from_id() so that they use output
instead of dsi_pdev_map to retrieve the dsi platform device pointer.
Signed-off-by: Archit Taneja <archit@ti.com>
---
drivers/video/omap2/dss/dsi.c | 14 +++++++++-----
1 file changed, 9 insertions(+), 5 deletions(-)
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index 22e0873..19a4d4d 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -344,8 +344,6 @@ struct dsi_packet_sent_handler_data {
struct completion *completion;
};
-static struct platform_device *dsi_pdev_map[MAX_NUM_DSI];
-
#ifdef DEBUG
static bool dsi_perf;
module_param(dsi_perf, bool, 0644);
@@ -358,12 +356,19 @@ static inline struct dsi_data *dsi_get_dsidrv_data(struct platform_device *dside
static inline struct platform_device *dsi_get_dsidev_from_dssdev(struct omap_dss_device *dssdev)
{
- return dsi_pdev_map[dssdev->phy.dsi.module];
+ return dssdev->output->pdev;
}
struct platform_device *dsi_get_dsidev_from_id(int module)
{
- return dsi_pdev_map[module];
+ struct omap_dss_output *out;
+ enum omap_dss_output_id id;
+
+ id = module = 0 ? OMAP_DSS_OUTPUT_DSI1 : OMAP_DSS_OUTPUT_DSI2;
+
+ out = omap_dss_get_output(id);
+
+ return out->pdev;
}
static inline void dsi_write_reg(struct platform_device *dsidev,
@@ -4934,7 +4939,6 @@ static int __init omap_dsihw_probe(struct platform_device *dsidev)
dsi->module_id = dsidev->id;
dsi->pdev = dsidev;
- dsi_pdev_map[dsi->module_id] = dsidev;
dev_set_drvdata(&dsidev->dev, dsi);
spin_lock_init(&dsi->irq_lock);
--
1.7.9.5
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox