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 */ 31unsigned long wmt_ic_base __initdata; 32unsigned long wmt_sic_base __initdata; 33unsigned long wmt_gpio_base __initdata; 34unsigned long wmt_pmc_base __initdata; 35unsigned long wmt_i8042_base __initdata; 36 37int wmt_nr_irqs __initdata; 38int wmt_timer_irq __initdata; 39int wmt_gpio_ext_irq[8] __initdata; 40 41/* Should remain accessible after init. 42 * i8042 driver desperately calls for attention... 43 */ 44int wmt_i8042_kbd_irq; 45int wmt_i8042_aux_irq; 46 47static u64 fb_dma_mask = DMA_BIT_MASK(32); 48 49struct 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 58struct platform_device vt8500_device_wm8505_fb = { 59 .name = "wm8505-fb", 60 .id = 0, 61}; 62 63/* Smallest to largest */ 64static 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 139static int current_panel_idx __initdata = ARRAY_SIZE(panels) - 1; 140 141static 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 154early_param("panel", panel_setup); 155 156static 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 166struct platform_device vt8500_device_uart0 = { 167 .name = "vt8500_serial", 168 .id = 0, 169}; 170 171struct platform_device vt8500_device_uart1 = { 172 .name = "vt8500_serial", 173 .id = 1, 174}; 175 176struct platform_device vt8500_device_uart2 = { 177 .name = "vt8500_serial", 178 .id = 2, 179}; 180 181struct platform_device vt8500_device_uart3 = { 182 .name = "vt8500_serial", 183 .id = 3, 184}; 185 186struct platform_device vt8500_device_uart4 = { 187 .name = "vt8500_serial", 188 .id = 4, 189}; 190 191struct platform_device vt8500_device_uart5 = { 192 .name = "vt8500_serial", 193 .id = 5, 194}; 195 196static u64 ehci_dma_mask = DMA_BIT_MASK(32); 197 198struct 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 207struct platform_device vt8500_device_ge_rops = { 208 .name = "wmt_ge_rops", 209 .id = -1, 210}; 211 212struct platform_device vt8500_device_pwm = { 213 .name = "vt8500-pwm", 214 .id = 0, 215}; 216 217static 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 224struct platform_device vt8500_device_pwmbl = { 225 .name = "pwm-backlight", 226 .id = 0, 227 .dev = { 228 .platform_data = &vt8500_pwmbl_data, 229 }, 230}; 231 232struct platform_device vt8500_device_rtc = { 233 .name = "vt8500-rtc", 234 .id = 0, 235}; 236 237struct 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 254void __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 263void __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} 271