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