Yuchen Huang | ec39cb3 | 2020-09-23 20:41:19 +0800 | [diff] [blame] | 1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
| 2 | |
| 3 | #include <console/console.h> |
| 4 | #include <delay.h> |
| 5 | #include <soc/addressmap.h> |
| 6 | #include <soc/pmif.h> |
| 7 | #include <soc/srclken_rc.h> |
| 8 | |
| 9 | #define RCTAG "[SRCLKEN_RC]" |
| 10 | #define rc_info(fmt, arg ...) printk(BIOS_INFO, RCTAG "%s,%d: " fmt, \ |
| 11 | __func__, __LINE__, ## arg) |
| 12 | |
| 13 | #define SRCLKEN_DBG 1 |
| 14 | |
| 15 | /* RC settle time setting */ |
| 16 | enum { |
| 17 | FULL_SET_HW_MODE = 0, /* dcxo mode use pmrc_en */ |
| 18 | VCORE_SETTLE_TIME = 1, /* ~= 30us */ |
| 19 | ULPOSC_SETTLE_TIME = 4, /* ~= 150us */ |
| 20 | XO_SETTLE_TIME = 0x1, /* 2 ^ (step_sz + 5) * 0x33 * 30.77ns ~= 400us */ |
| 21 | DCXO_SETTLE_TIME = 0x1, /* 2 ^ (step_sz + 5) * 0x87 * 30.77ns ~= 1063us */ |
| 22 | CENTROL_CNT_STEP = 0x3, /* fix in 3, central align with Mxx channel */ |
| 23 | DCXO_STABLE_TIME = 0x70, |
| 24 | XO_STABLE_TIME = 0x70, |
| 25 | KEEP_RC_SPI_ACTIVE_VAL = 1, |
| 26 | SRCLKEN_RC_EN_SEL_VAL = 0, |
| 27 | }; |
| 28 | |
| 29 | enum { |
| 30 | INIT_SUBSYS_FPM_TO_LPM = 1 << CHN_RF | 1 << CHN_DEEPIDLE | 1 << CHN_MD |
| 31 | | 1 << CHN_GPS | 1 << CHN_BT | 1 << CHN_WIFI |
| 32 | | 1 << CHN_MCU | 1 << CHN_COANT | 1 << CHN_NFC |
| 33 | | 1 << CHN_UFS | 1 << CHN_SCP | 1 << CHN_RESERVE, |
| 34 | INIT_SUBSYS_FPM_TO_BBLPM = 1 << CHN_DEEPIDLE, |
| 35 | INIT_SUBSYS_TO_HW = 1 << CHN_SUSPEND | 1 << CHN_DEEPIDLE | 1 << CHN_MCU, |
| 36 | }; |
| 37 | |
| 38 | /* RC central setting */ |
| 39 | enum { |
| 40 | RC_CENTRAL_ENABLE = 1, |
| 41 | RC_CENTRAL_DISABLE = 0, |
| 42 | SPI_TRIG_MODE = SRCLKENAO_MODE, /* use srlckenao to set vcore */ |
| 43 | IS_SPI_DONE_RELEASE = 0, /* release vcore when spi request done */ |
| 44 | IS_SPI2PMIC_SET_CLR = 0, /* register direct write */ |
| 45 | SRCLKENO_0_CTRL_M = MERGE_OR_MODE, /* merge with spm */ |
| 46 | VREQ_CTRL_M = BYPASS_MODE, /* merge with vreq */ |
| 47 | ULPOSC_CTRL_M_VAL = BYPASS_MODE, /* merge with ulposc */ |
| 48 | PWRAP_CTRL_M = MERGE_OR_MODE, /* merge with pwrap_scp */ |
| 49 | SPI_CLK_SRC = RC_32K, /* pmic spec under 200us */ |
| 50 | }; |
| 51 | |
| 52 | /* Other setting */ |
| 53 | enum { |
| 54 | DCXO_FPM_CTRL_MODE = MERGE_OR_MODE | ASYNC_MODE, /* merge with spm */ |
| 55 | PWRAP_TMOUT_VAL = 0xA, /* 31us * 0xa ~= 310us */ |
| 56 | FPM_MSK_B = FULL_SET_HW_MODE, |
| 57 | MD0_SRCLKENO_0_MASK_B = 0, /* md0 control by pmrc */ |
| 58 | }; |
| 59 | |
| 60 | enum { |
| 61 | SUB_BBLPM_SET = 1 << CHN_COANT | 1 << CHN_DEEPIDLE, |
| 62 | SUB_FPM_SET = 1 << CHN_SUSPEND | 1 << CHN_RF | 1 << CHN_MD |
| 63 | | 1 << CHN_GPS | 1 << CHN_BT | 1 << CHN_WIFI |
| 64 | | 1 << CHN_MCU | 1 << CHN_NFC | 1 << CHN_UFS |
| 65 | | 1 << CHN_SCP | 1 << CHN_RESERVE, |
| 66 | }; |
| 67 | |
| 68 | enum { |
| 69 | SW_FPM_LOW = 0, |
| 70 | SW_FPM_HIGH = 1, |
| 71 | }; |
| 72 | |
| 73 | enum { |
| 74 | SW_BBLPM_LOW = 0, |
| 75 | SW_BBLPM_HIGH = 1, |
| 76 | }; |
| 77 | |
| 78 | enum { |
| 79 | DXCO_SETTLE_BLK_DIS = 0, |
| 80 | DXCO_SETTLE_BLK_EN = 1, |
| 81 | }; |
| 82 | |
| 83 | #define SUB_CTRL_CON(_dcxo_prd, _xo_prd, _bypass_cmd, _dcxo_settle_blk_en) { \ |
| 84 | .dcxo_prd = _dcxo_prd, \ |
| 85 | .xo_prd = _xo_prd, \ |
| 86 | .cnt_step = CENTROL_CNT_STEP, \ |
| 87 | .track_en = 0x0, \ |
| 88 | .req_ack_imd_en = 0x1, \ |
| 89 | .xo_soc_link_en = 0x0, \ |
| 90 | .sw_bblpm = SW_BBLPM_LOW, \ |
| 91 | .sw_fpm = SW_FPM_HIGH, \ |
| 92 | .sw_rc = SW_MODE, \ |
| 93 | .bypass_cmd = _bypass_cmd, \ |
| 94 | .dcxo_settle_blk_en = _dcxo_settle_blk_en, \ |
| 95 | } |
| 96 | |
| 97 | static struct mtk_rc_regs *rc_regs = (struct mtk_rc_regs *)RC_BASE; |
| 98 | static struct mtk_rc_status_regs *rc_sta_regs = (struct mtk_rc_status_regs *)RC_STATUS_BASE; |
| 99 | |
| 100 | static struct subsys_rc_con rc_ctrl[MAX_CHN_NUM] = { |
| 101 | [CHN_SUSPEND] = SUB_CTRL_CON(DCXO_STABLE_TIME, XO_STABLE_TIME, 0x0, DXCO_SETTLE_BLK_EN), |
| 102 | [CHN_RF] = SUB_CTRL_CON(DCXO_STABLE_TIME, XO_STABLE_TIME, 0x0, DXCO_SETTLE_BLK_EN), |
| 103 | [CHN_DEEPIDLE] = SUB_CTRL_CON(DCXO_STABLE_TIME, XO_STABLE_TIME, |
| 104 | 0x0, DXCO_SETTLE_BLK_EN), |
| 105 | [CHN_MD] = SUB_CTRL_CON(DCXO_STABLE_TIME, XO_STABLE_TIME, 0x0, DXCO_SETTLE_BLK_EN), |
| 106 | [CHN_GPS] = SUB_CTRL_CON(DCXO_STABLE_TIME, XO_STABLE_TIME, 0x0, DXCO_SETTLE_BLK_EN), |
| 107 | [CHN_BT] = SUB_CTRL_CON(DCXO_STABLE_TIME, XO_STABLE_TIME, 0x0, DXCO_SETTLE_BLK_EN), |
| 108 | [CHN_WIFI] = SUB_CTRL_CON(DCXO_STABLE_TIME, XO_STABLE_TIME, 0x0, DXCO_SETTLE_BLK_EN), |
| 109 | [CHN_MCU] = SUB_CTRL_CON(DCXO_STABLE_TIME, XO_STABLE_TIME, 0x0, DXCO_SETTLE_BLK_EN), |
| 110 | [CHN_COANT] = SUB_CTRL_CON(0x0, 0x0, 0x1, DXCO_SETTLE_BLK_DIS), |
| 111 | [CHN_NFC] = SUB_CTRL_CON(DCXO_STABLE_TIME, XO_STABLE_TIME, 0x0, DXCO_SETTLE_BLK_EN), |
| 112 | [CHN_UFS] = SUB_CTRL_CON(DCXO_STABLE_TIME, XO_STABLE_TIME, 0x0, DXCO_SETTLE_BLK_EN), |
| 113 | [CHN_SCP] = SUB_CTRL_CON(0x0, 0x0, 0x1, DXCO_SETTLE_BLK_DIS), |
| 114 | [CHN_RESERVE] = SUB_CTRL_CON(0x0, 0x0, 0x1, DXCO_SETTLE_BLK_DIS), |
| 115 | }; |
| 116 | |
| 117 | static void pmic_read(u32 addr, u32 *rdata) |
| 118 | { |
| 119 | static struct pmif *pmif_arb; |
| 120 | |
| 121 | if (pmif_arb == NULL) |
| 122 | pmif_arb = get_pmif_controller(PMIF_SPI, 0); |
| 123 | |
| 124 | pmif_arb->read(pmif_arb, 0, addr, rdata); |
| 125 | } |
| 126 | |
| 127 | static void rc_dump_reg_info(void) |
| 128 | { |
| 129 | unsigned int chn_n; |
| 130 | |
| 131 | if (SRCLKEN_DBG) { |
| 132 | rc_info("SRCLKEN_RC_CFG:%#x\n", read32(&rc_regs->srclken_rc_cfg)); |
| 133 | rc_info("RC_CENTRAL_CFG1:%#x\n", read32(&rc_regs->rc_central_cfg1)); |
| 134 | rc_info("RC_CENTRAL_CFG2:%#x\n", read32(&rc_regs->rc_central_cfg2)); |
| 135 | rc_info("RC_CENTRAL_CFG3:%#x\n", read32(&rc_regs->rc_central_cfg3)); |
| 136 | rc_info("RC_CENTRAL_CFG4:%#x\n", read32(&rc_regs->rc_central_cfg4)); |
| 137 | rc_info("RC_DCXO_FPM_CFG:%#x\n", read32(&rc_regs->rc_dcxo_fpm_cfg)); |
| 138 | rc_info("SUBSYS_INTF_CFG:%#x\n", read32(&rc_regs->rc_subsys_intf_cfg)); |
| 139 | rc_info("RC_SPI_STA_0:%#x\n", read32(&rc_sta_regs->rc_spi_sta_0)); |
| 140 | rc_info("RC_PI_PO_STA:%#x\n", read32(&rc_sta_regs->rc_pi_po_sta_0)); |
| 141 | |
| 142 | for (chn_n = 0; chn_n < MAX_CHN_NUM; chn_n++) { |
| 143 | rc_info("M%02d: %#x\n", chn_n, |
| 144 | read32(&rc_regs->rc_mxx_srclken_cfg[chn_n])); |
| 145 | } |
| 146 | } |
| 147 | } |
| 148 | |
| 149 | /* RC initial flow and relative setting */ |
| 150 | static void __rc_ctrl_mode_switch(enum chn_id id, enum rc_ctrl_m mode) |
| 151 | { |
| 152 | switch (mode) { |
| 153 | case INIT_MODE: |
| 154 | SET32_BITFIELDS(&rc_regs->rc_mxx_srclken_cfg[id], |
| 155 | DCXO_SETTLE_BLK_EN, rc_ctrl[id].dcxo_settle_blk_en, |
| 156 | BYPASS_CMD_EN, rc_ctrl[id].bypass_cmd, |
| 157 | SW_SRCLKEN_RC, rc_ctrl[id].sw_rc, |
| 158 | SW_SRCLKEN_FPM, rc_ctrl[id].sw_fpm, |
| 159 | SW_SRCLKEN_BBLPM, rc_ctrl[id].sw_bblpm, |
| 160 | XO_SOC_LINK_EN, rc_ctrl[id].xo_soc_link_en, |
| 161 | REQ_ACK_LOW_IMD_EN, rc_ctrl[id].req_ack_imd_en, |
| 162 | SRCLKEN_TRACK_M_EN, rc_ctrl[id].track_en, |
| 163 | CNT_PRD_STEP, rc_ctrl[id].cnt_step, |
| 164 | XO_STABLE_PRD, rc_ctrl[id].xo_prd, |
| 165 | DCXO_STABLE_PRD, rc_ctrl[id].dcxo_prd); |
| 166 | break; |
| 167 | case SW_MODE: |
| 168 | SET32_BITFIELDS(&rc_regs->rc_mxx_srclken_cfg[id], SW_SRCLKEN_RC, 1); |
| 169 | break; |
| 170 | case HW_MODE: |
| 171 | SET32_BITFIELDS(&rc_regs->rc_mxx_srclken_cfg[id], SW_SRCLKEN_RC, 0); |
| 172 | break; |
| 173 | default: |
| 174 | die("Can't support rc_mode %d\n", mode); |
| 175 | } |
| 176 | |
| 177 | rc_info("M%02d: %#x\n", id, read32(&rc_regs->rc_mxx_srclken_cfg[id])); |
| 178 | } |
| 179 | |
| 180 | |
| 181 | /* RC subsys FPM control */ |
| 182 | static void __rc_ctrl_fpm_switch(enum chn_id id, unsigned int mode) |
| 183 | { |
| 184 | SET32_BITFIELDS(&rc_regs->rc_mxx_srclken_cfg[id], SW_SRCLKEN_FPM, !!mode); |
| 185 | rc_ctrl[id].sw_fpm = mode; |
| 186 | rc_info("M%02d FPM SWITCH: %#x\n", id, read32(&rc_regs->rc_mxx_srclken_cfg[id])); |
| 187 | } |
| 188 | |
| 189 | static void __rc_ctrl_bblpm_switch(enum chn_id id, unsigned int mode) |
| 190 | { |
| 191 | SET32_BITFIELDS(&rc_regs->rc_mxx_srclken_cfg[id], SW_SRCLKEN_BBLPM, !!mode); |
| 192 | rc_ctrl[id].sw_bblpm = mode; |
| 193 | rc_info("M%02d BBLPM SWITCH: %#x\n", id, read32(&rc_regs->rc_mxx_srclken_cfg[id])); |
| 194 | } |
| 195 | |
| 196 | static void rc_init_subsys_hw_mode(void) |
| 197 | { |
| 198 | unsigned int chn_n; |
| 199 | |
| 200 | for (chn_n = 0; chn_n < MAX_CHN_NUM; chn_n++) { |
| 201 | if (INIT_SUBSYS_TO_HW & (1 << chn_n)) |
| 202 | __rc_ctrl_mode_switch(chn_n, HW_MODE); |
| 203 | } |
| 204 | } |
| 205 | |
| 206 | static void rc_init_subsys_lpm(void) |
| 207 | { |
| 208 | unsigned int chn_n; |
| 209 | |
| 210 | for (chn_n = 0; chn_n < MAX_CHN_NUM; chn_n++) { |
| 211 | if (INIT_SUBSYS_FPM_TO_LPM & (1 << chn_n)) |
| 212 | __rc_ctrl_fpm_switch(chn_n, SW_FPM_LOW); |
| 213 | } |
| 214 | for (chn_n = 0; chn_n < MAX_CHN_NUM; chn_n++) { |
| 215 | if (INIT_SUBSYS_FPM_TO_BBLPM & (1 << chn_n)) |
| 216 | __rc_ctrl_bblpm_switch(chn_n, SW_BBLPM_HIGH); |
| 217 | } |
| 218 | } |
| 219 | |
| 220 | static void rc_ctrl_mode_switch_init(enum chn_id id) |
| 221 | { |
| 222 | __rc_ctrl_mode_switch(id, INIT_MODE); |
| 223 | } |
| 224 | |
| 225 | static enum rc_support srclken_rc_chk_init_cfg(void) |
| 226 | { |
| 227 | pmwrap_interface_init(); |
| 228 | if (!CONFIG(SRCLKEN_RC_SUPPORT)) { |
| 229 | rc_info("Bring-UP : skip srclken_rc init\n"); |
| 230 | return SRCLKEN_RC_DISABLE; |
| 231 | } |
| 232 | if (SRCLKEN_DBG) { |
| 233 | /* Enable debug trace */ |
| 234 | write32(&rc_sta_regs->rc_debug_trace, 1); |
| 235 | SET32_BITFIELDS(&rc_regs->rc_debug_cfg, TRACE_MODE_EN, 1); |
| 236 | } |
| 237 | return SRCLKEN_RC_ENABLE; |
| 238 | } |
| 239 | |
| 240 | int srclken_rc_init(void) |
| 241 | { |
| 242 | /* New co-clock architecture srclkenrc implement here */ |
| 243 | unsigned int chn_n; |
| 244 | int ret = 0; |
| 245 | |
| 246 | /* Check platform config to proceed init flow */ |
| 247 | if (srclken_rc_chk_init_cfg() != SRCLKEN_RC_ENABLE) |
| 248 | return ret; |
| 249 | |
| 250 | /* Set SW RESET 1 */ |
| 251 | SET32_BITFIELDS(&rc_regs->srclken_rc_cfg, SW_RESET, 1); |
| 252 | |
| 253 | /* Wait 100us */ |
| 254 | udelay(100); |
| 255 | |
| 256 | /* Set SW CG 1 */ |
| 257 | write32(&rc_regs->srclken_rc_cfg, |
| 258 | _BF_VALUE(SW_RESET, 1) | _BF_VALUE(CG_32K_EN, 1) | |
| 259 | _BF_VALUE(CG_FCLK_EN, 1) | _BF_VALUE(CG_FCLK_FR_EN, 1)); |
| 260 | |
| 261 | /* Wait 100us */ |
| 262 | udelay(100); |
| 263 | |
| 264 | /* Set Clock Mux */ |
| 265 | write32(&rc_regs->srclken_rc_cfg, |
| 266 | _BF_VALUE(SW_RESET, 1) | _BF_VALUE(CG_32K_EN, 1) | |
| 267 | _BF_VALUE(CG_FCLK_EN, 1) | _BF_VALUE(CG_FCLK_FR_EN, 1) | |
| 268 | _BF_VALUE(MUX_FCLK_FR, 1)); |
| 269 | |
| 270 | /* Set req_filter m00~m12 as default SW_FPM */ |
| 271 | for (chn_n = 0; chn_n < MAX_CHN_NUM; chn_n++) |
| 272 | rc_ctrl_mode_switch_init(chn_n); |
| 273 | |
| 274 | /* Set PMIC addr for SPI CMD */ |
| 275 | write32(&rc_regs->rc_pmic_rcen_addr, PMIC_PMRC_CON0); |
| 276 | |
| 277 | write32(&rc_regs->rc_pmic_rcen_set_clr_addr, |
| 278 | (PMIC_PMRC_CON0_CLR << 16) | PMIC_PMRC_CON0_SET); |
| 279 | |
| 280 | write32(&rc_regs->rc_cmd_arb_cfg, 0); |
| 281 | |
| 282 | /* CFG1 setting for spi cmd config */ |
| 283 | write32(&rc_regs->rc_central_cfg1, |
| 284 | _BF_VALUE(DCXO_SETTLE_T, DCXO_SETTLE_TIME) | |
| 285 | _BF_VALUE(NON_DCXO_SETTLE_T, XO_SETTLE_TIME) | |
| 286 | _BF_VALUE(ULPOSC_SETTLE_T, ULPOSC_SETTLE_TIME) | |
| 287 | _BF_VALUE(VCORE_SETTLE_T, VCORE_SETTLE_TIME) | |
| 288 | _BF_VALUE(SRCLKEN_RC_EN_SEL, SRCLKEN_RC_EN_SEL_VAL) | |
| 289 | _BF_VALUE(RC_SPI_ACTIVE, KEEP_RC_SPI_ACTIVE_VAL) | |
| 290 | _BF_VALUE(RCEN_ISSUE_M, IS_SPI2PMIC_SET_CLR) | |
| 291 | _BF_VALUE(SRCLKEN_RC_EN, RC_CENTRAL_DISABLE)); |
| 292 | |
| 293 | /* CFG2 setting for signal mode of each control mux */ |
| 294 | write32(&rc_regs->rc_central_cfg2, |
| 295 | _BF_VALUE(PWRAP_SLP_MUX_SEL, SPI_CLK_SRC) | |
| 296 | _BF_VALUE(PWRAP_SLP_CTRL_M, PWRAP_CTRL_M) | |
| 297 | _BF_VALUE(ULPOSC_CTRL_M, ULPOSC_CTRL_M_VAL) | |
| 298 | _BF_VALUE(SRCVOLTEN_VREQ_M, IS_SPI_DONE_RELEASE) | |
| 299 | _BF_VALUE(SRCVOLTEN_VREQ_SEL, SPI_TRIG_MODE) | |
| 300 | _BF_VALUE(VREQ_CTRL, VREQ_CTRL_M) | |
| 301 | _BF_VALUE(SRCVOLTEN_CTRL, SRCLKENO_0_CTRL_M)); |
| 302 | |
| 303 | write32(&rc_regs->rc_central_cfg3, |
| 304 | _BF_VALUE(TO_LPM_SETTLE_T, 0x4) | |
| 305 | _BF_VALUE(TO_BBLPM_SETTLE_EN, 1) | |
| 306 | _BF_VALUE(BLK_COANT_DXCO_MD_TARGET, 1) | |
| 307 | _BF_VALUE(BLK_SCP_DXCO_MD_TARGET, 1) | |
| 308 | _BF_VALUE(TO_LPM_SETTLE_EN, 1)); |
| 309 | |
| 310 | /* Set srclkeno_0/conn_bt as factor to allow dcxo change to FPM */ |
| 311 | write32(&rc_regs->rc_dcxo_fpm_cfg, |
| 312 | _BF_VALUE(SUB_SRCLKEN_FPM_MSK_B, FPM_MSK_B) | |
| 313 | _BF_VALUE(SRCVOLTEN_FPM_MSK_B, MD0_SRCLKENO_0_MASK_B) | |
| 314 | _BF_VALUE(DCXO_FPM_CTRL_M, DCXO_FPM_CTRL_MODE)); |
| 315 | |
| 316 | /* Set bblpm/fpm channel */ |
| 317 | write32(&rc_regs->rc_subsys_intf_cfg, |
| 318 | _BF_VALUE(SRCLKEN_BBLPM_MASK_B, SUB_BBLPM_SET) | |
| 319 | _BF_VALUE(SRCLKEN_FPM_MASK_B, SUB_FPM_SET)); |
| 320 | |
| 321 | /* Trigger srclken_rc enable */ |
| 322 | SET32_BITFIELDS(&rc_regs->rc_central_cfg1, |
| 323 | SRCLKEN_RC_EN, RC_CENTRAL_ENABLE); |
| 324 | |
| 325 | write32(&rc_regs->rc_central_cfg4, |
| 326 | _BF_VALUE(SLEEP_VLD_MODE, 0x1) | |
| 327 | _BF_VALUE(PWRAP_VLD_FORCE, 0x1) | |
| 328 | _BF_VALUE(KEEP_RC_SPI_ACTIVE, 0x800)); |
| 329 | |
| 330 | |
| 331 | /* Wait 100us */ |
| 332 | udelay(100); |
| 333 | |
| 334 | /* Set SW RESET 0 */ |
| 335 | write32(&rc_regs->srclken_rc_cfg, |
| 336 | _BF_VALUE(CG_32K_EN, 1) | _BF_VALUE(CG_FCLK_EN, 1) | |
| 337 | _BF_VALUE(CG_FCLK_FR_EN, 1) | _BF_VALUE(MUX_FCLK_FR, 1)); |
| 338 | |
| 339 | /* Wait 100us */ |
| 340 | udelay(100); |
| 341 | |
| 342 | /* Set SW CG 0 */ |
| 343 | write32(&rc_regs->srclken_rc_cfg, _BF_VALUE(MUX_FCLK_FR, 1)); |
| 344 | |
| 345 | /* Wait 500us */ |
| 346 | udelay(500); |
| 347 | |
| 348 | /* Set req_filter m00~m12 FPM to LPM */ |
| 349 | rc_init_subsys_lpm(); |
| 350 | |
| 351 | /* Polling ACK of Initial Subsys Input */ |
| 352 | for (chn_n = 0; chn_n < MAX_CHN_NUM; chn_n++) { |
| 353 | unsigned int chk_sta, shift_chn_n = 0; |
| 354 | int retry; |
| 355 | u32 temp; |
| 356 | |
| 357 | /* Fix RC_MXX_REQ_STA_0 register shift */ |
| 358 | if (chn_n > 0) |
| 359 | shift_chn_n = 1; |
| 360 | |
| 361 | chk_sta = (rc_ctrl[chn_n].sw_fpm & SW_SRCLKEN_FPM_MSK) << 1 | |
| 362 | (rc_ctrl[chn_n].sw_bblpm & SW_SRCLKEN_BBLPM_MSK) << 3; |
| 363 | retry = 200; |
| 364 | while ((read32(&rc_sta_regs->rc_mxx_req_sta_0[chn_n + shift_chn_n]) & 0xa) |
| 365 | != chk_sta && retry-- > 0) |
| 366 | udelay(10); |
| 367 | if (retry < 0) { |
| 368 | pmic_read(PMIC_PMRC_CON0, &temp); |
| 369 | rc_info("polling M%02d failed.(R:%#x)(C:%#x)(PMRC:%#x)\n", |
| 370 | chn_n, |
| 371 | read32(&rc_sta_regs->rc_mxx_req_sta_0[chn_n + shift_chn_n]), |
| 372 | read32(&rc_regs->rc_mxx_srclken_cfg[chn_n]), temp); |
| 373 | ret = -1; |
| 374 | } |
| 375 | } |
| 376 | |
| 377 | /* Set req_filter m00~m12 */ |
| 378 | rc_init_subsys_hw_mode(); |
| 379 | |
| 380 | /* Release force pmic req signal */ |
| 381 | write32(&rc_regs->rc_central_cfg4, |
| 382 | _BF_VALUE(SLEEP_VLD_MODE, 0x1) | |
| 383 | _BF_VALUE(KEEP_RC_SPI_ACTIVE, 0x800)); |
| 384 | |
| 385 | rc_dump_reg_info(); |
| 386 | |
| 387 | return ret; |
| 388 | } |