diff options
Diffstat (limited to 'arch/arm/mach-mx6/board-mx6q_sabresd.c')
-rw-r--r-- | arch/arm/mach-mx6/board-mx6q_sabresd.c | 268 |
1 files changed, 196 insertions, 72 deletions
diff --git a/arch/arm/mach-mx6/board-mx6q_sabresd.c b/arch/arm/mach-mx6/board-mx6q_sabresd.c index 986d291cf5da..183f1b9afe42 100644 --- a/arch/arm/mach-mx6/board-mx6q_sabresd.c +++ b/arch/arm/mach-mx6/board-mx6q_sabresd.c @@ -45,6 +45,7 @@ #include <linux/fec.h> #include <linux/memblock.h> #include <linux/gpio.h> +#include <linux/ion.h> #include <linux/etherdevice.h> #include <linux/power/sabresd_battery.h> #include <linux/regulator/anatop-regulator.h> @@ -200,8 +201,8 @@ static struct clk *sata_clk; static struct clk *clko; -static int mma8451_position = 1; -static int mag3110_position = 2; +static int mma8451_position; +static int mag3110_position = 1; static int max11801_mode = 1; static int enable_lcd_ldb; static int caam_enabled; @@ -220,6 +221,7 @@ static const struct esdhc_platform_data mx6q_sabresd_sd2_data __initconst = { .support_8bit = 1, .delay_line = 0, .cd_type = ESDHC_CD_CONTROLLER, + .runtime_pm = 1, }; static const struct esdhc_platform_data mx6q_sabresd_sd3_data __initconst = { @@ -229,6 +231,7 @@ static const struct esdhc_platform_data mx6q_sabresd_sd3_data __initconst = { .support_8bit = 1, .delay_line = 0, .cd_type = ESDHC_CD_CONTROLLER, + .runtime_pm = 1, }; static const struct esdhc_platform_data mx6q_sabresd_sd4_data __initconst = { @@ -832,6 +835,10 @@ static struct i2c_board_info mxc_i2c2_board_info[] __initdata = { I2C_BOARD_INFO("elan-touch", 0x10), .irq = gpio_to_irq(SABRESD_ELAN_INT), }, + { + I2C_BOARD_INFO("mxc_ldb_i2c", 0x50), + .platform_data = (void *)1, /* lvds port1 */ + }, }; static int epdc_get_pins(void) @@ -1216,7 +1223,7 @@ static const struct flexcan_platform_data }; static struct viv_gpu_platform_data imx6q_gpu_pdata __initdata = { - .reserved_mem_size = SZ_128M, + .reserved_mem_size = SZ_128M + SZ_64M - SZ_16M, }; static struct imx_asrc_platform_data imx_asrc_data = { @@ -1255,22 +1262,16 @@ static struct ipuv3_fb_platform_data sabresd_fb_data[] = { .int_clk = false, .late_init = false, }, { - .disp_dev = "ldb", - .interface_pix_fmt = IPU_PIX_FMT_RGB666, - .mode_str = "LDB-XGA", - .default_bpp = 16, - .int_clk = false, - }, { - .disp_dev = "lcd", - .interface_pix_fmt = IPU_PIX_FMT_RGB565, - .mode_str = "CLAA-WVGA", - .default_bpp = 16, + .disp_dev = "hdmi", + .interface_pix_fmt = IPU_PIX_FMT_RGB24, + .mode_str = "1920x1080M@60", + .default_bpp = 32, .int_clk = false, .late_init = false, }, { .disp_dev = "ldb", .interface_pix_fmt = IPU_PIX_FMT_RGB666, - .mode_str = "LDB-VGA", + .mode_str = "LDB-XGA", .default_bpp = 16, .int_clk = false, .late_init = false, @@ -1333,7 +1334,7 @@ static struct fsl_mxc_hdmi_platform_data hdmi_data = { }; static struct fsl_mxc_hdmi_core_platform_data hdmi_core_data = { - .ipu_id = 0, + .ipu_id = 1, .disp_id = 0, }; @@ -1344,12 +1345,12 @@ static struct fsl_mxc_lcd_platform_data lcdif_data = { }; static struct fsl_mxc_ldb_platform_data ldb_data = { - .ipu_id = 1, - .disp_id = 0, + .ipu_id = 0, + .disp_id = 1, .ext_ref = 1, - .mode = LDB_SEP0, - .sec_ipu_id = 1, - .sec_disp_id = 1, + .mode = LDB_SEP1, + .sec_ipu_id = 0, + .sec_disp_id = 0, }; static struct max8903_pdata charger1_data = { @@ -1382,6 +1383,19 @@ static struct imx_ipuv3_platform_data ipu_data[] = { }, }; +static struct ion_platform_data imx_ion_data = { + .nr = 1, + .heaps = { + { + .id = 0, + .type = ION_HEAP_TYPE_CARVEOUT, + .name = "vpu_ion", + .size = SZ_16M, + .cacheable = 1, + }, + }, +}; + static struct fsl_mxc_capture_platform_data capture_data[] = { { .csi = 0, @@ -1462,31 +1476,6 @@ static int __init imx6q_init_audio(void) return 0; } -#ifndef CONFIG_IMX_PCIE -static void pcie_3v3_power(void) -{ - /* disable PCIE_3V3 first */ - gpio_request(SABRESD_PCIE_PWR_EN, "pcie_3v3_en"); - gpio_direction_output(SABRESD_PCIE_PWR_EN, 0); - mdelay(10); - /* enable PCIE_3V3 again */ - gpio_set_value(SABRESD_PCIE_PWR_EN, 1); - gpio_free(SABRESD_PCIE_PWR_EN); -} - -static void pcie_3v3_reset(void) -{ - /* reset miniPCIe */ - gpio_request(SABRESD_PCIE_RST_B_REVB, "pcie_reset_rebB"); - gpio_direction_output(SABRESD_PCIE_RST_B_REVB, 0); - /* The PCI Express Mini CEM specification states that PREST# is - deasserted minimum 1ms after 3.3vVaux has been applied and stable*/ - mdelay(1); - gpio_set_value(SABRESD_PCIE_RST_B_REVB, 1); - gpio_free(SABRESD_PCIE_RST_B_REVB); -} -#endif - static void gps_power_on(bool on) { /* Enable/disable aux_3v15 */ @@ -1563,29 +1552,65 @@ static void __init imx6q_add_device_gpio_leds(void) {} .debounce_interval = debounce, \ } -static struct gpio_keys_button imx6q_buttons[] = { +static struct gpio_keys_button sabresd_buttons[] = { + GPIO_BUTTON(SABRESD_VOLUME_UP, KEY_VOLUMEUP, 1, "volume-up", 0, 1), + GPIO_BUTTON(SABRESD_VOLUME_DN, KEY_POWER, 1, "volume-down", 1, 1), +}; + +static struct gpio_keys_platform_data sabresd_button_data = { + .buttons = sabresd_buttons, + .nbuttons = ARRAY_SIZE(sabresd_buttons), +}; + +static struct gpio_keys_button new_sabresd_buttons[] = { GPIO_BUTTON(SABRESD_VOLUME_UP, KEY_VOLUMEUP, 1, "volume-up", 0, 1), GPIO_BUTTON(SABRESD_VOLUME_DN, KEY_VOLUMEDOWN, 1, "volume-down", 0, 1), - GPIO_BUTTON(SABRESD_POWER_OFF, KEY_POWER, 1, "power", 1, 1), + GPIO_BUTTON(SABRESD_POWER_OFF, KEY_POWER, 1, "power-key", 1, 1), }; -static struct gpio_keys_platform_data imx6q_button_data = { - .buttons = imx6q_buttons, - .nbuttons = ARRAY_SIZE(imx6q_buttons), +static struct gpio_keys_platform_data new_sabresd_button_data = { + .buttons = new_sabresd_buttons, + .nbuttons = ARRAY_SIZE(new_sabresd_buttons), }; -static struct platform_device imx6q_button_device = { +static struct platform_device sabresd_button_device = { .name = "gpio-keys", .id = -1, .num_resources = 0, - .dev = { - .platform_data = &imx6q_button_data, - } }; static void __init imx6q_add_device_buttons(void) { - platform_device_register(&imx6q_button_device); + /* fix me */ + /* For new sabresd(RevB4 ane above) change the + * ONOFF key(SW1) design, the SW1 now connect + * to GPIO_3_29, it can be use as a general power + * key that Android reuired. But those old sabresd + * such as RevB or older could not support this + * change, so it needs a way to distinguish different + * boards. Before board id/rev are defined cleary, + * there is a simple way to achive this, that is using + * SOC revison to identify differnt board revison. + * + * With the new sabresd change and SW mapping the + * SW1 as power key, below function related to power + * key are OK on new sabresd board(B4 or above). + * 1 Act as power button to power on the device when device is power off + * 2 Act as power button to power on the device(need keep press SW1 >5s) + * 3 Act as power key to let device suspend/resume + * 4 Act screenshort(hold power key and volume down key for 2s) + */ + if (mx6q_revision() >= IMX_CHIP_REVISION_1_2 || + mx6dl_revision() >= IMX_CHIP_REVISION_1_1) + platform_device_add_data(&sabresd_button_device, + &new_sabresd_button_data, + sizeof(new_sabresd_button_data)); + else + platform_device_add_data(&sabresd_button_device, + &sabresd_button_data, + sizeof(sabresd_button_data)); + + platform_device_register(&sabresd_button_device); } #else static void __init imx6q_add_device_buttons(void) {} @@ -1625,6 +1650,49 @@ static struct mxc_dvfs_platform_data sabresd_dvfscore_data = { static void __init fixup_mxc_board(struct machine_desc *desc, struct tag *tags, char **cmdline, struct meminfo *mi) { + char *str; + struct tag *t; + int i = 0; + struct ipuv3_fb_platform_data *pdata_fb = sabresd_fb_data; + + for_each_tag(t, tags) { + if (t->hdr.tag == ATAG_CMDLINE) { + str = t->u.cmdline.cmdline; + str = strstr(str, "fbmem="); + if (str != NULL) { + str += 6; + pdata_fb[i++].res_size[0] = memparse(str, &str); + while (*str == ',' && + i < ARRAY_SIZE(sabresd_fb_data)) { + str++; + pdata_fb[i++].res_size[0] = memparse(str, &str); + } + } + /* ION reserved memory */ + str = t->u.cmdline.cmdline; + str = strstr(str, "ionmem="); + if (str != NULL) { + str += 7; + imx_ion_data.heaps[0].size = memparse(str, &str); + } + /* Primary framebuffer base address */ + str = t->u.cmdline.cmdline; + str = strstr(str, "fb0base="); + if (str != NULL) { + str += 8; + pdata_fb[0].res_base[0] = + simple_strtol(str, &str, 16); + } + /* GPU reserved memory */ + str = t->u.cmdline.cmdline; + str = strstr(str, "gpumem="); + if (str != NULL) { + str += 7; + imx6q_gpu_pdata.reserved_mem_size = memparse(str, &str); + } + break; + } + } } static struct mipi_csi2_platform_data mipi_csi2_pdata = { @@ -1659,6 +1727,7 @@ static const struct imx_pcie_platform_data mx6_sabresd_pcie_data __initconst = { .pcie_rst = SABRESD_PCIE_RST_B_REVB, .pcie_wake_up = SABRESD_PCIE_WAKE_B, .pcie_dis = SABRESD_PCIE_DIS_B, + .pcie_power_always_on = 1, }; static int __init early_enable_lcd_ldb(char *p) @@ -1668,6 +1737,26 @@ static int __init early_enable_lcd_ldb(char *p) } early_param("enable_lcd_ldb", early_enable_lcd_ldb); +#ifdef CONFIG_ANDROID_RAM_CONSOLE +static struct resource ram_console_resource = { + .name = "android ram console", + .flags = IORESOURCE_MEM, +}; + +static struct platform_device android_ram_console = { + .name = "ram_console", + .num_resources = 1, + .resource = &ram_console_resource, +}; + +static int __init imx6x_add_ram_console(void) +{ + return platform_device_register(&android_ram_console); +} +#else +#define imx6x_add_ram_console() do {} while (0) +#endif + /*! * Board specific initialization. */ @@ -1699,6 +1788,7 @@ static void __init mx6_sabresd_board_init(void) gp_reg_id = sabresd_dvfscore_data.reg_id; soc_reg_id = sabresd_dvfscore_data.soc_id; mx6q_sabresd_init_uart(); + imx6x_add_ram_console(); /* * MX6DL/Solo only supports single IPU @@ -1709,16 +1799,11 @@ static void __init mx6_sabresd_board_init(void) */ if (cpu_is_mx6dl()) { ldb_data.ipu_id = 0; - ldb_data.disp_id = 0; - ldb_data.sec_ipu_id = 0; - ldb_data.sec_disp_id = 1; - hdmi_core_data.disp_id = 1; + ldb_data.disp_id = 1; + hdmi_core_data.ipu_id = 0; + hdmi_core_data.disp_id = 0; mipi_dsi_pdata.ipu_id = 0; mipi_dsi_pdata.disp_id = 1; - if (enable_lcd_ldb) { - ldb_data.disp_id = 1; - ldb_data.mode = LDB_SIN1; - } } imx6q_add_mxc_hdmi_core(&hdmi_core_data); @@ -1784,8 +1869,8 @@ static void __init mx6_sabresd_board_init(void) Mfgtools want emmc is mmcblk0 and other sd card is mmcblk1. */ imx6q_add_sdhci_usdhc_imx(3, &mx6q_sabresd_sd4_data); - imx6q_add_sdhci_usdhc_imx(1, &mx6q_sabresd_sd2_data); imx6q_add_sdhci_usdhc_imx(2, &mx6q_sabresd_sd3_data); + imx6q_add_sdhci_usdhc_imx(1, &mx6q_sabresd_sd2_data); imx_add_viv_gpu(&imx6_gpu_data, &imx6q_gpu_pdata); imx6q_sabresd_init_usb(); /* SATA is not supported by MX6DL/Solo */ @@ -1827,6 +1912,11 @@ static void __init mx6_sabresd_board_init(void) imx6q_add_dma(); imx6q_add_dvfs_core(&sabresd_dvfscore_data); + + if (imx_ion_data.heaps[0].size) + imx6q_add_ion(0, &imx_ion_data, + sizeof(imx_ion_data) + sizeof(struct ion_platform_heap)); + imx6q_add_device_buttons(); /* enable sensor 3v3 and 1v8 */ @@ -1883,13 +1973,6 @@ static void __init mx6_sabresd_board_init(void) gpio_direction_output(SABRESD_AUX_5V_EN, 1); gpio_set_value(SABRESD_AUX_5V_EN, 1); -#ifndef CONFIG_IMX_PCIE - /* enable pcie 3v3 power without pcie driver */ - pcie_3v3_power(); - mdelay(10); - pcie_3v3_reset(); -#endif - gps_power_on(true); /* Register charger chips */ platform_device_register(&sabresd_max8903_charger_1); @@ -1944,9 +2027,42 @@ static struct sys_timer mx6_sabresd_timer = { static void __init mx6q_sabresd_reserve(void) { -#if defined(CONFIG_MXC_GPU_VIV) || defined(CONFIG_MXC_GPU_VIV_MODULE) phys_addr_t phys; + int i, fb0_reserved = 0, fb_array_size; + + /* + * Reserve primary framebuffer memory if its base address + * is set by kernel command line. + */ + fb_array_size = ARRAY_SIZE(sabresd_fb_data); + if (fb_array_size > 0 && sabresd_fb_data[0].res_base[0] && + sabresd_fb_data[0].res_size[0]) { + memblock_reserve(sabresd_fb_data[0].res_base[0], + sabresd_fb_data[0].res_size[0]); + memblock_remove(sabresd_fb_data[0].res_base[0], + sabresd_fb_data[0].res_size[0]); + sabresd_fb_data[0].late_init = true; + ipu_data[ldb_data.ipu_id].bypass_reset = true; + fb0_reserved = 1; + } + for (i = fb0_reserved; i < fb_array_size; i++) + if (sabresd_fb_data[i].res_size[0]) { + /* Reserve for other background buffer. */ + phys = memblock_alloc(sabresd_fb_data[i].res_size[0], + SZ_4K); + memblock_remove(phys, sabresd_fb_data[i].res_size[0]); + sabresd_fb_data[i].res_base[0] = phys; + } + +#ifdef CONFIG_ANDROID_RAM_CONSOLE + phys = memblock_alloc_base(SZ_128K, SZ_4K, SZ_1G); + memblock_remove(phys, SZ_128K); + memblock_free(phys, SZ_128K); + ram_console_resource.start = phys; + ram_console_resource.end = phys + SZ_128K - 1; +#endif +#if defined(CONFIG_MXC_GPU_VIV) || defined(CONFIG_MXC_GPU_VIV_MODULE) if (imx6q_gpu_pdata.reserved_mem_size) { phys = memblock_alloc_base(imx6q_gpu_pdata.reserved_mem_size, SZ_4K, SZ_1G); @@ -1954,6 +2070,14 @@ static void __init mx6q_sabresd_reserve(void) imx6q_gpu_pdata.reserved_mem_base = phys; } #endif + +#if defined(CONFIG_ION) + if (imx_ion_data.heaps[0].size) { + phys = memblock_alloc(imx_ion_data.heaps[0].size, SZ_4K); + memblock_remove(phys, imx_ion_data.heaps[0].size); + imx_ion_data.heaps[0].base = phys; + } +#endif } /* |