arm: tegra: enterprise: Add drivers for flashless XMM modem
Michael Hsu [Wed, 9 Nov 2011 20:43:06 +0000 (12:43 -0800)]
XMM modem requires GPIO power on sequence before modem
software can be downloaded to it.

BUG 828389

Reviewed-on: http://git-master/r/46801
(cherry picked from commit 675f98979d6c6a281631d6590be5c7b6e5352b6f)

Change-Id: I56847ff0c002b9b6858c16ecca1bb9e9b18e3a60
Reviewed-on: http://git-master/r/62772
Reviewed-by: Varun Colbert <vcolbert@nvidia.com>
Tested-by: Varun Colbert <vcolbert@nvidia.com>

Rebase-Id: Re8d8478d1c96ff6a405c19aaf5b8d14659134c2f

arch/arm/mach-tegra/board-enterprise-pinmux.c
arch/arm/mach-tegra/board-enterprise.c
arch/arm/mach-tegra/board-enterprise.h

index f448a54..d8f7e40 100644 (file)
@@ -202,15 +202,15 @@ static __initdata struct tegra_pingroup_config enterprise_pinmux[] = {
        DEFAULT_PINMUX(DAP3_SCLK,       I2S2,            NORMAL,    NORMAL,     INPUT),
        DEFAULT_PINMUX(GPIO_PV2,        RSVD1,           NORMAL,    NORMAL,     OUTPUT),
        DEFAULT_PINMUX(GPIO_PV3,        RSVD1,           NORMAL,    NORMAL,     OUTPUT),
-       DEFAULT_PINMUX(LCD_PWR1,        DISPLAYA,        NORMAL,    NORMAL,     INPUT),
+       DEFAULT_PINMUX(LCD_PWR1,        DISPLAYA,        NORMAL,    NORMAL,     OUTPUT),
        DEFAULT_PINMUX(LCD_PWR2,        DISPLAYA,        NORMAL,    NORMAL,     INPUT),
        DEFAULT_PINMUX(LCD_CS0_N,       DISPLAYA,        NORMAL,    NORMAL,     INPUT),
        DEFAULT_PINMUX(LCD_DC0,         DISPLAYA,        NORMAL,    NORMAL,     INPUT),
        DEFAULT_PINMUX(LCD_DE,          DISPLAYA,        NORMAL,    NORMAL,     INPUT),
-       DEFAULT_PINMUX(LCD_D0,          DISPLAYA,        NORMAL,    NORMAL,     INPUT),
-       DEFAULT_PINMUX(LCD_D1,          DISPLAYA,        NORMAL,    NORMAL,     INPUT),
+       DEFAULT_PINMUX(LCD_D0,          DISPLAYA,        NORMAL,    NORMAL,     OUTPUT),
+       DEFAULT_PINMUX(LCD_D1,          DISPLAYA,        NORMAL,    NORMAL,     OUTPUT),
        DEFAULT_PINMUX(LCD_D2,          DISPLAYA,        NORMAL,    NORMAL,     INPUT),
-       DEFAULT_PINMUX(LCD_D3,          DISPLAYA,        NORMAL,    NORMAL,     INPUT),
+       DEFAULT_PINMUX(LCD_D3,          DISPLAYA,        NORMAL,    NORMAL,     OUTPUT),
        DEFAULT_PINMUX(LCD_D4,          DISPLAYA,        NORMAL,    NORMAL,     INPUT),
        DEFAULT_PINMUX(LCD_D5,          DISPLAYA,        NORMAL,    NORMAL,     INPUT),
        DEFAULT_PINMUX(LCD_D6,          RSVD1,           NORMAL,    NORMAL,     INPUT),
@@ -255,7 +255,7 @@ static __initdata struct tegra_pingroup_config enterprise_pinmux[] = {
        DEFAULT_PINMUX(GPIO_PU1,        UARTA,           NORMAL,    NORMAL,     INPUT),
        DEFAULT_PINMUX(GPIO_PU2,        UARTA,           NORMAL,    NORMAL,     INPUT),
        DEFAULT_PINMUX(GPIO_PU3,        UARTA,           NORMAL,    NORMAL,     OUTPUT),
-       DEFAULT_PINMUX(GPIO_PU5,        PWM2,            NORMAL,    NORMAL,     OUTPUT),
+       DEFAULT_PINMUX(GPIO_PU5,        PWM2,            NORMAL,    NORMAL,     INPUT),
        DEFAULT_PINMUX(GPIO_PU6,        RSVD1,           NORMAL,    NORMAL,     INPUT),
        DEFAULT_PINMUX(DAP4_FS,         I2S3,            NORMAL,    NORMAL,     INPUT),
        DEFAULT_PINMUX(DAP4_DIN,        I2S3,            NORMAL,    NORMAL,     INPUT),
index e36ed2d..5a9cc3d 100644 (file)
@@ -57,6 +57,7 @@
 #include "board.h"
 #include "clock.h"
 #include "board-enterprise.h"
+#include "baseband-xmm-power.h"
 #include "devices.h"
 #include "gpio-names.h"
 #include "fuse.h"
@@ -678,6 +679,23 @@ static struct usb_phy_plat_data tegra_usb_phy_pdata[] = {
        },
 };
 
+static struct tegra_uhsic_config uhsic_phy_config = {
+       .enable_gpio = -1,
+       .reset_gpio = -1,
+       .sync_start_delay = 9,
+       .idle_wait_delay = 17,
+       .term_range_adj = 0,
+       .elastic_underrun_limit = 16,
+       .elastic_overrun_limit = 16,
+};
+
+static struct tegra_ehci_platform_data tegra_ehci_uhsic_pdata = {
+       .phy_type = TEGRA_USB_PHY_TYPE_HSIC,
+       .phy_config = &uhsic_phy_config,
+       .operating_mode = TEGRA_USB_HOST,
+       .power_down_on_bus_suspend = 1,
+};
+
 static struct tegra_ehci_platform_data tegra_ehci_pdata[] = {
        [0] = {
                        .phy_config = &utmi_phy_config[0],
@@ -704,6 +722,42 @@ static struct tegra_otg_platform_data tegra_otg_pdata = {
        .ehci_pdata = &tegra_ehci_pdata[0],
 };
 
+static int enterprise_usb_hsic_postsupend(void)
+{
+       pr_debug("%s\n", __func__);
+#ifdef CONFIG_TEGRA_BB_XMM_POWER
+       baseband_xmm_set_power_status(BBXMM_PS_L2);
+#endif
+       return 0;
+}
+
+static int enterprise_usb_hsic_preresume(void)
+{
+       pr_debug("%s\n", __func__);
+#ifdef CONFIG_TEGRA_BB_XMM_POWER
+       baseband_xmm_set_power_status(BBXMM_PS_L2TOL0);
+#endif
+       return 0;
+}
+
+static int enterprise_usb_hsic_phy_ready(void)
+{
+       pr_debug("%s\n", __func__);
+#ifdef CONFIG_TEGRA_BB_XMM_POWER
+       baseband_xmm_set_power_status(BBXMM_PS_L0);
+#endif
+       return 0;
+}
+
+static int enterprise_usb_hsic_phy_off(void)
+{
+       pr_debug("%s\n", __func__);
+#ifdef CONFIG_TEGRA_BB_XMM_POWER
+       baseband_xmm_set_power_status(BBXMM_PS_L3);
+#endif
+       return 0;
+}
+
 static void enterprise_usb_init(void)
 {
        struct  fsl_usb2_platform_data *udc_pdata;
@@ -752,6 +806,37 @@ static void enterprise_gps_init(void)
        tegra_gpio_enable(TEGRA_GPIO_PE5);
 }
 
+static struct baseband_power_platform_data tegra_baseband_power_data = {
+       .baseband_type = BASEBAND_XMM,
+       .modem = {
+               .xmm = {
+                       .bb_rst = XMM_GPIO_BB_RST,
+                       .bb_on = XMM_GPIO_BB_ON,
+                       .ipc_bb_wake = XMM_GPIO_IPC_BB_WAKE,
+                       .ipc_ap_wake = XMM_GPIO_IPC_AP_WAKE,
+                       .ipc_hsic_active = XMM_GPIO_IPC_HSIC_ACTIVE,
+                       .ipc_hsic_sus_req = XMM_GPIO_IPC_HSIC_SUS_REQ,
+                       .hsic_device = &tegra_ehci2_device,
+               },
+       },
+};
+
+static struct platform_device tegra_baseband_power_device = {
+       .name = "baseband_xmm_power",
+       .id = -1,
+       .dev = {
+               .platform_data = &tegra_baseband_power_data,
+       },
+};
+
+static struct platform_device tegra_baseband_power2_device = {
+       .name = "baseband_xmm_power2",
+       .id = -1,
+       .dev = {
+               .platform_data = &tegra_baseband_power_data,
+       },
+};
+
 static void enterprise_baseband_init(void)
 {
        int modem_id = tegra_get_modem_id();
@@ -760,7 +845,31 @@ static void enterprise_baseband_init(void)
        case 1: /* PH450 ULPI */
                enterprise_modem_init();
                break;
-       case 2: /* 6260 HSIC */
+       case 2: /* XMM6260 HSIC */
+               /* xmm baseband - do not switch off phy during suspend */
+               tegra_ehci_uhsic_pdata.power_down_on_bus_suspend = 0;
+               uhsic_phy_config.postsuspend = enterprise_usb_hsic_postsupend;
+               uhsic_phy_config.preresume = enterprise_usb_hsic_preresume;
+               uhsic_phy_config.usb_phy_ready = enterprise_usb_hsic_phy_ready;
+               uhsic_phy_config.post_phy_off = enterprise_usb_hsic_phy_off;
+               /* baseband-power.ko will register ehci2 device */
+               tegra_ehci2_device.dev.platform_data
+                       = &tegra_ehci_uhsic_pdata;
+               /* enable XMM6260 baseband gpio(s) */
+               tegra_gpio_enable(tegra_baseband_power_data.modem.generic
+                       .mdm_reset);
+               tegra_gpio_enable(tegra_baseband_power_data.modem.generic
+                       .mdm_on);
+               tegra_gpio_enable(tegra_baseband_power_data.modem.generic
+                       .ap2mdm_ack);
+               tegra_gpio_enable(tegra_baseband_power_data.modem.generic
+                       .mdm2ap_ack);
+               tegra_gpio_enable(tegra_baseband_power_data.modem.generic
+                       .ap2mdm_ack2);
+               tegra_gpio_enable(tegra_baseband_power_data.modem.generic
+                       .mdm2ap_ack2);
+               platform_device_register(&tegra_baseband_power_device);
+               platform_device_register(&tegra_baseband_power2_device);
                break;
        }
 }
index d652acf..0300b88 100644 (file)
@@ -112,6 +112,22 @@ void enterprise_bpc_mgmt_init(void);
 /* Audio-related GPIOs */
 #define TEGRA_GPIO_HP_DET      TEGRA_GPIO_PW3
 
+/* Baseband GPIO addresses */
+
+#define BB_GPIO_MDM_PWRON_AP2BB                TEGRA_GPIO_PE0 /* LCD_D0 */
+#define BB_GPIO_RESET_AP2BB            TEGRA_GPIO_PE1 /* LCD_D1 */
+#define BB_GPIO_LCD_PWR1               TEGRA_GPIO_PC1
+#define BB_GPIO_LCD_PWR2               TEGRA_GPIO_PC6
+#define BB_GPIO_HS1_AP2BB              TEGRA_GPIO_PE3 /* LCD_D3 */
+#define BB_GPIO_HS1_BB2AP              TEGRA_GPIO_PU5
+
+#define XMM_GPIO_BB_ON                 BB_GPIO_MDM_PWRON_AP2BB
+#define XMM_GPIO_BB_RST                        BB_GPIO_RESET_AP2BB
+#define XMM_GPIO_IPC_HSIC_ACTIVE       BB_GPIO_LCD_PWR1
+#define XMM_GPIO_IPC_HSIC_SUS_REQ      BB_GPIO_LCD_PWR2
+#define XMM_GPIO_IPC_BB_WAKE           BB_GPIO_HS1_AP2BB
+#define XMM_GPIO_IPC_AP_WAKE           BB_GPIO_HS1_BB2AP
+
 #define TDIODE_OFFSET  (9000)  /* in millicelsius */
 
 /* Battery Peak Current Management */