summaryrefslogtreecommitdiff
path: root/arch/arm/mach-msm/board-comet.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-msm/board-comet.c')
-rw-r--r--arch/arm/mach-msm/board-comet.c488
1 files changed, 488 insertions, 0 deletions
diff --git a/arch/arm/mach-msm/board-comet.c b/arch/arm/mach-msm/board-comet.c
new file mode 100644
index 000000000000..01333821f343
--- /dev/null
+++ b/arch/arm/mach-msm/board-comet.c
@@ -0,0 +1,488 @@
+/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Code Aurora Forum nor
+ * the names of its contributors may be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * Alternatively, provided that this notice is retained in full, this software
+ * may be relicensed by the recipient under the terms of the GNU General Public
+ * License version 2 ("GPL") and only version 2, in which case the provisions of
+ * the GPL apply INSTEAD OF those given above. If the recipient relicenses the
+ * software under the GPL, then the identification text in the MODULE_LICENSE
+ * macro must be changed to reflect "GPLv2" instead of "Dual BSD/GPL". Once a
+ * recipient changes the license terms to the GPL, subsequent recipients shall
+ * not relicense under alternate licensing terms, including the BSD or dual
+ * BSD/GPL terms. In addition, the following license statement immediately
+ * below and between the words START and END shall also then apply when this
+ * software is relicensed under the GPL:
+ *
+ * START
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 and only version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * END
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/irq.h>
+#include <linux/gpio.h>
+#include <linux/platform_device.h>
+#include <linux/bootmem.h>
+#include <linux/i2c.h>
+#include <linux/io.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <mach/mmc.h>
+#include <mach/vreg.h>
+#include <mach/board.h>
+#include <mach/sirc.h>
+#include <linux/spi/spi.h>
+
+#include "devices.h"
+#include "timer.h"
+#include "pm.h"
+
+#define TOUCHPAD_SUSPEND 34
+#define TOUCHPAD_IRQ 42
+
+#define MSM_PMEM_MDP_SIZE 0x800000
+#define MSM_FB_SIZE 0x500000
+#define MSM_AUDIO_SIZE 0x200000
+
+#define MSM_SMI_BASE 0x2b00000
+#define MSM_SMI_SIZE 0x1500000
+
+#define MSM_FB_BASE MSM_SMI_BASE
+#define MSM_PMEM_GPU0_BASE (MSM_FB_BASE + MSM_FB_SIZE)
+#define MSM_PMEM_GPU0_SIZE (MSM_SMI_SIZE - MSM_FB_SIZE)
+
+#define COMET_CPLD_START 0x70004000
+#define COMET_CPLD_PER_ENABLE 0x00000010
+#define COMET_CPLD_PER_RESET 0x00000018
+#define COMET_CPLD_STATUS 0x00000028
+#define COMET_CPLD_EXT_PER_ENABLE 0x00000030
+#define COMET_CPLD_I2C_ENABLE 0x00000038
+#define COMET_CPLD_EXT_PER_RESET 0x00000048
+#define COMET_CPLD_VERSION 0x00000058
+
+#define COMET_CPLD_SIZE 0x00000060
+#define COMET_CPLD_STATUS_WVGA 0x0004
+#define COMET_CPLD_VERSION_MAJOR 0xFF00
+#define COMET_CPLD_PER_ENABLE_WVGA 0x0400
+#define COMET_CPLD_PER_ENABLE_LVDS 0x0200
+#define COMET_CPLD_PER_ENABLE_WXGA 0x0040
+#define COMET_CPLD_EXT_PER_ENABLE_WXGA 0x0080
+
+static unsigned long vreg_sts, gpio_sts;
+static struct vreg *vreg_mmc;
+static int gp6_enabled;
+
+static int cpld_version;
+static bool wvga_present;
+static bool wxga_present;
+static struct comet_cpld_t {
+ u16 per_reset_all_reset;
+ u16 ext_per_reset_all_reset;
+ u16 i2c_enable;
+ u16 per_enable_all;
+ u16 ext_per_enable_all;
+ u16 bt_reset_reg;
+ u16 bt_reset_mask;
+} comet_cpld[] = {
+ [0] = {
+ .per_reset_all_reset = 0x00FF,
+ /* enable all peripherals except microphones and */
+ /* reset line for i2c touchpad */
+ .per_enable_all = 0xFFD8,
+ .bt_reset_reg = 0x0018,
+ .bt_reset_mask = 0x0001,
+ },
+ [1] = {
+ .per_reset_all_reset = 0x00BF,
+ .ext_per_reset_all_reset = 0x0007,
+ .i2c_enable = 0x07F7,
+ /* enable all peripherals except microphones and */
+ /* displays */
+ .per_enable_all = 0xF9B8,
+ .ext_per_enable_all = 0x007D,
+ .bt_reset_reg = 0x0048,
+ .bt_reset_mask = 0x0004,
+ },
+};
+static struct comet_cpld_t *cpld_info;
+
+static struct resource smc911x_resources[] = {
+ [0] = {
+ .start = 0x84000000,
+ .end = 0x84000100,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = MSM_GPIO_TO_INT(156),
+ .end = 156,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device smc911x_device = {
+ .name = "smc911x",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(smc911x_resources),
+ .resource = smc911x_resources,
+};
+
+static void __iomem *comet_cpld_base(void)
+{
+ static void __iomem *comet_cpld_base_addr;
+
+ if (!comet_cpld_base_addr) {
+ if (!request_mem_region(COMET_CPLD_START, COMET_CPLD_SIZE,
+ "cpld")) {
+ printk(KERN_ERR
+ "%s: request_mem_region for comet cpld failed\n",
+ __func__);
+ goto cpld_base_exit;
+ }
+ comet_cpld_base_addr = ioremap(COMET_CPLD_START,
+ COMET_CPLD_SIZE);
+ if (!comet_cpld_base_addr) {
+ release_mem_region(COMET_CPLD_START,
+ COMET_CPLD_SIZE);
+ printk(KERN_ERR "%s: Could not map comet cpld\n",
+ __func__);
+ }
+ }
+cpld_base_exit:
+ return comet_cpld_base_addr;
+}
+
+static struct platform_device *devices[] __initdata = {
+ &msm_device_smd,
+ &msm_device_dmov,
+ &smc911x_device,
+ &msm_device_nand,
+};
+
+
+#define KBD_RST 35
+#define KBD_IRQ 144
+
+static void kbd_gpio_release(void)
+{
+ gpio_free(KBD_IRQ);
+ gpio_free(KBD_RST);
+}
+
+static int kbd_gpio_setup(void)
+{
+ int rc;
+ int respin = KBD_RST;
+ int irqpin = KBD_IRQ;
+ unsigned rescfg =
+ GPIO_CFG(respin, 0, GPIO_OUTPUT, GPIO_PULL_UP, GPIO_8MA);
+ unsigned irqcfg =
+ GPIO_CFG(irqpin, 0, GPIO_INPUT, GPIO_NO_PULL, GPIO_2MA);
+
+ rc = gpio_request(irqpin, "gpio_keybd_irq");
+ if (rc) {
+ pr_err("gpio_request failed on pin %d (rc=%d)\n",
+ irqpin, rc);
+ goto err_gpioconfig;
+ }
+ rc = gpio_request(respin, "gpio_keybd_reset");
+ if (rc) {
+ pr_err("gpio_request failed on pin %d (rc=%d)\n",
+ respin, rc);
+ goto err_gpioconfig;
+ }
+ rc = gpio_tlmm_config(rescfg, GPIO_ENABLE);
+ if (rc) {
+ pr_err("gpio_tlmm_config failed on pin %d (rc=%d)\n",
+ respin, rc);
+ goto err_gpioconfig;
+ }
+ rc = gpio_tlmm_config(irqcfg, GPIO_ENABLE);
+ if (rc) {
+ pr_err("gpio_tlmm_config failed on pin %d (rc=%d)\n",
+ irqpin, rc);
+ goto err_gpioconfig;
+ }
+ return rc;
+
+err_gpioconfig:
+ kbd_gpio_release();
+ return rc;
+}
+
+static void __init comet_init_irq(void)
+{
+ msm_init_irq();
+ msm_init_sirc();
+}
+
+static void sdcc_gpio_init(void)
+{
+ /* SDC1 GPIOs */
+ if (gpio_request(51, "sdc1_data_3"))
+ pr_err("failed to request gpio sdc1_data_3\n");
+ if (gpio_request(52, "sdc1_data_2"))
+ pr_err("failed to request gpio sdc1_data_2\n");
+ if (gpio_request(53, "sdc1_data_1"))
+ pr_err("failed to request gpio sdc1_data_1\n");
+ if (gpio_request(54, "sdc1_data_0"))
+ pr_err("failed to request gpio sdc1_data_0\n");
+ if (gpio_request(55, "sdc1_cmd"))
+ pr_err("failed to request gpio sdc1_cmd\n");
+ if (gpio_request(56, "sdc1_clk"))
+ pr_err("failed to request gpio sdc1_clk\n");
+
+ /* SDC2 GPIOs */
+ if (gpio_request(62, "sdc2_clk"))
+ pr_err("failed to request gpio sdc2_clk\n");
+ if (gpio_request(63, "sdc2_cmd"))
+ pr_err("failed to request gpio sdc2_cmd\n");
+ if (gpio_request(64, "sdc2_data_3"))
+ pr_err("failed to request gpio sdc2_data_3\n");
+ if (gpio_request(65, "sdc2_data_2"))
+ pr_err("failed to request gpio sdc2_data_2\n");
+ if (gpio_request(66, "sdc2_data_1"))
+ pr_err("failed to request gpio sdc2_data_1\n");
+ if (gpio_request(67, "sdc2_data_0"))
+ pr_err("failed to request gpio sdc2_data_0\n");
+
+ /* SDC3 GPIOs */
+ if (gpio_request(88, "sdc3_clk"))
+ pr_err("failed to request gpio sdc3_clk\n");
+ if (gpio_request(89, "sdc3_cmd"))
+ pr_err("failed to request gpio sdc3_cmd\n");
+ if (gpio_request(90, "sdc3_data_3"))
+ pr_err("failed to request gpio sdc3_data_3\n");
+ if (gpio_request(91, "sdc3_data_2"))
+ pr_err("failed to request gpio sdc3_data_2\n");
+ if (gpio_request(92, "sdc3_data_1"))
+ pr_err("failed to request gpio sdc3_data_1\n");
+ if (gpio_request(93, "sdc3_data_0"))
+ pr_err("failed to request gpio sdc3_data_0\n");
+
+}
+
+static unsigned sdcc_cfg_data[][6] = {
+ /* SDC1 configs */
+ {
+ GPIO_CFG(51, 1, GPIO_OUTPUT, GPIO_PULL_UP, GPIO_8MA),
+ GPIO_CFG(52, 1, GPIO_OUTPUT, GPIO_PULL_UP, GPIO_8MA),
+ GPIO_CFG(53, 1, GPIO_OUTPUT, GPIO_PULL_UP, GPIO_8MA),
+ GPIO_CFG(54, 1, GPIO_OUTPUT, GPIO_PULL_UP, GPIO_8MA),
+ GPIO_CFG(55, 1, GPIO_OUTPUT, GPIO_PULL_UP, GPIO_8MA),
+ GPIO_CFG(56, 1, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_8MA),
+ },
+ /* SDC2 configs */
+ {
+ GPIO_CFG(62, 1, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_8MA),
+ GPIO_CFG(63, 1, GPIO_OUTPUT, GPIO_PULL_UP, GPIO_8MA),
+ GPIO_CFG(64, 1, GPIO_OUTPUT, GPIO_PULL_UP, GPIO_8MA),
+ GPIO_CFG(65, 1, GPIO_OUTPUT, GPIO_PULL_UP, GPIO_8MA),
+ GPIO_CFG(66, 1, GPIO_OUTPUT, GPIO_PULL_UP, GPIO_8MA),
+ GPIO_CFG(67, 1, GPIO_OUTPUT, GPIO_PULL_UP, GPIO_8MA),
+ },
+ /* SDC3 configs */
+ {
+ GPIO_CFG(88, 1, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_8MA),
+ GPIO_CFG(89, 1, GPIO_OUTPUT, GPIO_PULL_UP, GPIO_8MA),
+ GPIO_CFG(90, 1, GPIO_OUTPUT, GPIO_PULL_UP, GPIO_8MA),
+ GPIO_CFG(91, 1, GPIO_OUTPUT, GPIO_PULL_UP, GPIO_8MA),
+ GPIO_CFG(92, 1, GPIO_OUTPUT, GPIO_PULL_UP, GPIO_8MA),
+ GPIO_CFG(93, 1, GPIO_OUTPUT, GPIO_PULL_UP, GPIO_8MA),
+ },
+};
+
+static void msm_sdcc_setup_gpio(int dev_id, unsigned int enable)
+{
+ int i, rc;
+
+ if (!(test_bit(dev_id, &gpio_sts)^enable))
+ return;
+
+ if (enable)
+ set_bit(dev_id, &gpio_sts);
+ else
+ clear_bit(dev_id, &gpio_sts);
+
+ for (i = 0; i < ARRAY_SIZE(sdcc_cfg_data[dev_id - 1]); i++) {
+ rc = gpio_tlmm_config(sdcc_cfg_data[dev_id - 1][i],
+ enable ? GPIO_ENABLE : GPIO_DISABLE);
+ if (rc)
+ printk(KERN_ERR "%s: gpio_tlmm_config(%#x)=%d\n",
+ __func__, sdcc_cfg_data[dev_id - 1][i], rc);
+ }
+}
+
+static uint32_t msm_sdcc_setup_power(struct device *dv, unsigned int vdd)
+{
+ int rc = 0;
+ struct platform_device *pdev;
+
+ pdev = container_of(dv, struct platform_device, dev);
+ msm_sdcc_setup_gpio(pdev->id, !!vdd);
+
+ if (vdd == 0) {
+ if (!vreg_sts)
+ return 0;
+
+ clear_bit(pdev->id, &vreg_sts);
+
+ if (!vreg_sts && !gp6_enabled) {
+ rc = vreg_disable(vreg_mmc);
+ if (rc)
+ printk(KERN_ERR "%s: return val: %d \n",
+ __func__, rc);
+ }
+ return 0;
+ }
+
+ if (!vreg_sts && !gp6_enabled) {
+ rc = vreg_set_level(vreg_mmc, 2850);
+ if (!rc)
+ rc = vreg_enable(vreg_mmc);
+ if (rc)
+ printk(KERN_ERR "%s: return val: %d \n",
+ __func__, rc);
+ }
+ set_bit(pdev->id, &vreg_sts);
+ return 0;
+}
+
+static struct mmc_platform_data comet_sdcc_data = {
+ .ocr_mask = MMC_VDD_27_28 | MMC_VDD_28_29,
+ .translate_vdd = msm_sdcc_setup_power,
+};
+
+static struct msm_pm_platform_data msm_pm_data[MSM_PM_SLEEP_MODE_NR] = {
+ [MSM_PM_SLEEP_MODE_POWER_COLLAPSE].supported = 1,
+ [MSM_PM_SLEEP_MODE_POWER_COLLAPSE].suspend_enabled = 1,
+ [MSM_PM_SLEEP_MODE_POWER_COLLAPSE].idle_enabled = 1,
+ [MSM_PM_SLEEP_MODE_POWER_COLLAPSE].latency = 8594,
+ [MSM_PM_SLEEP_MODE_POWER_COLLAPSE].residency = 23740,
+
+ [MSM_PM_SLEEP_MODE_POWER_COLLAPSE_NO_XO_SHUTDOWN].supported = 1,
+ [MSM_PM_SLEEP_MODE_POWER_COLLAPSE_NO_XO_SHUTDOWN].suspend_enabled = 1,
+ [MSM_PM_SLEEP_MODE_POWER_COLLAPSE_NO_XO_SHUTDOWN].idle_enabled = 1,
+ [MSM_PM_SLEEP_MODE_POWER_COLLAPSE_NO_XO_SHUTDOWN].latency = 4594,
+ [MSM_PM_SLEEP_MODE_POWER_COLLAPSE_NO_XO_SHUTDOWN].residency = 23740,
+
+ [MSM_PM_SLEEP_MODE_RAMP_DOWN_AND_WAIT_FOR_INTERRUPT].supported = 1,
+ [MSM_PM_SLEEP_MODE_RAMP_DOWN_AND_WAIT_FOR_INTERRUPT].suspend_enabled
+ = 1,
+ [MSM_PM_SLEEP_MODE_RAMP_DOWN_AND_WAIT_FOR_INTERRUPT].idle_enabled = 0,
+ [MSM_PM_SLEEP_MODE_RAMP_DOWN_AND_WAIT_FOR_INTERRUPT].latency = 443,
+ [MSM_PM_SLEEP_MODE_RAMP_DOWN_AND_WAIT_FOR_INTERRUPT].residency = 1098,
+
+ [MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT].supported = 1,
+ [MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT].suspend_enabled = 1,
+ [MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT].idle_enabled = 1,
+ [MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT].latency = 2,
+ [MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT].residency = 0,
+};
+
+static void __init comet_init(void)
+{
+ char __iomem *cpld_base;
+ int per_enable;
+ int ext_per_enable;
+
+ cpld_base = comet_cpld_base();
+
+ if (!cpld_base)
+ return;
+
+ cpld_version = (readw(cpld_base + COMET_CPLD_VERSION) &
+ COMET_CPLD_VERSION_MAJOR) >> 8;
+ if (cpld_version >= 2) {
+ cpld_info = &comet_cpld[1];
+ per_enable = cpld_info->per_enable_all;
+ wvga_present = (readw(cpld_base + COMET_CPLD_STATUS)
+ & COMET_CPLD_STATUS_WVGA) != 0;
+ wxga_present = !wvga_present;
+ ext_per_enable = cpld_info->ext_per_enable_all;
+ if (wvga_present)
+ per_enable |= COMET_CPLD_PER_ENABLE_WVGA;
+ else {
+ per_enable |= COMET_CPLD_PER_ENABLE_LVDS |
+ COMET_CPLD_PER_ENABLE_WXGA;
+ ext_per_enable |= COMET_CPLD_EXT_PER_ENABLE_WXGA;
+ }
+ writew(ext_per_enable,
+ cpld_base + COMET_CPLD_EXT_PER_ENABLE);
+ writew(cpld_info->i2c_enable,
+ cpld_base + COMET_CPLD_I2C_ENABLE);
+ writew(cpld_info->ext_per_reset_all_reset,
+ cpld_base + COMET_CPLD_EXT_PER_RESET);
+ } else {
+ cpld_info = &comet_cpld[0];
+ wvga_present = 1;
+ wxga_present = 0;
+ per_enable = cpld_info->per_enable_all;
+ smc911x_resources[0].start = 0x90000000;
+ smc911x_resources[0].end = 0x90000100;
+ }
+
+ writew(per_enable,
+ cpld_base + COMET_CPLD_PER_ENABLE);
+ writew(cpld_info->per_reset_all_reset,
+ cpld_base + COMET_CPLD_PER_RESET);
+
+ platform_add_devices(devices, ARRAY_SIZE(devices));
+ msm_pm_set_platform_data(msm_pm_data);
+}
+
+static void __init comet_map_io(void)
+{
+ msm_map_comet_io();
+ msm_clock_init(msm_clocks_8x50, msm_num_clocks_8x50);
+}
+
+MACHINE_START(QSD8X50_COMET, "QCT QSD8x50 Comet")
+#ifdef CONFIG_MSM_DEBUG_UART
+ .phys_io = MSM_DEBUG_UART_PHYS,
+ .io_pg_offst = ((MSM_DEBUG_UART_BASE) >> 18) & 0xfffc,
+#endif
+ .boot_params = 0x0,
+ .map_io = comet_map_io,
+ .init_irq = comet_init_irq,
+ .init_machine = comet_init,
+ .timer = &msm_timer,
+MACHINE_END