Home | History | Annotate | Download | only in arch_msm7k
      1 /*
      2  * Copyright (c) 2008, Google Inc.
      3  * All rights reserved.
      4  *
      5  * Redistribution and use in source and binary forms, with or without
      6  * modification, are permitted provided that the following conditions
      7  * are met:
      8  *  * Redistributions of source code must retain the above copyright
      9  *    notice, this list of conditions and the following disclaimer.
     10  *  * Redistributions in binary form must reproduce the above copyright
     11  *    notice, this list of conditions and the following disclaimer in
     12  *    the documentation and/or other materials provided with the
     13  *    distribution.
     14  *
     15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     16  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     17  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
     18  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
     19  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
     20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
     21  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
     22  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
     23  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
     24  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
     25  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     26  * SUCH DAMAGE.
     27  */
     28 
     29 #include <boot/boot.h>
     30 #include <msm7k/shared.h>
     31 
     32 static void get_version(char *s, unsigned id)
     33 {
     34     unsigned *ver = (unsigned*) MSM7K_VERSION;
     35     unsigned n = ver[id];
     36 
     37     snprintf(s, 32, "%d.%d", n >> 16, n & 0xffff);
     38 }
     39 
     40 void get_version_modem(char *s)
     41 {
     42     get_version(s, VERSION_MODEM);
     43 }
     44 
     45 void get_version_modem_sbl(char *s)
     46 {
     47     get_version(s, VERSION_MODEM_SBL);
     48 }
     49 
     50 #define MSM_CSR_BASE 0xC0100000
     51 
     52 #define MSM_A2M_INT(n) (MSM_CSR_BASE + 0x400 + (n) * 4)
     53 
     54 static inline void notify_other_proc_comm(void)
     55 {
     56 	writel(1, MSM_A2M_INT(6));
     57 }
     58 
     59 #define APP_COMMAND (MSM7K_SHARED_PHYS + 0x00)
     60 #define APP_STATUS  (MSM7K_SHARED_PHYS + 0x04)
     61 #define APP_DATA1   (MSM7K_SHARED_PHYS + 0x08)
     62 #define APP_DATA2   (MSM7K_SHARED_PHYS + 0x0C)
     63 
     64 #define MDM_COMMAND (MSM7K_SHARED_PHYS + 0x10)
     65 #define MDM_STATUS  (MSM7K_SHARED_PHYS + 0x14)
     66 #define MDM_DATA1   (MSM7K_SHARED_PHYS + 0x18)
     67 #define MDM_DATA2   (MSM7K_SHARED_PHYS + 0x1C)
     68 
     69 
     70 enum
     71 {
     72 	PCOM_CMD_IDLE = 0x0,
     73 	PCOM_CMD_DONE,
     74 	PCOM_RESET_APPS,
     75 	PCOM_RESET_CHIP,
     76 	PCOM_CONFIG_NAND_MPU,
     77 	PCOM_CONFIG_USB_CLKS,
     78 	PCOM_GET_POWER_ON_STATUS,
     79 	PCOM_GET_WAKE_UP_STATUS,
     80 	PCOM_GET_BATT_LEVEL,
     81 	PCOM_CHG_IS_CHARGING,
     82 	PCOM_POWER_DOWN,
     83 	PCOM_USB_PIN_CONFIG,
     84 	PCOM_USB_PIN_SEL,
     85 	PCOM_SET_RTC_ALARM,
     86 	PCOM_NV_READ,
     87 	PCOM_NV_WRITE,
     88 	PCOM_GET_UUID_HIGH,
     89 	PCOM_GET_UUID_LOW,
     90 	PCOM_GET_HW_ENTROPY,
     91 	PCOM_RPC_GPIO_TLMM_CONFIG_REMOTE,
     92 	PCOM_CLKCTL_RPC_ENABLE,
     93 	PCOM_CLKCTL_RPC_DISABLE,
     94 	PCOM_CLKCTL_RPC_RESET,
     95 	PCOM_CLKCTL_RPC_SET_FLAGS,
     96 	PCOM_CLKCTL_RPC_SET_RATE,
     97 	PCOM_CLKCTL_RPC_MIN_RATE,
     98 	PCOM_CLKCTL_RPC_MAX_RATE,
     99 	PCOM_CLKCTL_RPC_RATE,
    100 	PCOM_CLKCTL_RPC_PLL_REQUEST,
    101 	PCOM_CLKCTL_RPC_ENABLED,
    102 	PCOM_VREG_SWITCH,
    103 	PCOM_VREG_SET_LEVEL,
    104 	PCOM_GPIO_TLMM_CONFIG_GROUP,
    105 	PCOM_GPIO_TLMM_UNCONFIG_GROUP,
    106 	PCOM_NV_READ_HIGH_BITS,
    107 	PCOM_NV_WRITE_HIGH_BITS,
    108 	PCOM_NUM_CMDS,
    109 };
    110 
    111 enum
    112 {
    113 	 PCOM_INVALID_STATUS = 0x0,
    114 	 PCOM_READY,
    115 	 PCOM_CMD_RUNNING,
    116 	 PCOM_CMD_SUCCESS,
    117 	 PCOM_CMD_FAIL,
    118 };
    119 
    120 int msm_proc_comm(unsigned cmd, unsigned *data1, unsigned *data2)
    121 {
    122 	int ret = -1;
    123 
    124 	while (readl(MDM_STATUS) != PCOM_READY) {
    125 		/* XXX check for A9 reset */
    126 	}
    127 
    128 	writel(cmd, APP_COMMAND);
    129 	if (data1)
    130 		writel(*data1, APP_DATA1);
    131 	if (data2)
    132 		writel(*data2, APP_DATA2);
    133 
    134 	notify_other_proc_comm();
    135 	while (readl(APP_COMMAND) != PCOM_CMD_DONE) {
    136 		/* XXX check for A9 reset */
    137 	}
    138 
    139 	if (readl(APP_STATUS) != PCOM_CMD_FAIL) {
    140 		if (data1)
    141 			*data1 = readl(APP_DATA1);
    142 		if (data2)
    143 			*data2 = readl(APP_DATA2);
    144 		ret = 0;
    145 	}
    146 
    147 	return ret;
    148 }
    149 
    150 int clock_enable(unsigned id)
    151 {
    152     return msm_proc_comm(PCOM_CLKCTL_RPC_ENABLE, &id, 0);
    153 }
    154 
    155 int clock_disable(unsigned id)
    156 {
    157     return msm_proc_comm(PCOM_CLKCTL_RPC_DISABLE, &id, 0);
    158 }
    159 
    160 int clock_set_rate(unsigned id, unsigned rate)
    161 {
    162     return msm_proc_comm(PCOM_CLKCTL_RPC_SET_RATE, &id, &rate);
    163 }
    164 
    165 int clock_get_rate(unsigned id)
    166 {
    167     if (msm_proc_comm(PCOM_CLKCTL_RPC_RATE, &id, 0)) {
    168         return -1;
    169     } else {
    170         return (int) id;
    171     }
    172 }
    173 
    174 void reboot(void)
    175 {
    176     msm_proc_comm(PCOM_RESET_CHIP, 0, 0);
    177     for (;;) ;
    178 }
    179 
    180 int vreg_enable(unsigned id)
    181 {
    182     unsigned n = 1;
    183     return msm_proc_comm(PCOM_VREG_SWITCH, &id, &n);
    184 }
    185 
    186 int vreg_disable(unsigned id)
    187 {
    188     unsigned n = 0;
    189     return msm_proc_comm(PCOM_VREG_SWITCH, &id, &n);
    190 }
    191 
    192 int vreg_set_level(unsigned id, unsigned level)
    193 {
    194     return msm_proc_comm(PCOM_VREG_SET_LEVEL, &id, &level);
    195 }
    196 
    197 
    198