Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ARM: 6597/1: Add basic architecture support for VIA/WonderMedia 85xx SoC's

This adds support for the family of Systems-on-Chip produced initially
by VIA and now its subsidiary WonderMedia that have recently become
widespread in lower-end Chinese ARM-based tablets and netbooks.

Support is included for both VT8500 and WM8505, selectable by a
configuration switch at kernel build time.

Included are basic machine initialization files, register and
interrupt definitions, support for the on-chip interrupt controller,
high-precision OS timer, GPIO lines, necessary macros for early debug,
pulse-width-modulated outputs control, as well as platform device
configurations for the specific drivers implemented elsewhere.

Signed-off-by: Alexey Charkov <alchark@gmail.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>

authored by

Alexey Charkov and committed by
Russell King
21f47fbc 1bae4ce2

+2356
+12
arch/arm/Kconfig
··· 875 875 help 876 876 Support for ST's SPEAr platform (SPEAr3xx, SPEAr6xx and SPEAr13xx). 877 877 878 + config ARCH_VT8500 879 + bool "VIA/WonderMedia 85xx" 880 + select CPU_ARM926T 881 + select GENERIC_GPIO 882 + select ARCH_HAS_CPUFREQ 883 + select GENERIC_CLOCKEVENTS 884 + select ARCH_REQUIRE_GPIOLIB 885 + select HAVE_PWM 886 + help 887 + Support for VIA/WonderMedia VT8500/WM85xx System-on-Chip. 878 888 endchoice 879 889 880 890 # ··· 1016 1006 source "arch/arm/mach-versatile/Kconfig" 1017 1007 1018 1008 source "arch/arm/mach-vexpress/Kconfig" 1009 + 1010 + source "arch/arm/mach-vt8500/Kconfig" 1019 1011 1020 1012 source "arch/arm/mach-w90x900/Kconfig" 1021 1013
+1
arch/arm/Makefile
··· 190 190 machine-$(CONFIG_ARCH_U8500) := ux500 191 191 machine-$(CONFIG_ARCH_VERSATILE) := versatile 192 192 machine-$(CONFIG_ARCH_VEXPRESS) := vexpress 193 + machine-$(CONFIG_ARCH_VT8500) := vt8500 193 194 machine-$(CONFIG_ARCH_W90X900) := w90x900 194 195 machine-$(CONFIG_ARCH_NUC93X) := nuc93x 195 196 machine-$(CONFIG_FOOTBRIDGE) := footbridge
+4
arch/arm/boot/compressed/Makefile
··· 29 29 OBJS += head-sa1100.o 30 30 endif 31 31 32 + ifeq ($(CONFIG_ARCH_VT8500),y) 33 + OBJS += head-vt8500.o 34 + endif 35 + 32 36 ifeq ($(CONFIG_CPU_XSCALE),y) 33 37 OBJS += head-xscale.o 34 38 endif
+46
arch/arm/boot/compressed/head-vt8500.S
··· 1 + /* 2 + * linux/arch/arm/boot/compressed/head-vt8500.S 3 + * 4 + * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com> 5 + * 6 + * VIA VT8500 specific tweaks. This is merged into head.S by the linker. 7 + * 8 + */ 9 + 10 + #include <linux/linkage.h> 11 + #include <asm/mach-types.h> 12 + 13 + .section ".start", "ax" 14 + 15 + __VT8500_start: 16 + @ Compare the SCC ID register against a list of known values 17 + ldr r1, .SCCID 18 + ldr r3, [r1] 19 + 20 + @ VT8500 override 21 + ldr r4, .VT8500SCC 22 + cmp r3, r4 23 + ldreq r7, .ID_BV07 24 + beq .Lendvt8500 25 + 26 + @ WM8505 override 27 + ldr r4, .WM8505SCC 28 + cmp r3, r4 29 + ldreq r7, .ID_8505 30 + beq .Lendvt8500 31 + 32 + @ Otherwise, leave the bootloader's machine id untouched 33 + 34 + .SCCID: 35 + .word 0xd8120000 36 + .VT8500SCC: 37 + .word 0x34000102 38 + .WM8505SCC: 39 + .word 0x34260103 40 + 41 + .ID_BV07: 42 + .word MACH_TYPE_BV07 43 + .ID_8505: 44 + .word MACH_TYPE_WM8505_7IN_NETBOOK 45 + 46 + .Lendvt8500:
+73
arch/arm/mach-vt8500/Kconfig
··· 1 + if ARCH_VT8500 2 + 3 + config VTWM_VERSION_VT8500 4 + bool 5 + 6 + config VTWM_VERSION_WM8505 7 + bool 8 + 9 + config MACH_BV07 10 + bool "Benign BV07-8500 Mini Netbook" 11 + depends on ARCH_VT8500 12 + select VTWM_VERSION_VT8500 13 + help 14 + Add support for the inexpensive 7-inch netbooks sold by many 15 + Chinese distributors under various names. Note that there are 16 + many hardware implementations in identical exterior, make sure 17 + that yours is indeed based on a VIA VT8500 chip. 18 + 19 + config MACH_WM8505_7IN_NETBOOK 20 + bool "WM8505 7-inch generic netbook" 21 + depends on ARCH_VT8500 22 + select VTWM_VERSION_WM8505 23 + help 24 + Add support for the inexpensive 7-inch netbooks sold by many 25 + Chinese distributors under various names. Note that there are 26 + many hardware implementations in identical exterior, make sure 27 + that yours is indeed based on a WonderMedia WM8505 chip. 28 + 29 + comment "LCD panel size" 30 + 31 + config WMT_PANEL_800X480 32 + bool "7-inch with 800x480 resolution" 33 + depends on (FB_VT8500 || FB_WM8505) 34 + default y 35 + help 36 + These are found in most of the netbooks in generic cases, as 37 + well as in Eken M001 tablets and possibly elsewhere. 38 + 39 + To select this panel at runtime, say y here and append 40 + 'panel=800x480' to your kernel command line. Otherwise, the 41 + largest one available will be used. 42 + 43 + config WMT_PANEL_800X600 44 + bool "8-inch with 800x600 resolution" 45 + depends on (FB_VT8500 || FB_WM8505) 46 + help 47 + These are found in Eken M003 tablets and possibly elsewhere. 48 + 49 + To select this panel at runtime, say y here and append 50 + 'panel=800x600' to your kernel command line. Otherwise, the 51 + largest one available will be used. 52 + 53 + config WMT_PANEL_1024X576 54 + bool "10-inch with 1024x576 resolution" 55 + depends on (FB_VT8500 || FB_WM8505) 56 + help 57 + These are found in CherryPal netbooks and possibly elsewhere. 58 + 59 + To select this panel at runtime, say y here and append 60 + 'panel=1024x576' to your kernel command line. Otherwise, the 61 + largest one available will be used. 62 + 63 + config WMT_PANEL_1024X600 64 + bool "10-inch with 1024x600 resolution" 65 + depends on (FB_VT8500 || FB_WM8505) 66 + help 67 + These are found in Eken M006 tablets and possibly elsewhere. 68 + 69 + To select this panel at runtime, say y here and append 70 + 'panel=1024x600' to your kernel command line. Otherwise, the 71 + largest one available will be used. 72 + 73 + endif
+9
arch/arm/mach-vt8500/Makefile
··· 1 + obj-y += devices.o gpio.o irq.o timer.o 2 + 3 + obj-$(CONFIG_VTWM_VERSION_VT8500) += devices-vt8500.o 4 + obj-$(CONFIG_VTWM_VERSION_WM8505) += devices-wm8505.o 5 + 6 + obj-$(CONFIG_MACH_BV07) += bv07.o 7 + obj-$(CONFIG_MACH_WM8505_7IN_NETBOOK) += wm8505_7in.o 8 + 9 + obj-$(CONFIG_HAVE_PWM) += pwm.o
+3
arch/arm/mach-vt8500/Makefile.boot
··· 1 + zreladdr-y := 0x00008000 2 + params_phys-y := 0x00000100 3 + initrd_phys-y := 0x01000000
+77
arch/arm/mach-vt8500/bv07.c
··· 1 + /* 2 + * arch/arm/mach-vt8500/bv07.c 3 + * 4 + * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com> 5 + * 6 + * This program is free software; you can redistribute it and/or modify 7 + * it under the terms of the GNU General Public License as published by 8 + * the Free Software Foundation; either version 2 of the License, or 9 + * (at your option) any later version. 10 + * 11 + * This program is distributed in the hope that it will be useful, 12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + * GNU General Public License for more details. 15 + * 16 + * You should have received a copy of the GNU General Public License 17 + * along with this program; if not, write to the Free Software 18 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 + */ 20 + 21 + #include <linux/io.h> 22 + #include <linux/pm.h> 23 + 24 + #include <asm/mach-types.h> 25 + #include <asm/mach/arch.h> 26 + 27 + #include "devices.h" 28 + 29 + static void __iomem *pmc_hiber; 30 + 31 + static struct platform_device *devices[] __initdata = { 32 + &vt8500_device_uart0, 33 + &vt8500_device_lcdc, 34 + &vt8500_device_ehci, 35 + &vt8500_device_ge_rops, 36 + &vt8500_device_pwm, 37 + &vt8500_device_pwmbl, 38 + &vt8500_device_rtc, 39 + }; 40 + 41 + static void vt8500_power_off(void) 42 + { 43 + local_irq_disable(); 44 + writew(5, pmc_hiber); 45 + asm("mcr%? p15, 0, %0, c7, c0, 4" : : "r" (0)); 46 + } 47 + 48 + void __init bv07_init(void) 49 + { 50 + #ifdef CONFIG_FB_VT8500 51 + void __iomem *gpio_mux_reg = ioremap(wmt_gpio_base + 0x200, 4); 52 + if (gpio_mux_reg) { 53 + writel(readl(gpio_mux_reg) | 1, gpio_mux_reg); 54 + iounmap(gpio_mux_reg); 55 + } else { 56 + printk(KERN_ERR "Could not remap the GPIO mux register, display may not work properly!\n"); 57 + } 58 + #endif 59 + pmc_hiber = ioremap(wmt_pmc_base + 0x12, 2); 60 + if (pmc_hiber) 61 + pm_power_off = &vt8500_power_off; 62 + else 63 + printk(KERN_ERR "PMC Hibernation register could not be remapped, not enabling power off!\n"); 64 + 65 + vt8500_set_resources(); 66 + platform_add_devices(devices, ARRAY_SIZE(devices)); 67 + vt8500_gpio_init(); 68 + } 69 + 70 + MACHINE_START(BV07, "Benign BV07 Mini Netbook") 71 + .boot_params = 0x00000100, 72 + .reserve = vt8500_reserve_mem, 73 + .map_io = vt8500_map_io, 74 + .init_irq = vt8500_init_irq, 75 + .timer = &vt8500_timer, 76 + .init_machine = bv07_init, 77 + MACHINE_END
+91
arch/arm/mach-vt8500/devices-vt8500.c
··· 1 + /* linux/arch/arm/mach-vt8500/devices-vt8500.c 2 + * 3 + * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com> 4 + * 5 + * This software is licensed under the terms of the GNU General Public 6 + * License version 2, as published by the Free Software Foundation, and 7 + * may be copied, distributed, and modified under those terms. 8 + * 9 + * This program is distributed in the hope that it will be useful, 10 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 + * GNU General Public License for more details. 13 + * 14 + */ 15 + 16 + #include <linux/platform_device.h> 17 + 18 + #include <mach/vt8500_regs.h> 19 + #include <mach/vt8500_irqs.h> 20 + #include <mach/i8042.h> 21 + #include "devices.h" 22 + 23 + void __init vt8500_set_resources(void) 24 + { 25 + struct resource tmp[3]; 26 + 27 + tmp[0] = wmt_mmio_res(VT8500_LCDC_BASE, SZ_1K); 28 + tmp[1] = wmt_irq_res(IRQ_LCDC); 29 + wmt_res_add(&vt8500_device_lcdc, tmp, 2); 30 + 31 + tmp[0] = wmt_mmio_res(VT8500_UART0_BASE, 0x1040); 32 + tmp[1] = wmt_irq_res(IRQ_UART0); 33 + wmt_res_add(&vt8500_device_uart0, tmp, 2); 34 + 35 + tmp[0] = wmt_mmio_res(VT8500_UART1_BASE, 0x1040); 36 + tmp[1] = wmt_irq_res(IRQ_UART1); 37 + wmt_res_add(&vt8500_device_uart1, tmp, 2); 38 + 39 + tmp[0] = wmt_mmio_res(VT8500_UART2_BASE, 0x1040); 40 + tmp[1] = wmt_irq_res(IRQ_UART2); 41 + wmt_res_add(&vt8500_device_uart2, tmp, 2); 42 + 43 + tmp[0] = wmt_mmio_res(VT8500_UART3_BASE, 0x1040); 44 + tmp[1] = wmt_irq_res(IRQ_UART3); 45 + wmt_res_add(&vt8500_device_uart3, tmp, 2); 46 + 47 + tmp[0] = wmt_mmio_res(VT8500_EHCI_BASE, SZ_512); 48 + tmp[1] = wmt_irq_res(IRQ_EHCI); 49 + wmt_res_add(&vt8500_device_ehci, tmp, 2); 50 + 51 + tmp[0] = wmt_mmio_res(VT8500_GEGEA_BASE, SZ_256); 52 + wmt_res_add(&vt8500_device_ge_rops, tmp, 1); 53 + 54 + tmp[0] = wmt_mmio_res(VT8500_PWM_BASE, 0x44); 55 + wmt_res_add(&vt8500_device_pwm, tmp, 1); 56 + 57 + tmp[0] = wmt_mmio_res(VT8500_RTC_BASE, 0x2c); 58 + tmp[1] = wmt_irq_res(IRQ_RTC); 59 + tmp[2] = wmt_irq_res(IRQ_RTCSM); 60 + wmt_res_add(&vt8500_device_rtc, tmp, 3); 61 + } 62 + 63 + static void __init vt8500_set_externs(void) 64 + { 65 + /* Non-resource-aware stuff */ 66 + wmt_ic_base = VT8500_IC_BASE; 67 + wmt_gpio_base = VT8500_GPIO_BASE; 68 + wmt_pmc_base = VT8500_PMC_BASE; 69 + wmt_i8042_base = VT8500_PS2_BASE; 70 + 71 + wmt_nr_irqs = VT8500_NR_IRQS; 72 + wmt_timer_irq = IRQ_PMCOS0; 73 + wmt_gpio_ext_irq[0] = IRQ_EXT0; 74 + wmt_gpio_ext_irq[1] = IRQ_EXT1; 75 + wmt_gpio_ext_irq[2] = IRQ_EXT2; 76 + wmt_gpio_ext_irq[3] = IRQ_EXT3; 77 + wmt_gpio_ext_irq[4] = IRQ_EXT4; 78 + wmt_gpio_ext_irq[5] = IRQ_EXT5; 79 + wmt_gpio_ext_irq[6] = IRQ_EXT6; 80 + wmt_gpio_ext_irq[7] = IRQ_EXT7; 81 + wmt_i8042_kbd_irq = IRQ_PS2KBD; 82 + wmt_i8042_aux_irq = IRQ_PS2MOUSE; 83 + } 84 + 85 + void __init vt8500_map_io(void) 86 + { 87 + iotable_init(wmt_io_desc, ARRAY_SIZE(wmt_io_desc)); 88 + 89 + /* Should be done before interrupts and timers are initialized */ 90 + vt8500_set_externs(); 91 + }
+99
arch/arm/mach-vt8500/devices-wm8505.c
··· 1 + /* linux/arch/arm/mach-vt8500/devices-wm8505.c 2 + * 3 + * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com> 4 + * 5 + * This software is licensed under the terms of the GNU General Public 6 + * License version 2, as published by the Free Software Foundation, and 7 + * may be copied, distributed, and modified under those terms. 8 + * 9 + * This program is distributed in the hope that it will be useful, 10 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 + * GNU General Public License for more details. 13 + * 14 + */ 15 + 16 + #include <linux/platform_device.h> 17 + 18 + #include <mach/wm8505_regs.h> 19 + #include <mach/wm8505_irqs.h> 20 + #include <mach/i8042.h> 21 + #include "devices.h" 22 + 23 + void __init wm8505_set_resources(void) 24 + { 25 + struct resource tmp[3]; 26 + 27 + tmp[0] = wmt_mmio_res(WM8505_GOVR_BASE, SZ_512); 28 + wmt_res_add(&vt8500_device_wm8505_fb, tmp, 1); 29 + 30 + tmp[0] = wmt_mmio_res(WM8505_UART0_BASE, 0x1040); 31 + tmp[1] = wmt_irq_res(IRQ_UART0); 32 + wmt_res_add(&vt8500_device_uart0, tmp, 2); 33 + 34 + tmp[0] = wmt_mmio_res(WM8505_UART1_BASE, 0x1040); 35 + tmp[1] = wmt_irq_res(IRQ_UART1); 36 + wmt_res_add(&vt8500_device_uart1, tmp, 2); 37 + 38 + tmp[0] = wmt_mmio_res(WM8505_UART2_BASE, 0x1040); 39 + tmp[1] = wmt_irq_res(IRQ_UART2); 40 + wmt_res_add(&vt8500_device_uart2, tmp, 2); 41 + 42 + tmp[0] = wmt_mmio_res(WM8505_UART3_BASE, 0x1040); 43 + tmp[1] = wmt_irq_res(IRQ_UART3); 44 + wmt_res_add(&vt8500_device_uart3, tmp, 2); 45 + 46 + tmp[0] = wmt_mmio_res(WM8505_UART4_BASE, 0x1040); 47 + tmp[1] = wmt_irq_res(IRQ_UART4); 48 + wmt_res_add(&vt8500_device_uart4, tmp, 2); 49 + 50 + tmp[0] = wmt_mmio_res(WM8505_UART5_BASE, 0x1040); 51 + tmp[1] = wmt_irq_res(IRQ_UART5); 52 + wmt_res_add(&vt8500_device_uart5, tmp, 2); 53 + 54 + tmp[0] = wmt_mmio_res(WM8505_EHCI_BASE, SZ_512); 55 + tmp[1] = wmt_irq_res(IRQ_EHCI); 56 + wmt_res_add(&vt8500_device_ehci, tmp, 2); 57 + 58 + tmp[0] = wmt_mmio_res(WM8505_GEGEA_BASE, SZ_256); 59 + wmt_res_add(&vt8500_device_ge_rops, tmp, 1); 60 + 61 + tmp[0] = wmt_mmio_res(WM8505_PWM_BASE, 0x44); 62 + wmt_res_add(&vt8500_device_pwm, tmp, 1); 63 + 64 + tmp[0] = wmt_mmio_res(WM8505_RTC_BASE, 0x2c); 65 + tmp[1] = wmt_irq_res(IRQ_RTC); 66 + tmp[2] = wmt_irq_res(IRQ_RTCSM); 67 + wmt_res_add(&vt8500_device_rtc, tmp, 3); 68 + } 69 + 70 + static void __init wm8505_set_externs(void) 71 + { 72 + /* Non-resource-aware stuff */ 73 + wmt_ic_base = WM8505_IC_BASE; 74 + wmt_sic_base = WM8505_SIC_BASE; 75 + wmt_gpio_base = WM8505_GPIO_BASE; 76 + wmt_pmc_base = WM8505_PMC_BASE; 77 + wmt_i8042_base = WM8505_PS2_BASE; 78 + 79 + wmt_nr_irqs = WM8505_NR_IRQS; 80 + wmt_timer_irq = IRQ_PMCOS0; 81 + wmt_gpio_ext_irq[0] = IRQ_EXT0; 82 + wmt_gpio_ext_irq[1] = IRQ_EXT1; 83 + wmt_gpio_ext_irq[2] = IRQ_EXT2; 84 + wmt_gpio_ext_irq[3] = IRQ_EXT3; 85 + wmt_gpio_ext_irq[4] = IRQ_EXT4; 86 + wmt_gpio_ext_irq[5] = IRQ_EXT5; 87 + wmt_gpio_ext_irq[6] = IRQ_EXT6; 88 + wmt_gpio_ext_irq[7] = IRQ_EXT7; 89 + wmt_i8042_kbd_irq = IRQ_PS2KBD; 90 + wmt_i8042_aux_irq = IRQ_PS2MOUSE; 91 + } 92 + 93 + void __init wm8505_map_io(void) 94 + { 95 + iotable_init(wmt_io_desc, ARRAY_SIZE(wmt_io_desc)); 96 + 97 + /* Should be done before interrupts and timers are initialized */ 98 + wm8505_set_externs(); 99 + }
+270
arch/arm/mach-vt8500/devices.c
··· 1 + /* linux/arch/arm/mach-vt8500/devices.c 2 + * 3 + * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com> 4 + * 5 + * This software is licensed under the terms of the GNU General Public 6 + * License version 2, as published by the Free Software Foundation, and 7 + * may be copied, distributed, and modified under those terms. 8 + * 9 + * This program is distributed in the hope that it will be useful, 10 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 + * GNU General Public License for more details. 13 + * 14 + */ 15 + 16 + #include <linux/kernel.h> 17 + #include <linux/io.h> 18 + #include <linux/device.h> 19 + #include <linux/dma-mapping.h> 20 + #include <linux/platform_device.h> 21 + #include <linux/pwm_backlight.h> 22 + #include <linux/memblock.h> 23 + 24 + #include <asm/mach/arch.h> 25 + 26 + #include <mach/vt8500fb.h> 27 + #include <mach/i8042.h> 28 + #include "devices.h" 29 + 30 + /* These can't use resources currently */ 31 + unsigned long wmt_ic_base __initdata; 32 + unsigned long wmt_sic_base __initdata; 33 + unsigned long wmt_gpio_base __initdata; 34 + unsigned long wmt_pmc_base __initdata; 35 + unsigned long wmt_i8042_base __initdata; 36 + 37 + int wmt_nr_irqs __initdata; 38 + int wmt_timer_irq __initdata; 39 + int wmt_gpio_ext_irq[8] __initdata; 40 + 41 + /* Should remain accessible after init. 42 + * i8042 driver desperately calls for attention... 43 + */ 44 + int wmt_i8042_kbd_irq; 45 + int wmt_i8042_aux_irq; 46 + 47 + static u64 fb_dma_mask = DMA_BIT_MASK(32); 48 + 49 + struct platform_device vt8500_device_lcdc = { 50 + .name = "vt8500-lcd", 51 + .id = 0, 52 + .dev = { 53 + .dma_mask = &fb_dma_mask, 54 + .coherent_dma_mask = DMA_BIT_MASK(32), 55 + }, 56 + }; 57 + 58 + struct platform_device vt8500_device_wm8505_fb = { 59 + .name = "wm8505-fb", 60 + .id = 0, 61 + }; 62 + 63 + /* Smallest to largest */ 64 + static struct vt8500fb_platform_data panels[] = { 65 + #ifdef CONFIG_WMT_PANEL_800X480 66 + { 67 + .xres_virtual = 800, 68 + .yres_virtual = 480 * 2, 69 + .mode = { 70 + .name = "800x480", 71 + .xres = 800, 72 + .yres = 480, 73 + .left_margin = 88, 74 + .right_margin = 40, 75 + .upper_margin = 32, 76 + .lower_margin = 11, 77 + .hsync_len = 0, 78 + .vsync_len = 1, 79 + .vmode = FB_VMODE_NONINTERLACED, 80 + }, 81 + }, 82 + #endif 83 + #ifdef CONFIG_WMT_PANEL_800X600 84 + { 85 + .xres_virtual = 800, 86 + .yres_virtual = 600 * 2, 87 + .mode = { 88 + .name = "800x600", 89 + .xres = 800, 90 + .yres = 600, 91 + .left_margin = 88, 92 + .right_margin = 40, 93 + .upper_margin = 32, 94 + .lower_margin = 11, 95 + .hsync_len = 0, 96 + .vsync_len = 1, 97 + .vmode = FB_VMODE_NONINTERLACED, 98 + }, 99 + }, 100 + #endif 101 + #ifdef CONFIG_WMT_PANEL_1024X576 102 + { 103 + .xres_virtual = 1024, 104 + .yres_virtual = 576 * 2, 105 + .mode = { 106 + .name = "1024x576", 107 + .xres = 1024, 108 + .yres = 576, 109 + .left_margin = 40, 110 + .right_margin = 24, 111 + .upper_margin = 32, 112 + .lower_margin = 11, 113 + .hsync_len = 96, 114 + .vsync_len = 2, 115 + .vmode = FB_VMODE_NONINTERLACED, 116 + }, 117 + }, 118 + #endif 119 + #ifdef CONFIG_WMT_PANEL_1024X600 120 + { 121 + .xres_virtual = 1024, 122 + .yres_virtual = 600 * 2, 123 + .mode = { 124 + .name = "1024x600", 125 + .xres = 1024, 126 + .yres = 600, 127 + .left_margin = 66, 128 + .right_margin = 2, 129 + .upper_margin = 19, 130 + .lower_margin = 1, 131 + .hsync_len = 23, 132 + .vsync_len = 8, 133 + .vmode = FB_VMODE_NONINTERLACED, 134 + }, 135 + }, 136 + #endif 137 + }; 138 + 139 + static int current_panel_idx __initdata = ARRAY_SIZE(panels) - 1; 140 + 141 + static int __init panel_setup(char *str) 142 + { 143 + int i; 144 + 145 + for (i = 0; i < ARRAY_SIZE(panels); i++) { 146 + if (strcmp(panels[i].mode.name, str) == 0) { 147 + current_panel_idx = i; 148 + break; 149 + } 150 + } 151 + return 0; 152 + } 153 + 154 + early_param("panel", panel_setup); 155 + 156 + static inline void preallocate_fb(struct vt8500fb_platform_data *p, 157 + unsigned long align) { 158 + p->video_mem_len = (p->xres_virtual * p->yres_virtual * 4) >> 159 + (p->bpp > 16 ? 0 : (p->bpp > 8 ? 1 : 160 + (8 / p->bpp) + 1)); 161 + p->video_mem_phys = (unsigned long)memblock_alloc(p->video_mem_len, 162 + align); 163 + p->video_mem_virt = phys_to_virt(p->video_mem_phys); 164 + } 165 + 166 + struct platform_device vt8500_device_uart0 = { 167 + .name = "vt8500_serial", 168 + .id = 0, 169 + }; 170 + 171 + struct platform_device vt8500_device_uart1 = { 172 + .name = "vt8500_serial", 173 + .id = 1, 174 + }; 175 + 176 + struct platform_device vt8500_device_uart2 = { 177 + .name = "vt8500_serial", 178 + .id = 2, 179 + }; 180 + 181 + struct platform_device vt8500_device_uart3 = { 182 + .name = "vt8500_serial", 183 + .id = 3, 184 + }; 185 + 186 + struct platform_device vt8500_device_uart4 = { 187 + .name = "vt8500_serial", 188 + .id = 4, 189 + }; 190 + 191 + struct platform_device vt8500_device_uart5 = { 192 + .name = "vt8500_serial", 193 + .id = 5, 194 + }; 195 + 196 + static u64 ehci_dma_mask = DMA_BIT_MASK(32); 197 + 198 + struct platform_device vt8500_device_ehci = { 199 + .name = "vt8500-ehci", 200 + .id = 0, 201 + .dev = { 202 + .dma_mask = &ehci_dma_mask, 203 + .coherent_dma_mask = DMA_BIT_MASK(32), 204 + }, 205 + }; 206 + 207 + struct platform_device vt8500_device_ge_rops = { 208 + .name = "wmt_ge_rops", 209 + .id = -1, 210 + }; 211 + 212 + struct platform_device vt8500_device_pwm = { 213 + .name = "vt8500-pwm", 214 + .id = 0, 215 + }; 216 + 217 + static struct platform_pwm_backlight_data vt8500_pwmbl_data = { 218 + .pwm_id = 0, 219 + .max_brightness = 128, 220 + .dft_brightness = 70, 221 + .pwm_period_ns = 250000, /* revisit when clocks are implemented */ 222 + }; 223 + 224 + struct platform_device vt8500_device_pwmbl = { 225 + .name = "pwm-backlight", 226 + .id = 0, 227 + .dev = { 228 + .platform_data = &vt8500_pwmbl_data, 229 + }, 230 + }; 231 + 232 + struct platform_device vt8500_device_rtc = { 233 + .name = "vt8500-rtc", 234 + .id = 0, 235 + }; 236 + 237 + struct map_desc wmt_io_desc[] __initdata = { 238 + /* SoC MMIO registers */ 239 + [0] = { 240 + .virtual = 0xf8000000, 241 + .pfn = __phys_to_pfn(0xd8000000), 242 + .length = 0x00390000, /* max of all chip variants */ 243 + .type = MT_DEVICE 244 + }, 245 + /* PCI I/O space, numbers tied to those in <mach/io.h> */ 246 + [1] = { 247 + .virtual = 0xf0000000, 248 + .pfn = __phys_to_pfn(0xc0000000), 249 + .length = SZ_64K, 250 + .type = MT_DEVICE 251 + }, 252 + }; 253 + 254 + void __init vt8500_reserve_mem(void) 255 + { 256 + #ifdef CONFIG_FB_VT8500 257 + panels[current_panel_idx].bpp = 16; /* Always use RGB565 */ 258 + preallocate_fb(&panels[current_panel_idx], SZ_4M); 259 + vt8500_device_lcdc.dev.platform_data = &panels[current_panel_idx]; 260 + #endif 261 + } 262 + 263 + void __init wm8505_reserve_mem(void) 264 + { 265 + #if defined CONFIG_FB_WM8505 266 + panels[current_panel_idx].bpp = 32; /* Always use RGB888 */ 267 + preallocate_fb(&panels[current_panel_idx], 32); 268 + vt8500_device_wm8505_fb.dev.platform_data = &panels[current_panel_idx]; 269 + #endif 270 + }
+88
arch/arm/mach-vt8500/devices.h
··· 1 + /* linux/arch/arm/mach-vt8500/devices.h 2 + * 3 + * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com> 4 + * 5 + * This software is licensed under the terms of the GNU General Public 6 + * License version 2, as published by the Free Software Foundation, and 7 + * may be copied, distributed, and modified under those terms. 8 + * 9 + * This program is distributed in the hope that it will be useful, 10 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 + * GNU General Public License for more details. 13 + * 14 + */ 15 + 16 + #ifndef __ARCH_ARM_MACH_VT8500_DEVICES_H 17 + #define __ARCH_ARM_MACH_VT8500_DEVICES_H 18 + 19 + #include <linux/platform_device.h> 20 + #include <asm/mach/map.h> 21 + 22 + void __init vt8500_init_irq(void); 23 + void __init wm8505_init_irq(void); 24 + void __init vt8500_map_io(void); 25 + void __init wm8505_map_io(void); 26 + void __init vt8500_reserve_mem(void); 27 + void __init wm8505_reserve_mem(void); 28 + void __init vt8500_gpio_init(void); 29 + void __init vt8500_set_resources(void); 30 + void __init wm8505_set_resources(void); 31 + 32 + extern unsigned long wmt_ic_base __initdata; 33 + extern unsigned long wmt_sic_base __initdata; 34 + extern unsigned long wmt_gpio_base __initdata; 35 + extern unsigned long wmt_pmc_base __initdata; 36 + 37 + extern int wmt_nr_irqs __initdata; 38 + extern int wmt_timer_irq __initdata; 39 + extern int wmt_gpio_ext_irq[8] __initdata; 40 + 41 + extern struct map_desc wmt_io_desc[2] __initdata; 42 + 43 + static inline struct resource wmt_mmio_res(u32 start, u32 size) 44 + { 45 + struct resource tmp = { 46 + .flags = IORESOURCE_MEM, 47 + .start = start, 48 + .end = start + size - 1, 49 + }; 50 + 51 + return tmp; 52 + } 53 + 54 + static inline struct resource wmt_irq_res(int irq) 55 + { 56 + struct resource tmp = { 57 + .flags = IORESOURCE_IRQ, 58 + .start = irq, 59 + .end = irq, 60 + }; 61 + 62 + return tmp; 63 + } 64 + 65 + static inline void wmt_res_add(struct platform_device *pdev, 66 + const struct resource *res, unsigned int num) 67 + { 68 + if (unlikely(platform_device_add_resources(pdev, res, num))) 69 + pr_err("Failed to assign resources\n"); 70 + } 71 + 72 + extern struct sys_timer vt8500_timer; 73 + 74 + extern struct platform_device vt8500_device_uart0; 75 + extern struct platform_device vt8500_device_uart1; 76 + extern struct platform_device vt8500_device_uart2; 77 + extern struct platform_device vt8500_device_uart3; 78 + extern struct platform_device vt8500_device_uart4; 79 + extern struct platform_device vt8500_device_uart5; 80 + 81 + extern struct platform_device vt8500_device_lcdc; 82 + extern struct platform_device vt8500_device_wm8505_fb; 83 + extern struct platform_device vt8500_device_ehci; 84 + extern struct platform_device vt8500_device_ge_rops; 85 + extern struct platform_device vt8500_device_pwm; 86 + extern struct platform_device vt8500_device_pwmbl; 87 + extern struct platform_device vt8500_device_rtc; 88 + #endif
+240
arch/arm/mach-vt8500/gpio.c
··· 1 + /* linux/arch/arm/mach-vt8500/gpio.c 2 + * 3 + * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com> 4 + * 5 + * This software is licensed under the terms of the GNU General Public 6 + * License version 2, as published by the Free Software Foundation, and 7 + * may be copied, distributed, and modified under those terms. 8 + * 9 + * This program is distributed in the hope that it will be useful, 10 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 + * GNU General Public License for more details. 13 + * 14 + */ 15 + 16 + #include <linux/gpio.h> 17 + #include <linux/init.h> 18 + #include <linux/irq.h> 19 + #include <linux/io.h> 20 + 21 + #include "devices.h" 22 + 23 + #define to_vt8500(__chip) container_of(__chip, struct vt8500_gpio_chip, chip) 24 + 25 + #define ENABLE_REGS 0x0 26 + #define DIRECTION_REGS 0x20 27 + #define OUTVALUE_REGS 0x40 28 + #define INVALUE_REGS 0x60 29 + 30 + #define EXT_REGOFF 0x1c 31 + 32 + static void __iomem *regbase; 33 + 34 + struct vt8500_gpio_chip { 35 + struct gpio_chip chip; 36 + unsigned int shift; 37 + unsigned int regoff; 38 + }; 39 + 40 + static int gpio_to_irq_map[8]; 41 + 42 + static int vt8500_muxed_gpio_request(struct gpio_chip *chip, 43 + unsigned offset) 44 + { 45 + struct vt8500_gpio_chip *vt8500_chip = to_vt8500(chip); 46 + unsigned val = readl(regbase + ENABLE_REGS + vt8500_chip->regoff); 47 + 48 + val |= (1 << vt8500_chip->shift << offset); 49 + writel(val, regbase + ENABLE_REGS + vt8500_chip->regoff); 50 + 51 + return 0; 52 + } 53 + 54 + static void vt8500_muxed_gpio_free(struct gpio_chip *chip, 55 + unsigned offset) 56 + { 57 + struct vt8500_gpio_chip *vt8500_chip = to_vt8500(chip); 58 + unsigned val = readl(regbase + ENABLE_REGS + vt8500_chip->regoff); 59 + 60 + val &= ~(1 << vt8500_chip->shift << offset); 61 + writel(val, regbase + ENABLE_REGS + vt8500_chip->regoff); 62 + } 63 + 64 + static int vt8500_muxed_gpio_direction_input(struct gpio_chip *chip, 65 + unsigned offset) 66 + { 67 + struct vt8500_gpio_chip *vt8500_chip = to_vt8500(chip); 68 + unsigned val = readl(regbase + DIRECTION_REGS + vt8500_chip->regoff); 69 + 70 + val &= ~(1 << vt8500_chip->shift << offset); 71 + writel(val, regbase + DIRECTION_REGS + vt8500_chip->regoff); 72 + 73 + return 0; 74 + } 75 + 76 + static int vt8500_muxed_gpio_direction_output(struct gpio_chip *chip, 77 + unsigned offset, int value) 78 + { 79 + struct vt8500_gpio_chip *vt8500_chip = to_vt8500(chip); 80 + unsigned val = readl(regbase + DIRECTION_REGS + vt8500_chip->regoff); 81 + 82 + val |= (1 << vt8500_chip->shift << offset); 83 + writel(val, regbase + DIRECTION_REGS + vt8500_chip->regoff); 84 + 85 + if (value) { 86 + val = readl(regbase + OUTVALUE_REGS + vt8500_chip->regoff); 87 + val |= (1 << vt8500_chip->shift << offset); 88 + writel(val, regbase + OUTVALUE_REGS + vt8500_chip->regoff); 89 + } 90 + return 0; 91 + } 92 + 93 + static int vt8500_muxed_gpio_get_value(struct gpio_chip *chip, 94 + unsigned offset) 95 + { 96 + struct vt8500_gpio_chip *vt8500_chip = to_vt8500(chip); 97 + 98 + return (readl(regbase + INVALUE_REGS + vt8500_chip->regoff) 99 + >> vt8500_chip->shift >> offset) & 1; 100 + } 101 + 102 + static void vt8500_muxed_gpio_set_value(struct gpio_chip *chip, 103 + unsigned offset, int value) 104 + { 105 + struct vt8500_gpio_chip *vt8500_chip = to_vt8500(chip); 106 + unsigned val = readl(regbase + INVALUE_REGS + vt8500_chip->regoff); 107 + 108 + if (value) 109 + val |= (1 << vt8500_chip->shift << offset); 110 + else 111 + val &= ~(1 << vt8500_chip->shift << offset); 112 + 113 + writel(val, regbase + INVALUE_REGS + vt8500_chip->regoff); 114 + } 115 + 116 + #define VT8500_GPIO_BANK(__name, __shift, __off, __base, __num) \ 117 + { \ 118 + .chip = { \ 119 + .label = __name, \ 120 + .request = vt8500_muxed_gpio_request, \ 121 + .free = vt8500_muxed_gpio_free, \ 122 + .direction_input = vt8500_muxed_gpio_direction_input, \ 123 + .direction_output = vt8500_muxed_gpio_direction_output, \ 124 + .get = vt8500_muxed_gpio_get_value, \ 125 + .set = vt8500_muxed_gpio_set_value, \ 126 + .can_sleep = 0, \ 127 + .base = __base, \ 128 + .ngpio = __num, \ 129 + }, \ 130 + .shift = __shift, \ 131 + .regoff = __off, \ 132 + } 133 + 134 + static struct vt8500_gpio_chip vt8500_muxed_gpios[] = { 135 + VT8500_GPIO_BANK("uart0", 0, 0x0, 8, 4), 136 + VT8500_GPIO_BANK("uart1", 4, 0x0, 12, 4), 137 + VT8500_GPIO_BANK("spi0", 8, 0x0, 16, 4), 138 + VT8500_GPIO_BANK("spi1", 12, 0x0, 20, 4), 139 + VT8500_GPIO_BANK("spi2", 16, 0x0, 24, 4), 140 + VT8500_GPIO_BANK("pwmout", 24, 0x0, 28, 2), 141 + 142 + VT8500_GPIO_BANK("sdmmc", 0, 0x4, 30, 11), 143 + VT8500_GPIO_BANK("ms", 16, 0x4, 41, 7), 144 + VT8500_GPIO_BANK("i2c0", 24, 0x4, 48, 2), 145 + VT8500_GPIO_BANK("i2c1", 26, 0x4, 50, 2), 146 + 147 + VT8500_GPIO_BANK("mii", 0, 0x8, 52, 20), 148 + VT8500_GPIO_BANK("see", 20, 0x8, 72, 4), 149 + VT8500_GPIO_BANK("ide", 24, 0x8, 76, 7), 150 + 151 + VT8500_GPIO_BANK("ccir", 0, 0xc, 83, 19), 152 + 153 + VT8500_GPIO_BANK("ts", 8, 0x10, 102, 11), 154 + 155 + VT8500_GPIO_BANK("lcd", 0, 0x14, 113, 23), 156 + }; 157 + 158 + static int vt8500_gpio_direction_input(struct gpio_chip *chip, 159 + unsigned offset) 160 + { 161 + unsigned val = readl(regbase + DIRECTION_REGS + EXT_REGOFF); 162 + 163 + val &= ~(1 << offset); 164 + writel(val, regbase + DIRECTION_REGS + EXT_REGOFF); 165 + return 0; 166 + } 167 + 168 + static int vt8500_gpio_direction_output(struct gpio_chip *chip, 169 + unsigned offset, int value) 170 + { 171 + unsigned val = readl(regbase + DIRECTION_REGS + EXT_REGOFF); 172 + 173 + val |= (1 << offset); 174 + writel(val, regbase + DIRECTION_REGS + EXT_REGOFF); 175 + 176 + if (value) { 177 + val = readl(regbase + OUTVALUE_REGS + EXT_REGOFF); 178 + val |= (1 << offset); 179 + writel(val, regbase + OUTVALUE_REGS + EXT_REGOFF); 180 + } 181 + return 0; 182 + } 183 + 184 + static int vt8500_gpio_get_value(struct gpio_chip *chip, 185 + unsigned offset) 186 + { 187 + return (readl(regbase + INVALUE_REGS + EXT_REGOFF) >> offset) & 1; 188 + } 189 + 190 + static void vt8500_gpio_set_value(struct gpio_chip *chip, 191 + unsigned offset, int value) 192 + { 193 + unsigned val = readl(regbase + OUTVALUE_REGS + EXT_REGOFF); 194 + 195 + if (value) 196 + val |= (1 << offset); 197 + else 198 + val &= ~(1 << offset); 199 + 200 + writel(val, regbase + OUTVALUE_REGS + EXT_REGOFF); 201 + } 202 + 203 + static int vt8500_gpio_to_irq(struct gpio_chip *chip, unsigned offset) 204 + { 205 + if (offset > 7) 206 + return -EINVAL; 207 + 208 + return gpio_to_irq_map[offset]; 209 + } 210 + 211 + static struct gpio_chip vt8500_external_gpios = { 212 + .label = "extgpio", 213 + .direction_input = vt8500_gpio_direction_input, 214 + .direction_output = vt8500_gpio_direction_output, 215 + .get = vt8500_gpio_get_value, 216 + .set = vt8500_gpio_set_value, 217 + .to_irq = vt8500_gpio_to_irq, 218 + .can_sleep = 0, 219 + .base = 0, 220 + .ngpio = 8, 221 + }; 222 + 223 + void __init vt8500_gpio_init(void) 224 + { 225 + int i; 226 + 227 + for (i = 0; i < 8; i++) 228 + gpio_to_irq_map[i] = wmt_gpio_ext_irq[i]; 229 + 230 + regbase = ioremap(wmt_gpio_base, SZ_64K); 231 + if (!regbase) { 232 + printk(KERN_ERR "Failed to map MMIO registers for GPIO\n"); 233 + return; 234 + } 235 + 236 + gpiochip_add(&vt8500_external_gpios); 237 + 238 + for (i = 0; i < ARRAY_SIZE(vt8500_muxed_gpios); i++) 239 + gpiochip_add(&vt8500_muxed_gpios[i].chip); 240 + }
+31
arch/arm/mach-vt8500/include/mach/debug-macro.S
··· 1 + /* 2 + * arch/arm/mach-vt8500/include/mach/debug-macro.S 3 + * 4 + * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com> 5 + * 6 + * Debugging macro include header 7 + * 8 + * This program is free software; you can redistribute it and/or modify 9 + * it under the terms of the GNU General Public License version 2 as 10 + * published by the Free Software Foundation. 11 + * 12 + */ 13 + 14 + .macro addruart, rp, rv 15 + mov \rp, #0x00200000 16 + orr \rv, \rp, #0xf8000000 17 + orr \rp, \rp, #0xd8000000 18 + .endm 19 + 20 + .macro senduart,rd,rx 21 + strb \rd, [\rx, #0] 22 + .endm 23 + 24 + .macro busyuart,rd,rx 25 + 1001: ldr \rd, [\rx, #0x1c] 26 + ands \rd, \rd, #0x2 27 + bne 1001b 28 + .endm 29 + 30 + .macro waituart,rd,rx 31 + .endm
+32
arch/arm/mach-vt8500/include/mach/entry-macro.S
··· 1 + /* 2 + * arch/arm/mach-vt8500/include/mach/entry-macro.S 3 + * 4 + * Low-level IRQ helper macros for VIA VT8500 5 + * 6 + * This file is licensed under the terms of the GNU General Public 7 + * License version 2. This program is licensed "as is" without any 8 + * warranty of any kind, whether express or implied. 9 + */ 10 + 11 + .macro disable_fiq 12 + .endm 13 + 14 + .macro get_irqnr_preamble, base, tmp 15 + @ physical 0xd8140000 is virtual 0xf8140000 16 + mov \base, #0xf8000000 17 + orr \base, \base, #0x00140000 18 + .endm 19 + 20 + .macro arch_ret_to_user, tmp1, tmp2 21 + .endm 22 + 23 + .macro get_irqnr_and_base, irqnr, irqstat, base, tmp 24 + ldr \irqnr, [\base] 25 + cmp \irqnr, #63 @ may be false positive, check interrupt status 26 + bne 1001f 27 + ldr \irqstat, [\base, #0x84] 28 + ands \irqstat, #0x80000000 29 + moveq \irqnr, #0 30 + 1001: 31 + .endm 32 +
+6
arch/arm/mach-vt8500/include/mach/gpio.h
··· 1 + #include <asm-generic/gpio.h> 2 + 3 + #define gpio_get_value __gpio_get_value 4 + #define gpio_set_value __gpio_set_value 5 + #define gpio_cansleep __gpio_cansleep 6 + #define gpio_to_irq __gpio_to_irq
+12
arch/arm/mach-vt8500/include/mach/hardware.h
··· 1 + /* arch/arm/mach-vt8500/include/mach/hardware.h 2 + * 3 + * This software is licensed under the terms of the GNU General Public 4 + * License version 2, as published by the Free Software Foundation, and 5 + * may be copied, distributed, and modified under those terms. 6 + * 7 + * This program is distributed in the hope that it will be useful, 8 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 + * GNU General Public License for more details. 11 + * 12 + */
+18
arch/arm/mach-vt8500/include/mach/i8042.h
··· 1 + /* arch/arm/mach-vt8500/include/mach/i8042.h 2 + * 3 + * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com> 4 + * 5 + * This software is licensed under the terms of the GNU General Public 6 + * License version 2, as published by the Free Software Foundation, and 7 + * may be copied, distributed, and modified under those terms. 8 + * 9 + * This program is distributed in the hope that it will be useful, 10 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 + * GNU General Public License for more details. 13 + * 14 + */ 15 + 16 + extern unsigned long wmt_i8042_base __initdata; 17 + extern int wmt_i8042_kbd_irq; 18 + extern int wmt_i8042_aux_irq;
+28
arch/arm/mach-vt8500/include/mach/io.h
··· 1 + /* 2 + * arch/arm/mach-vt8500/include/mach/io.h 3 + * 4 + * Copyright (C) 2010 Alexey Charkov 5 + * 6 + * This program is free software; you can redistribute it and/or modify 7 + * it under the terms of the GNU General Public License as published by 8 + * the Free Software Foundation; either version 2 of the License, or 9 + * (at your option) any later version. 10 + * 11 + * This program is distributed in the hope that it will be useful, 12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + * GNU General Public License for more details. 15 + * 16 + * You should have received a copy of the GNU General Public License 17 + * along with this program; if not, write to the Free Software 18 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 + */ 20 + #ifndef __ASM_ARM_ARCH_IO_H 21 + #define __ASM_ARM_ARCH_IO_H 22 + 23 + #define IO_SPACE_LIMIT 0xffff 24 + 25 + #define __io(a) __typesafe_io((a) + 0xf0000000) 26 + #define __mem_pci(a) (a) 27 + 28 + #endif
+22
arch/arm/mach-vt8500/include/mach/irqs.h
··· 1 + /* 2 + * arch/arm/mach-vt8500/include/mach/irqs.h 3 + * 4 + * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com> 5 + * 6 + * This program is free software; you can redistribute it and/or modify 7 + * it under the terms of the GNU General Public License as published by 8 + * the Free Software Foundation; either version 2 of the License, or 9 + * (at your option) any later version. 10 + * 11 + * This program is distributed in the hope that it will be useful, 12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + * GNU General Public License for more details. 15 + * 16 + * You should have received a copy of the GNU General Public License 17 + * along with this program; if not, write to the Free Software 18 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 + */ 20 + 21 + /* This value is just to make the core happy, never used otherwise */ 22 + #define NR_IRQS 128
+28
arch/arm/mach-vt8500/include/mach/memory.h
··· 1 + /* 2 + * arch/arm/mach-vt8500/include/mach/memory.h 3 + * 4 + * Copyright (C) 2003 ARM Limited 5 + * 6 + * This program is free software; you can redistribute it and/or modify 7 + * it under the terms of the GNU General Public License as published by 8 + * the Free Software Foundation; either version 2 of the License, or 9 + * (at your option) any later version. 10 + * 11 + * This program is distributed in the hope that it will be useful, 12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + * GNU General Public License for more details. 15 + * 16 + * You should have received a copy of the GNU General Public License 17 + * along with this program; if not, write to the Free Software 18 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 + */ 20 + #ifndef __ASM_ARCH_MEMORY_H 21 + #define __ASM_ARCH_MEMORY_H 22 + 23 + /* 24 + * Physical DRAM offset. 25 + */ 26 + #define PHYS_OFFSET UL(0x00000000) 27 + 28 + #endif
+18
arch/arm/mach-vt8500/include/mach/system.h
··· 1 + /* 2 + * arch/arm/mach-vt8500/include/mach/system.h 3 + * 4 + */ 5 + #include <asm/io.h> 6 + 7 + /* PM Software Reset request register */ 8 + #define VT8500_PMSR_VIRT 0xf8130060 9 + 10 + static inline void arch_idle(void) 11 + { 12 + cpu_do_idle(); 13 + } 14 + 15 + static inline void arch_reset(char mode, const char *cmd) 16 + { 17 + writel(1, VT8500_PMSR_VIRT); 18 + }
+26
arch/arm/mach-vt8500/include/mach/timex.h
··· 1 + /* 2 + * arch/arm/mach-vt8500/include/mach/timex.h 3 + * 4 + * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com> 5 + * 6 + * This program is free software; you can redistribute it and/or modify 7 + * it under the terms of the GNU General Public License as published by 8 + * the Free Software Foundation; either version 2 of the License, or 9 + * (at your option) any later version. 10 + * 11 + * This program is distributed in the hope that it will be useful, 12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + * GNU General Public License for more details. 15 + * 16 + * You should have received a copy of the GNU General Public License 17 + * along with this program; if not, write to the Free Software 18 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 + */ 20 + 21 + #ifndef MACH_TIMEX_H 22 + #define MACH_TIMEX_H 23 + 24 + #define CLOCK_TICK_RATE (3000000) 25 + 26 + #endif /* MACH_TIMEX_H */
+37
arch/arm/mach-vt8500/include/mach/uncompress.h
··· 1 + /* arch/arm/mach-vt8500/include/mach/uncompress.h 2 + * 3 + * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com> 4 + * 5 + * Based on arch/arm/mach-dove/include/mach/uncompress.h 6 + * 7 + * This software is licensed under the terms of the GNU General Public 8 + * License version 2, as published by the Free Software Foundation, and 9 + * may be copied, distributed, and modified under those terms. 10 + * 11 + * This program is distributed in the hope that it will be useful, 12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + * GNU General Public License for more details. 15 + * 16 + */ 17 + 18 + #define UART0_PHYS 0xd8200000 19 + #include <asm/io.h> 20 + 21 + static void putc(const char c) 22 + { 23 + while (readb(UART0_PHYS + 0x1c) & 0x2) 24 + /* Tx busy, wait and poll */; 25 + 26 + writeb(c, UART0_PHYS); 27 + } 28 + 29 + static void flush(void) 30 + { 31 + } 32 + 33 + /* 34 + * nothing to do 35 + */ 36 + #define arch_decomp_setup() 37 + #define arch_decomp_wdog()
+20
arch/arm/mach-vt8500/include/mach/vmalloc.h
··· 1 + /* 2 + * arch/arm/mach-vt8500/include/mach/vmalloc.h 3 + * 4 + * Copyright (C) 2000 Russell King. 5 + * 6 + * This program is free software; you can redistribute it and/or modify 7 + * it under the terms of the GNU General Public License as published by 8 + * the Free Software Foundation; either version 2 of the License, or 9 + * (at your option) any later version. 10 + * 11 + * This program is distributed in the hope that it will be useful, 12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + * GNU General Public License for more details. 15 + * 16 + * You should have received a copy of the GNU General Public License 17 + * along with this program; if not, write to the Free Software 18 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 + */ 20 + #define VMALLOC_END 0xd0000000UL
+88
arch/arm/mach-vt8500/include/mach/vt8500_irqs.h
··· 1 + /* 2 + * arch/arm/mach-vt8500/include/mach/vt8500_irqs.h 3 + * 4 + * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com> 5 + * 6 + * This program is free software; you can redistribute it and/or modify 7 + * it under the terms of the GNU General Public License as published by 8 + * the Free Software Foundation; either version 2 of the License, or 9 + * (at your option) any later version. 10 + * 11 + * This program is distributed in the hope that it will be useful, 12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + * GNU General Public License for more details. 15 + * 16 + * You should have received a copy of the GNU General Public License 17 + * along with this program; if not, write to the Free Software 18 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 + */ 20 + 21 + /* VT8500 Interrupt Sources */ 22 + 23 + #define IRQ_JPEGENC 0 /* JPEG Encoder */ 24 + #define IRQ_JPEGDEC 1 /* JPEG Decoder */ 25 + /* Reserved */ 26 + #define IRQ_PATA 3 /* PATA Controller */ 27 + /* Reserved */ 28 + #define IRQ_DMA 5 /* DMA Controller */ 29 + #define IRQ_EXT0 6 /* External Interrupt 0 */ 30 + #define IRQ_EXT1 7 /* External Interrupt 1 */ 31 + #define IRQ_GE 8 /* Graphic Engine */ 32 + #define IRQ_GOV 9 /* Graphic Overlay Engine */ 33 + #define IRQ_ETHER 10 /* Ethernet MAC */ 34 + #define IRQ_MPEGTS 11 /* Transport Stream Interface */ 35 + #define IRQ_LCDC 12 /* LCD Controller */ 36 + #define IRQ_EXT2 13 /* External Interrupt 2 */ 37 + #define IRQ_EXT3 14 /* External Interrupt 3 */ 38 + #define IRQ_EXT4 15 /* External Interrupt 4 */ 39 + #define IRQ_CIPHER 16 /* Cipher */ 40 + #define IRQ_VPP 17 /* Video Post-Processor */ 41 + #define IRQ_I2C1 18 /* I2C 1 */ 42 + #define IRQ_I2C0 19 /* I2C 0 */ 43 + #define IRQ_SDMMC 20 /* SD/MMC Controller */ 44 + #define IRQ_SDMMC_DMA 21 /* SD/MMC Controller DMA */ 45 + #define IRQ_PMC_WU 22 /* Power Management Controller Wakeup */ 46 + /* Reserved */ 47 + #define IRQ_SPI0 24 /* SPI 0 */ 48 + #define IRQ_SPI1 25 /* SPI 1 */ 49 + #define IRQ_SPI2 26 /* SPI 2 */ 50 + #define IRQ_LCDDF 27 /* LCD Data Formatter */ 51 + #define IRQ_NAND 28 /* NAND Flash Controller */ 52 + #define IRQ_NAND_DMA 29 /* NAND Flash Controller DMA */ 53 + #define IRQ_MS 30 /* MemoryStick Controller */ 54 + #define IRQ_MS_DMA 31 /* MemoryStick Controller DMA */ 55 + #define IRQ_UART0 32 /* UART 0 */ 56 + #define IRQ_UART1 33 /* UART 1 */ 57 + #define IRQ_I2S 34 /* I2S */ 58 + #define IRQ_PCM 35 /* PCM */ 59 + #define IRQ_PMCOS0 36 /* PMC OS Timer 0 */ 60 + #define IRQ_PMCOS1 37 /* PMC OS Timer 1 */ 61 + #define IRQ_PMCOS2 38 /* PMC OS Timer 2 */ 62 + #define IRQ_PMCOS3 39 /* PMC OS Timer 3 */ 63 + #define IRQ_VPU 40 /* Video Processing Unit */ 64 + #define IRQ_VID 41 /* Video Digital Input Interface */ 65 + #define IRQ_AC97 42 /* AC97 Interface */ 66 + #define IRQ_EHCI 43 /* USB */ 67 + #define IRQ_NOR 44 /* NOR Flash Controller */ 68 + #define IRQ_PS2MOUSE 45 /* PS/2 Mouse */ 69 + #define IRQ_PS2KBD 46 /* PS/2 Keyboard */ 70 + #define IRQ_UART2 47 /* UART 2 */ 71 + #define IRQ_RTC 48 /* RTC Interrupt */ 72 + #define IRQ_RTCSM 49 /* RTC Second/Minute Update Interrupt */ 73 + #define IRQ_UART3 50 /* UART 3 */ 74 + #define IRQ_ADC 51 /* ADC */ 75 + #define IRQ_EXT5 52 /* External Interrupt 5 */ 76 + #define IRQ_EXT6 53 /* External Interrupt 6 */ 77 + #define IRQ_EXT7 54 /* External Interrupt 7 */ 78 + #define IRQ_CIR 55 /* CIR */ 79 + #define IRQ_DMA0 56 /* DMA Channel 0 */ 80 + #define IRQ_DMA1 57 /* DMA Channel 1 */ 81 + #define IRQ_DMA2 58 /* DMA Channel 2 */ 82 + #define IRQ_DMA3 59 /* DMA Channel 3 */ 83 + #define IRQ_DMA4 60 /* DMA Channel 4 */ 84 + #define IRQ_DMA5 61 /* DMA Channel 5 */ 85 + #define IRQ_DMA6 62 /* DMA Channel 6 */ 86 + #define IRQ_DMA7 63 /* DMA Channel 7 */ 87 + 88 + #define VT8500_NR_IRQS 64
+79
arch/arm/mach-vt8500/include/mach/vt8500_regs.h
··· 1 + /* 2 + * arch/arm/mach-vt8500/include/mach/vt8500_regs.h 3 + * 4 + * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com> 5 + * 6 + * This program is free software; you can redistribute it and/or modify 7 + * it under the terms of the GNU General Public License as published by 8 + * the Free Software Foundation; either version 2 of the License, or 9 + * (at your option) any later version. 10 + * 11 + * This program is distributed in the hope that it will be useful, 12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + * GNU General Public License for more details. 15 + * 16 + * You should have received a copy of the GNU General Public License 17 + * along with this program; if not, write to the Free Software 18 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 + */ 20 + #ifndef __ASM_ARM_ARCH_VT8500_REGS_H 21 + #define __ASM_ARM_ARCH_VT8500_REGS_H 22 + 23 + /* VT8500 Registers Map */ 24 + 25 + #define VT8500_REGS_START_PHYS 0xd8000000 /* Start of MMIO registers */ 26 + #define VT8500_REGS_START_VIRT 0xf8000000 /* Virtual mapping start */ 27 + 28 + #define VT8500_DDR_BASE 0xd8000000 /* 1k DDR/DDR2 Memory 29 + Controller */ 30 + #define VT8500_DMA_BASE 0xd8001000 /* 1k DMA Controller */ 31 + #define VT8500_SFLASH_BASE 0xd8002000 /* 1k Serial Flash Memory 32 + Controller */ 33 + #define VT8500_ETHER_BASE 0xd8004000 /* 1k Ethernet MAC 0 */ 34 + #define VT8500_CIPHER_BASE 0xd8006000 /* 4k Cipher */ 35 + #define VT8500_USB_BASE 0xd8007800 /* 2k USB OTG */ 36 + # define VT8500_EHCI_BASE 0xd8007900 /* EHCI */ 37 + # define VT8500_UHCI_BASE 0xd8007b01 /* UHCI */ 38 + #define VT8500_PATA_BASE 0xd8008000 /* 512 PATA */ 39 + #define VT8500_PS2_BASE 0xd8008800 /* 1k PS/2 */ 40 + #define VT8500_NAND_BASE 0xd8009000 /* 1k NAND Controller */ 41 + #define VT8500_NOR_BASE 0xd8009400 /* 1k NOR Controller */ 42 + #define VT8500_SDMMC_BASE 0xd800a000 /* 1k SD/MMC Controller */ 43 + #define VT8500_MS_BASE 0xd800b000 /* 1k MS/MSPRO Controller */ 44 + #define VT8500_LCDC_BASE 0xd800e400 /* 1k LCD Controller */ 45 + #define VT8500_VPU_BASE 0xd8050000 /* 256 VPU */ 46 + #define VT8500_GOV_BASE 0xd8050300 /* 256 GOV */ 47 + #define VT8500_GEGEA_BASE 0xd8050400 /* 768 GE/GE Alpha Mixing */ 48 + #define VT8500_LCDF_BASE 0xd8050900 /* 256 LCD Formatter */ 49 + #define VT8500_VID_BASE 0xd8050a00 /* 256 VID */ 50 + #define VT8500_VPP_BASE 0xd8050b00 /* 256 VPP */ 51 + #define VT8500_TSBK_BASE 0xd80f4000 /* 4k TSBK */ 52 + #define VT8500_JPEGDEC_BASE 0xd80fe000 /* 4k JPEG Decoder */ 53 + #define VT8500_JPEGENC_BASE 0xd80ff000 /* 4k JPEG Encoder */ 54 + #define VT8500_RTC_BASE 0xd8100000 /* 64k RTC */ 55 + #define VT8500_GPIO_BASE 0xd8110000 /* 64k GPIO Configuration */ 56 + #define VT8500_SCC_BASE 0xd8120000 /* 64k System Configuration*/ 57 + #define VT8500_PMC_BASE 0xd8130000 /* 64k PMC Configuration */ 58 + #define VT8500_IC_BASE 0xd8140000 /* 64k Interrupt Controller*/ 59 + #define VT8500_UART0_BASE 0xd8200000 /* 64k UART 0 */ 60 + #define VT8500_UART2_BASE 0xd8210000 /* 64k UART 2 */ 61 + #define VT8500_PWM_BASE 0xd8220000 /* 64k PWM Configuration */ 62 + #define VT8500_SPI0_BASE 0xd8240000 /* 64k SPI 0 */ 63 + #define VT8500_SPI1_BASE 0xd8250000 /* 64k SPI 1 */ 64 + #define VT8500_CIR_BASE 0xd8270000 /* 64k CIR */ 65 + #define VT8500_I2C0_BASE 0xd8280000 /* 64k I2C 0 */ 66 + #define VT8500_AC97_BASE 0xd8290000 /* 64k AC97 */ 67 + #define VT8500_SPI2_BASE 0xd82a0000 /* 64k SPI 2 */ 68 + #define VT8500_UART1_BASE 0xd82b0000 /* 64k UART 1 */ 69 + #define VT8500_UART3_BASE 0xd82c0000 /* 64k UART 3 */ 70 + #define VT8500_PCM_BASE 0xd82d0000 /* 64k PCM */ 71 + #define VT8500_I2C1_BASE 0xd8320000 /* 64k I2C 1 */ 72 + #define VT8500_I2S_BASE 0xd8330000 /* 64k I2S */ 73 + #define VT8500_ADC_BASE 0xd8340000 /* 64k ADC */ 74 + 75 + #define VT8500_REGS_END_PHYS 0xd834ffff /* End of MMIO registers */ 76 + #define VT8500_REGS_LENGTH (VT8500_REGS_END_PHYS \ 77 + - VT8500_REGS_START_PHYS + 1) 78 + 79 + #endif
+31
arch/arm/mach-vt8500/include/mach/vt8500fb.h
··· 1 + /* 2 + * VT8500/WM8505 Frame Buffer platform data definitions 3 + * 4 + * Copyright (C) 2010 Ed Spiridonov <edo.rus@gmail.com> 5 + * 6 + * This software is licensed under the terms of the GNU General Public 7 + * License version 2, as published by the Free Software Foundation, and 8 + * may be copied, distributed, and modified under those terms. 9 + * 10 + * This program is distributed in the hope that it will be useful, 11 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 + * GNU General Public License for more details. 14 + */ 15 + 16 + #ifndef _VT8500FB_H 17 + #define _VT8500FB_H 18 + 19 + #include <linux/fb.h> 20 + 21 + struct vt8500fb_platform_data { 22 + struct fb_videomode mode; 23 + u32 xres_virtual; 24 + u32 yres_virtual; 25 + u32 bpp; 26 + unsigned long video_mem_phys; 27 + void *video_mem_virt; 28 + unsigned long video_mem_len; 29 + }; 30 + 31 + #endif /* _VT8500FB_H */
+115
arch/arm/mach-vt8500/include/mach/wm8505_irqs.h
··· 1 + /* 2 + * arch/arm/mach-vt8500/include/mach/wm8505_irqs.h 3 + * 4 + * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com> 5 + * 6 + * This program is free software; you can redistribute it and/or modify 7 + * it under the terms of the GNU General Public License as published by 8 + * the Free Software Foundation; either version 2 of the License, or 9 + * (at your option) any later version. 10 + * 11 + * This program is distributed in the hope that it will be useful, 12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + * GNU General Public License for more details. 15 + * 16 + * You should have received a copy of the GNU General Public License 17 + * along with this program; if not, write to the Free Software 18 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 + */ 20 + 21 + /* WM8505 Interrupt Sources */ 22 + 23 + #define IRQ_UHCI 0 /* UHC FS (UHCI?) */ 24 + #define IRQ_EHCI 1 /* UHC HS */ 25 + #define IRQ_UDCDMA 2 /* UDC DMA */ 26 + /* Reserved */ 27 + #define IRQ_PS2MOUSE 4 /* PS/2 Mouse */ 28 + #define IRQ_UDC 5 /* UDC */ 29 + #define IRQ_EXT0 6 /* External Interrupt 0 */ 30 + #define IRQ_EXT1 7 /* External Interrupt 1 */ 31 + #define IRQ_KEYPAD 8 /* Keypad */ 32 + #define IRQ_DMA 9 /* DMA Controller */ 33 + #define IRQ_ETHER 10 /* Ethernet MAC */ 34 + /* Reserved */ 35 + /* Reserved */ 36 + #define IRQ_EXT2 13 /* External Interrupt 2 */ 37 + #define IRQ_EXT3 14 /* External Interrupt 3 */ 38 + #define IRQ_EXT4 15 /* External Interrupt 4 */ 39 + #define IRQ_APB 16 /* APB Bridge */ 40 + #define IRQ_DMA0 17 /* DMA Channel 0 */ 41 + #define IRQ_I2C1 18 /* I2C 1 */ 42 + #define IRQ_I2C0 19 /* I2C 0 */ 43 + #define IRQ_SDMMC 20 /* SD/MMC Controller */ 44 + #define IRQ_SDMMC_DMA 21 /* SD/MMC Controller DMA */ 45 + #define IRQ_PMC_WU 22 /* Power Management Controller Wakeup */ 46 + #define IRQ_PS2KBD 23 /* PS/2 Keyboard */ 47 + #define IRQ_SPI0 24 /* SPI 0 */ 48 + #define IRQ_SPI1 25 /* SPI 1 */ 49 + #define IRQ_SPI2 26 /* SPI 2 */ 50 + #define IRQ_DMA1 27 /* DMA Channel 1 */ 51 + #define IRQ_NAND 28 /* NAND Flash Controller */ 52 + #define IRQ_NAND_DMA 29 /* NAND Flash Controller DMA */ 53 + #define IRQ_UART5 30 /* UART 5 */ 54 + #define IRQ_UART4 31 /* UART 4 */ 55 + #define IRQ_UART0 32 /* UART 0 */ 56 + #define IRQ_UART1 33 /* UART 1 */ 57 + #define IRQ_DMA2 34 /* DMA Channel 2 */ 58 + #define IRQ_I2S 35 /* I2S */ 59 + #define IRQ_PMCOS0 36 /* PMC OS Timer 0 */ 60 + #define IRQ_PMCOS1 37 /* PMC OS Timer 1 */ 61 + #define IRQ_PMCOS2 38 /* PMC OS Timer 2 */ 62 + #define IRQ_PMCOS3 39 /* PMC OS Timer 3 */ 63 + #define IRQ_DMA3 40 /* DMA Channel 3 */ 64 + #define IRQ_DMA4 41 /* DMA Channel 4 */ 65 + #define IRQ_AC97 42 /* AC97 Interface */ 66 + /* Reserved */ 67 + #define IRQ_NOR 44 /* NOR Flash Controller */ 68 + #define IRQ_DMA5 45 /* DMA Channel 5 */ 69 + #define IRQ_DMA6 46 /* DMA Channel 6 */ 70 + #define IRQ_UART2 47 /* UART 2 */ 71 + #define IRQ_RTC 48 /* RTC Interrupt */ 72 + #define IRQ_RTCSM 49 /* RTC Second/Minute Update Interrupt */ 73 + #define IRQ_UART3 50 /* UART 3 */ 74 + #define IRQ_DMA7 51 /* DMA Channel 7 */ 75 + #define IRQ_EXT5 52 /* External Interrupt 5 */ 76 + #define IRQ_EXT6 53 /* External Interrupt 6 */ 77 + #define IRQ_EXT7 54 /* External Interrupt 7 */ 78 + #define IRQ_CIR 55 /* CIR */ 79 + #define IRQ_SIC0 56 /* SIC IRQ0 */ 80 + #define IRQ_SIC1 57 /* SIC IRQ1 */ 81 + #define IRQ_SIC2 58 /* SIC IRQ2 */ 82 + #define IRQ_SIC3 59 /* SIC IRQ3 */ 83 + #define IRQ_SIC4 60 /* SIC IRQ4 */ 84 + #define IRQ_SIC5 61 /* SIC IRQ5 */ 85 + #define IRQ_SIC6 62 /* SIC IRQ6 */ 86 + #define IRQ_SIC7 63 /* SIC IRQ7 */ 87 + /* Reserved */ 88 + #define IRQ_JPEGDEC 65 /* JPEG Decoder */ 89 + #define IRQ_SAE 66 /* SAE (?) */ 90 + /* Reserved */ 91 + #define IRQ_VPU 79 /* Video Processing Unit */ 92 + #define IRQ_VPP 80 /* Video Post-Processor */ 93 + #define IRQ_VID 81 /* Video Digital Input Interface */ 94 + #define IRQ_SPU 82 /* SPU (?) */ 95 + #define IRQ_PIP 83 /* PIP Error */ 96 + #define IRQ_GE 84 /* Graphic Engine */ 97 + #define IRQ_GOV 85 /* Graphic Overlay Engine */ 98 + #define IRQ_DVO 86 /* Digital Video Output */ 99 + /* Reserved */ 100 + #define IRQ_DMA8 92 /* DMA Channel 8 */ 101 + #define IRQ_DMA9 93 /* DMA Channel 9 */ 102 + #define IRQ_DMA10 94 /* DMA Channel 10 */ 103 + #define IRQ_DMA11 95 /* DMA Channel 11 */ 104 + #define IRQ_DMA12 96 /* DMA Channel 12 */ 105 + #define IRQ_DMA13 97 /* DMA Channel 13 */ 106 + #define IRQ_DMA14 98 /* DMA Channel 14 */ 107 + #define IRQ_DMA15 99 /* DMA Channel 15 */ 108 + /* Reserved */ 109 + #define IRQ_GOVW 111 /* GOVW (?) */ 110 + #define IRQ_GOVRSDSCD 112 /* GOVR SDSCD (?) */ 111 + #define IRQ_GOVRSDMIF 113 /* GOVR SDMIF (?) */ 112 + #define IRQ_GOVRHDSCD 114 /* GOVR HDSCD (?) */ 113 + #define IRQ_GOVRHDMIF 115 /* GOVR HDMIF (?) */ 114 + 115 + #define WM8505_NR_IRQS 116
+78
arch/arm/mach-vt8500/include/mach/wm8505_regs.h
··· 1 + /* 2 + * arch/arm/mach-vt8500/include/mach/wm8505_regs.h 3 + * 4 + * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com> 5 + * 6 + * This program is free software; you can redistribute it and/or modify 7 + * it under the terms of the GNU General Public License as published by 8 + * the Free Software Foundation; either version 2 of the License, or 9 + * (at your option) any later version. 10 + * 11 + * This program is distributed in the hope that it will be useful, 12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + * GNU General Public License for more details. 15 + * 16 + * You should have received a copy of the GNU General Public License 17 + * along with this program; if not, write to the Free Software 18 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 + */ 20 + #ifndef __ASM_ARM_ARCH_WM8505_REGS_H 21 + #define __ASM_ARM_ARCH_WM8505_REGS_H 22 + 23 + /* WM8505 Registers Map */ 24 + 25 + #define WM8505_REGS_START_PHYS 0xd8000000 /* Start of MMIO registers */ 26 + #define WM8505_REGS_START_VIRT 0xf8000000 /* Virtual mapping start */ 27 + 28 + #define WM8505_DDR_BASE 0xd8000400 /* 1k DDR/DDR2 Memory 29 + Controller */ 30 + #define WM8505_DMA_BASE 0xd8001800 /* 1k DMA Controller */ 31 + #define WM8505_VDMA_BASE 0xd8001c00 /* 1k VDMA */ 32 + #define WM8505_SFLASH_BASE 0xd8002000 /* 1k Serial Flash Memory 33 + Controller */ 34 + #define WM8505_ETHER_BASE 0xd8004000 /* 1k Ethernet MAC 0 */ 35 + #define WM8505_CIPHER_BASE 0xd8006000 /* 4k Cipher */ 36 + #define WM8505_USB_BASE 0xd8007000 /* 2k USB 2.0 Host */ 37 + # define WM8505_EHCI_BASE 0xd8007100 /* EHCI */ 38 + # define WM8505_UHCI_BASE 0xd8007301 /* UHCI */ 39 + #define WM8505_PS2_BASE 0xd8008800 /* 1k PS/2 */ 40 + #define WM8505_NAND_BASE 0xd8009000 /* 1k NAND Controller */ 41 + #define WM8505_NOR_BASE 0xd8009400 /* 1k NOR Controller */ 42 + #define WM8505_SDMMC_BASE 0xd800a000 /* 1k SD/MMC Controller */ 43 + #define WM8505_VPU_BASE 0xd8050000 /* 256 VPU */ 44 + #define WM8505_GOV_BASE 0xd8050300 /* 256 GOV */ 45 + #define WM8505_GEGEA_BASE 0xd8050400 /* 768 GE/GE Alpha Mixing */ 46 + #define WM8505_GOVR_BASE 0xd8050800 /* 512 GOVR (frambuffer) */ 47 + #define WM8505_VID_BASE 0xd8050a00 /* 256 VID */ 48 + #define WM8505_SCL_BASE 0xd8050d00 /* 256 SCL */ 49 + #define WM8505_VPP_BASE 0xd8050f00 /* 256 VPP */ 50 + #define WM8505_JPEGDEC_BASE 0xd80fe000 /* 4k JPEG Decoder */ 51 + #define WM8505_RTC_BASE 0xd8100000 /* 64k RTC */ 52 + #define WM8505_GPIO_BASE 0xd8110000 /* 64k GPIO Configuration */ 53 + #define WM8505_SCC_BASE 0xd8120000 /* 64k System Configuration*/ 54 + #define WM8505_PMC_BASE 0xd8130000 /* 64k PMC Configuration */ 55 + #define WM8505_IC_BASE 0xd8140000 /* 64k Interrupt Controller*/ 56 + #define WM8505_SIC_BASE 0xd8150000 /* 64k Secondary IC */ 57 + #define WM8505_UART0_BASE 0xd8200000 /* 64k UART 0 */ 58 + #define WM8505_UART2_BASE 0xd8210000 /* 64k UART 2 */ 59 + #define WM8505_PWM_BASE 0xd8220000 /* 64k PWM Configuration */ 60 + #define WM8505_SPI0_BASE 0xd8240000 /* 64k SPI 0 */ 61 + #define WM8505_SPI1_BASE 0xd8250000 /* 64k SPI 1 */ 62 + #define WM8505_KEYPAD_BASE 0xd8260000 /* 64k Keypad control */ 63 + #define WM8505_CIR_BASE 0xd8270000 /* 64k CIR */ 64 + #define WM8505_I2C0_BASE 0xd8280000 /* 64k I2C 0 */ 65 + #define WM8505_AC97_BASE 0xd8290000 /* 64k AC97 */ 66 + #define WM8505_SPI2_BASE 0xd82a0000 /* 64k SPI 2 */ 67 + #define WM8505_UART1_BASE 0xd82b0000 /* 64k UART 1 */ 68 + #define WM8505_UART3_BASE 0xd82c0000 /* 64k UART 3 */ 69 + #define WM8505_I2C1_BASE 0xd8320000 /* 64k I2C 1 */ 70 + #define WM8505_I2S_BASE 0xd8330000 /* 64k I2S */ 71 + #define WM8505_UART4_BASE 0xd8370000 /* 64k UART 4 */ 72 + #define WM8505_UART5_BASE 0xd8380000 /* 64k UART 5 */ 73 + 74 + #define WM8505_REGS_END_PHYS 0xd838ffff /* End of MMIO registers */ 75 + #define WM8505_REGS_LENGTH (WM8505_REGS_END_PHYS \ 76 + - WM8505_REGS_START_PHYS + 1) 77 + 78 + #endif
+177
arch/arm/mach-vt8500/irq.c
··· 1 + /* 2 + * arch/arm/mach-vt8500/irq.c 3 + * 4 + * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com> 5 + * 6 + * This program is free software; you can redistribute it and/or modify 7 + * it under the terms of the GNU General Public License as published by 8 + * the Free Software Foundation; either version 2 of the License, or 9 + * (at your option) any later version. 10 + * 11 + * This program is distributed in the hope that it will be useful, 12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + * GNU General Public License for more details. 15 + * 16 + * You should have received a copy of the GNU General Public License 17 + * along with this program; if not, write to the Free Software 18 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 + */ 20 + 21 + #include <linux/io.h> 22 + #include <linux/irq.h> 23 + #include <linux/interrupt.h> 24 + 25 + #include <asm/irq.h> 26 + 27 + #include "devices.h" 28 + 29 + #define VT8500_IC_DCTR 0x40 /* Destination control 30 + register, 64*u8 */ 31 + #define VT8500_INT_ENABLE (1 << 3) 32 + #define VT8500_TRIGGER_HIGH (0 << 4) 33 + #define VT8500_TRIGGER_RISING (1 << 4) 34 + #define VT8500_TRIGGER_FALLING (2 << 4) 35 + #define VT8500_EDGE ( VT8500_TRIGGER_RISING \ 36 + | VT8500_TRIGGER_FALLING) 37 + #define VT8500_IC_STATUS 0x80 /* Interrupt status, 2*u32 */ 38 + 39 + static void __iomem *ic_regbase; 40 + static void __iomem *sic_regbase; 41 + 42 + static void vt8500_irq_mask(unsigned int irq) 43 + { 44 + void __iomem *base = ic_regbase; 45 + u8 edge; 46 + 47 + if (irq >= 64) { 48 + base = sic_regbase; 49 + irq -= 64; 50 + } 51 + edge = readb(base + VT8500_IC_DCTR + irq) & VT8500_EDGE; 52 + if (edge) { 53 + void __iomem *stat_reg = base + VT8500_IC_STATUS 54 + + (irq < 32 ? 0 : 4); 55 + unsigned status = readl(stat_reg); 56 + 57 + status |= (1 << (irq & 0x1f)); 58 + writel(status, stat_reg); 59 + } else { 60 + u8 dctr = readb(base + VT8500_IC_DCTR + irq); 61 + 62 + dctr &= ~VT8500_INT_ENABLE; 63 + writeb(dctr, base + VT8500_IC_DCTR + irq); 64 + } 65 + } 66 + 67 + static void vt8500_irq_unmask(unsigned int irq) 68 + { 69 + void __iomem *base = ic_regbase; 70 + u8 dctr; 71 + 72 + if (irq >= 64) { 73 + base = sic_regbase; 74 + irq -= 64; 75 + } 76 + dctr = readb(base + VT8500_IC_DCTR + irq); 77 + dctr |= VT8500_INT_ENABLE; 78 + writeb(dctr, base + VT8500_IC_DCTR + irq); 79 + } 80 + 81 + static int vt8500_irq_set_type(unsigned int irq, unsigned int flow_type) 82 + { 83 + void __iomem *base = ic_regbase; 84 + unsigned int orig_irq = irq; 85 + u8 dctr; 86 + 87 + if (irq >= 64) { 88 + base = sic_regbase; 89 + irq -= 64; 90 + } 91 + 92 + dctr = readb(base + VT8500_IC_DCTR + irq); 93 + dctr &= ~VT8500_EDGE; 94 + 95 + switch (flow_type) { 96 + case IRQF_TRIGGER_LOW: 97 + return -EINVAL; 98 + case IRQF_TRIGGER_HIGH: 99 + dctr |= VT8500_TRIGGER_HIGH; 100 + irq_desc[orig_irq].handle_irq = handle_level_irq; 101 + break; 102 + case IRQF_TRIGGER_FALLING: 103 + dctr |= VT8500_TRIGGER_FALLING; 104 + irq_desc[orig_irq].handle_irq = handle_edge_irq; 105 + break; 106 + case IRQF_TRIGGER_RISING: 107 + dctr |= VT8500_TRIGGER_RISING; 108 + irq_desc[orig_irq].handle_irq = handle_edge_irq; 109 + break; 110 + } 111 + writeb(dctr, base + VT8500_IC_DCTR + irq); 112 + 113 + return 0; 114 + } 115 + 116 + static struct irq_chip vt8500_irq_chip = { 117 + .name = "vt8500", 118 + .ack = vt8500_irq_mask, 119 + .mask = vt8500_irq_mask, 120 + .unmask = vt8500_irq_unmask, 121 + .set_type = vt8500_irq_set_type, 122 + }; 123 + 124 + void __init vt8500_init_irq(void) 125 + { 126 + unsigned int i; 127 + 128 + ic_regbase = ioremap(wmt_ic_base, SZ_64K); 129 + 130 + if (ic_regbase) { 131 + /* Enable rotating priority for IRQ */ 132 + writel((1 << 6), ic_regbase + 0x20); 133 + writel(0, ic_regbase + 0x24); 134 + 135 + for (i = 0; i < wmt_nr_irqs; i++) { 136 + /* Disable all interrupts and route them to IRQ */ 137 + writeb(0x00, ic_regbase + VT8500_IC_DCTR + i); 138 + 139 + set_irq_chip(i, &vt8500_irq_chip); 140 + set_irq_handler(i, handle_level_irq); 141 + set_irq_flags(i, IRQF_VALID); 142 + } 143 + } else { 144 + printk(KERN_ERR "Unable to remap the Interrupt Controller registers, not enabling IRQs!\n"); 145 + } 146 + } 147 + 148 + void __init wm8505_init_irq(void) 149 + { 150 + unsigned int i; 151 + 152 + ic_regbase = ioremap(wmt_ic_base, SZ_64K); 153 + sic_regbase = ioremap(wmt_sic_base, SZ_64K); 154 + 155 + if (ic_regbase && sic_regbase) { 156 + /* Enable rotating priority for IRQ */ 157 + writel((1 << 6), ic_regbase + 0x20); 158 + writel(0, ic_regbase + 0x24); 159 + writel((1 << 6), sic_regbase + 0x20); 160 + writel(0, sic_regbase + 0x24); 161 + 162 + for (i = 0; i < wmt_nr_irqs; i++) { 163 + /* Disable all interrupts and route them to IRQ */ 164 + if (i < 64) 165 + writeb(0x00, ic_regbase + VT8500_IC_DCTR + i); 166 + else 167 + writeb(0x00, sic_regbase + VT8500_IC_DCTR 168 + + i - 64); 169 + 170 + set_irq_chip(i, &vt8500_irq_chip); 171 + set_irq_handler(i, handle_level_irq); 172 + set_irq_flags(i, IRQF_VALID); 173 + } 174 + } else { 175 + printk(KERN_ERR "Unable to remap the Interrupt Controller registers, not enabling IRQs!\n"); 176 + } 177 + }
+265
arch/arm/mach-vt8500/pwm.c
··· 1 + /* 2 + * arch/arm/mach-vt8500/pwm.c 3 + * 4 + * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com> 5 + * 6 + * This software is licensed under the terms of the GNU General Public 7 + * License version 2, as published by the Free Software Foundation, and 8 + * may be copied, distributed, and modified under those terms. 9 + * 10 + * This program is distributed in the hope that it will be useful, 11 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 + * GNU General Public License for more details. 14 + */ 15 + 16 + #include <linux/module.h> 17 + #include <linux/kernel.h> 18 + #include <linux/platform_device.h> 19 + #include <linux/slab.h> 20 + #include <linux/err.h> 21 + #include <linux/io.h> 22 + #include <linux/pwm.h> 23 + #include <linux/delay.h> 24 + 25 + #include <asm/div64.h> 26 + 27 + #define VT8500_NR_PWMS 4 28 + 29 + static DEFINE_MUTEX(pwm_lock); 30 + static LIST_HEAD(pwm_list); 31 + 32 + struct pwm_device { 33 + struct list_head node; 34 + struct platform_device *pdev; 35 + 36 + const char *label; 37 + 38 + void __iomem *regbase; 39 + 40 + unsigned int use_count; 41 + unsigned int pwm_id; 42 + }; 43 + 44 + #define msecs_to_loops(t) (loops_per_jiffy / 1000 * HZ * t) 45 + static inline void pwm_busy_wait(void __iomem *reg, u8 bitmask) 46 + { 47 + int loops = msecs_to_loops(10); 48 + while ((readb(reg) & bitmask) && --loops) 49 + cpu_relax(); 50 + 51 + if (unlikely(!loops)) 52 + pr_warning("Waiting for status bits 0x%x to clear timed out\n", 53 + bitmask); 54 + } 55 + 56 + int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns) 57 + { 58 + unsigned long long c; 59 + unsigned long period_cycles, prescale, pv, dc; 60 + 61 + if (pwm == NULL || period_ns == 0 || duty_ns > period_ns) 62 + return -EINVAL; 63 + 64 + c = 25000000/2; /* wild guess --- need to implement clocks */ 65 + c = c * period_ns; 66 + do_div(c, 1000000000); 67 + period_cycles = c; 68 + 69 + if (period_cycles < 1) 70 + period_cycles = 1; 71 + prescale = (period_cycles - 1) / 4096; 72 + pv = period_cycles / (prescale + 1) - 1; 73 + if (pv > 4095) 74 + pv = 4095; 75 + 76 + if (prescale > 1023) 77 + return -EINVAL; 78 + 79 + c = (unsigned long long)pv * duty_ns; 80 + do_div(c, period_ns); 81 + dc = c; 82 + 83 + pwm_busy_wait(pwm->regbase + 0x40 + pwm->pwm_id, (1 << 1)); 84 + writel(prescale, pwm->regbase + 0x4 + (pwm->pwm_id << 4)); 85 + 86 + pwm_busy_wait(pwm->regbase + 0x40 + pwm->pwm_id, (1 << 2)); 87 + writel(pv, pwm->regbase + 0x8 + (pwm->pwm_id << 4)); 88 + 89 + pwm_busy_wait(pwm->regbase + 0x40 + pwm->pwm_id, (1 << 3)); 90 + writel(dc, pwm->regbase + 0xc + (pwm->pwm_id << 4)); 91 + 92 + return 0; 93 + } 94 + EXPORT_SYMBOL(pwm_config); 95 + 96 + int pwm_enable(struct pwm_device *pwm) 97 + { 98 + pwm_busy_wait(pwm->regbase + 0x40 + pwm->pwm_id, (1 << 0)); 99 + writel(5, pwm->regbase + (pwm->pwm_id << 4)); 100 + return 0; 101 + } 102 + EXPORT_SYMBOL(pwm_enable); 103 + 104 + void pwm_disable(struct pwm_device *pwm) 105 + { 106 + pwm_busy_wait(pwm->regbase + 0x40 + pwm->pwm_id, (1 << 0)); 107 + writel(0, pwm->regbase + (pwm->pwm_id << 4)); 108 + } 109 + EXPORT_SYMBOL(pwm_disable); 110 + 111 + struct pwm_device *pwm_request(int pwm_id, const char *label) 112 + { 113 + struct pwm_device *pwm; 114 + int found = 0; 115 + 116 + mutex_lock(&pwm_lock); 117 + 118 + list_for_each_entry(pwm, &pwm_list, node) { 119 + if (pwm->pwm_id == pwm_id) { 120 + found = 1; 121 + break; 122 + } 123 + } 124 + 125 + if (found) { 126 + if (pwm->use_count == 0) { 127 + pwm->use_count++; 128 + pwm->label = label; 129 + } else { 130 + pwm = ERR_PTR(-EBUSY); 131 + } 132 + } else { 133 + pwm = ERR_PTR(-ENOENT); 134 + } 135 + 136 + mutex_unlock(&pwm_lock); 137 + return pwm; 138 + } 139 + EXPORT_SYMBOL(pwm_request); 140 + 141 + void pwm_free(struct pwm_device *pwm) 142 + { 143 + mutex_lock(&pwm_lock); 144 + 145 + if (pwm->use_count) { 146 + pwm->use_count--; 147 + pwm->label = NULL; 148 + } else { 149 + pr_warning("PWM device already freed\n"); 150 + } 151 + 152 + mutex_unlock(&pwm_lock); 153 + } 154 + EXPORT_SYMBOL(pwm_free); 155 + 156 + static inline void __add_pwm(struct pwm_device *pwm) 157 + { 158 + mutex_lock(&pwm_lock); 159 + list_add_tail(&pwm->node, &pwm_list); 160 + mutex_unlock(&pwm_lock); 161 + } 162 + 163 + static int __devinit pwm_probe(struct platform_device *pdev) 164 + { 165 + struct pwm_device *pwms; 166 + struct resource *r; 167 + int ret = 0; 168 + int i; 169 + 170 + pwms = kzalloc(sizeof(struct pwm_device) * VT8500_NR_PWMS, GFP_KERNEL); 171 + if (pwms == NULL) { 172 + dev_err(&pdev->dev, "failed to allocate memory\n"); 173 + return -ENOMEM; 174 + } 175 + 176 + for (i = 0; i < VT8500_NR_PWMS; i++) { 177 + pwms[i].use_count = 0; 178 + pwms[i].pwm_id = i; 179 + pwms[i].pdev = pdev; 180 + } 181 + 182 + r = platform_get_resource(pdev, IORESOURCE_MEM, 0); 183 + if (r == NULL) { 184 + dev_err(&pdev->dev, "no memory resource defined\n"); 185 + ret = -ENODEV; 186 + goto err_free; 187 + } 188 + 189 + r = request_mem_region(r->start, resource_size(r), pdev->name); 190 + if (r == NULL) { 191 + dev_err(&pdev->dev, "failed to request memory resource\n"); 192 + ret = -EBUSY; 193 + goto err_free; 194 + } 195 + 196 + pwms[0].regbase = ioremap(r->start, resource_size(r)); 197 + if (pwms[0].regbase == NULL) { 198 + dev_err(&pdev->dev, "failed to ioremap() registers\n"); 199 + ret = -ENODEV; 200 + goto err_free_mem; 201 + } 202 + 203 + for (i = 1; i < VT8500_NR_PWMS; i++) 204 + pwms[i].regbase = pwms[0].regbase; 205 + 206 + for (i = 0; i < VT8500_NR_PWMS; i++) 207 + __add_pwm(&pwms[i]); 208 + 209 + platform_set_drvdata(pdev, pwms); 210 + return 0; 211 + 212 + err_free_mem: 213 + release_mem_region(r->start, resource_size(r)); 214 + err_free: 215 + kfree(pwms); 216 + return ret; 217 + } 218 + 219 + static int __devexit pwm_remove(struct platform_device *pdev) 220 + { 221 + struct pwm_device *pwms; 222 + struct resource *r; 223 + int i; 224 + 225 + pwms = platform_get_drvdata(pdev); 226 + if (pwms == NULL) 227 + return -ENODEV; 228 + 229 + mutex_lock(&pwm_lock); 230 + 231 + for (i = 0; i < VT8500_NR_PWMS; i++) 232 + list_del(&pwms[i].node); 233 + mutex_unlock(&pwm_lock); 234 + 235 + iounmap(pwms[0].regbase); 236 + 237 + r = platform_get_resource(pdev, IORESOURCE_MEM, 0); 238 + release_mem_region(r->start, resource_size(r)); 239 + 240 + kfree(pwms); 241 + return 0; 242 + } 243 + 244 + static struct platform_driver pwm_driver = { 245 + .driver = { 246 + .name = "vt8500-pwm", 247 + .owner = THIS_MODULE, 248 + }, 249 + .probe = pwm_probe, 250 + .remove = __devexit_p(pwm_remove), 251 + }; 252 + 253 + static int __init pwm_init(void) 254 + { 255 + return platform_driver_register(&pwm_driver); 256 + } 257 + arch_initcall(pwm_init); 258 + 259 + static void __exit pwm_exit(void) 260 + { 261 + platform_driver_unregister(&pwm_driver); 262 + } 263 + module_exit(pwm_exit); 264 + 265 + MODULE_LICENSE("GPL");
+155
arch/arm/mach-vt8500/timer.c
··· 1 + /* 2 + * arch/arm/mach-vt8500/timer.c 3 + * 4 + * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com> 5 + * 6 + * This program is free software; you can redistribute it and/or modify 7 + * it under the terms of the GNU General Public License as published by 8 + * the Free Software Foundation; either version 2 of the License, or 9 + * (at your option) any later version. 10 + * 11 + * This program is distributed in the hope that it will be useful, 12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + * GNU General Public License for more details. 15 + * 16 + * You should have received a copy of the GNU General Public License 17 + * along with this program; if not, write to the Free Software 18 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 + */ 20 + 21 + #include <linux/io.h> 22 + #include <linux/irq.h> 23 + #include <linux/interrupt.h> 24 + #include <linux/clocksource.h> 25 + #include <linux/clockchips.h> 26 + #include <linux/delay.h> 27 + 28 + #include <asm/mach/time.h> 29 + 30 + #include "devices.h" 31 + 32 + #define VT8500_TIMER_OFFSET 0x0100 33 + #define TIMER_MATCH_VAL 0x0000 34 + #define TIMER_COUNT_VAL 0x0010 35 + #define TIMER_STATUS_VAL 0x0014 36 + #define TIMER_IER_VAL 0x001c /* interrupt enable */ 37 + #define TIMER_CTRL_VAL 0x0020 38 + #define TIMER_AS_VAL 0x0024 /* access status */ 39 + #define TIMER_COUNT_R_ACTIVE (1 << 5) /* not ready for read */ 40 + #define TIMER_COUNT_W_ACTIVE (1 << 4) /* not ready for write */ 41 + #define TIMER_MATCH_W_ACTIVE (1 << 0) /* not ready for write */ 42 + #define VT8500_TIMER_HZ 3000000 43 + 44 + #define msecs_to_loops(t) (loops_per_jiffy / 1000 * HZ * t) 45 + 46 + static void __iomem *regbase; 47 + 48 + static cycle_t vt8500_timer_read(struct clocksource *cs) 49 + { 50 + int loops = msecs_to_loops(10); 51 + writel(3, regbase + TIMER_CTRL_VAL); 52 + while ((readl((regbase + TIMER_AS_VAL)) & TIMER_COUNT_R_ACTIVE) 53 + && --loops) 54 + cpu_relax(); 55 + return readl(regbase + TIMER_COUNT_VAL); 56 + } 57 + 58 + struct clocksource clocksource = { 59 + .name = "vt8500_timer", 60 + .rating = 200, 61 + .read = vt8500_timer_read, 62 + .mask = CLOCKSOURCE_MASK(32), 63 + .flags = CLOCK_SOURCE_IS_CONTINUOUS, 64 + }; 65 + 66 + static int vt8500_timer_set_next_event(unsigned long cycles, 67 + struct clock_event_device *evt) 68 + { 69 + int loops = msecs_to_loops(10); 70 + cycle_t alarm = clocksource.read(&clocksource) + cycles; 71 + while ((readl(regbase + TIMER_AS_VAL) & TIMER_MATCH_W_ACTIVE) 72 + && --loops) 73 + cpu_relax(); 74 + writel((unsigned long)alarm, regbase + TIMER_MATCH_VAL); 75 + 76 + if ((signed)(alarm - clocksource.read(&clocksource)) <= 16) 77 + return -ETIME; 78 + 79 + writel(1, regbase + TIMER_IER_VAL); 80 + 81 + return 0; 82 + } 83 + 84 + static void vt8500_timer_set_mode(enum clock_event_mode mode, 85 + struct clock_event_device *evt) 86 + { 87 + switch (mode) { 88 + case CLOCK_EVT_MODE_RESUME: 89 + case CLOCK_EVT_MODE_PERIODIC: 90 + break; 91 + case CLOCK_EVT_MODE_ONESHOT: 92 + case CLOCK_EVT_MODE_UNUSED: 93 + case CLOCK_EVT_MODE_SHUTDOWN: 94 + writel(readl(regbase + TIMER_CTRL_VAL) | 1, 95 + regbase + TIMER_CTRL_VAL); 96 + writel(0, regbase + TIMER_IER_VAL); 97 + break; 98 + } 99 + } 100 + 101 + struct clock_event_device clockevent = { 102 + .name = "vt8500_timer", 103 + .features = CLOCK_EVT_FEAT_ONESHOT, 104 + .rating = 200, 105 + .set_next_event = vt8500_timer_set_next_event, 106 + .set_mode = vt8500_timer_set_mode, 107 + }; 108 + 109 + static irqreturn_t vt8500_timer_interrupt(int irq, void *dev_id) 110 + { 111 + struct clock_event_device *evt = dev_id; 112 + writel(0xf, regbase + TIMER_STATUS_VAL); 113 + evt->event_handler(evt); 114 + 115 + return IRQ_HANDLED; 116 + } 117 + 118 + struct irqaction irq = { 119 + .name = "vt8500_timer", 120 + .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, 121 + .handler = vt8500_timer_interrupt, 122 + .dev_id = &clockevent, 123 + }; 124 + 125 + static void __init vt8500_timer_init(void) 126 + { 127 + regbase = ioremap(wmt_pmc_base + VT8500_TIMER_OFFSET, 0x28); 128 + if (!regbase) 129 + printk(KERN_ERR "vt8500_timer_init: failed to map MMIO registers\n"); 130 + 131 + writel(1, regbase + TIMER_CTRL_VAL); 132 + writel(0xf, regbase + TIMER_STATUS_VAL); 133 + writel(~0, regbase + TIMER_MATCH_VAL); 134 + 135 + if (clocksource_register_hz(&clocksource, VT8500_TIMER_HZ)) 136 + printk(KERN_ERR "vt8500_timer_init: clocksource_register failed for %s\n", 137 + clocksource.name); 138 + 139 + clockevents_calc_mult_shift(&clockevent, VT8500_TIMER_HZ, 4); 140 + 141 + /* copy-pasted from mach-msm; no idea */ 142 + clockevent.max_delta_ns = 143 + clockevent_delta2ns(0xf0000000, &clockevent); 144 + clockevent.min_delta_ns = clockevent_delta2ns(4, &clockevent); 145 + clockevent.cpumask = cpumask_of(0); 146 + 147 + if (setup_irq(wmt_timer_irq, &irq)) 148 + printk(KERN_ERR "vt8500_timer_init: setup_irq failed for %s\n", 149 + clockevent.name); 150 + clockevents_register_device(&clockevent); 151 + } 152 + 153 + struct sys_timer vt8500_timer = { 154 + .init = vt8500_timer_init 155 + };
+77
arch/arm/mach-vt8500/wm8505_7in.c
··· 1 + /* 2 + * arch/arm/mach-vt8500/wm8505_7in.c 3 + * 4 + * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com> 5 + * 6 + * This program is free software; you can redistribute it and/or modify 7 + * it under the terms of the GNU General Public License as published by 8 + * the Free Software Foundation; either version 2 of the License, or 9 + * (at your option) any later version. 10 + * 11 + * This program is distributed in the hope that it will be useful, 12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + * GNU General Public License for more details. 15 + * 16 + * You should have received a copy of the GNU General Public License 17 + * along with this program; if not, write to the Free Software 18 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 + */ 20 + 21 + #include <linux/io.h> 22 + #include <linux/pm.h> 23 + 24 + #include <asm/mach-types.h> 25 + #include <asm/mach/arch.h> 26 + 27 + #include "devices.h" 28 + 29 + static void __iomem *pmc_hiber; 30 + 31 + static struct platform_device *devices[] __initdata = { 32 + &vt8500_device_uart0, 33 + &vt8500_device_ehci, 34 + &vt8500_device_wm8505_fb, 35 + &vt8500_device_ge_rops, 36 + &vt8500_device_pwm, 37 + &vt8500_device_pwmbl, 38 + &vt8500_device_rtc, 39 + }; 40 + 41 + static void vt8500_power_off(void) 42 + { 43 + local_irq_disable(); 44 + writew(5, pmc_hiber); 45 + asm("mcr%? p15, 0, %0, c7, c0, 4" : : "r" (0)); 46 + } 47 + 48 + void __init wm8505_7in_init(void) 49 + { 50 + #ifdef CONFIG_FB_WM8505 51 + void __iomem *gpio_mux_reg = ioremap(wmt_gpio_base + 0x200, 4); 52 + if (gpio_mux_reg) { 53 + writel(readl(gpio_mux_reg) | 0x80000000, gpio_mux_reg); 54 + iounmap(gpio_mux_reg); 55 + } else { 56 + printk(KERN_ERR "Could not remap the GPIO mux register, display may not work properly!\n"); 57 + } 58 + #endif 59 + pmc_hiber = ioremap(wmt_pmc_base + 0x12, 2); 60 + if (pmc_hiber) 61 + pm_power_off = &vt8500_power_off; 62 + else 63 + printk(KERN_ERR "PMC Hibernation register could not be remapped, not enabling power off!\n"); 64 + 65 + wm8505_set_resources(); 66 + platform_add_devices(devices, ARRAY_SIZE(devices)); 67 + vt8500_gpio_init(); 68 + } 69 + 70 + MACHINE_START(WM8505_7IN_NETBOOK, "WM8505 7-inch generic netbook") 71 + .boot_params = 0x00000100, 72 + .reserve = wm8505_reserve_mem, 73 + .map_io = wm8505_map_io, 74 + .init_irq = wm8505_init_irq, 75 + .timer = &vt8500_timer, 76 + .init_machine = wm8505_7in_init, 77 + MACHINE_END