Commit e9a91de7 authored by Tony Prisk's avatar Tony Prisk
Browse files

arm: vt8500: Update arch-vt8500 to devicetree support.



Merged existing board files to a single dt-capable file.
Converted irq and timer code to devicetree.
Removed existing device files that are no longer required with
devicetree support.
All existing platform devices are converted to devicetree nodes
except PWM.

Removed restart.c and moved code into vt8500.c to remove
duplicate PMC code.
Signed-off-by: default avatarTony Prisk <linux@prisktech.co.nz>
Acked-by: default avatarArnd Bergmann <arnd@arndb.de>
parent 4e48b1c5
......@@ -1005,6 +1005,10 @@ config ARCH_VT8500
select ARCH_HAS_CPUFREQ
select GENERIC_CLOCKEVENTS
select ARCH_REQUIRE_GPIOLIB
select USE_OF
select COMMON_CLK
select HAVE_CLK
select CLKDEV_LOOKUP
help
Support for VIA/WonderMedia VT8500/WM85xx System-on-Chip.
......@@ -1129,8 +1133,6 @@ source "arch/arm/mach-versatile/Kconfig"
source "arch/arm/mach-vexpress/Kconfig"
source "arch/arm/plat-versatile/Kconfig"
source "arch/arm/mach-vt8500/Kconfig"
source "arch/arm/mach-w90x900/Kconfig"
# Definitions to make life easier
......@@ -1623,6 +1625,7 @@ config ARCH_NR_GPIO
default 355 if ARCH_U8500
default 264 if MACH_H4700
default 512 if SOC_OMAP5
default 288 if ARCH_VT8500
default 0
help
Maximum number of GPIOs in the system.
......
if ARCH_VT8500
config VTWM_VERSION_VT8500
bool
config VTWM_VERSION_WM8505
bool
config MACH_BV07
bool "Benign BV07-8500 Mini Netbook"
depends on ARCH_VT8500
select VTWM_VERSION_VT8500
help
Add support for the inexpensive 7-inch netbooks sold by many
Chinese distributors under various names. Note that there are
many hardware implementations in identical exterior, make sure
that yours is indeed based on a VIA VT8500 chip.
config MACH_WM8505_7IN_NETBOOK
bool "WM8505 7-inch generic netbook"
depends on ARCH_VT8500
select VTWM_VERSION_WM8505
help
Add support for the inexpensive 7-inch netbooks sold by many
Chinese distributors under various names. Note that there are
many hardware implementations in identical exterior, make sure
that yours is indeed based on a WonderMedia WM8505 chip.
comment "LCD panel size"
config WMT_PANEL_800X480
bool "7-inch with 800x480 resolution"
depends on (FB_VT8500 || FB_WM8505)
default y
help
These are found in most of the netbooks in generic cases, as
well as in Eken M001 tablets and possibly elsewhere.
To select this panel at runtime, say y here and append
'panel=800x480' to your kernel command line. Otherwise, the
largest one available will be used.
config WMT_PANEL_800X600
bool "8-inch with 800x600 resolution"
depends on (FB_VT8500 || FB_WM8505)
help
These are found in Eken M003 tablets and possibly elsewhere.
To select this panel at runtime, say y here and append
'panel=800x600' to your kernel command line. Otherwise, the
largest one available will be used.
config WMT_PANEL_1024X576
bool "10-inch with 1024x576 resolution"
depends on (FB_VT8500 || FB_WM8505)
help
These are found in CherryPal netbooks and possibly elsewhere.
To select this panel at runtime, say y here and append
'panel=1024x576' to your kernel command line. Otherwise, the
largest one available will be used.
config WMT_PANEL_1024X600
bool "10-inch with 1024x600 resolution"
depends on (FB_VT8500 || FB_WM8505)
help
These are found in Eken M006 tablets and possibly elsewhere.
To select this panel at runtime, say y here and append
'panel=1024x600' to your kernel command line. Otherwise, the
largest one available will be used.
endif
obj-y += devices.o gpio.o irq.o timer.o restart.o
obj-$(CONFIG_VTWM_VERSION_VT8500) += devices-vt8500.o
obj-$(CONFIG_VTWM_VERSION_WM8505) += devices-wm8505.o
obj-$(CONFIG_MACH_BV07) += bv07.o
obj-$(CONFIG_MACH_WM8505_7IN_NETBOOK) += wm8505_7in.o
obj-$(CONFIG_ARCH_VT8500) += irq.o timer.o vt8500.o
/*
* arch/arm/mach-vt8500/bv07.c
*
* Copyright (C) 2010 Alexey Charkov <alchark@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* 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, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <linux/io.h>
#include <linux/pm.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <mach/restart.h>
#include "devices.h"
static void __iomem *pmc_hiber;
static struct platform_device *devices[] __initdata = {
&vt8500_device_uart0,
&vt8500_device_lcdc,
&vt8500_device_ehci,
&vt8500_device_ge_rops,
&vt8500_device_pwm,
&vt8500_device_pwmbl,
&vt8500_device_rtc,
};
static void vt8500_power_off(void)
{
local_irq_disable();
writew(5, pmc_hiber);
asm("mcr%? p15, 0, %0, c7, c0, 4" : : "r" (0));
}
void __init bv07_init(void)
{
#ifdef CONFIG_FB_VT8500
void __iomem *gpio_mux_reg = ioremap(wmt_gpio_base + 0x200, 4);
if (gpio_mux_reg) {
writel(readl(gpio_mux_reg) | 1, gpio_mux_reg);
iounmap(gpio_mux_reg);
} else {
printk(KERN_ERR "Could not remap the GPIO mux register, display may not work properly!\n");
}
#endif
pmc_hiber = ioremap(wmt_pmc_base + 0x12, 2);
if (pmc_hiber)
pm_power_off = &vt8500_power_off;
else
printk(KERN_ERR "PMC Hibernation register could not be remapped, not enabling power off!\n");
wmt_setup_restart();
vt8500_set_resources();
platform_add_devices(devices, ARRAY_SIZE(devices));
vt8500_gpio_init();
}
MACHINE_START(BV07, "Benign BV07 Mini Netbook")
.atag_offset = 0x100,
.restart = wmt_restart,
.reserve = vt8500_reserve_mem,
.map_io = vt8500_map_io,
.init_irq = vt8500_init_irq,
.timer = &vt8500_timer,
.init_machine = bv07_init,
MACHINE_END
/* linux/arch/arm/mach-vt8500/restart.c
/* linux/arch/arm/mach-vt8500/dt_common.h
*
* Copyright (C) 2012 Tony Prisk <linux@prisktech.co.nz>
*
......@@ -12,43 +12,17 @@
* GNU General Public License for more details.
*
*/
#include <asm/io.h>
#include <linux/of.h>
#include <linux/of_address.h>
#define LEGACY_PMC_BASE 0xD8130000
#define WMT_PRIZM_PMSR_REG 0x60
static void __iomem *pmc_base;
#ifndef __ARCH_ARM_MACH_VT8500_DT_COMMON_H
#define __ARCH_ARM_MACH_VT8500_DT_COMMON_H
void wmt_setup_restart(void)
{
struct device_node *np;
/*
* Check if Power Mgmt Controller node is present in device tree. If no
* device tree node, use the legacy PMSR value (valid for all current
* SoCs).
*/
np = of_find_compatible_node(NULL, NULL, "wmt,prizm-pmc");
if (np) {
pmc_base = of_iomap(np, 0);
#include <linux/of.h>
if (!pmc_base)
pr_err("%s:of_iomap(pmc) failed\n", __func__);
void __init vt8500_timer_init(void);
int __init vt8500_irq_init(struct device_node *node,
struct device_node *parent);
of_node_put(np);
} else {
pmc_base = ioremap(LEGACY_PMC_BASE, 0x1000);
if (!pmc_base) {
pr_err("%s:ioremap(rstc) failed\n", __func__);
return;
}
}
}
/* defined in drivers/clk/clk-vt8500.c */
void __init vtwm_clk_init(void __iomem *pmc_base);
void wmt_restart(char mode, const char *cmd)
{
if (pmc_base)
writel(1, pmc_base + WMT_PRIZM_PMSR_REG);
}
#endif
/* linux/arch/arm/mach-vt8500/devices-vt8500.c
*
* Copyright (C) 2010 Alexey Charkov <alchark@gmail.com>
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* 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.
*
*/
#include <linux/platform_device.h>
#include <mach/vt8500_regs.h>
#include <mach/vt8500_irqs.h>
#include <mach/i8042.h>
#include "devices.h"
void __init vt8500_set_resources(void)
{
struct resource tmp[3];
tmp[0] = wmt_mmio_res(VT8500_LCDC_BASE, SZ_1K);
tmp[1] = wmt_irq_res(IRQ_LCDC);
wmt_res_add(&vt8500_device_lcdc, tmp, 2);
tmp[0] = wmt_mmio_res(VT8500_UART0_BASE, 0x1040);
tmp[1] = wmt_irq_res(IRQ_UART0);
wmt_res_add(&vt8500_device_uart0, tmp, 2);
tmp[0] = wmt_mmio_res(VT8500_UART1_BASE, 0x1040);
tmp[1] = wmt_irq_res(IRQ_UART1);
wmt_res_add(&vt8500_device_uart1, tmp, 2);
tmp[0] = wmt_mmio_res(VT8500_UART2_BASE, 0x1040);
tmp[1] = wmt_irq_res(IRQ_UART2);
wmt_res_add(&vt8500_device_uart2, tmp, 2);
tmp[0] = wmt_mmio_res(VT8500_UART3_BASE, 0x1040);
tmp[1] = wmt_irq_res(IRQ_UART3);
wmt_res_add(&vt8500_device_uart3, tmp, 2);
tmp[0] = wmt_mmio_res(VT8500_EHCI_BASE, SZ_512);
tmp[1] = wmt_irq_res(IRQ_EHCI);
wmt_res_add(&vt8500_device_ehci, tmp, 2);
tmp[0] = wmt_mmio_res(VT8500_GEGEA_BASE, SZ_256);
wmt_res_add(&vt8500_device_ge_rops, tmp, 1);
tmp[0] = wmt_mmio_res(VT8500_PWM_BASE, 0x44);
wmt_res_add(&vt8500_device_pwm, tmp, 1);
tmp[0] = wmt_mmio_res(VT8500_RTC_BASE, 0x2c);
tmp[1] = wmt_irq_res(IRQ_RTC);
tmp[2] = wmt_irq_res(IRQ_RTCSM);
wmt_res_add(&vt8500_device_rtc, tmp, 3);
}
static void __init vt8500_set_externs(void)
{
/* Non-resource-aware stuff */
wmt_ic_base = VT8500_IC_BASE;
wmt_gpio_base = VT8500_GPIO_BASE;
wmt_pmc_base = VT8500_PMC_BASE;
wmt_i8042_base = VT8500_PS2_BASE;
wmt_nr_irqs = VT8500_NR_IRQS;
wmt_timer_irq = IRQ_PMCOS0;
wmt_gpio_ext_irq[0] = IRQ_EXT0;
wmt_gpio_ext_irq[1] = IRQ_EXT1;
wmt_gpio_ext_irq[2] = IRQ_EXT2;
wmt_gpio_ext_irq[3] = IRQ_EXT3;
wmt_gpio_ext_irq[4] = IRQ_EXT4;
wmt_gpio_ext_irq[5] = IRQ_EXT5;
wmt_gpio_ext_irq[6] = IRQ_EXT6;
wmt_gpio_ext_irq[7] = IRQ_EXT7;
wmt_i8042_kbd_irq = IRQ_PS2KBD;
wmt_i8042_aux_irq = IRQ_PS2MOUSE;
}
void __init vt8500_map_io(void)
{
iotable_init(wmt_io_desc, ARRAY_SIZE(wmt_io_desc));
/* Should be done before interrupts and timers are initialized */
vt8500_set_externs();
}
/* linux/arch/arm/mach-vt8500/devices-wm8505.c
*
* Copyright (C) 2010 Alexey Charkov <alchark@gmail.com>
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* 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.
*
*/
#include <linux/platform_device.h>
#include <mach/wm8505_regs.h>
#include <mach/wm8505_irqs.h>
#include <mach/i8042.h>
#include "devices.h"
void __init wm8505_set_resources(void)
{
struct resource tmp[3];
tmp[0] = wmt_mmio_res(WM8505_GOVR_BASE, SZ_512);
wmt_res_add(&vt8500_device_wm8505_fb, tmp, 1);
tmp[0] = wmt_mmio_res(WM8505_UART0_BASE, 0x1040);
tmp[1] = wmt_irq_res(IRQ_UART0);
wmt_res_add(&vt8500_device_uart0, tmp, 2);
tmp[0] = wmt_mmio_res(WM8505_UART1_BASE, 0x1040);
tmp[1] = wmt_irq_res(IRQ_UART1);
wmt_res_add(&vt8500_device_uart1, tmp, 2);
tmp[0] = wmt_mmio_res(WM8505_UART2_BASE, 0x1040);
tmp[1] = wmt_irq_res(IRQ_UART2);
wmt_res_add(&vt8500_device_uart2, tmp, 2);
tmp[0] = wmt_mmio_res(WM8505_UART3_BASE, 0x1040);
tmp[1] = wmt_irq_res(IRQ_UART3);
wmt_res_add(&vt8500_device_uart3, tmp, 2);
tmp[0] = wmt_mmio_res(WM8505_UART4_BASE, 0x1040);
tmp[1] = wmt_irq_res(IRQ_UART4);
wmt_res_add(&vt8500_device_uart4, tmp, 2);
tmp[0] = wmt_mmio_res(WM8505_UART5_BASE, 0x1040);
tmp[1] = wmt_irq_res(IRQ_UART5);
wmt_res_add(&vt8500_device_uart5, tmp, 2);
tmp[0] = wmt_mmio_res(WM8505_EHCI_BASE, SZ_512);
tmp[1] = wmt_irq_res(IRQ_EHCI);
wmt_res_add(&vt8500_device_ehci, tmp, 2);
tmp[0] = wmt_mmio_res(WM8505_GEGEA_BASE, SZ_256);
wmt_res_add(&vt8500_device_ge_rops, tmp, 1);
tmp[0] = wmt_mmio_res(WM8505_PWM_BASE, 0x44);
wmt_res_add(&vt8500_device_pwm, tmp, 1);
tmp[0] = wmt_mmio_res(WM8505_RTC_BASE, 0x2c);
tmp[1] = wmt_irq_res(IRQ_RTC);
tmp[2] = wmt_irq_res(IRQ_RTCSM);
wmt_res_add(&vt8500_device_rtc, tmp, 3);
}
static void __init wm8505_set_externs(void)
{
/* Non-resource-aware stuff */
wmt_ic_base = WM8505_IC_BASE;
wmt_sic_base = WM8505_SIC_BASE;
wmt_gpio_base = WM8505_GPIO_BASE;
wmt_pmc_base = WM8505_PMC_BASE;
wmt_i8042_base = WM8505_PS2_BASE;
wmt_nr_irqs = WM8505_NR_IRQS;
wmt_timer_irq = IRQ_PMCOS0;
wmt_gpio_ext_irq[0] = IRQ_EXT0;
wmt_gpio_ext_irq[1] = IRQ_EXT1;
wmt_gpio_ext_irq[2] = IRQ_EXT2;
wmt_gpio_ext_irq[3] = IRQ_EXT3;
wmt_gpio_ext_irq[4] = IRQ_EXT4;
wmt_gpio_ext_irq[5] = IRQ_EXT5;
wmt_gpio_ext_irq[6] = IRQ_EXT6;
wmt_gpio_ext_irq[7] = IRQ_EXT7;
wmt_i8042_kbd_irq = IRQ_PS2KBD;
wmt_i8042_aux_irq = IRQ_PS2MOUSE;
}
void __init wm8505_map_io(void)
{
iotable_init(wmt_io_desc, ARRAY_SIZE(wmt_io_desc));
/* Should be done before interrupts and timers are initialized */
wm8505_set_externs();
}
/* linux/arch/arm/mach-vt8500/devices.c
*
* Copyright (C) 2010 Alexey Charkov <alchark@gmail.com>
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* 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.
*
*/
#include <linux/kernel.h>
#include <linux/io.h>
#include <linux/device.h>
#include <linux/dma-mapping.h>
#include <linux/platform_device.h>
#include <linux/pwm_backlight.h>
#include <linux/memblock.h>
#include <asm/mach/arch.h>
#include <mach/vt8500fb.h>
#include <mach/i8042.h>
#include "devices.h"
/* These can't use resources currently */
unsigned long wmt_ic_base __initdata;
unsigned long wmt_sic_base __initdata;
unsigned long wmt_gpio_base __initdata;
unsigned long wmt_pmc_base __initdata;
unsigned long wmt_i8042_base __initdata;
int wmt_nr_irqs __initdata;
int wmt_timer_irq __initdata;
int wmt_gpio_ext_irq[8] __initdata;
/* Should remain accessible after init.
* i8042 driver desperately calls for attention...
*/
int wmt_i8042_kbd_irq;
int wmt_i8042_aux_irq;
static u64 fb_dma_mask = DMA_BIT_MASK(32);
struct platform_device vt8500_device_lcdc = {
.name = "vt8500-lcd",
.id = 0,
.dev = {
.dma_mask = &fb_dma_mask,
.coherent_dma_mask = DMA_BIT_MASK(32),
},
};
struct platform_device vt8500_device_wm8505_fb = {
.name = "wm8505-fb",
.id = 0,
};
/* Smallest to largest */
static struct vt8500fb_platform_data panels[] = {
#ifdef CONFIG_WMT_PANEL_800X480
{
.xres_virtual = 800,
.yres_virtual = 480 * 2,
.mode = {
.name = "800x480",
.xres = 800,
.yres = 480,
.left_margin = 88,
.right_margin = 40,
.upper_margin = 32,
.lower_margin = 11,
.hsync_len = 0,
.vsync_len = 1,
.vmode = FB_VMODE_NONINTERLACED,
},
},
#endif
#ifdef CONFIG_WMT_PANEL_800X600
{
.xres_virtual = 800,
.yres_virtual = 600 * 2,
.mode = {
.name = "800x600",
.xres = 800,
.yres = 600,
.left_margin = 88,
.right_margin = 40,
.upper_margin = 32,
.lower_margin = 11,
.hsync_len = 0,
.vsync_len = 1,
.vmode = FB_VMODE_NONINTERLACED,
},
},
#endif
#ifdef CONFIG_WMT_PANEL_1024X576
{
.xres_virtual = 1024,
.yres_virtual = 576 * 2,
.mode = {
.name = "1024x576",
.xres = 1024,
.yres = 576,
.left_margin = 40,
.right_margin = 24,
.upper_margin = 32,
.lower_margin = 11,
.hsync_len = 96,
.vsync_len = 2,
.vmode = FB_VMODE_NONINTERLACED,
},
},
#endif
#ifdef CONFIG_WMT_PANEL_1024X600
{
.xres_virtual = 1024,
.yres_virtual = 600 * 2,
.mode = {
.name = "1024x600",
.xres = 1024,
.yres = 600,
.left_margin = 66,
.right_margin = 2,
.upper_margin = 19,
.lower_margin = 1,
.hsync_len = 23,
.vsync_len = 8,
.vmode = FB_VMODE_NONINTERLACED,
},
},
#endif
};
static int current_panel_idx __initdata = ARRAY_SIZE(panels) - 1;
static int __init panel_setup(char *str)
{
int i;
for (i = 0; i < ARRAY_SIZE(panels); i++) {
if (strcmp(panels[i].mode.name, str) == 0) {
current_panel_idx = i;
break;
}
}
return 0;
}
early_param("panel", panel_setup);
static inline void preallocate_fb(struct vt8500fb_platform_data *p,
unsigned long align) {
p->video_mem_len = (p->xres_virtual * p->yres_virtual * 4) >>
(p->bpp > 16 ? 0 : (p->bpp > 8 ? 1 :
(8 / p->bpp) + 1));
p->video_mem_phys = (unsigned long)memblock_alloc(p->video_mem_len,
align);
p->video_mem_virt = phys_to_virt(p->video_mem_phys);
}
struct platform_device vt8500_device_uart0 = {
.name = "vt8500_serial",
.id = 0,
};
struct platform_device vt8500_device_uart1 = {
.name = "vt8500_serial",
.id = 1,
};