summaryrefslogtreecommitdiff
path: root/arch/arm/mach-mx6/board-mx6q_sabresd.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-mx6/board-mx6q_sabresd.c')
-rw-r--r--arch/arm/mach-mx6/board-mx6q_sabresd.c268
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
}
/*