diff options
Diffstat (limited to 'arch/arm/mach-exynos/board-c1-modems.c')
-rw-r--r-- | arch/arm/mach-exynos/board-c1-modems.c | 1167 |
1 files changed, 415 insertions, 752 deletions
diff --git a/arch/arm/mach-exynos/board-c1-modems.c b/arch/arm/mach-exynos/board-c1-modems.c index 9c33fda..f8cd0ce 100644 --- a/arch/arm/mach-exynos/board-c1-modems.c +++ b/arch/arm/mach-exynos/board-c1-modems.c @@ -24,281 +24,33 @@ #include <linux/clk.h> /* inlcude platform specific file */ +#include <linux/cpufreq_pegasusq.h> #include <linux/platform_data/modem.h> -#include <mach/sec_modem.h> + +#include <plat/gpio-cfg.h> +#include <plat/regs-srom.h> +#include <plat/devs.h> +#include <plat/ehci.h> + +#include <mach/dev.h> #include <mach/gpio.h> #include <mach/gpio-exynos4.h> -#include <plat/gpio-cfg.h> #include <mach/regs-mem.h> -#include <plat/regs-srom.h> +#include <mach/cpufreq.h> +#include <mach/sec_modem.h> +#include <mach/sromc-exynos4.h> #ifdef CONFIG_USBHUB_USB3503 #include <linux/i2c.h> #include <linux/i2c-gpio.h> #include <linux/platform_data/usb3503.h> -#include <mach/cpufreq.h> #include <plat/usb-phy.h> #endif -#include <plat/devs.h> -#include <plat/ehci.h> - -#define SROM_CS0_BASE 0x04000000 -#define SROM_WIDTH 0x01000000 -#define SROM_NUM_ADDR_BITS 14 - -/* For "bus width and wait control (BW)" register */ -enum sromc_attr { - SROMC_DATA_16 = 0x1, /* 16-bit data bus */ - SROMC_BYTE_ADDR = 0x2, /* Byte base address */ - SROMC_WAIT_EN = 0x4, /* Wait enabled */ - SROMC_BYTE_EN = 0x8, /* Byte access enabled */ - SROMC_MASK = 0xF -}; -/* DPRAM configuration */ -struct sromc_cfg { - enum sromc_attr attr; - unsigned size; - unsigned csn; /* CSn # */ - unsigned addr; /* Start address (physical) */ - unsigned end; /* End address (physical) */ -}; +#define C1ATT_REV_0_7 9 /* rev0.7 == system_rev:9 */ -/* DPRAM access timing configuration */ -struct sromc_access_cfg { - u32 tacs; /* Address set-up before CSn */ - u32 tcos; /* Chip selection set-up before OEn */ - u32 tacc; /* Access cycle */ - u32 tcoh; /* Chip selection hold on OEn */ - u32 tcah; /* Address holding time after CSn */ - u32 tacp; /* Page mode access cycle at Page mode */ - u32 pmc; /* Page Mode config */ -}; - -/* For CMC221 IDPRAM (Internal DPRAM) */ -#define CMC_IDPRAM_SIZE 0x4000 /* 16 KB */ - -/* FOR CMC221 SFR for IDPRAM */ -#define CMC_INT2CP_REG 0x10 /* Interrupt to CP */ -#define CMC_INT2AP_REG 0x50 -#define CMC_CLR_INT_REG 0x28 /* Clear Interrupt to AP */ -#define CMC_RESET_REG 0x3C -#define CMC_PUT_REG 0x40 /* AP->CP reg for hostbooting */ -#define CMC_GET_REG 0x50 /* CP->AP reg for hostbooting */ - -#define INT_MASK_REQ_ACK_F 0x0020 -#define INT_MASK_REQ_ACK_R 0x0010 -#define INT_MASK_RES_ACK_F 0x0008 -#define INT_MASK_RES_ACK_R 0x0004 -#define INT_MASK_SEND_F 0x0002 -#define INT_MASK_SEND_R 0x0001 - -/* Function prototypes */ -static void config_dpram_port_gpio(void); -static void init_sromc(void); -static void setup_sromc(unsigned csn, struct sromc_cfg *cfg, - struct sromc_access_cfg *acc_cfg); -static void setup_dpram_speed(unsigned csn, struct sromc_access_cfg *acc_cfg); static int __init init_modem(void); -#ifdef CONFIG_USBHUB_USB3503 -static int host_port_enable(int port, int enable); -#else -static int host_port_enable(int port, int enable) -{ - return s5p_ehci_port_control(&s5p_device_ehci, port, enable); -} -#endif - -static struct sromc_cfg cmc_idpram_cfg = { - .attr = SROMC_DATA_16, - .size = CMC_IDPRAM_SIZE, -}; - -static struct sromc_access_cfg cmc_idpram_access_cfg[] = { - [DPRAM_SPEED_LOW] = { - /* for 33 MHz clock, 64 cycles */ - .tacs = 0x08 << 28, - .tcos = 0x08 << 24, - .tacc = 0x1F << 16, - .tcoh = 0x08 << 12, - .tcah = 0x08 << 8, - .tacp = 0x00 << 4, - .pmc = 0x00 << 0, - }, - [DPRAM_SPEED_MID] = { - /* for 66 MHz clock, 32 cycles */ - .tacs = 0x01 << 28, - .tcos = 0x01 << 24, - .tacc = 0x1B << 16, - .tcoh = 0x01 << 12, - .tcah = 0x01 << 8, - .tacp = 0x00 << 4, - .pmc = 0x00 << 0, - }, - [DPRAM_SPEED_HIGH] = { - /* for 133 MHz clock, 16 cycles */ - .tacs = 0x01 << 28, - .tcos = 0x01 << 24, - .tacc = 0x0B << 16, - .tcoh = 0x01 << 12, - .tcah = 0x01 << 8, - .tacp = 0x00 << 4, - .pmc = 0x00 << 0, - }, -}; - -/* - magic_code + - access_enable + - fmt_tx_head + fmt_tx_tail + fmt_tx_buff + - raw_tx_head + raw_tx_tail + raw_tx_buff + - fmt_rx_head + fmt_rx_tail + fmt_rx_buff + - raw_rx_head + raw_rx_tail + raw_rx_buff + - mbx_cp2ap + - mbx_ap2cp - = 2 + - 2 + - 2 + 2 + 1336 + - 2 + 2 + 4564 + - 2 + 2 + 1336 + - 2 + 2 + 9124 + - 2 + - 2 - = 16384 -*/ - -#define DP_FMT_TX_BUFF_SZ 1336 -#define DP_RAW_TX_BUFF_SZ 4564 -#define DP_FMT_RX_BUFF_SZ 1336 -#define DP_RAW_RX_BUFF_SZ 9124 - -#define MAX_CMC_IDPRAM_IPC_DEV (IPC_RAW + 1) /* FMT, RAW */ - -struct dpram_ipc_cfg { - u16 magic; - u16 access; - - u16 fmt_tx_head; - u16 fmt_tx_tail; - u8 fmt_tx_buff[DP_FMT_TX_BUFF_SZ]; - - u16 raw_tx_head; - u16 raw_tx_tail; - u8 raw_tx_buff[DP_RAW_TX_BUFF_SZ]; - - u16 fmt_rx_head; - u16 fmt_rx_tail; - u8 fmt_rx_buff[DP_FMT_RX_BUFF_SZ]; - - u16 raw_rx_head; - u16 raw_rx_tail; - u8 raw_rx_buff[DP_RAW_RX_BUFF_SZ]; - - u16 mbx_cp2ap; - u16 mbx_ap2cp; -}; - -struct cmc221_idpram_sfr { - u16 __iomem *int2cp; - u16 __iomem *int2ap; - u16 __iomem *clr_int2ap; - u16 __iomem *reset; - u16 __iomem *msg2cp; - u16 __iomem *msg2ap; -}; - -static struct dpram_ipc_map cmc_ipc_map; -static u8 *cmc_sfr_base; -static struct cmc221_idpram_sfr cmc_sfr; - -/* Function prototypes */ -static void cmc_idpram_reset(void); -static void cmc_idpram_setup_speed(enum dpram_speed); -static int cmc_idpram_wakeup(void); -static void cmc_idpram_sleep(void); -static void cmc_idpram_clr_intr(void); -static u16 cmc_idpram_recv_intr(void); -static void cmc_idpram_send_intr(u16 irq_mask); -static u16 cmc_idpram_recv_msg(void); -static void cmc_idpram_send_msg(u16 msg); - -static u16 cmc_idpram_get_magic(void); -static void cmc_idpram_set_magic(u16 value); -static u16 cmc_idpram_get_access(void); -static void cmc_idpram_set_access(u16 value); - -static u32 cmc_idpram_get_tx_head(int dev_id); -static u32 cmc_idpram_get_tx_tail(int dev_id); -static void cmc_idpram_set_tx_head(int dev_id, u32 head); -static void cmc_idpram_set_tx_tail(int dev_id, u32 tail); -static u8 __iomem *cmc_idpram_get_tx_buff(int dev_id); -static u32 cmc_idpram_get_tx_buff_size(int dev_id); - -static u32 cmc_idpram_get_rx_head(int dev_id); -static u32 cmc_idpram_get_rx_tail(int dev_id); -static void cmc_idpram_set_rx_head(int dev_id, u32 head); -static void cmc_idpram_set_rx_tail(int dev_id, u32 tail); -static u8 __iomem *cmc_idpram_get_rx_buff(int dev_id); -static u32 cmc_idpram_get_rx_buff_size(int dev_id); - -static u16 cmc_idpram_get_mask_req_ack(int dev_id); -static u16 cmc_idpram_get_mask_res_ack(int dev_id); -static u16 cmc_idpram_get_mask_send(int dev_id); - -static struct modemlink_dpram_control cmc_idpram_ctrl = { - .reset = cmc_idpram_reset, - - .setup_speed = cmc_idpram_setup_speed, - - .wakeup = cmc_idpram_wakeup, - .sleep = cmc_idpram_sleep, - - .clear_intr = cmc_idpram_clr_intr, - .recv_intr = cmc_idpram_recv_intr, - .send_intr = cmc_idpram_send_intr, - .recv_msg = cmc_idpram_recv_msg, - .send_msg = cmc_idpram_send_msg, - - .get_magic = cmc_idpram_get_magic, - .set_magic = cmc_idpram_set_magic, - .get_access = cmc_idpram_get_access, - .set_access = cmc_idpram_set_access, - - .get_tx_head = cmc_idpram_get_tx_head, - .get_tx_tail = cmc_idpram_get_tx_tail, - .set_tx_head = cmc_idpram_set_tx_head, - .set_tx_tail = cmc_idpram_set_tx_tail, - .get_tx_buff = cmc_idpram_get_tx_buff, - .get_tx_buff_size = cmc_idpram_get_tx_buff_size, - - .get_rx_head = cmc_idpram_get_rx_head, - .get_rx_tail = cmc_idpram_get_rx_tail, - .set_rx_head = cmc_idpram_set_rx_head, - .set_rx_tail = cmc_idpram_set_rx_tail, - .get_rx_buff = cmc_idpram_get_rx_buff, - .get_rx_buff_size = cmc_idpram_get_rx_buff_size, - - .get_mask_req_ack = cmc_idpram_get_mask_req_ack, - .get_mask_res_ack = cmc_idpram_get_mask_res_ack, - .get_mask_send = cmc_idpram_get_mask_send, - - .dp_base = NULL, - .dp_size = 0, - .dp_type = CP_IDPRAM, - .aligned = 1, - - .dpram_irq = CMC_IDPRAM_INT_IRQ_00, - .dpram_irq_flags = (IRQF_NO_SUSPEND | IRQF_TRIGGER_RISING), - .dpram_irq_name = "CMC221_IDPRAM_IRQ", - .dpram_wlock_name = "CMC221_IDPRAM_WLOCK", - - .max_ipc_dev = MAX_CMC_IDPRAM_IPC_DEV, -}; - -/* -** UMTS target platform data -*/ static struct modem_io_t umts_io_devices[] = { [0] = { .name = "umts_boot0", @@ -322,7 +74,7 @@ static struct modem_io_t umts_io_devices[] = { .links = LINKTYPE(LINKDEV_DPRAM), }, [3] = { - .name = "umts_multipdp", + .name = "multipdp", .id = 0, .format = IPC_MULTI_RAW, .io_type = IODEV_DUMMY, @@ -383,14 +135,15 @@ static struct modem_io_t umts_io_devices[] = { .links = LINKTYPE(LINKDEV_DPRAM), }, [11] = { - .name = "umts_loopback_ap2cp", + .name = "umts_loopback_cp2ap", .id = 30, .format = IPC_RAW, .io_type = IODEV_MISC, - .links = LINKTYPE(LINKDEV_DPRAM), + .links = LINKTYPE(LINKDEV_DPRAM) | LINKTYPE(LINKDEV_USB), + .tx_link = LINKDEV_DPRAM, }, [12] = { - .name = "umts_loopback_cp2ap", + .name = "umts_loopback_ap2cp", .id = 31, .format = IPC_RAW, .io_type = IODEV_MISC, @@ -404,6 +157,13 @@ static struct modem_io_t umts_io_devices[] = { .links = LINKTYPE(LINKDEV_DPRAM), }, [14] = { + .name = "umts_log", + .id = 0, + .format = IPC_RAMDUMP, + .io_type = IODEV_MISC, + .links = LINKTYPE(LINKDEV_DPRAM), + }, + [15] = { .name = "lte_ipc0", .id = 235, .format = IPC_FMT, @@ -412,28 +172,134 @@ static struct modem_io_t umts_io_devices[] = { }, }; -static int exynos_cpu_frequency_lock(void); -static int exynos_cpu_frequency_unlock(void); +/* +** addr_bits: 14 bits = 13 bits (8K words) + 1 bit (SFR) +** data_bits: 16 bits +** byte_acc: N/A +*/ +static struct sromc_bus_cfg c1_sromc_bus_cfg = { + .addr_bits = 14, + .data_bits = 16, + .byte_acc = 0, +}; -static struct modemlink_pm_data umts_link_pm_data = { - .name = "umts_link_pm", +/* For CMC221 IDPRAM (Internal DPRAM) */ +#define CMC_IDPRAM_SIZE DPRAM_SIZE_16KB - .gpio_link_enable = 0, - .gpio_link_active = GPIO_ACTIVE_STATE, - .gpio_link_hostwake = GPIO_IPC_HOST_WAKEUP, - .gpio_link_slavewake = GPIO_IPC_SLAVE_WAKEUP, +/* For CMC221 SFR for IDPRAM */ +#define CMC_INT2CP_REG 0x10 /* Interrupt to CP */ +#define CMC_INT2AP_REG 0x50 +#define CMC_CLR_INT_REG 0x28 /* Clear Interrupt to AP */ +#define CMC_RESET_REG 0x3C +#define CMC_PUT_REG 0x40 /* AP->CP reg for hostbooting */ +#define CMC_GET_REG 0x50 /* CP->AP reg for hostbooting */ + +struct cmc22x_idpram_sfr { + u16 __iomem *int2cp; + u16 __iomem *int2ap; + u16 __iomem *clr_int2ap; + u16 __iomem *reset; + u16 __iomem *msg2cp; + u16 __iomem *msg2ap; +}; - .port_enable = host_port_enable, /* - .link_reconnect = umts_link_reconnect, +** Function prototypes for CMC221 */ - .freqlock = ATOMIC_INIT(0), - .cpufreq_lock = exynos_cpu_frequency_lock, - .cpufreq_unlock = exynos_cpu_frequency_unlock, +static void cmc_idpram_reset(void); +static void cmc_idpram_clr_intr(void); +static u16 cmc_idpram_recv_intr(void); +static void cmc_idpram_send_intr(u16 irq_mask); +static u16 cmc_idpram_recv_msg(void); +static void cmc_idpram_send_msg(u16 msg); - .autosuspend_delay_ms = 2000, +static int cmc_idpram_wakeup(void); +static void cmc_idpram_sleep(void); + +static void cmc_idpram_setup_speed(enum dpram_speed speed); + +/* +** Static variables +*/ +static struct sromc_bank_cfg cmc_idpram_bank_cfg = { + .csn = 0, + .attr = SROMC_DATA_16, + .size = CMC_IDPRAM_SIZE, + .addr = SROM_CS0_BASE, +}; + +static struct sromc_timing_cfg cmc_idpram_timing_cfg[] = { + [DPRAM_SPEED_LOW] = { + /* CP 33 MHz clk, 315 ns (63 cycles) with 200 MHz INT clk */ + .tacs = 0x0F << 28, + .tcos = 0x0F << 24, + .tacc = 0x1F << 16, + .tcoh = 0x01 << 12, + .tcah = 0x00 << 8, + .tacp = 0x00 << 4, + .pmc = 0x00 << 0, + }, + [DPRAM_SPEED_MID] = { + /* CP 66 MHz clk, 160 ns (32 cycles) with 200 MHz INT clk */ + .tacs = 0x01 << 28, + .tcos = 0x01 << 24, + .tacc = 0x1C << 16, + .tcoh = 0x01 << 12, + .tcah = 0x00 << 8, + .tacp = 0x00 << 4, + .pmc = 0x00 << 0, + }, + [DPRAM_SPEED_HIGH] = { + /* CP 133 MHz clk, 80 ns (16 cycles) with 200 MHz INT clk */ + .tacs = 0x01 << 28, + .tcos = 0x01 << 24, + .tacc = 0x0C << 16, + .tcoh = 0x01 << 12, + .tcah = 0x00 << 8, + .tacp = 0x00 << 4, + .pmc = 0x00 << 0, + }, +}; - .has_usbhub = true, +static struct modemlink_dpram_control cmc_idpram_ctrl = { + .reset = cmc_idpram_reset, + .clear_intr = cmc_idpram_clr_intr, + .recv_intr = cmc_idpram_recv_intr, + .send_intr = cmc_idpram_send_intr, + .recv_msg = cmc_idpram_recv_msg, + .send_msg = cmc_idpram_send_msg, + + .wakeup = cmc_idpram_wakeup, + .sleep = cmc_idpram_sleep, + + .setup_speed = cmc_idpram_setup_speed, + + .dp_type = CP_IDPRAM, + + .dpram_irq_flags = (IRQF_NO_SUSPEND | IRQF_TRIGGER_RISING), +}; + +static struct cmc22x_idpram_sfr cmc_idpram_sfr; + +static struct resource umts_modem_res[] = { + [RES_CP_ACTIVE_IRQ_ID] = { + .name = "cp_active_irq", + .start = LTE_ACTIVE_IRQ, + .end = LTE_ACTIVE_IRQ, + .flags = IORESOURCE_IRQ, + }, + [RES_DPRAM_MEM_ID] = { + .name = "dpram_base", + .start = SROM_CS0_BASE, + .end = SROM_CS0_BASE + (CMC_IDPRAM_SIZE - 1), + .flags = IORESOURCE_MEM, + }, + [RES_DPRAM_IRQ_ID] = { + .name = "dpram_irq", + .start = CMC_IDPRAM_INT_IRQ_00, + .end = CMC_IDPRAM_INT_IRQ_00, + .flags = IORESOURCE_IRQ, + }, }; static struct modem_data umts_modem_data = { @@ -442,6 +308,9 @@ static struct modem_data umts_modem_data = { .gpio_cp_on = CP_CMC221_PMIC_PWRON, .gpio_cp_reset = CP_CMC221_CPU_RST, .gpio_phone_active = GPIO_LTE_ACTIVE, +#if defined(CONFIG_MACH_C1_KOR_SKT) || defined(CONFIG_MACH_C1_KOR_KT) + .gpio_pda_active = GPIO_PDA_ACTIVE, +#endif .gpio_dpram_int = GPIO_CMC_IDPRAM_INT_00, .gpio_dpram_status = GPIO_CMC_IDPRAM_STATUS, @@ -461,21 +330,12 @@ static struct modem_data umts_modem_data = { .num_iodevs = ARRAY_SIZE(umts_io_devices), .iodevs = umts_io_devices, - .link_pm_data = &umts_link_pm_data, + .use_handover = false, .ipc_version = SIPC_VER_50, .use_mif_log = true, }; -static struct resource umts_modem_res[] = { - [0] = { - .name = "cp_active_irq", - .start = LTE_ACTIVE_IRQ, - .end = LTE_ACTIVE_IRQ, - .flags = IORESOURCE_IRQ, - }, -}; - static struct platform_device umts_modem = { .name = "mif_sipc5", .id = 1, @@ -486,33 +346,38 @@ static struct platform_device umts_modem = { }, }; -#define HUB_STATE_OFF 0 -void set_hsic_lpa_states(int states) +/* +** Function definitions +*/ +static void cmc_idpram_reset(void) { - int val = gpio_get_value(umts_modem_data.gpio_cp_reset); + iowrite16(1, cmc_idpram_sfr.reset); +} - mif_trace("\n"); +static void cmc_idpram_clr_intr(void) +{ + iowrite16(0xFFFF, cmc_idpram_sfr.clr_int2ap); + iowrite16(0, cmc_idpram_sfr.int2ap); +} - if (val && states == STATE_HSIC_LPA_ENTER) { - mif_info("usb3503: hub off - lpa\n"); - host_port_enable(2, 0); - *(umts_link_pm_data.p_hub_status) = HUB_STATE_OFF; - } +static u16 cmc_idpram_recv_intr(void) +{ + return ioread16(cmc_idpram_sfr.int2ap); } -int get_cp_active_state(void) +static void cmc_idpram_send_intr(u16 irq_mask) { - return gpio_get_value(umts_modem_data.gpio_phone_active); + iowrite16(irq_mask, cmc_idpram_sfr.int2cp); } -static void cmc_idpram_reset(void) +static u16 cmc_idpram_recv_msg(void) { - iowrite16(1, cmc_sfr.reset); + return ioread16(cmc_idpram_sfr.msg2ap); } -static void cmc_idpram_setup_speed(enum dpram_speed speed) +static void cmc_idpram_send_msg(u16 msg) { - setup_dpram_speed(cmc_idpram_cfg.csn, &cmc_idpram_access_cfg[speed]); + iowrite16(msg, cmc_idpram_sfr.msg2cp); } static int cmc_idpram_wakeup(void) @@ -523,14 +388,18 @@ static int cmc_idpram_wakeup(void) while (!gpio_get_value(umts_modem_data.gpio_dpram_status)) { if (cnt++ > 10) { - mif_err("ERR: gpio_dpram_status == 0\n"); - return -EAGAIN; + if (in_irq()) + mif_err("ERR! gpio_dpram_status == 0 in IRQ\n"); + else + mif_err("ERR! gpio_dpram_status == 0\n"); + return -EACCES; } + mif_info("gpio_dpram_status == 0 (cnt %d)\n", cnt); if (in_interrupt()) - mdelay(1); + udelay(1000); else - msleep_interruptible(1); + usleep_range(1000, 2000); } return 0; @@ -541,196 +410,33 @@ static void cmc_idpram_sleep(void) gpio_set_value(umts_modem_data.gpio_dpram_wakeup, 0); } -static void cmc_idpram_clr_intr(void) -{ - iowrite16(0xFFFF, cmc_sfr.clr_int2ap); - iowrite16(0, cmc_sfr.int2ap); -} - -static u16 cmc_idpram_recv_intr(void) -{ - return ioread16(cmc_sfr.int2ap); -} - -static void cmc_idpram_send_intr(u16 irq_mask) -{ - iowrite16(irq_mask, cmc_sfr.int2cp); -} - -static u16 cmc_idpram_recv_msg(void) -{ - return ioread16(cmc_sfr.msg2ap); -} - -static void cmc_idpram_send_msg(u16 msg) -{ - iowrite16(msg, cmc_sfr.msg2cp); -} - -static u16 cmc_idpram_get_magic(void) -{ - return ioread16(cmc_ipc_map.magic); -} - -static void cmc_idpram_set_magic(u16 value) -{ - iowrite16(value, cmc_ipc_map.magic); -} - -static u16 cmc_idpram_get_access(void) -{ - return ioread16(cmc_ipc_map.access); -} - -static void cmc_idpram_set_access(u16 value) -{ - iowrite16(value, cmc_ipc_map.access); -} - -static u32 cmc_idpram_get_tx_head(int dev_id) -{ - return ioread16(cmc_ipc_map.dev[dev_id].txq.head); -} - -static u32 cmc_idpram_get_tx_tail(int dev_id) -{ - return ioread16(cmc_ipc_map.dev[dev_id].txq.tail); -} - -static void cmc_idpram_set_tx_head(int dev_id, u32 head) -{ - int cnt = 100; - u32 val = 0; - - iowrite16((u16)head, cmc_ipc_map.dev[dev_id].txq.head); - - do { - /* Check head value written */ - val = ioread16(cmc_ipc_map.dev[dev_id].txq.head); - if (val == head) - break; - - mif_err("ERR: txq.head(%d) != head(%d)\n", val, head); - - /* Write head value again */ - iowrite16((u16)head, cmc_ipc_map.dev[dev_id].txq.head); - } while (cnt--); -} - -static void cmc_idpram_set_tx_tail(int dev_id, u32 tail) -{ - int cnt = 100; - u32 val = 0; - - iowrite16((u16)tail, cmc_ipc_map.dev[dev_id].txq.tail); - - do { - /* Check tail value written */ - val = ioread16(cmc_ipc_map.dev[dev_id].txq.tail); - if (val == tail) - break; - - mif_err("ERR: txq.tail(%d) != tail(%d)\n", val, tail); - - /* Write tail value again */ - iowrite16((u16)tail, cmc_ipc_map.dev[dev_id].txq.tail); - } while (cnt--); -} - -static u8 __iomem *cmc_idpram_get_tx_buff(int dev_id) -{ - return cmc_ipc_map.dev[dev_id].txq.buff; -} - -static u32 cmc_idpram_get_tx_buff_size(int dev_id) -{ - return cmc_ipc_map.dev[dev_id].txq.size; -} - -static u32 cmc_idpram_get_rx_head(int dev_id) -{ - return ioread16(cmc_ipc_map.dev[dev_id].rxq.head); -} - -static u32 cmc_idpram_get_rx_tail(int dev_id) -{ - return ioread16(cmc_ipc_map.dev[dev_id].rxq.tail); -} - -static void cmc_idpram_set_rx_head(int dev_id, u32 head) -{ - int cnt = 100; - u32 val = 0; - - iowrite16((u16)head, cmc_ipc_map.dev[dev_id].rxq.head); - - do { - /* Check head value written */ - val = ioread16(cmc_ipc_map.dev[dev_id].rxq.head); - if (val == head) - break; - - mif_err("ERR: rxq.head(%d) != head(%d)\n", val, head); - - /* Write head value again */ - iowrite16((u16)head, cmc_ipc_map.dev[dev_id].rxq.head); - } while (cnt--); -} - -static void cmc_idpram_set_rx_tail(int dev_id, u32 tail) -{ - int cnt = 100; - u32 val = 0; - - iowrite16((u16)tail, cmc_ipc_map.dev[dev_id].rxq.tail); - - do { - /* Check tail value written */ - val = ioread16(cmc_ipc_map.dev[dev_id].rxq.tail); - if (val == tail) - break; - - mif_err("ERR: rxq.tail(%d) != tail(%d)\n", val, tail); - - /* Write tail value again */ - iowrite16((u16)tail, cmc_ipc_map.dev[dev_id].rxq.tail); - } while (cnt--); -} - -static u8 __iomem *cmc_idpram_get_rx_buff(int dev_id) -{ - return cmc_ipc_map.dev[dev_id].rxq.buff; -} - -static u32 cmc_idpram_get_rx_buff_size(int dev_id) -{ - return cmc_ipc_map.dev[dev_id].rxq.size; -} - -static u16 cmc_idpram_get_mask_req_ack(int dev_id) +static void cmc_idpram_setup_speed(enum dpram_speed speed) { - return cmc_ipc_map.dev[dev_id].mask_req_ack; + sromc_config_access_timing(cmc_idpram_bank_cfg.csn, + &cmc_idpram_timing_cfg[speed]); } -static u16 cmc_idpram_get_mask_res_ack(int dev_id) +static u8 *cmc_idpram_remap_sfr_region(struct sromc_bank_cfg *cfg) { - return cmc_ipc_map.dev[dev_id].mask_res_ack; -} + int dp_addr = cfg->addr + cfg->size; + int dp_size = cfg->size; + u8 __iomem *sfr_base; -static u16 cmc_idpram_get_mask_send(int dev_id) -{ - return cmc_ipc_map.dev[dev_id].mask_send; -} + /* Remap DPRAM SFR region */ + sfr_base = (u8 __iomem *)ioremap_nocache(dp_addr, dp_size); + if (!sfr_base) { + mif_err("ERR: ioremap_nocache fail\n"); + return NULL; + } -/* Set dynamic environment for a modem */ -static void setup_umts_modem_env(void) -{ - /* Config DPRAM control structure */ - cmc_idpram_cfg.csn = 0; - cmc_idpram_cfg.addr = SROM_CS0_BASE + (SROM_WIDTH * cmc_idpram_cfg.csn); - cmc_idpram_cfg.end = cmc_idpram_cfg.addr + cmc_idpram_cfg.size - 1; + cmc_idpram_sfr.int2cp = (u16 __iomem *)(sfr_base + CMC_INT2CP_REG); + cmc_idpram_sfr.int2ap = (u16 __iomem *)(sfr_base + CMC_INT2AP_REG); + cmc_idpram_sfr.clr_int2ap = (u16 __iomem *)(sfr_base + CMC_CLR_INT_REG); + cmc_idpram_sfr.reset = (u16 __iomem *)(sfr_base + CMC_RESET_REG); + cmc_idpram_sfr.msg2cp = (u16 __iomem *)(sfr_base + CMC_PUT_REG); + cmc_idpram_sfr.msg2ap = (u16 __iomem *)(sfr_base + CMC_GET_REG); - umts_modem_data.gpio_dpram_int = GPIO_CMC_IDPRAM_INT_00; + return sfr_base; } static void config_umts_modem_gpio(void) @@ -869,290 +575,192 @@ static void config_umts_modem_gpio(void) } else { gpio_direction_input(gpio_dynamic_switching); s3c_gpio_setpull(gpio_dynamic_switching, - S3C_GPIO_PULL_NONE); + S3C_GPIO_PULL_DOWN); } } -} -static u8 *cmc_idpram_remap_mem_region(struct sromc_cfg *cfg) -{ - int dp_addr = cfg->addr; - int dp_size = cfg->size; - u8 __iomem *dp_base; - struct dpram_ipc_cfg *ipc_map; - struct dpram_ipc_device *dev; - - /* Remap DPRAM memory region */ - dp_base = (u8 __iomem *)ioremap_nocache(dp_addr, dp_size); - if (!dp_base) { - mif_err("ERR: ioremap_nocache for dp_base fail\n"); - return NULL; - } - mif_err("DPRAM VA=0x%08X\n", (int)dp_base); - - /* Remap DPRAM SFR region */ - dp_addr += dp_size; - cmc_sfr_base = (u8 __iomem *)ioremap_nocache(dp_addr, dp_size); - if (cmc_sfr_base == NULL) { - iounmap(dp_base); - mif_err("ERR: ioremap_nocache for cmc_sfr_base fail\n"); - return NULL; - } - - cmc_sfr.int2cp = (u16 __iomem *)(cmc_sfr_base + CMC_INT2CP_REG); - cmc_sfr.int2ap = (u16 __iomem *)(cmc_sfr_base + CMC_INT2AP_REG); - cmc_sfr.clr_int2ap = (u16 __iomem *)(cmc_sfr_base + CMC_CLR_INT_REG); - cmc_sfr.reset = (u16 __iomem *)(cmc_sfr_base + CMC_RESET_REG); - cmc_sfr.msg2cp = (u16 __iomem *)(cmc_sfr_base + CMC_PUT_REG); - cmc_sfr.msg2ap = (u16 __iomem *)(cmc_sfr_base + CMC_GET_REG); + mif_info("done\n"); +} - cmc_idpram_ctrl.dp_base = (u8 __iomem *)dp_base; - cmc_idpram_ctrl.dp_size = dp_size; +static int host_port_enable(int port, int enable); +static int exynos_frequency_lock(struct device *dev); +static int exynos_frequency_unlock(struct device *dev); - /* Map for IPC */ - ipc_map = (struct dpram_ipc_cfg *)dp_base; +static struct modemlink_pm_data umts_link_pm_data = { + .name = "umts_link_pm", - /* Magic code and access enable fields */ - cmc_ipc_map.magic = (u16 __iomem *)&ipc_map->magic; - cmc_ipc_map.access = (u16 __iomem *)&ipc_map->access; + .gpio_link_enable = 0, + .gpio_link_active = GPIO_ACTIVE_STATE, + .gpio_link_hostwake = GPIO_IPC_HOST_WAKEUP, + .gpio_link_slavewake = GPIO_IPC_SLAVE_WAKEUP, - /* FMT */ - dev = &cmc_ipc_map.dev[IPC_FMT]; + .port_enable = host_port_enable, +/* + .link_reconnect = umts_link_reconnect, +*/ + .freqlock = ATOMIC_INIT(0), + .freq_lock = exynos_frequency_lock, + .freq_unlock = exynos_frequency_unlock, - strcpy(dev->name, "FMT"); - dev->id = IPC_FMT; + .autosuspend_delay_ms = 2000, - dev->txq.head = (u16 __iomem *)&ipc_map->fmt_tx_head; - dev->txq.tail = (u16 __iomem *)&ipc_map->fmt_tx_tail; - dev->txq.buff = (u8 __iomem *)&ipc_map->fmt_tx_buff[0]; - dev->txq.size = DP_FMT_TX_BUFF_SZ; + .has_usbhub = true, /* change this in init_modem if C1-ATT >= rev0.7 */ +}; - dev->rxq.head = (u16 __iomem *)&ipc_map->fmt_rx_head; - dev->rxq.tail = (u16 __iomem *)&ipc_map->fmt_rx_tail; - dev->rxq.buff = (u8 __iomem *)&ipc_map->fmt_rx_buff[0]; - dev->rxq.size = DP_FMT_RX_BUFF_SZ; +static struct modemlink_pm_link_activectl active_ctl; - dev->mask_req_ack = INT_MASK_REQ_ACK_F; - dev->mask_res_ack = INT_MASK_RES_ACK_F; - dev->mask_send = INT_MASK_SEND_F; +#ifdef CONFIG_EXYNOS4_CPUFREQ +static int exynos_frequency_lock(struct device *dev) +{ + unsigned int level, cpufreq = 600; /* 200 ~ 1400 */ + unsigned int busfreq = 400200; /* 100100 ~ 400200 */ + int ret = 0; + struct device *busdev = dev_get("exynos-busfreq"); - /* RAW */ - dev = &cmc_ipc_map.dev[IPC_RAW]; + if (atomic_read(&umts_link_pm_data.freqlock) == 0) { + /* cpu frequency lock */ + ret = exynos_cpufreq_get_level(cpufreq * 1000, &level); + if (ret < 0) { + mif_err("ERR: exynos_cpufreq_get_level fail: %d\n", + ret); + goto exit; + } - strcpy(dev->name, "RAW"); - dev->id = IPC_RAW; + ret = exynos_cpufreq_lock(DVFS_LOCK_ID_USB_IF, level); + if (ret < 0) { + mif_err("ERR: exynos_cpufreq_lock fail: %d\n", ret); + goto exit; + } - dev->txq.head = (u16 __iomem *)&ipc_map->raw_tx_head; - dev->txq.tail = (u16 __iomem *)&ipc_map->raw_tx_tail; - dev->txq.buff = (u8 __iomem *)&ipc_map->raw_tx_buff[0]; - dev->txq.size = DP_RAW_TX_BUFF_SZ; + /* bus frequncy lock */ + if (!busdev) { + mif_err("ERR: busdev is not exist\n"); + ret = -ENODEV; + goto exit; + } - dev->rxq.head = (u16 __iomem *)&ipc_map->raw_rx_head; - dev->rxq.tail = (u16 __iomem *)&ipc_map->raw_rx_tail; - dev->rxq.buff = (u8 __iomem *)&ipc_map->raw_rx_buff[0]; - dev->rxq.size = DP_RAW_RX_BUFF_SZ; + ret = dev_lock(busdev, dev, busfreq); + if (ret < 0) { + mif_err("ERR: dev_lock error: %d\n", ret); + goto exit; + } - dev->mask_req_ack = INT_MASK_REQ_ACK_R; - dev->mask_res_ack = INT_MASK_RES_ACK_R; - dev->mask_send = INT_MASK_SEND_R; + /* lock minimum number of cpu cores */ + cpufreq_pegasusq_min_cpu_lock(2); - return dp_base; + atomic_set(&umts_link_pm_data.freqlock, 1); + mif_debug("level=%d, cpufreq=%d MHz, busfreq=%06d\n", + level, cpufreq, busfreq); + } +exit: + return ret; } -/** - * DPRAM GPIO settings - * - * SROM_NUM_ADDR_BITS value indicate the address line number or - * the mux/demux dpram type. if you want to set mux mode, define the - * SROM_NUM_ADDR_BITS to zero. - * - * for CMC22x - * CMC22x has 16KB + a SFR register address. - * It used 14 bits (13bits for 16KB word address and 1 bit for SFR - * register) - */ -static void config_dpram_port_gpio(void) +static int exynos_frequency_unlock(struct device *dev) { - int addr_bits = SROM_NUM_ADDR_BITS; + int ret = 0; + struct device *busdev = dev_get("exynos-busfreq"); - mif_info("address line = %d bits\n", addr_bits); - - /* - ** Config DPRAM address/data GPIO pins - */ + if (atomic_read(&umts_link_pm_data.freqlock) == 1) { + /* cpu frequency unlock */ + exynos_cpufreq_lock_free(DVFS_LOCK_ID_USB_IF); - /* Set GPIO for address bus (13 ~ 14 bits) */ - switch (addr_bits) { - case 0: - break; + /* bus frequency unlock */ + ret = dev_unlock(busdev, dev); + if (ret < 0) { + mif_err("ERR: dev_unlock error: %d\n", ret); + goto exit; + } - case 13 ... 14: - s3c_gpio_cfgrange_nopull(GPIO_SROM_ADDR_BUS_LOW, - EXYNOS4_GPIO_Y3_NR, S3C_GPIO_SFN(2)); - s3c_gpio_cfgrange_nopull(GPIO_SROM_ADDR_BUS_HIGH, - (addr_bits - EXYNOS4_GPIO_Y3_NR), S3C_GPIO_SFN(2)); - break; + /* unlock minimum number of cpu cores */ + cpufreq_pegasusq_min_cpu_unlock(); - default: - mif_err("ERR: invalid addr_bits!!!\n"); - return; + atomic_set(&umts_link_pm_data.freqlock, 0); + mif_debug("success\n"); } - - /* Set GPIO for data bus (16 bits) */ - s3c_gpio_cfgrange_nopull(GPIO_SROM_DATA_BUS_LOW, 8, S3C_GPIO_SFN(2)); - s3c_gpio_cfgrange_nopull(GPIO_SROM_DATA_BUS_HIGH, 8, S3C_GPIO_SFN(2)); - - /* Setup SROMC CSn pins */ - s3c_gpio_cfgpin(GPIO_DPRAM_CSN0, S3C_GPIO_SFN(2)); - - /* Config OEn, WEn */ - s3c_gpio_cfgpin(GPIO_DPRAM_REN, S3C_GPIO_SFN(2)); - s3c_gpio_cfgpin(GPIO_DPRAM_WEN, S3C_GPIO_SFN(2)); +exit: + return ret; } - -static void init_sromc(void) +#else +static int exynos_frequency_lock(void) { - struct clk *clk = NULL; - - /* SROMC clk enable */ - clk = clk_get(NULL, "sromc"); - if (!clk) { - mif_err("ERR: SROMC clock gate fail\n"); - return; - } - clk_enable(clk); + return 0; } -static void setup_sromc -( - unsigned csn, - struct sromc_cfg *cfg, - struct sromc_access_cfg *acc_cfg -) +static int exynos_frequency_unlock(void) { - unsigned bw = 0; /* Bus width and wait control */ - unsigned bc = 0; /* Vank control */ - void __iomem *bank_sfr = S5P_SROM_BC0 + (4 * csn); - - mif_err("SROMC settings for CS%d...\n", csn); - - bw = __raw_readl(S5P_SROM_BW); - bc = __raw_readl(bank_sfr); - mif_err("Old SROMC settings = BW(0x%08X) BC%d(0x%08X)\n", bw, csn, bc); - - /* Set the BW control field for the CSn */ - bw &= ~(SROMC_MASK << (csn << 2)); - bw |= (cfg->attr << (csn << 2)); - writel(bw, S5P_SROM_BW); - - /* Set SROMC memory access timing for the CSn */ - bc = acc_cfg->tacs | acc_cfg->tcos | acc_cfg->tacc | - acc_cfg->tcoh | acc_cfg->tcah | acc_cfg->tacp | acc_cfg->pmc; - - writel(bc, bank_sfr); - - /* Verify SROMC settings */ - bw = __raw_readl(S5P_SROM_BW); - bc = __raw_readl(bank_sfr); - mif_err("New SROMC settings = BW(0x%08X) BC%d(0x%08X)\n", bw, csn, bc); + return 0; } +#endif -static void setup_dpram_speed(unsigned csn, struct sromc_access_cfg *acc_cfg) +bool modem_using_hub(void) { - void __iomem *bank_sfr = S5P_SROM_BC0 + (4 * csn); - unsigned bc = 0; - - bc = __raw_readl(bank_sfr); - mif_info("Old CS%d setting = 0x%08X\n", csn, bc); - - /* SROMC memory access timing setting */ - bc = acc_cfg->tacs | acc_cfg->tcos | acc_cfg->tacc | - acc_cfg->tcoh | acc_cfg->tcah | acc_cfg->tacp | acc_cfg->pmc; - writel(bc, bank_sfr); - - bc = __raw_readl(bank_sfr); - mif_info("New CS%d setting = 0x%08X\n", csn, bc); + return umts_link_pm_data.has_usbhub; } -static int __init init_modem(void) +void set_slave_wake(void) { - struct sromc_cfg *cfg = NULL; - struct sromc_access_cfg *acc_cfg = NULL; - - mif_err("System Revision = %d\n", system_rev); - - setup_umts_modem_env(); - - config_dpram_port_gpio(); + int slavewake = umts_link_pm_data.gpio_link_slavewake; - config_umts_modem_gpio(); - - init_sromc(); - - cfg = &cmc_idpram_cfg; - acc_cfg = &cmc_idpram_access_cfg[DPRAM_SPEED_LOW]; - - setup_sromc(cfg->csn, cfg, acc_cfg); - - if (!cmc_idpram_remap_mem_region(&cmc_idpram_cfg)) - return -1; - - platform_device_register(&umts_modem); - - return 0; + if (gpio_get_value(slavewake)) { + gpio_direction_output(slavewake, 0); + mif_info("> S-WUP 0\n"); + mdelay(10); + } + gpio_direction_output(slavewake, 1); + mif_info("> S-WUP 1\n"); } -late_initcall(init_modem); -/*device_initcall(init_modem);*/ - -#ifdef CONFIG_USBHUB_USB3503 -static int (*usbhub_set_mode)(struct usb3503_hubctl *, int); -static struct usb3503_hubctl *usbhub_ctl; -#ifdef CONFIG_EXYNOS4_CPUFREQ -static int exynos_cpu_frequency_lock(void) +void set_hsic_lpa_states(int states) { - unsigned int level, freq = 700; + int val = gpio_get_value(umts_modem_data.gpio_cp_reset); + struct modemlink_pm_data *pm_data = &umts_link_pm_data; - if (atomic_read(&umts_link_pm_data.freqlock) == 0) { - if (exynos_cpufreq_get_level(freq * 1000, &level)) { - mif_err("ERR: exynos_cpufreq_get_level fail\n"); - return -EINVAL; - } + mif_trace("\n"); - if (exynos_cpufreq_lock(DVFS_LOCK_ID_USB_IF, level)) { - mif_err("ERR: exynos_cpufreq_lock fail\n"); - return -EINVAL; + if (val) { + switch (states) { + case STATE_HSIC_LPA_ENTER: + mif_info("lpa_enter\n"); + /* gpio_link_active == gpio_host_active in C1 */ + gpio_set_value(umts_modem_data.gpio_host_active, 0); + mif_info("> H-ACT %d\n", 0); + if (pm_data->hub_standby && pm_data->hub_pm_data) + pm_data->hub_standby(pm_data->hub_pm_data); + break; + case STATE_HSIC_LPA_WAKE: + mif_info("lpa_wake\n"); + gpio_set_value(umts_modem_data.gpio_host_active, 1); + mif_info("> H-ACT %d\n", 1); + break; + case STATE_HSIC_LPA_PHY_INIT: + mif_info("lpa_phy_init\n"); + if (!modem_using_hub() && active_ctl.gpio_initialized) + set_slave_wake(); + break; } - - atomic_set(&umts_link_pm_data.freqlock, 1); - mif_debug("<%d> %d MHz\n", level, freq); } - return 0; } -static int exynos_cpu_frequency_unlock(void) -{ - if (atomic_read(&umts_link_pm_data.freqlock) == 1) { - exynos_cpufreq_lock_free(DVFS_LOCK_ID_USB_IF); - atomic_set(&umts_link_pm_data.freqlock, 0); - mif_debug("\n"); - } - return 0; -} -#else -static int exynos_cpu_frequency_lock(void) +int get_cp_active_state(void) { - return 0; + return gpio_get_value(umts_modem_data.gpio_phone_active); } -static int exynos_cpu_frequency_unlock(void) -{ - return 0; -} -#endif +static int (*usbhub_set_mode)(struct usb3503_hubctl *, int); +static struct usb3503_hubctl *usbhub_ctl; void set_host_states(struct platform_device *pdev, int type) { + if (modem_using_hub()) + return; + + if (active_ctl.gpio_initialized) { + mif_err("%s: > H-ACT %d\n", pdev->name, type); + gpio_direction_output(umts_link_pm_data.gpio_link_active, type); + } else { + active_ctl.gpio_request_host_active = 1; + } } static int usb3503_hub_handler(void (*set_mode)(void), void *ctl) @@ -1239,18 +847,6 @@ static struct platform_device s3c_device_i2c20 = { .dev.platform_data = &i2c20_platdata, }; -static int __init init_usbhub(void) -{ - usb3503_hw_config(); - i2c_register_board_info(20, i2c_devs20_emul, - ARRAY_SIZE(i2c_devs20_emul)); - - platform_device_register(&s3c_device_i2c20); - return 0; -} - -device_initcall(init_usbhub); - static int host_port_enable(int port, int enable) { int err; @@ -1258,10 +854,12 @@ static int host_port_enable(int port, int enable) mif_info("port(%d) control(%d)\n", port, enable); if (enable) { - err = usbhub_set_mode(usbhub_ctl, USB3503_MODE_HUB); - if (err < 0) { - mif_err("ERR: hub on fail\n"); - goto exit; + if (modem_using_hub()) { + err = usbhub_set_mode(usbhub_ctl, USB3503_MODE_HUB); + if (err < 0) { + mif_err("ERR: hub on fail\n"); + goto exit; + } } err = s5p_ehci_port_control(&s5p_device_ehci, port, 1); if (err < 0) { @@ -1269,16 +867,18 @@ static int host_port_enable(int port, int enable) goto exit; } } else { + if (modem_using_hub()) { + err = usbhub_set_mode(usbhub_ctl, USB3503_MODE_STANDBY); + if (err < 0) { + mif_err("ERR: hub off fail\n"); + goto exit; + } + } err = s5p_ehci_port_control(&s5p_device_ehci, port, 0); if (err < 0) { mif_err("ERR: port(%d) enable fail\n", port); goto exit; } - err = usbhub_set_mode(usbhub_ctl, USB3503_MODE_STANDBY); - if (err < 0) { - mif_err("ERR: hub off fail\n"); - goto exit; - } } err = gpio_direction_output(umts_modem_data.gpio_host_active, enable); @@ -1288,15 +888,78 @@ static int host_port_enable(int port, int enable) exit: return err; } -#else -void set_host_states(struct platform_device *pdev, int type) + +static int __init init_usbhub(void) { - if (active_ctl.gpio_initialized) { - mif_err("<%s> Active States =%d, %s\n", pdev->name, type); - gpio_direction_output(umts_link_pm_data.gpio_link_active, type); - } else { - active_ctl.gpio_request_host_active = 1; - } + usb3503_hw_config(); + i2c_register_board_info(20, i2c_devs20_emul, + ARRAY_SIZE(i2c_devs20_emul)); + + platform_device_register(&s3c_device_i2c20); + return 0; } +device_initcall(init_usbhub); + +static int __init init_modem(void) +{ + struct sromc_bus_cfg *bus_cfg; + struct sromc_bank_cfg *bnk_cfg; + struct sromc_timing_cfg *tm_cfg; + + mif_err("System Revision = %d\n", system_rev); + +#ifdef CONFIG_MACH_C1_USA_ATT + /* check C1-ATT rev >=0.7 + * <=rev0.6: <EXYNOS>--hsic--<HUB>--usb--<CMC221S> + * >=rev0.7: <EXYNOS>--hsic--------------<CMC221D> + */ + if (system_rev >= C1ATT_REV_0_7) + umts_link_pm_data.has_usbhub = false; #endif +#ifdef CONFIG_MACH_BAFFIN + umts_link_pm_data.has_usbhub = false; +#endif + /* + ** Complete modem_data configuration including link_pm_data + */ + umts_modem_data.link_pm_data = &umts_link_pm_data, + + /* + ** Configure GPIO pins for the modem + */ + config_umts_modem_gpio(); + active_ctl.gpio_initialized = 1; + + /* + ** Configure SROM controller + */ + if (sromc_enable() < 0) + return -1; + + bus_cfg = &c1_sromc_bus_cfg; + if (sromc_config_demux_gpio(bus_cfg) < 0) + return -1; + + bnk_cfg = &cmc_idpram_bank_cfg; + if (sromc_config_csn_gpio(bnk_cfg->csn) < 0) + return -1; + sromc_config_access_attr(bnk_cfg->csn, bnk_cfg->attr); + + tm_cfg = &cmc_idpram_timing_cfg[DPRAM_SPEED_LOW]; + sromc_config_access_timing(bnk_cfg->csn, tm_cfg); + + /* + ** Remap SFR region for CMC22x IDPRAM + */ + if (!cmc_idpram_remap_sfr_region(&cmc_idpram_bank_cfg)) + return -1; + + /* + ** Register the modem device + */ + platform_device_register(&umts_modem); + + return 0; +} +late_initcall(init_modem); |