#include <linux/kernel.h> #include <linux/irq.h> #include <linux/gpio.h> #include <linux/platform_device.h> #include <linux/bootmem.h> #include <linux/delay.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> #include <asm/io.h> #include <asm/setup.h> #include <mach/board.h> #include <mach/irqs.h> #include <mach/sirc.h> #include <mach/gpio.h> #include "msm_mdp.h" #include "memory_ll.h" //#include "android_pmem.h" #ifdef CONFIG_MSM_SOC_REV_A #define MSM_SMI_BASE 0xE0000000 #else #define MSM_SMI_BASE 0x00000000 #endif #define TOUCHPAD_SUSPEND 34 #define TOUCHPAD_IRQ 38 #define MSM_PMEM_MDP_SIZE 0x1591000 #ifdef CONFIG_MSM_SOC_REV_A #define SMEM_SPINLOCK_I2C "D:I2C02000021" #else #define SMEM_SPINLOCK_I2C "S:6" #endif #define MSM_PMEM_ADSP_SIZE 0x1C00000 #define MSM_FB_SIZE 0x500000 #define MSM_FB_SIZE_ST15 0x800000 #define MSM_AUDIO_SIZE 0x80000 #define MSM_GPU_PHYS_SIZE SZ_2M #ifdef CONFIG_MSM_SOC_REV_A #define MSM_SMI_BASE 0xE0000000 #else #define MSM_SMI_BASE 0x00000000 #endif #define MSM_SHARED_RAM_PHYS (MSM_SMI_BASE + 0x00100000) #define MSM_PMEM_SMI_BASE (MSM_SMI_BASE + 0x02B00000) #define MSM_PMEM_SMI_SIZE 0x01500000 #define MSM_FB_BASE MSM_PMEM_SMI_BASE #define MSM_GPU_PHYS_BASE (MSM_FB_BASE + MSM_FB_SIZE) #define MSM_PMEM_SMIPOOL_BASE (MSM_GPU_PHYS_BASE + MSM_GPU_PHYS_SIZE) #define MSM_PMEM_SMIPOOL_SIZE (MSM_PMEM_SMI_SIZE - MSM_FB_SIZE \ - MSM_GPU_PHYS_SIZE) #if defined(CONFIG_FB_MSM_MDP40) #define MDP_BASE 0xA3F00000 #define PMDH_BASE 0xAD600000 #define EMDH_BASE 0xAD700000 #define TVENC_BASE 0xAD400000 #else #define MDP_BASE 0xAA200000 #define PMDH_BASE 0xAA600000 #define EMDH_BASE 0xAA700000 #define TVENC_BASE 0xAA400000 #endif #define PMEM_KERNEL_EBI1_SIZE (CONFIG_PMEM_KERNEL_SIZE * 1024 * 1024) static struct resource msm_fb_resources[] = { { .flags = IORESOURCE_DMA, } }; static struct resource msm_mdp_resources[] = { { .name = "mdp", .start = MDP_BASE, .end = MDP_BASE + 0x000F0000 - 1, .flags = IORESOURCE_MEM, } }; static struct platform_device msm_mdp_device = { .name = "mdp", .id = 0, .num_resources = ARRAY_SIZE(msm_mdp_resources), .resource = msm_mdp_resources, }; static struct platform_device msm_lcdc_device = { .name = "lcdc", .id = 0, }; static int msm_fb_detect_panel(const char *name) { int ret = -EPERM; if (machine_is_qsd8x50_ffa() || machine_is_qsd8x50a_ffa()) { if (!strncmp(name, "mddi_toshiba_wvga_pt", 20)) ret = 0; else ret = -ENODEV; } else if ((machine_is_qsd8x50_surf() || machine_is_qsd8x50a_surf()) && !strcmp(name, "lcdc_external")) ret = 0; else if (machine_is_qsd8x50a_st1_5()) { if (!strcmp(name, "lcdc_st15") || !strcmp(name, "hdmi_sii9022")) ret = 0; else ret = -ENODEV; } return ret; } /* Only allow a small subset of machines to set the offset via FB PAN_DISPLAY */ static int msm_fb_allow_set_offset(void) { return (machine_is_qsd8x50_st1() || machine_is_qsd8x50a_st1_5()) ? 1 : 0; } static struct msm_fb_platform_data msm_fb_pdata = { .detect_client = msm_fb_detect_panel, .allow_set_offset = msm_fb_allow_set_offset, }; static struct platform_device msm_fb_device = { .name = "msm_fb", .id = 0, .num_resources = ARRAY_SIZE(msm_fb_resources), .resource = msm_fb_resources, .dev = { .platform_data = &msm_fb_pdata, } }; static void __init qsd8x50_allocate_memory_regions(void) { void *addr; unsigned long size; if (machine_is_qsd8x50a_st1_5()) size = MSM_FB_SIZE_ST15; else size = MSM_FB_SIZE; addr = alloc_bootmem(size); // (void *)MSM_FB_BASE; if (!addr) printk("Failed to allocate bootmem for framebuffer\n"); msm_fb_resources[0].start = __pa(addr); msm_fb_resources[0].end = msm_fb_resources[0].start + size - 1; pr_info("using %lu bytes of SMI at %lx physical for fb\n", size, (unsigned long)addr); } static int msm_fb_lcdc_gpio_config(int on) { // return 0; if (machine_is_qsd8x50_st1()) { if (on) { gpio_set_value(32, 1); mdelay(100); gpio_set_value(20, 1); gpio_set_value(17, 1); gpio_set_value(19, 1); } else { gpio_set_value(17, 0); gpio_set_value(19, 0); gpio_set_value(20, 0); mdelay(100); gpio_set_value(32, 0); } } else if (machine_is_qsd8x50a_st1_5()) { if (on) { gpio_set_value(17, 1); gpio_set_value(19, 1); gpio_set_value(20, 1); gpio_set_value(22, 0); gpio_set_value(32, 1); gpio_set_value(155, 1); //st15_hdmi_power(1); gpio_set_value(22, 1); } else { gpio_set_value(17, 0); gpio_set_value(19, 0); gpio_set_value(22, 0); gpio_set_value(32, 0); gpio_set_value(155, 0); // st15_hdmi_power(0); } } return 0; } static struct lcdc_platform_data lcdc_pdata = { .lcdc_gpio_config = msm_fb_lcdc_gpio_config, }; static struct msm_gpio msm_fb_st15_gpio_config_data[] = { { GPIO_CFG(17, 0, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA), "lcdc_en0" }, { GPIO_CFG(19, 0, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA), "dat_pwr_sv" }, { GPIO_CFG(20, 0, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA), "lvds_pwr_dn" }, { GPIO_CFG(22, 0, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA), "lcdc_en1" }, { GPIO_CFG(32, 0, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA), "lcdc_en2" }, { GPIO_CFG(103, 0, GPIO_INPUT, GPIO_NO_PULL, GPIO_2MA), "hdmi_irq" }, { GPIO_CFG(155, 0, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA), "hdmi_3v3" }, }; static struct msm_panel_common_pdata mdp_pdata = { .gpio = 98, }; static struct platform_device *devices[] __initdata = { &msm_fb_device, }; static void __init msm_register_device(struct platform_device *pdev, void *data) { int ret; pdev->dev.platform_data = data; ret = platform_device_register(pdev); if (ret) dev_err(&pdev->dev, "%s: platform_device_register() failed = %d\n", __func__, ret); } void __init msm_fb_register_device(char *name, void *data) { if (!strncmp(name, "mdp", 3)) msm_register_device(&msm_mdp_device, data); /* else if (!strncmp(name, "pmdh", 4)) msm_register_device(&msm_mddi_device, data); else if (!strncmp(name, "emdh", 4)) msm_register_device(&msm_mddi_ext_device, data); else if (!strncmp(name, "ebi2", 4)) msm_register_device(&msm_ebi2_lcd_device, data); else if (!strncmp(name, "tvenc", 5)) msm_register_device(&msm_tvenc_device, data); else */ if (!strncmp(name, "lcdc", 4)) msm_register_device(&msm_lcdc_device, data); /*else printk(KERN_ERR "%s: unknown device! %s\n", __func__, name); */ } static void __init msm_fb_add_devices(void) { int rc; msm_fb_register_device("mdp", &mdp_pdata); // msm_fb_register_device("pmdh", &mddi_pdata); // msm_fb_register_device("emdh", &mddi_pdata); // msm_fb_register_device("tvenc", 0); if (machine_is_qsd8x50a_st1_5()) { /* rc = st15_hdmi_vreg_init(); if (rc) return; */ rc = msm_gpios_request_enable( msm_fb_st15_gpio_config_data, ARRAY_SIZE(msm_fb_st15_gpio_config_data)); if (rc) { printk(KERN_ERR "%s: unable to init lcdc gpios\n", __func__); return; } msm_fb_register_device("lcdc", &lcdc_pdata); } else msm_fb_register_device("lcdc", 0); } int __init staging_init_pmem(void) { qsd8x50_allocate_memory_regions(); return 0; } int __init staging_init_devices(void) { platform_add_devices(devices, ARRAY_SIZE(devices)); msm_fb_add_devices(); return 0; } arch_initcall(staging_init_pmem); arch_initcall(staging_init_devices);