1 /* 2 * Arm SCP/MCP Software 3 * Copyright (c) 2019-2021, Arm Limited and Contributors. All rights reserved. 4 * 5 * SPDX-License-Identifier: BSD-3-Clause 6 * 7 * Description: 8 * Utility functions for Juno. 9 */ 10 11 #include "pl35x.h" 12 #include "scp_config.h" 13 14 #include <fwk_assert.h> 15 16 #include <stdbool.h> 17 #include <stddef.h> 18 #include <stdint.h> 19 20 #define SNOOP_CONTROL_L2ACCREQ UINT32_C(0x00000001) 21 #define SNOOP_CONTROL_L2ACCACK UINT32_C(0x00000002) 22 23 #define SMC_INIT_SET_CYCLES UINT32_C(0x000251FF) 24 #define SMC_INIT_SET_OP_MODE UINT32_C(0x00000046) 25 #define SMC_INIT_CMD_SET_CS3 UINT32_C(3U << 23) 26 #define SMC_INIT_CMD_UPDATE_REG UINT32_C(2U << 21) 27 juno_utils_open_snoop_gate_and_wait(volatile uint32_t * snoop_ctrl)28void juno_utils_open_snoop_gate_and_wait(volatile uint32_t *snoop_ctrl) 29 { 30 fwk_assert(snoop_ctrl != NULL); 31 32 *snoop_ctrl = SNOOP_CONTROL_L2ACCREQ; 33 while ((*snoop_ctrl & SNOOP_CONTROL_L2ACCACK) == 0) { 34 continue; 35 } 36 } 37 juno_utils_close_snoop_gate(volatile uint32_t * snoop_ctrl)38void juno_utils_close_snoop_gate(volatile uint32_t *snoop_ctrl) 39 { 40 fwk_assert(snoop_ctrl != NULL); 41 42 *snoop_ctrl &= ~SNOOP_CONTROL_L2ACCREQ; 43 } 44 juno_utils_atclk_clock_div_set(uint32_t divider)45void juno_utils_atclk_clock_div_set(uint32_t divider) 46 { 47 fwk_assert(divider <= 16); 48 fwk_assert(divider != 0); 49 50 SCP_CONFIG->ATCLK_CONTROL = 51 (SCP_CONFIG->ATCLK_CONTROL & ~SCP_CONFIG_STDCLK_CONTROL_CLKDIV_MASK) | 52 ((divider - 1) << SCP_CONFIG_STDCLK_CONTROL_CLKDIV_POS); 53 } 54 juno_utils_atclk_clock_div_set_check(uint32_t divider)55bool juno_utils_atclk_clock_div_set_check(uint32_t divider) 56 { 57 fwk_assert(divider <= 16); 58 fwk_assert(divider != 0); 59 60 return 61 ((SCP_CONFIG->ATCLK_CONTROL & SCP_CONFIG_STDCLK_CONTROL_CRNTCLKDIV_MASK) 62 == ((divider - 1) << SCP_CONFIG_STDCLK_CONTROL_CRNTCLKDIV_POS)); 63 } 64 juno_utils_atclk_clock_sel_set(uint32_t source)65void juno_utils_atclk_clock_sel_set(uint32_t source) 66 { 67 fwk_assert(source <= 2); 68 69 SCP_CONFIG->ATCLK_CONTROL = 70 (SCP_CONFIG->ATCLK_CONTROL & ~SCP_CONFIG_STDCLK_CONTROL_CLKSEL_MASK) | 71 (source << SCP_CONFIG_STDCLK_CONTROL_CLKSEL_POS); 72 } 73 juno_utils_atclk_clock_sel_set_check(uint32_t source)74bool juno_utils_atclk_clock_sel_set_check(uint32_t source) 75 { 76 fwk_assert(source <= 2); 77 78 return 79 ((SCP_CONFIG->ATCLK_CONTROL & SCP_CONFIG_STDCLK_CONTROL_CRNTCLK_MASK) == 80 (source << SCP_CONFIG_STDCLK_CONTROL_CRNTCLK_POS)); 81 } 82 juno_utils_traceclk_clock_div_set(uint32_t divider)83void juno_utils_traceclk_clock_div_set(uint32_t divider) 84 { 85 fwk_assert(divider <= 16); 86 fwk_assert(divider != 0); 87 88 SCP_CONFIG->TRACECLKIN_CONTROL = 89 (SCP_CONFIG->TRACECLKIN_CONTROL & 90 ~SCP_CONFIG_STDCLK_CONTROL_CLKDIV_MASK) | 91 ((divider - 1) << SCP_CONFIG_STDCLK_CONTROL_CLKDIV_POS); 92 } 93 juno_utils_traceclk_clock_div_set_check(uint32_t divider)94bool juno_utils_traceclk_clock_div_set_check(uint32_t divider) 95 { 96 fwk_assert(divider <= 16); 97 fwk_assert(divider != 0); 98 99 return ((SCP_CONFIG->TRACECLKIN_CONTROL & 100 SCP_CONFIG_STDCLK_CONTROL_CRNTCLKDIV_MASK) == 101 ((divider - 1) << SCP_CONFIG_STDCLK_CONTROL_CRNTCLKDIV_POS)); 102 } 103 juno_utils_traceclk_clock_sel_set(uint32_t source)104void juno_utils_traceclk_clock_sel_set(uint32_t source) 105 { 106 fwk_assert(source <= 2); 107 108 SCP_CONFIG->TRACECLKIN_CONTROL = 109 (SCP_CONFIG->TRACECLKIN_CONTROL & 110 ~SCP_CONFIG_STDCLK_CONTROL_CLKSEL_MASK) | 111 (source << SCP_CONFIG_STDCLK_CONTROL_CLKSEL_POS); 112 } 113 juno_utils_traceclk_clock_sel_set_check(uint32_t source)114bool juno_utils_traceclk_clock_sel_set_check(uint32_t source) 115 { 116 fwk_assert(source <= 2); 117 118 return ((SCP_CONFIG->TRACECLKIN_CONTROL & 119 SCP_CONFIG_STDCLK_CONTROL_CRNTCLK_MASK) == 120 (source << SCP_CONFIG_STDCLK_CONTROL_CRNTCLK_POS)); 121 } 122 juno_utils_pclkdbg_clock_div_set(uint32_t divider)123void juno_utils_pclkdbg_clock_div_set(uint32_t divider) 124 { 125 fwk_assert(divider <= 16); 126 fwk_assert(divider != 0); 127 128 SCP_CONFIG->PCLKDBG_CONTROL = 129 (SCP_CONFIG->PCLKDBG_CONTROL & ~SCP_CONFIG_STDCLK_CONTROL_CLKDIV_MASK) | 130 ((divider - 1) << SCP_CONFIG_STDCLK_CONTROL_CLKDIV_POS); 131 } 132 juno_utils_pclkdbg_clock_div_set_check(uint32_t divider)133bool juno_utils_pclkdbg_clock_div_set_check(uint32_t divider) 134 { 135 fwk_assert(divider <= 16); 136 fwk_assert(divider != 0); 137 138 return ((SCP_CONFIG->PCLKDBG_CONTROL & 139 SCP_CONFIG_STDCLK_CONTROL_CRNTCLKDIV_MASK) == 140 ((divider - 1) << SCP_CONFIG_STDCLK_CONTROL_CRNTCLKDIV_POS)); 141 } 142 juno_utils_system_clock_enable(uint32_t mask)143void juno_utils_system_clock_enable(uint32_t mask) 144 { 145 fwk_assert((mask & ~SCP_CONFIG_CLOCK_ENABLE_ALL) == 0); 146 147 SCP_CONFIG->CLOCK_ENABLE_SET |= mask; 148 while ((SCP_CONFIG->CLOCK_ENABLE_STATUS & mask) != mask) { 149 continue; 150 } 151 } 152 juno_utils_smc_init(void)153void juno_utils_smc_init(void) 154 { 155 /* Switch CS3 to 32 bit mode, with read and write sync */ 156 SMC->SET_CYCLES = SMC_INIT_SET_CYCLES; 157 SMC->SET_OPMODE = SMC_INIT_SET_OP_MODE; 158 SMC->DIRECT_CMD = SMC_INIT_CMD_SET_CS3 | SMC_INIT_CMD_UPDATE_REG; 159 } 160