Commit 7ab0a484 authored by Tony Prisk's avatar Tony Prisk Committed by Tomi Valkeinen

video: fb: vt8500: Convert framebuffer drivers to standardized binding

Now that a display timing binding is available, convert our almost identical
binding to use the standard binding.

This patch converts the vt8500 and wm8505 framebuffer drivers and
associated dts/dtsi files to use the standard binding as defined in
bindings/video/display-timing.txt.

There are two side-effects of making this conversion:

1) The fb node should now be in the board file, rather than the soc file as
the display-timing node is a child of the fb node.

2) We still require a bits per pixel property to initialize the framebuffer
for the different lcd panels. Rather than including this as part of the
display timing, it is moved into the framebuffer node.

I have also taken the opportunity to alphabetise the includes of each
driver to avoid double-ups.
Signed-off-by: default avatarTony Prisk <linux@prisktech.co.nz>
Signed-off-by: default avatarTomi Valkeinen <tomi.valkeinen@ti.com>
parent de68efce
...@@ -5,58 +5,32 @@ Required properties: ...@@ -5,58 +5,32 @@ Required properties:
- compatible : "via,vt8500-fb" - compatible : "via,vt8500-fb"
- reg : Should contain 1 register ranges(address and length) - reg : Should contain 1 register ranges(address and length)
- interrupts : framebuffer controller interrupt - interrupts : framebuffer controller interrupt
- display: a phandle pointing to the display node - bits-per-pixel : bit depth of framebuffer (16 or 32)
Required nodes: Required subnodes:
- display: a display node is required to initialize the lcd panel - display-timings: see display-timing.txt for information
This should be in the board dts.
- default-mode: a videomode within the display with timing parameters
as specified below.
Example: Example:
fb@d800e400 { fb@d8050800 {
compatible = "via,vt8500-fb"; compatible = "via,vt8500-fb";
reg = <0xd800e400 0x400>; reg = <0xd800e400 0x400>;
interrupts = <12>; interrupts = <12>;
display = <&display>; bits-per-pixel = <16>;
default-mode = <&mode0>;
};
VIA VT8500 Display
-----------------------------------------------------
Required properties (as per of_videomode_helper):
- hactive, vactive: Display resolution
- hfront-porch, hback-porch, hsync-len: Horizontal Display timing parameters
in pixels
vfront-porch, vback-porch, vsync-len: Vertical display timing parameters in
lines
- clock: displayclock in Hz
- bpp: lcd panel bit-depth.
<16> for RGB565, <32> for RGB888
Optional properties (as per of_videomode_helper):
- width-mm, height-mm: Display dimensions in mm
- hsync-active-high (bool): Hsync pulse is active high
- vsync-active-high (bool): Vsync pulse is active high
- interlaced (bool): This is an interlaced mode
- doublescan (bool): This is a doublescan mode
Example: display-timings {
display: display@0 { native-mode = <&timing0>;
modes { timing0: 800x480 {
mode0: mode@0 { clock-frequency = <0>; /* unused but required */
hactive = <800>; hactive = <800>;
vactive = <480>; vactive = <480>;
hback-porch = <88>;
hfront-porch = <40>; hfront-porch = <40>;
hback-porch = <88>;
hsync-len = <0>; hsync-len = <0>;
vback-porch = <32>; vback-porch = <32>;
vfront-porch = <11>; vfront-porch = <11>;
vsync-len = <1>; vsync-len = <1>;
clock = <0>; /* unused but required */
bpp = <16>; /* non-standard but required */
}; };
}; };
}; };
...@@ -4,20 +4,30 @@ Wondermedia WM8505 Framebuffer ...@@ -4,20 +4,30 @@ Wondermedia WM8505 Framebuffer
Required properties: Required properties:
- compatible : "wm,wm8505-fb" - compatible : "wm,wm8505-fb"
- reg : Should contain 1 register ranges(address and length) - reg : Should contain 1 register ranges(address and length)
- via,display: a phandle pointing to the display node - bits-per-pixel : bit depth of framebuffer (16 or 32)
Required nodes: Required subnodes:
- display: a display node is required to initialize the lcd panel - display-timings: see display-timing.txt for information
This should be in the board dts. See definition in
Documentation/devicetree/bindings/video/via,vt8500-fb.txt
- default-mode: a videomode node as specified in
Documentation/devicetree/bindings/video/via,vt8500-fb.txt
Example: Example:
fb@d8050800 { fb@d8051700 {
compatible = "wm,wm8505-fb"; compatible = "wm,wm8505-fb";
reg = <0xd8050800 0x200>; reg = <0xd8051700 0x200>;
display = <&display>; bits-per-pixel = <16>;
default-mode = <&mode0>;
display-timings {
native-mode = <&timing0>;
timing0: 800x480 {
clock-frequency = <0>; /* unused but required */
hactive = <800>;
vactive = <480>;
hfront-porch = <40>;
hback-porch = <88>;
hsync-len = <0>;
vback-porch = <32>;
vfront-porch = <11>;
vsync-len = <1>;
};
};
}; };
...@@ -11,26 +11,22 @@ ...@@ -11,26 +11,22 @@
/ { / {
model = "Benign BV07 Netbook"; model = "Benign BV07 Netbook";
};
/* &fb {
* Display node is based on Sascha Hauer's patch on dri-devel. bits-per-pixel = <16>;
* Added a bpp property to calculate the size of the framebuffer display-timings {
* until the binding is formalized. native-mode = <&timing0>;
*/ timing0: 800x480 {
display: display@0 { clock-frequency = <0>; /* unused but required */
modes { hactive = <800>;
mode0: mode@0 { vactive = <480>;
hactive = <800>; hfront-porch = <40>;
vactive = <480>; hback-porch = <88>;
hback-porch = <88>; hsync-len = <0>;
hfront-porch = <40>; vback-porch = <32>;
hsync-len = <0>; vfront-porch = <11>;
vback-porch = <32>; vsync-len = <1>;
vfront-porch = <11>;
vsync-len = <1>;
clock = <0>; /* unused but required */
bpp = <16>; /* non-standard but required */
};
}; };
}; };
}; };
...@@ -98,12 +98,10 @@ uhci@d8007b00 { ...@@ -98,12 +98,10 @@ uhci@d8007b00 {
interrupts = <43>; interrupts = <43>;
}; };
fb@d800e400 { fb: fb@d8050800 {
compatible = "via,vt8500-fb"; compatible = "via,vt8500-fb";
reg = <0xd800e400 0x400>; reg = <0xd800e400 0x400>;
interrupts = <12>; interrupts = <12>;
display = <&display>;
default-mode = <&mode0>;
}; };
ge_rops@d8050400 { ge_rops@d8050400 {
......
...@@ -11,26 +11,22 @@ ...@@ -11,26 +11,22 @@
/ { / {
model = "Wondermedia WM8505 Netbook"; model = "Wondermedia WM8505 Netbook";
};
/* &fb {
* Display node is based on Sascha Hauer's patch on dri-devel. bits-per-pixel = <32>;
* Added a bpp property to calculate the size of the framebuffer display-timings {
* until the binding is formalized. native-mode = <&timing0>;
*/ timing0: 800x480 {
display: display@0 { clock-frequency = <0>; /* unused but required */
modes { hactive = <800>;
mode0: mode@0 { vactive = <480>;
hactive = <800>; hfront-porch = <40>;
vactive = <480>; hback-porch = <88>;
hback-porch = <88>; hsync-len = <0>;
hfront-porch = <40>; vback-porch = <32>;
hsync-len = <0>; vfront-porch = <11>;
vback-porch = <32>; vsync-len = <1>;
vfront-porch = <11>;
vsync-len = <1>;
clock = <0>; /* unused but required */
bpp = <32>; /* non-standard but required */
};
}; };
}; };
}; };
...@@ -128,11 +128,9 @@ uhci@d8007300 { ...@@ -128,11 +128,9 @@ uhci@d8007300 {
interrupts = <0>; interrupts = <0>;
}; };
fb@d8050800 { fb: fb@d8050800 {
compatible = "wm,wm8505-fb"; compatible = "wm,wm8505-fb";
reg = <0xd8050800 0x200>; reg = <0xd8050800 0x200>;
display = <&display>;
default-mode = <&mode0>;
}; };
ge_rops@d8050400 { ge_rops@d8050400 {
......
...@@ -11,26 +11,24 @@ ...@@ -11,26 +11,24 @@
/ { / {
model = "Wondermedia WM8650-MID Tablet"; model = "Wondermedia WM8650-MID Tablet";
};
&fb {
bits-per-pixel = <16>;
/* display-timings {
* Display node is based on Sascha Hauer's patch on dri-devel. native-mode = <&timing0>;
* Added a bpp property to calculate the size of the framebuffer timing0: 800x480 {
* until the binding is formalized. clock-frequency = <0>; /* unused but required */
*/ hactive = <800>;
display: display@0 { vactive = <480>;
modes { hfront-porch = <40>;
mode0: mode@0 { hback-porch = <88>;
hactive = <800>; hsync-len = <0>;
vactive = <480>; vback-porch = <32>;
hback-porch = <88>; vfront-porch = <11>;
hfront-porch = <40>; vsync-len = <1>;
hsync-len = <0>;
vback-porch = <32>;
vfront-porch = <11>;
vsync-len = <1>;
clock = <0>; /* unused but required */
bpp = <16>; /* non-standard but required */
};
}; };
}; };
}; };
...@@ -128,11 +128,9 @@ uhci@d8007b00 { ...@@ -128,11 +128,9 @@ uhci@d8007b00 {
interrupts = <43>; interrupts = <43>;
}; };
fb@d8050800 { fb: fb@d8050800 {
compatible = "wm,wm8505-fb"; compatible = "wm,wm8505-fb";
reg = <0xd8050800 0x200>; reg = <0xd8050800 0x200>;
display = <&display>;
default-mode = <&mode0>;
}; };
ge_rops@d8050400 { ge_rops@d8050400 {
......
...@@ -15,28 +15,6 @@ ...@@ -15,28 +15,6 @@
/ { / {
model = "Wondermedia WM8850-W70v2 Tablet"; model = "Wondermedia WM8850-W70v2 Tablet";
/*
* Display node is based on Sascha Hauer's patch on dri-devel.
* Added a bpp property to calculate the size of the framebuffer
* until the binding is formalized.
*/
display: display@0 {
modes {
mode0: mode@0 {
hactive = <800>;
vactive = <480>;
hback-porch = <88>;
hfront-porch = <40>;
hsync-len = <0>;
vback-porch = <32>;
vfront-porch = <11>;
vsync-len = <1>;
clock = <0>; /* unused but required */
bpp = <16>; /* non-standard but required */
};
};
};
backlight { backlight {
compatible = "pwm-backlight"; compatible = "pwm-backlight";
pwms = <&pwm 0 50000 1>; /* duty inverted */ pwms = <&pwm 0 50000 1>; /* duty inverted */
...@@ -45,3 +23,21 @@ backlight { ...@@ -45,3 +23,21 @@ backlight {
default-brightness-level = <5>; default-brightness-level = <5>;
}; };
}; };
&fb {
bits-per-pixel = <16>;
display-timings {
native-mode = <&timing0>;
timing0: 800x480 {
clock-frequency = <0>; /* unused but required */
hactive = <800>;
vactive = <480>;
hfront-porch = <40>;
hback-porch = <88>;
hsync-len = <0>;
vback-porch = <32>;
vfront-porch = <11>;
vsync-len = <1>;
};
};
};
...@@ -135,11 +135,9 @@ clksdhc: sdhc { ...@@ -135,11 +135,9 @@ clksdhc: sdhc {
}; };
}; };
fb@d8051700 { fb: fb@d8051700 {
compatible = "wm,wm8505-fb"; compatible = "wm,wm8505-fb";
reg = <0xd8051700 0x200>; reg = <0xd8051700 0x200>;
display = <&display>;
default-mode = <&mode0>;
}; };
ge_rops@d8050400 { ge_rops@d8050400 {
......
...@@ -1794,6 +1794,9 @@ config FB_VT8500 ...@@ -1794,6 +1794,9 @@ config FB_VT8500
select FB_SYS_FILLRECT if (!FB_WMT_GE_ROPS) select FB_SYS_FILLRECT if (!FB_WMT_GE_ROPS)
select FB_SYS_COPYAREA if (!FB_WMT_GE_ROPS) select FB_SYS_COPYAREA if (!FB_WMT_GE_ROPS)
select FB_SYS_IMAGEBLIT select FB_SYS_IMAGEBLIT
select FB_MODE_HELPERS
select OF_DISPLAY_TIMING
select OF_VIDEOMODE
help help
This is the framebuffer driver for VIA VT8500 integrated LCD This is the framebuffer driver for VIA VT8500 integrated LCD
controller. controller.
...@@ -1804,6 +1807,9 @@ config FB_WM8505 ...@@ -1804,6 +1807,9 @@ config FB_WM8505
select FB_SYS_FILLRECT if (!FB_WMT_GE_ROPS) select FB_SYS_FILLRECT if (!FB_WMT_GE_ROPS)
select FB_SYS_COPYAREA if (!FB_WMT_GE_ROPS) select FB_SYS_COPYAREA if (!FB_WMT_GE_ROPS)
select FB_SYS_IMAGEBLIT select FB_SYS_IMAGEBLIT
select FB_MODE_HELPERS
select OF_DISPLAY_TIMING
select OF_VIDEOMODE
help help
This is the framebuffer driver for WonderMedia WM8xxx-series This is the framebuffer driver for WonderMedia WM8xxx-series
integrated LCD controller. This driver covers the WM8505, WM8650 integrated LCD controller. This driver covers the WM8505, WM8650
......
...@@ -15,20 +15,21 @@ ...@@ -15,20 +15,21 @@
* GNU General Public License for more details. * GNU General Public License for more details.
*/ */
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/dma-mapping.h>
#include <linux/errno.h>
#include <linux/fb.h> #include <linux/fb.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/dma-mapping.h> #include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/wait.h> #include <linux/wait.h>
#include <video/of_display_timing.h>
#include "vt8500lcdfb.h" #include "vt8500lcdfb.h"
#include "wmt_ge_rops.h" #include "wmt_ge_rops.h"
...@@ -275,11 +276,11 @@ static int vt8500lcd_probe(struct platform_device *pdev) ...@@ -275,11 +276,11 @@ static int vt8500lcd_probe(struct platform_device *pdev)
{ {
struct vt8500lcd_info *fbi; struct vt8500lcd_info *fbi;
struct resource *res; struct resource *res;
struct display_timings *disp_timing;
void *addr; void *addr;
int irq, ret; int irq, ret;
struct fb_videomode of_mode; struct fb_videomode of_mode;
struct device_node *np;
u32 bpp; u32 bpp;
dma_addr_t fb_mem_phys; dma_addr_t fb_mem_phys;
unsigned long fb_mem_len; unsigned long fb_mem_len;
...@@ -344,32 +345,18 @@ static int vt8500lcd_probe(struct platform_device *pdev) ...@@ -344,32 +345,18 @@ static int vt8500lcd_probe(struct platform_device *pdev)
goto failed_free_res; goto failed_free_res;
} }
np = of_parse_phandle(pdev->dev.of_node, "default-mode", 0); disp_timing = of_get_display_timings(pdev->dev.of_node);
if (!np) { if (!disp_timing)
pr_err("%s: No display description in Device Tree\n", __func__); return -EINVAL;
ret = -EINVAL;
goto failed_free_res;
}
/* ret = of_get_fb_videomode(pdev->dev.of_node, &of_mode,
* This code is copied from Sascha Hauer's of_videomode helper OF_USE_NATIVE_MODE);
* and can be replaced with a call to the helper once mainlined if (ret)
*/ return ret;
ret = 0;
ret |= of_property_read_u32(np, "hactive", &of_mode.xres); ret = of_property_read_u32(pdev->dev.of_node, "bits-per-pixel", &bpp);
ret |= of_property_read_u32(np, "vactive", &of_mode.yres); if (ret)
ret |= of_property_read_u32(np, "hback-porch", &of_mode.left_margin); return ret;
ret |= of_property_read_u32(np, "hfront-porch", &of_mode.right_margin);
ret |= of_property_read_u32(np, "hsync-len", &of_mode.hsync_len);
ret |= of_property_read_u32(np, "vback-porch", &of_mode.upper_margin);
ret |= of_property_read_u32(np, "vfront-porch", &of_mode.lower_margin);
ret |= of_property_read_u32(np, "vsync-len", &of_mode.vsync_len);
ret |= of_property_read_u32(np, "bpp", &bpp);
if (ret) {
pr_err("%s: Unable to read display properties\n", __func__);
goto failed_free_res;
}
of_mode.vmode = FB_VMODE_NONINTERLACED;
/* try allocating the framebuffer */ /* try allocating the framebuffer */
fb_mem_len = of_mode.xres * of_mode.yres * 2 * (bpp / 8); fb_mem_len = of_mode.xres * of_mode.yres * 2 * (bpp / 8);
......
...@@ -14,23 +14,24 @@ ...@@ -14,23 +14,24 @@
* GNU General Public License for more details. * GNU General Public License for more details.
*/ */
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/dma-mapping.h>
#include <linux/fb.h> #include <linux/fb.h>
#include <linux/errno.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/dma-mapping.h> #include <linux/kernel.h>
#include <linux/platform_device.h> #include <linux/memblock.h>
#include <linux/wait.h> #include <linux/mm.h>
#include <linux/module.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/of_fdt.h> #include <linux/of_fdt.h>
#include <linux/memblock.h> #include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/wait.h>
#include <video/of_display_timing.h>
#include "wm8505fb_regs.h" #include "wm8505fb_regs.h"
#include "wmt_ge_rops.h" #include "wmt_ge_rops.h"
...@@ -261,12 +262,12 @@ static struct fb_ops wm8505fb_ops = { ...@@ -261,12 +262,12 @@ static struct fb_ops wm8505fb_ops = {
static int wm8505fb_probe(struct platform_device *pdev) static int wm8505fb_probe(struct platform_device *pdev)
{ {
struct wm8505fb_info *fbi; struct wm8505fb_info *fbi;
struct resource *res; struct resource *res;
struct display_timings *disp_timing;
void *addr; void *addr;
int ret; int ret;
struct fb_videomode of_mode; struct fb_videomode mode;
struct device_node *np;
u32 bpp; u32 bpp;
dma_addr_t fb_mem_phys; dma_addr_t fb_mem_phys;
unsigned long fb_mem_len; unsigned long fb_mem_len;
...@@ -306,33 +307,19 @@ static int wm8505fb_probe(struct platform_device *pdev) ...@@ -306,33 +307,19 @@ static int wm8505fb_probe(struct platform_device *pdev)
if (fbi->regbase == NULL) if (fbi->regbase == NULL)
return -EBUSY; return -EBUSY;
np = of_parse_phandle(pdev->dev.of_node, "default-mode", 0); disp_timing = of_get_display_timings(pdev->dev.of_node);
if (!np) { if (!disp_timing)
pr_err("%s: No display description in Device Tree\n", __func__);
return -EINVAL; return -EINVAL;
}
/* ret = of_get_fb_videomode(pdev->dev.of_node, &mode, OF_USE_NATIVE_MODE);
* This code is copied from Sascha Hauer's of_videomode helper if (ret)
* and can be replaced with a call to the helper once mainlined return ret;
*/
ret = 0; ret = of_property_read_u32(pdev->dev.of_node, "bits-per-pixel", &bpp);
ret |= of_property_read_u32(np, "hactive", &of_mode.xres); if (ret)
ret |= of_property_read_u32(np, "vactive", &of_mode.yres); return ret;
ret |= of_property_read_u32(np, "hback-porch", &of_mode.left_margin);
ret |= of_property_read_u32(np, "hfront-porch", &of_mode.right_margin);
ret |= of_property_read_u32(np, "hsync-len", &of_mode.hsync_len);
ret |= of_property_read_u32(np, "vback-porch", &of_mode.upper_margin);
ret |= of_property_read_u32(np, "vfront-porch", &of_mode.lower_margin);
ret |= of_property_read_u32(np, "vsync-len", &of_mode.vsync_len);
ret |= of_property_read_u32(np, "bpp", &bpp);
if (ret) {
pr_err("%s: Unable to read display properties\n", __func__);
return -EINVAL;
}
of_mode.vmode = FB_VMODE_NONINTERLACED; fb_videomode_to_var(&fbi->fb.var, &mode);
fb_videomode_to_var(&fbi->fb.var, &of_mode);
fbi->fb.var.nonstd = 0; fbi->fb.var.nonstd = 0;
fbi->fb.var.activate = FB_ACTIVATE_NOW; fbi->fb.var.activate = FB_ACTIVATE_NOW;
...@@ -341,7 +328,7 @@ static int wm8505fb_probe(struct platform_device *pdev) ...@@ -341,7 +328,7 @@ static int wm8505fb_probe(struct platform_device *pdev)
fbi->fb.var.width = -1; fbi->fb.var.width = -1;
/* try allocating the framebuffer */ /* try allocating the framebuffer */
fb_mem_len = of_mode.xres * of_mode.yres * 2 * (bpp / 8); fb_mem_len = mode.xres * mode.yres * 2 * (bpp / 8);
fb_mem_virt = dmam_alloc_coherent(&pdev->dev, fb_mem_len, &fb_mem_phys, fb_mem_virt = dmam_alloc_coherent(&pdev->dev, fb_mem_len, &fb_mem_phys,
GFP_KERNEL); GFP_KERNEL);
if (!fb_mem_virt) { if (!fb_mem_virt) {
...@@ -349,8 +336,8 @@ static int wm8505fb_probe(struct platform_device *pdev) ...@@ -349,8 +336,8 @@ static int wm8505fb_probe(struct platform_device *pdev)
return -ENOMEM; return -ENOMEM;
} }
fbi->fb.var.xres_virtual = of_mode.xres; fbi->fb.var.xres_virtual = mode.xres;
fbi->fb.var.yres_virtual = of_mode.yres * 2; fbi->fb.var.yres_virtual = mode.yres * 2;
fbi->fb.var.bits_per_pixel = bpp; fbi->fb.var.bits_per_pixel = bpp;
fbi->fb.fix.smem_start = fb_mem_phys; fbi->fb.fix.smem_start = fb_mem_phys;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment