1#include <linux/kernel.h> 2#include <linux/irq.h> 3#include <linux/gpio.h> 4#include <linux/platform_device.h> 5#include <linux/bootmem.h> 6#include <linux/delay.h> 7 8#include <asm/mach-types.h> 9#include <asm/mach/arch.h> 10#include <asm/io.h> 11#include <asm/setup.h> 12 13#include <mach/board.h> 14#include <mach/irqs.h> 15#include <mach/sirc.h> 16#include <mach/gpio.h> 17 18#include "msm_mdp.h" 19#include "memory_ll.h" 20//#include "android_pmem.h" 21 22#ifdef CONFIG_MSM_SOC_REV_A 23#define MSM_SMI_BASE 0xE0000000 24#else 25#define MSM_SMI_BASE 0x00000000 26#endif 27 28 29#define TOUCHPAD_SUSPEND 34 30#define TOUCHPAD_IRQ 38 31 32#define MSM_PMEM_MDP_SIZE 0x1591000 33 34#ifdef CONFIG_MSM_SOC_REV_A 35#define SMEM_SPINLOCK_I2C "D:I2C02000021" 36#else 37#define SMEM_SPINLOCK_I2C "S:6" 38#endif 39 40#define MSM_PMEM_ADSP_SIZE 0x1C00000 41 42#define MSM_FB_SIZE 0x500000 43#define MSM_FB_SIZE_ST15 0x800000 44#define MSM_AUDIO_SIZE 0x80000 45#define MSM_GPU_PHYS_SIZE SZ_2M 46 47#ifdef CONFIG_MSM_SOC_REV_A 48#define MSM_SMI_BASE 0xE0000000 49#else 50#define MSM_SMI_BASE 0x00000000 51#endif 52 53#define MSM_SHARED_RAM_PHYS (MSM_SMI_BASE + 0x00100000) 54 55#define MSM_PMEM_SMI_BASE (MSM_SMI_BASE + 0x02B00000) 56#define MSM_PMEM_SMI_SIZE 0x01500000 57 58#define MSM_FB_BASE MSM_PMEM_SMI_BASE 59#define MSM_GPU_PHYS_BASE (MSM_FB_BASE + MSM_FB_SIZE) 60#define MSM_PMEM_SMIPOOL_BASE (MSM_GPU_PHYS_BASE + MSM_GPU_PHYS_SIZE) 61#define MSM_PMEM_SMIPOOL_SIZE (MSM_PMEM_SMI_SIZE - MSM_FB_SIZE \ 62 - MSM_GPU_PHYS_SIZE) 63 64#if defined(CONFIG_FB_MSM_MDP40) 65#define MDP_BASE 0xA3F00000 66#define PMDH_BASE 0xAD600000 67#define EMDH_BASE 0xAD700000 68#define TVENC_BASE 0xAD400000 69#else 70#define MDP_BASE 0xAA200000 71#define PMDH_BASE 0xAA600000 72#define EMDH_BASE 0xAA700000 73#define TVENC_BASE 0xAA400000 74#endif 75 76#define PMEM_KERNEL_EBI1_SIZE (CONFIG_PMEM_KERNEL_SIZE * 1024 * 1024) 77 78static struct resource msm_fb_resources[] = { 79 { 80 .flags = IORESOURCE_DMA, 81 } 82}; 83 84static struct resource msm_mdp_resources[] = { 85 { 86 .name = "mdp", 87 .start = MDP_BASE, 88 .end = MDP_BASE + 0x000F0000 - 1, 89 .flags = IORESOURCE_MEM, 90 } 91}; 92 93static struct platform_device msm_mdp_device = { 94 .name = "mdp", 95 .id = 0, 96 .num_resources = ARRAY_SIZE(msm_mdp_resources), 97 .resource = msm_mdp_resources, 98}; 99 100static struct platform_device msm_lcdc_device = { 101 .name = "lcdc", 102 .id = 0, 103}; 104 105static int msm_fb_detect_panel(const char *name) 106{ 107 int ret = -EPERM; 108 109 if (machine_is_qsd8x50_ffa() || machine_is_qsd8x50a_ffa()) { 110 if (!strncmp(name, "mddi_toshiba_wvga_pt", 20)) 111 ret = 0; 112 else 113 ret = -ENODEV; 114 } else if ((machine_is_qsd8x50_surf() || machine_is_qsd8x50a_surf()) 115 && !strcmp(name, "lcdc_external")) 116 ret = 0; 117 else if (machine_is_qsd8x50a_st1_5()) { 118 if (!strcmp(name, "lcdc_st15") || 119 !strcmp(name, "hdmi_sii9022")) 120 ret = 0; 121 else 122 ret = -ENODEV; 123 } 124 125 return ret; 126} 127 128/* Only allow a small subset of machines to set the offset via 129 FB PAN_DISPLAY */ 130 131static int msm_fb_allow_set_offset(void) 132{ 133 return (machine_is_qsd8x50_st1() || 134 machine_is_qsd8x50a_st1_5()) ? 1 : 0; 135} 136 137 138static struct msm_fb_platform_data msm_fb_pdata = { 139 .detect_client = msm_fb_detect_panel, 140 .allow_set_offset = msm_fb_allow_set_offset, 141}; 142 143static struct platform_device msm_fb_device = { 144 .name = "msm_fb", 145 .id = 0, 146 .num_resources = ARRAY_SIZE(msm_fb_resources), 147 .resource = msm_fb_resources, 148 .dev = { 149 .platform_data = &msm_fb_pdata, 150 } 151}; 152 153static void __init qsd8x50_allocate_memory_regions(void) 154{ 155 void *addr; 156 unsigned long size; 157 if (machine_is_qsd8x50a_st1_5()) 158 size = MSM_FB_SIZE_ST15; 159 else 160 size = MSM_FB_SIZE; 161 162 addr = alloc_bootmem(size); // (void *)MSM_FB_BASE; 163 if (!addr) 164 printk("Failed to allocate bootmem for framebuffer\n"); 165 166 167 msm_fb_resources[0].start = __pa(addr); 168 msm_fb_resources[0].end = msm_fb_resources[0].start + size - 1; 169 pr_info(KERN_ERR "using %lu bytes of SMI at %lx physical for fb\n", 170 size, (unsigned long)addr); 171} 172 173static int msm_fb_lcdc_gpio_config(int on) 174{ 175// return 0; 176 if (machine_is_qsd8x50_st1()) { 177 if (on) { 178 gpio_set_value(32, 1); 179 mdelay(100); 180 gpio_set_value(20, 1); 181 gpio_set_value(17, 1); 182 gpio_set_value(19, 1); 183 } else { 184 gpio_set_value(17, 0); 185 gpio_set_value(19, 0); 186 gpio_set_value(20, 0); 187 mdelay(100); 188 gpio_set_value(32, 0); 189 } 190 } else if (machine_is_qsd8x50a_st1_5()) { 191 if (on) { 192 gpio_set_value(17, 1); 193 gpio_set_value(19, 1); 194 gpio_set_value(20, 1); 195 gpio_set_value(22, 0); 196 gpio_set_value(32, 1); 197 gpio_set_value(155, 1); 198 //st15_hdmi_power(1); 199 gpio_set_value(22, 1); 200 201 } else { 202 gpio_set_value(17, 0); 203 gpio_set_value(19, 0); 204 gpio_set_value(22, 0); 205 gpio_set_value(32, 0); 206 gpio_set_value(155, 0); 207 // st15_hdmi_power(0); 208 } 209 } 210 return 0; 211} 212 213 214static struct lcdc_platform_data lcdc_pdata = { 215 .lcdc_gpio_config = msm_fb_lcdc_gpio_config, 216}; 217 218static struct msm_gpio msm_fb_st15_gpio_config_data[] = { 219 { GPIO_CFG(17, 0, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA), "lcdc_en0" }, 220 { GPIO_CFG(19, 0, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA), "dat_pwr_sv" }, 221 { GPIO_CFG(20, 0, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA), "lvds_pwr_dn" }, 222 { GPIO_CFG(22, 0, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA), "lcdc_en1" }, 223 { GPIO_CFG(32, 0, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA), "lcdc_en2" }, 224 { GPIO_CFG(103, 0, GPIO_INPUT, GPIO_NO_PULL, GPIO_2MA), "hdmi_irq" }, 225 { GPIO_CFG(155, 0, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA), "hdmi_3v3" }, 226}; 227 228static struct msm_panel_common_pdata mdp_pdata = { 229 .gpio = 98, 230}; 231 232static struct platform_device *devices[] __initdata = { 233 &msm_fb_device, 234}; 235 236 237static void __init msm_register_device(struct platform_device *pdev, void *data) 238{ 239 int ret; 240 241 pdev->dev.platform_data = data; 242 243 ret = platform_device_register(pdev); 244 if (ret) 245 dev_err(&pdev->dev, 246 "%s: platform_device_register() failed = %d\n", 247 __func__, ret); 248} 249 250void __init msm_fb_register_device(char *name, void *data) 251{ 252 if (!strncmp(name, "mdp", 3)) 253 msm_register_device(&msm_mdp_device, data); 254/* 255 else if (!strncmp(name, "pmdh", 4)) 256 msm_register_device(&msm_mddi_device, data); 257 else if (!strncmp(name, "emdh", 4)) 258 msm_register_device(&msm_mddi_ext_device, data); 259 else if (!strncmp(name, "ebi2", 4)) 260 msm_register_device(&msm_ebi2_lcd_device, data); 261 else if (!strncmp(name, "tvenc", 5)) 262 msm_register_device(&msm_tvenc_device, data); 263 else */ 264 265 if (!strncmp(name, "lcdc", 4)) 266 msm_register_device(&msm_lcdc_device, data); 267 /*else 268 printk(KERN_ERR "%s: unknown device! %s\n", __func__, name); 269*/ 270} 271 272static void __init msm_fb_add_devices(void) 273{ 274 int rc; 275 msm_fb_register_device("mdp", &mdp_pdata); 276// msm_fb_register_device("pmdh", &mddi_pdata); 277// msm_fb_register_device("emdh", &mddi_pdata); 278// msm_fb_register_device("tvenc", 0); 279 280 if (machine_is_qsd8x50a_st1_5()) { 281/* rc = st15_hdmi_vreg_init(); 282 if (rc) 283 return; 284*/ 285 rc = msm_gpios_request_enable( 286 msm_fb_st15_gpio_config_data, 287 ARRAY_SIZE(msm_fb_st15_gpio_config_data)); 288 if (rc) { 289 printk(KERN_ERR "%s: unable to init lcdc gpios\n", 290 __func__); 291 return; 292 } 293 msm_fb_register_device("lcdc", &lcdc_pdata); 294 } else 295 msm_fb_register_device("lcdc", 0); 296} 297 298int __init staging_init_pmem(void) 299{ 300 qsd8x50_allocate_memory_regions(); 301 return 0; 302} 303 304int __init staging_init_devices(void) 305{ 306 platform_add_devices(devices, ARRAY_SIZE(devices)); 307 msm_fb_add_devices(); 308 return 0; 309} 310 311arch_initcall(staging_init_pmem); 312arch_initcall(staging_init_devices); 313