/* * Copyright (C) 2007 Google, Inc. * Copyright (c) 2008-2012, The Linux Foundation. All rights reserved. * Author: Brian Swetland * * This software is licensed under the terms of the GNU General Public * License version 2, as published by the Free Software Foundation, and * may be copied, distributed, and modified under those terms. * * 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. * */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef CONFIG_CACHE_L2X0 #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef CONFIG_USB_G_ANDROID #include #include #endif #include "board-msm7627-regulator.h" #include "devices.h" #include "clock.h" #include "msm-keypad-devices.h" #include "pm.h" #include "pm-boot.h" #ifdef CONFIG_ARCH_MSM7X25 #define MSM_PMEM_MDP_SIZE 0xb21000 #define MSM_PMEM_ADSP_SIZE 0x97b000 #define MSM_PMEM_AUDIO_SIZE 0x121000 #define MSM_FB_SIZE 0x200000 #define PMEM_KERNEL_EBI1_SIZE 0x64000 #endif #ifdef CONFIG_ARCH_MSM7X27 #define MSM_PMEM_MDP_SIZE 0x1B76000 #define MSM_PMEM_ADSP_SIZE 0xC8A000 #define MSM_PMEM_AUDIO_SIZE 0x5B000 #ifdef CONFIG_FB_MSM_TRIPLE_BUFFER #define MSM_FB_SIZE 0x233000 #else #define MSM_FB_SIZE 0x177000 #endif #define PMEM_KERNEL_EBI1_SIZE 0x1C000 #endif #define ADSP_RPC_PROG 0x3000000a static struct resource smc91x_resources[] = { [0] = { .start = 0x9C004300, .end = 0x9C0043ff, .flags = IORESOURCE_MEM, }, [1] = { .start = MSM_GPIO_TO_INT(132), .end = MSM_GPIO_TO_INT(132), .flags = IORESOURCE_IRQ, }, }; static struct platform_device smc91x_device = { .name = "smc91x", .id = 0, .num_resources = ARRAY_SIZE(smc91x_resources), .resource = smc91x_resources, }; #ifdef CONFIG_USB_G_ANDROID static struct android_usb_platform_data android_usb_pdata = { .update_pid_and_serial_num = usb_diag_update_pid_and_serial_num, }; static struct platform_device android_usb_device = { .name = "android_usb", .id = -1, .dev = { .platform_data = &android_usb_pdata, }, }; #endif #ifdef CONFIG_USB_EHCI_MSM_72K static void msm_hsusb_vbus_power(unsigned phy_info, int on) { if (on) msm_hsusb_vbus_powerup(); else msm_hsusb_vbus_shutdown(); } static struct msm_usb_host_platform_data msm_usb_host_pdata = { .phy_info = (USB_PHY_INTEGRATED | USB_PHY_MODEL_65NM), }; static void __init msm7x2x_init_host(void) { if (machine_is_msm7x25_ffa() || machine_is_msm7x27_ffa()) return; msm_add_host(0, &msm_usb_host_pdata); } #endif #define SND(desc, num) { .name = #desc, .id = num } static struct snd_endpoint snd_endpoints_list[] = { SND(HANDSET, 0), SND(MONO_HEADSET, 2), SND(HEADSET, 3), SND(SPEAKER, 6), SND(TTY_HEADSET, 8), SND(TTY_VCO, 9), SND(TTY_HCO, 10), SND(BT, 12), SND(IN_S_SADC_OUT_HANDSET, 16), SND(IN_S_SADC_OUT_SPEAKER_PHONE, 25), SND(CURRENT, 27), }; #undef SND static struct msm_snd_endpoints msm_device_snd_endpoints = { .endpoints = snd_endpoints_list, .num = sizeof(snd_endpoints_list) / sizeof(struct snd_endpoint) }; static struct platform_device msm_device_snd = { .name = "msm_snd", .id = -1, .dev = { .platform_data = &msm_device_snd_endpoints }, }; #define DEC0_FORMAT ((1< 0; i--) regulator_put(vreg[i - 1]); return rc; vreg_lcdc_fail: if (on) { for (; i > 0; i--) regulator_disable(vreg[i - 1]); } else { for (; i > 0; i--) regulator_enable(vreg[i - 1]); } return rc; } static struct lcdc_platform_data lcdc_pdata = { .lcdc_gpio_config = msm_fb_lcdc_config, .lcdc_power_save = msm_fb_lcdc_power_save, }; static struct msm_panel_common_pdata lcdc_gordon_panel_data = { .panel_config_gpio = lcdc_gordon_config_gpios, .gpio_num = gpio_array_num, }; static struct platform_device lcdc_gordon_panel_device = { .name = "lcdc_gordon_vga", .id = 0, .dev = { .platform_data = &lcdc_gordon_panel_data, } }; static struct resource msm_fb_resources[] = { { .flags = IORESOURCE_DMA, } }; static int msm_fb_detect_panel(const char *name) { int ret = -EPERM; if (machine_is_msm7x25_ffa() || machine_is_msm7x27_ffa()) { if (!strcmp(name, "lcdc_gordon_vga")) ret = 0; else ret = -ENODEV; } return ret; } static struct msm_fb_platform_data msm_fb_pdata = { .detect_client = msm_fb_detect_panel, .mddi_prescan = 1, }; 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, } }; #ifdef CONFIG_BT static struct platform_device msm_bt_power_device = { .name = "bt_power", }; enum { BT_WAKE, BT_RFR, BT_CTS, BT_RX, BT_TX, BT_PCM_DOUT, BT_PCM_DIN, BT_PCM_SYNC, BT_PCM_CLK, BT_HOST_WAKE, }; static unsigned bt_config_power_on[] = { GPIO_CFG(42, 0, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), /* WAKE */ GPIO_CFG(43, 2, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), /* RFR */ GPIO_CFG(44, 2, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), /* CTS */ GPIO_CFG(45, 2, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), /* Rx */ GPIO_CFG(46, 3, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), /* Tx */ GPIO_CFG(68, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), /* PCM_DOUT */ GPIO_CFG(69, 1, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), /* PCM_DIN */ GPIO_CFG(70, 2, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), /* PCM_SYNC */ GPIO_CFG(71, 2, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), /* PCM_CLK */ GPIO_CFG(83, 0, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), /* HOST_WAKE */ }; static unsigned bt_config_power_off[] = { GPIO_CFG(42, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), /* WAKE */ GPIO_CFG(43, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), /* RFR */ GPIO_CFG(44, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), /* CTS */ GPIO_CFG(45, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), /* Rx */ GPIO_CFG(46, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), /* Tx */ GPIO_CFG(68, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), /* PCM_DOUT */ GPIO_CFG(69, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), /* PCM_DIN */ GPIO_CFG(70, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), /* PCM_SYNC */ GPIO_CFG(71, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), /* PCM_CLK */ GPIO_CFG(83, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), /* HOST_WAKE */ }; static int bluetooth_power(int on) { int pin, rc; static struct regulator *vreg_bt; printk(KERN_DEBUG "%s\n", __func__); /* do not have vreg bt defined, gp6 is the same */ /* vreg_get parameter 1 (struct device *) is ignored */ if (on) { for (pin = 0; pin < ARRAY_SIZE(bt_config_power_on); pin++) { rc = gpio_tlmm_config(bt_config_power_on[pin], GPIO_CFG_ENABLE); if (rc) { printk(KERN_ERR "%s: gpio_tlmm_config(%#x)=%d\n", __func__, bt_config_power_on[pin], rc); return -EIO; } } vreg_bt = regulator_get(NULL, "gp6"); if (IS_ERR(vreg_bt)) { rc = PTR_ERR(vreg_bt); pr_err("%s: could get not regulator: %d\n", __func__, rc); goto out; } /* units of mV, steps of 50 mV */ rc = regulator_set_voltage(vreg_bt, 2600000, 2600000); if (rc < 0) { pr_err("%s: could not set voltage: %d\n", __func__, rc); goto bt_vreg_fail; } rc = regulator_enable(vreg_bt); if (rc < 0) { pr_err("%s: could not enable regulator: %d\n", __func__, rc); goto bt_vreg_fail; } } else { rc = regulator_disable(vreg_bt); if (rc < 0) { pr_err("%s: could not disable regulator: %d\n", __func__, rc); goto bt_vreg_fail; } regulator_put(vreg_bt); for (pin = 0; pin < ARRAY_SIZE(bt_config_power_off); pin++) { rc = gpio_tlmm_config(bt_config_power_off[pin], GPIO_CFG_ENABLE); if (rc) { printk(KERN_ERR "%s: gpio_tlmm_config(%#x)=%d\n", __func__, bt_config_power_off[pin], rc); return -EIO; } } } return 0; bt_vreg_fail: regulator_put(vreg_bt); out: return rc; } static void __init bt_power_init(void) { msm_bt_power_device.dev.platform_data = &bluetooth_power; } #else #define bt_power_init(x) do {} while (0) #endif static struct platform_device msm_device_pmic_leds = { .name = "pmic-leds", .id = -1, }; static struct resource bluesleep_resources[] = { { .name = "gpio_host_wake", .start = 83, .end = 83, .flags = IORESOURCE_IO, }, { .name = "gpio_ext_wake", .start = 42, .end = 42, .flags = IORESOURCE_IO, }, { .name = "host_wake", .start = MSM_GPIO_TO_INT(83), .end = MSM_GPIO_TO_INT(83), .flags = IORESOURCE_IRQ, }, }; static struct platform_device msm_bluesleep_device = { .name = "bluesleep", .id = -1, .num_resources = ARRAY_SIZE(bluesleep_resources), .resource = bluesleep_resources, }; static struct i2c_board_info i2c_devices[] = { #if defined(CONFIG_SENSORS_MT9T013) { I2C_BOARD_INFO("mt9t013", 0x6C), }, #endif }; static u32 msm_calculate_batt_capacity(u32 current_voltage); static struct msm_psy_batt_pdata msm_psy_batt_data = { .voltage_min_design = 2800, .voltage_max_design = 4300, .avail_chg_sources = AC_CHG | USB_CHG , .batt_technology = POWER_SUPPLY_TECHNOLOGY_LION, .calculate_capacity = &msm_calculate_batt_capacity, }; static u32 msm_calculate_batt_capacity(u32 current_voltage) { u32 low_voltage = msm_psy_batt_data.voltage_min_design; u32 high_voltage = msm_psy_batt_data.voltage_max_design; return (current_voltage - low_voltage) * 100 / (high_voltage - low_voltage); } static struct platform_device msm_batt_device = { .name = "msm-battery", .id = -1, .dev.platform_data = &msm_psy_batt_data, }; static struct platform_device *devices[] __initdata = { &asoc_msm_pcm, &asoc_msm_dai0, &asoc_msm_dai1, &msm_device_smd, &msm_device_dmov, &msm_device_nand, #ifdef CONFIG_USB_G_ANDROID &android_usb_device, #endif &msm_device_i2c, &smc91x_device, &msm_device_tssc, &android_pmem_device, &android_pmem_adsp_device, &android_pmem_audio_device, &msm_fb_device, &lcdc_gordon_panel_device, &msm_device_uart_dm1, #ifdef CONFIG_BT &msm_bt_power_device, #endif &msm_device_pmic_leds, &msm_device_snd, &msm_device_adspdec, &msm_bluesleep_device, #ifdef CONFIG_ARCH_MSM7X27 &msm_kgsl_3d0, #endif #if defined(CONFIG_TSIF) || defined(CONFIG_TSIF_MODULE) &msm_device_tsif, #endif &hs_device, &msm_batt_device, }; static struct msm_panel_common_pdata mdp_pdata = { .gpio = 97, .mdp_rev = MDP_REV_30, }; static void __init msm_fb_add_devices(void) { msm_fb_register_device("mdp", &mdp_pdata); msm_fb_register_device("pmdh", 0); msm_fb_register_device("lcdc", &lcdc_pdata); } extern struct sys_timer msm_timer; static void __init msm7x2x_init_irq(void) { msm_init_irq(); } void msm_serial_debug_init(unsigned int base, int irq, struct device *clk_device, int signal_irq); #if (defined(CONFIG_MMC_MSM_SDC1_SUPPORT)\ || defined(CONFIG_MMC_MSM_SDC2_SUPPORT)\ || defined(CONFIG_MMC_MSM_SDC3_SUPPORT)\ || defined(CONFIG_MMC_MSM_SDC4_SUPPORT)) static unsigned long vreg_sts, gpio_sts; static struct regulator *vreg_mmc; static unsigned mpp_mmc = 2; struct sdcc_gpio { struct msm_gpio *cfg_data; uint32_t size; struct msm_gpio *sleep_cfg_data; }; static struct msm_gpio sdc1_cfg_data[] = { {GPIO_CFG(51, 1, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_8MA), "sdc1_dat_3"}, {GPIO_CFG(52, 1, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_8MA), "sdc1_dat_2"}, {GPIO_CFG(53, 1, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_8MA), "sdc1_dat_1"}, {GPIO_CFG(54, 1, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_8MA), "sdc1_dat_0"}, {GPIO_CFG(55, 1, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_8MA), "sdc1_cmd"}, {GPIO_CFG(56, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_8MA), "sdc1_clk"}, }; static struct msm_gpio sdc2_cfg_data[] = { {GPIO_CFG(62, 2, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_8MA), "sdc2_clk"}, {GPIO_CFG(63, 2, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_8MA), "sdc2_cmd"}, {GPIO_CFG(64, 2, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_8MA), "sdc2_dat_3"}, {GPIO_CFG(65, 2, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_8MA), "sdc2_dat_2"}, {GPIO_CFG(66, 2, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_8MA), "sdc2_dat_1"}, {GPIO_CFG(67, 2, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_8MA), "sdc2_dat_0"}, }; static struct msm_gpio sdc2_sleep_cfg_data[] = { {GPIO_CFG(62, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), "sdc2_clk"}, {GPIO_CFG(63, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), "sdc2_cmd"}, {GPIO_CFG(64, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), "sdc2_dat_3"}, {GPIO_CFG(65, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), "sdc2_dat_2"}, {GPIO_CFG(66, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), "sdc2_dat_1"}, {GPIO_CFG(67, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), "sdc2_dat_0"}, }; static struct msm_gpio sdc3_cfg_data[] = { {GPIO_CFG(88, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_8MA), "sdc3_clk"}, {GPIO_CFG(89, 1, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_8MA), "sdc3_cmd"}, {GPIO_CFG(90, 1, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_8MA), "sdc3_dat_3"}, {GPIO_CFG(91, 1, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_8MA), "sdc3_dat_2"}, {GPIO_CFG(92, 1, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_8MA), "sdc3_dat_1"}, {GPIO_CFG(93, 1, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_8MA), "sdc3_dat_0"}, }; static struct msm_gpio sdc4_cfg_data[] = { {GPIO_CFG(19, 3, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_8MA), "sdc4_dat_3"}, {GPIO_CFG(20, 3, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_8MA), "sdc4_dat_2"}, {GPIO_CFG(21, 4, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_8MA), "sdc4_dat_1"}, {GPIO_CFG(107, 1, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_8MA), "sdc4_cmd"}, {GPIO_CFG(108, 1, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_8MA), "sdc4_dat_0"}, {GPIO_CFG(109, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_8MA), "sdc4_clk"}, }; static struct sdcc_gpio sdcc_cfg_data[] = { { .cfg_data = sdc1_cfg_data, .size = ARRAY_SIZE(sdc1_cfg_data), .sleep_cfg_data = NULL, }, { .cfg_data = sdc2_cfg_data, .size = ARRAY_SIZE(sdc2_cfg_data), .sleep_cfg_data = sdc2_sleep_cfg_data, }, { .cfg_data = sdc3_cfg_data, .size = ARRAY_SIZE(sdc3_cfg_data), .sleep_cfg_data = NULL, }, { .cfg_data = sdc4_cfg_data, .size = ARRAY_SIZE(sdc4_cfg_data), .sleep_cfg_data = NULL, }, }; static void msm_sdcc_setup_gpio(int dev_id, unsigned int enable) { int rc = 0; struct sdcc_gpio *curr; curr = &sdcc_cfg_data[dev_id - 1]; if (!(test_bit(dev_id, &gpio_sts)^enable)) return; if (enable) { set_bit(dev_id, &gpio_sts); rc = msm_gpios_request_enable(curr->cfg_data, curr->size); if (rc) printk(KERN_ERR "%s: Failed to turn on GPIOs for slot %d\n", __func__, dev_id); } else { clear_bit(dev_id, &gpio_sts); if (curr->sleep_cfg_data) { msm_gpios_enable(curr->sleep_cfg_data, curr->size); msm_gpios_free(curr->sleep_cfg_data, curr->size); return; } msm_gpios_disable_free(curr->cfg_data, curr->size); } } 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) { if (machine_is_msm7x25_ffa() || machine_is_msm7x27_ffa()) { rc = mpp_config_digital_out(mpp_mmc, MPP_CFG(MPP_DLOGIC_LVL_MSMP, MPP_DLOGIC_OUT_CTRL_LOW)); } else rc = regulator_disable(vreg_mmc); if (rc) { pr_err("%s: return val: %d\n", __func__, rc); } } return 0; } if (!vreg_sts) { if (machine_is_msm7x25_ffa() || machine_is_msm7x27_ffa()) { rc = mpp_config_digital_out(mpp_mmc, MPP_CFG(MPP_DLOGIC_LVL_MSMP, MPP_DLOGIC_OUT_CTRL_HIGH)); } else { rc = regulator_set_voltage(vreg_mmc, 2850000, 2850000); if (!rc) rc = regulator_enable(vreg_mmc); } if (rc) { pr_err("%s: return val: %d\n", __func__, rc); } } set_bit(pdev->id, &vreg_sts); return 0; } #ifdef CONFIG_MMC_MSM_SDC1_SUPPORT static struct mmc_platform_data msm7x2x_sdc1_data = { .ocr_mask = MMC_VDD_28_29, .translate_vdd = msm_sdcc_setup_power, .mmc_bus_width = MMC_CAP_4_BIT_DATA, .msmsdcc_fmin = 144000, .msmsdcc_fmid = 24576000, .msmsdcc_fmax = 49152000, .nonremovable = 0, }; #endif #ifdef CONFIG_MMC_MSM_SDC2_SUPPORT static struct mmc_platform_data msm7x2x_sdc2_data = { .ocr_mask = MMC_VDD_28_29, .translate_vdd = msm_sdcc_setup_power, .mmc_bus_width = MMC_CAP_4_BIT_DATA, .sdiowakeup_irq = MSM_GPIO_TO_INT(66), .msmsdcc_fmin = 144000, .msmsdcc_fmid = 24576000, .msmsdcc_fmax = 49152000, .nonremovable = 0, }; #endif #ifdef CONFIG_MMC_MSM_SDC3_SUPPORT static struct mmc_platform_data msm7x2x_sdc3_data = { .ocr_mask = MMC_VDD_28_29, .translate_vdd = msm_sdcc_setup_power, .mmc_bus_width = MMC_CAP_4_BIT_DATA, .msmsdcc_fmin = 144000, .msmsdcc_fmid = 24576000, .msmsdcc_fmax = 49152000, .nonremovable = 0, }; #endif #ifdef CONFIG_MMC_MSM_SDC4_SUPPORT static struct mmc_platform_data msm7x2x_sdc4_data = { .ocr_mask = MMC_VDD_28_29, .translate_vdd = msm_sdcc_setup_power, .mmc_bus_width = MMC_CAP_4_BIT_DATA, .msmsdcc_fmin = 144000, .msmsdcc_fmid = 24576000, .msmsdcc_fmax = 49152000, .nonremovable = 0, }; #endif static void __init msm7x2x_init_mmc(void) { if (!machine_is_msm7x25_ffa() && !machine_is_msm7x27_ffa()) { vreg_mmc = regulator_get(NULL, "mmc"); if (IS_ERR(vreg_mmc)) { pr_err("%s: could not get regulator: %ld\n", __func__, PTR_ERR(vreg_mmc)); } } #ifdef CONFIG_MMC_MSM_SDC1_SUPPORT msm_add_sdcc(1, &msm7x2x_sdc1_data); #endif if (machine_is_msm7x25_surf() || machine_is_msm7x27_surf() || machine_is_msm7x27_ffa()) { #ifdef CONFIG_MMC_MSM_SDC2_SUPPORT msm_sdcc_setup_gpio(2, 1); msm_add_sdcc(2, &msm7x2x_sdc2_data); #endif } if (machine_is_msm7x25_surf() || machine_is_msm7x27_surf()) { #ifdef CONFIG_MMC_MSM_SDC3_SUPPORT msm_add_sdcc(3, &msm7x2x_sdc3_data); #endif #ifdef CONFIG_MMC_MSM_SDC4_SUPPORT msm_add_sdcc(4, &msm7x2x_sdc4_data); #endif } } #else #define msm7x2x_init_mmc() do {} while (0) #endif static struct msm_pm_platform_data msm7x25_pm_data[MSM_PM_SLEEP_MODE_NR] = { [MSM_PM_MODE(0, MSM_PM_SLEEP_MODE_POWER_COLLAPSE)].latency = 16000, [MSM_PM_MODE(0, MSM_PM_SLEEP_MODE_POWER_COLLAPSE_NO_XO_SHUTDOWN)] .latency = 12000, [MSM_PM_MODE(0, MSM_PM_SLEEP_MODE_RAMP_DOWN_AND_WAIT_FOR_INTERRUPT)] .latency = 2000, }; static struct msm_pm_platform_data msm7x27_pm_data[MSM_PM_SLEEP_MODE_NR] = { [MSM_PM_MODE(0, MSM_PM_SLEEP_MODE_POWER_COLLAPSE)] = { .idle_supported = 1, .suspend_supported = 1, .idle_enabled = 1, .suspend_enabled = 1, .latency = 16000, .residency = 20000, }, [MSM_PM_MODE(0, MSM_PM_SLEEP_MODE_POWER_COLLAPSE_NO_XO_SHUTDOWN)] = { .idle_supported = 1, .suspend_supported = 1, .idle_enabled = 1, .suspend_enabled = 1, .latency = 12000, .residency = 20000, }, [MSM_PM_MODE(0, MSM_PM_SLEEP_MODE_RAMP_DOWN_AND_WAIT_FOR_INTERRUPT)] = { .idle_supported = 1, .suspend_supported = 1, .idle_enabled = 1, .suspend_enabled = 1, .latency = 2000, .residency = 0, }, }; static struct msm_pm_boot_platform_data msm_pm_boot_pdata __initdata = { .mode = MSM_PM_BOOT_CONFIG_RESET_VECTOR_PHYS, .p_addr = 0, }; static void msm_i2c_gpio_config(int iface, int config_type) { int gpio_scl; int gpio_sda; if (iface) { gpio_scl = 95; gpio_sda = 96; } else { gpio_scl = 60; gpio_sda = 61; } if (config_type) { gpio_tlmm_config(GPIO_CFG(gpio_scl, 1, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_16MA), GPIO_CFG_ENABLE); gpio_tlmm_config(GPIO_CFG(gpio_sda, 1, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_16MA), GPIO_CFG_ENABLE); } else { gpio_tlmm_config(GPIO_CFG(gpio_scl, 0, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_16MA), GPIO_CFG_ENABLE); gpio_tlmm_config(GPIO_CFG(gpio_sda, 0, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_16MA), GPIO_CFG_ENABLE); } } static struct msm_i2c_platform_data msm_i2c_pdata = { .clk_freq = 100000, .rmutex = 0, .pri_clk = 60, .pri_dat = 61, .aux_clk = 95, .aux_dat = 96, .msm_i2c_config_gpio = msm_i2c_gpio_config, }; static struct platform_device msm_proccomm_regulator_dev = { .name = PROCCOMM_REGULATOR_DEV_NAME, .id = -1, .dev = { .platform_data = &msm7627_proccomm_regulator_data } }; static void __init msm7627_init_regulators(void) { int rc = platform_device_register(&msm_proccomm_regulator_dev); if (rc) pr_err("%s: could not register regulator device: %d\n", __func__, rc); } static void __init msm_device_i2c_init(void) { if (gpio_request(60, "i2c_pri_clk")) pr_err("failed to request gpio i2c_pri_clk\n"); if (gpio_request(61, "i2c_pri_dat")) pr_err("failed to request gpio i2c_pri_dat\n"); if (gpio_request(95, "i2c_sec_clk")) pr_err("failed to request gpio i2c_sec_clk\n"); if (gpio_request(96, "i2c_sec_dat")) pr_err("failed to request gpio i2c_sec_dat\n"); if (cpu_is_msm7x27()) msm_i2c_pdata.pm_lat = msm7x27_pm_data[MSM_PM_SLEEP_MODE_POWER_COLLAPSE_NO_XO_SHUTDOWN] .latency; else msm_i2c_pdata.pm_lat = msm7x25_pm_data[MSM_PM_SLEEP_MODE_POWER_COLLAPSE_NO_XO_SHUTDOWN] .latency; msm_device_i2c.dev.platform_data = &msm_i2c_pdata; } static void usb_mpp_init(void) { unsigned rc; unsigned mpp_usb = 7; if (machine_is_msm7x25_ffa() || machine_is_msm7x27_ffa()) { rc = mpp_config_digital_out(mpp_usb, MPP_CFG(MPP_DLOGIC_LVL_VDD, MPP_DLOGIC_OUT_CTRL_HIGH)); if (rc) pr_err("%s: configuring mpp pin" "to enable 3.3V LDO failed\n", __func__); } } static void msm7x27_wlan_init(void) { int rc = 0; /* TBD: if (machine_is_msm7x27_ffa_with_wcn1312()) */ if (machine_is_msm7x27_ffa()) { rc = mpp_config_digital_out(3, MPP_CFG(MPP_DLOGIC_LVL_MSMP, MPP_DLOGIC_OUT_CTRL_LOW)); if (rc) printk(KERN_ERR "%s: return val: %d \n", __func__, rc); } } static void msm_adsp_add_pdev(void) { int rc = 0; struct rpc_board_dev *rpc_adsp_pdev; rpc_adsp_pdev = kzalloc(sizeof(struct rpc_board_dev), GFP_KERNEL); if (rpc_adsp_pdev == NULL) { pr_err("%s: Memory Allocation failure\n", __func__); return; } rpc_adsp_pdev->prog = ADSP_RPC_PROG; rpc_adsp_pdev->pdev = msm_adsp_device; rc = msm_rpc_add_board_dev(rpc_adsp_pdev, 1); if (rc < 0) { pr_err("%s: return val: %d\n", __func__, rc); kfree(rpc_adsp_pdev); } } static void __init msm7x2x_init(void) { msm7627_init_regulators(); #ifdef CONFIG_ARCH_MSM7X25 msm_clock_init(msm_clocks_7x25, msm_num_clocks_7x25); #elif defined(CONFIG_ARCH_MSM7X27) msm_clock_init(&msm7x27_clock_init_data); #endif #if defined(CONFIG_SMC91X) if (machine_is_msm7x25_ffa() || machine_is_msm7x27_ffa()) { smc91x_resources[0].start = 0x98000300; smc91x_resources[0].end = 0x980003ff; smc91x_resources[1].start = MSM_GPIO_TO_INT(85); smc91x_resources[1].end = MSM_GPIO_TO_INT(85); if (gpio_tlmm_config(GPIO_CFG(85, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), GPIO_CFG_ENABLE)) { printk(KERN_ERR "%s: Err: Config GPIO-85 INT\n", __func__); } } #endif platform_device_register(&msm7x27_device_acpuclk); usb_mpp_init(); #if defined(CONFIG_TSIF) || defined(CONFIG_TSIF_MODULE) msm_device_tsif.dev.platform_data = &tsif_platform_data; #endif platform_add_devices(msm_footswitch_devices, msm_num_footswitch_devices); platform_add_devices(devices, ARRAY_SIZE(devices)); msm_adsp_add_pdev(); msm_device_i2c_init(); i2c_register_board_info(0, i2c_devices, ARRAY_SIZE(i2c_devices)); lcdc_gordon_gpio_init(); msm_fb_add_devices(); #ifdef CONFIG_USB_EHCI_MSM_72K msm7x2x_init_host(); #endif msm7x2x_init_mmc(); bt_power_init(); if (cpu_is_msm7x27()) msm_pm_set_platform_data(msm7x27_pm_data, ARRAY_SIZE(msm7x27_pm_data)); else msm_pm_set_platform_data(msm7x25_pm_data, ARRAY_SIZE(msm7x25_pm_data)); BUG_ON(msm_pm_boot_init(&msm_pm_boot_pdata)); msm7x27_wlan_init(); } static unsigned pmem_kernel_ebi1_size = PMEM_KERNEL_EBI1_SIZE; static int __init pmem_kernel_ebi1_size_setup(char *p) { pmem_kernel_ebi1_size = memparse(p, NULL); return 0; } early_param("pmem_kernel_ebi1_size", pmem_kernel_ebi1_size_setup); static unsigned pmem_mdp_size = MSM_PMEM_MDP_SIZE; static int __init pmem_mdp_size_setup(char *p) { pmem_mdp_size = memparse(p, NULL); return 0; } early_param("pmem_mdp_size", pmem_mdp_size_setup); static unsigned pmem_adsp_size = MSM_PMEM_ADSP_SIZE; static int __init pmem_adsp_size_setup(char *p) { pmem_adsp_size = memparse(p, NULL); return 0; } early_param("pmem_adsp_size", pmem_adsp_size_setup); static unsigned pmem_audio_size = MSM_PMEM_AUDIO_SIZE; static int __init pmem_audio_size_setup(char *p) { pmem_audio_size = memparse(p, NULL); return 0; } early_param("pmem_audio_size", pmem_audio_size_setup); static unsigned fb_size = MSM_FB_SIZE; static int __init fb_size_setup(char *p) { fb_size = memparse(p, NULL); return 0; } early_param("fb_size", fb_size_setup); static void __init msm_msm7x2x_allocate_memory_regions(void) { void *addr; unsigned long size; size = fb_size ? : MSM_FB_SIZE; addr = alloc_bootmem_align(size, 0x1000); msm_fb_resources[0].start = __pa(addr); msm_fb_resources[0].end = msm_fb_resources[0].start + size - 1; pr_info("allocating %lu bytes at %p (%lx physical) for fb\n", size, addr, __pa(addr)); } static struct memtype_reserve msm7x27_reserve_table[] __initdata = { [MEMTYPE_SMI] = { }, [MEMTYPE_EBI0] = { .flags = MEMTYPE_FLAGS_1M_ALIGN, }, [MEMTYPE_EBI1] = { .flags = MEMTYPE_FLAGS_1M_ALIGN, }, }; static void __init size_pmem_devices(void) { } static void __init reserve_memory_for(struct android_pmem_platform_data *p) { msm7x27_reserve_table[p->memory_type].size += p->size; } static void __init reserve_pmem_memory(void) { } static void __init msm7x27_calculate_reserve_sizes(void) { size_pmem_devices(); reserve_pmem_memory(); } static int msm7x27_paddr_to_memtype(unsigned int paddr) { return MEMTYPE_EBI1; } static struct reserve_info msm7x27_reserve_info __initdata = { .memtype_reserve_table = msm7x27_reserve_table, .calculate_reserve_sizes = msm7x27_calculate_reserve_sizes, .paddr_to_memtype = msm7x27_paddr_to_memtype, }; static void __init msm7x27_reserve(void) { reserve_info = &msm7x27_reserve_info; msm_reserve(); } static void __init msm7x27_init_early(void) { msm_msm7x2x_allocate_memory_regions(); } static void __init msm7x2x_map_io(void) { msm_map_common_io(); if (socinfo_init() < 0) BUG(); #ifdef CONFIG_CACHE_L2X0 if (machine_is_msm7x27_surf() || machine_is_msm7x27_ffa()) { /* 7x27 has 256KB L2 cache: 64Kb/Way and 4-Way Associativity; evmon/parity/share disabled. */ if ((SOCINFO_VERSION_MAJOR(socinfo_get_version()) > 1) || ((SOCINFO_VERSION_MAJOR(socinfo_get_version()) == 1) && (SOCINFO_VERSION_MINOR(socinfo_get_version()) >= 3))) /* R/W latency: 4 cycles; */ l2x0_init(MSM_L2CC_BASE, 0x0006801B, 0xfe000000); else /* R/W latency: 3 cycles; */ l2x0_init(MSM_L2CC_BASE, 0x00068012, 0xfe000000); } #endif } static void __init msm7x2x_init_late(void) { smd_debugfs_init(); } MACHINE_START(MSM7X27_SURF, "QCT MSM7x27 SURF") .atag_offset = 0x100, .map_io = msm7x2x_map_io, .reserve = msm7x27_reserve, .init_irq = msm7x2x_init_irq, .init_machine = msm7x2x_init, .init_late = msm7x2x_init_late, .timer = &msm_timer, .init_early = msm7x27_init_early, .handle_irq = vic_handle_irq, MACHINE_END MACHINE_START(MSM7X27_FFA, "QCT MSM7x27 FFA") .atag_offset = 0x100, .map_io = msm7x2x_map_io, .reserve = msm7x27_reserve, .init_irq = msm7x2x_init_irq, .init_machine = msm7x2x_init, .init_late = msm7x2x_init_late, .timer = &msm_timer, .init_early = msm7x27_init_early, .handle_irq = vic_handle_irq, MACHINE_END MACHINE_START(MSM7X25_SURF, "QCT MSM7x25 SURF") .atag_offset = 0x100, .map_io = msm7x2x_map_io, .reserve = msm7x27_reserve, .init_irq = msm7x2x_init_irq, .init_machine = msm7x2x_init, .init_late = msm7x2x_init_late, .timer = &msm_timer, .init_early = msm7x27_init_early, .handle_irq = vic_handle_irq, MACHINE_END MACHINE_START(MSM7X25_FFA, "QCT MSM7x25 FFA") .atag_offset = 0x100, .map_io = msm7x2x_map_io, .reserve = msm7x27_reserve, .init_irq = msm7x2x_init_irq, .init_machine = msm7x2x_init, .init_late = msm7x2x_init_late, .timer = &msm_timer, .init_early = msm7x27_init_early, .handle_irq = vic_handle_irq, MACHINE_END