6 #include "flash_layout.h"
8 #if (!QM_SENSOR) || (UNIT_TEST)
12 #include "soc_watch.h"
14 #if (QM_SENSOR) && (!UNIT_TEST)
16 #define get_ticks() __builtin_arc_lr(QM_SS_TSC_BASE + QM_SS_TIMER_COUNT)
17 #elif(QM_SENSOR) && (UNIT_TEST)
18 #define get_ticks() _rdtsc() % ((uint32_t)-1)
21 #define get_ticks() _rdtsc()
28 static uint32_t ticks_per_us = SYS_TICKS_PER_US_32MHZ;
36 static void apply_flash_timings(uint32_t sys_ticks_per_us)
40 for (flash = QM_FLASH_0; flash < QM_FLASH_NUM; flash++) {
41 if (sys_ticks_per_us <= SYS_TICKS_PER_US_4MHZ) {
46 QM_FLASH[flash]->tmg_ctrl |= QM_FLASH_CLK_SLOW;
47 QM_FLASH[flash]->tmg_ctrl &= ~QM_FLASH_WAIT_STATE_MASK;
48 }
else if (sys_ticks_per_us <= SYS_TICKS_PER_US_16MHZ) {
49 QM_FLASH[flash]->tmg_ctrl &= ~QM_FLASH_CLK_SLOW;
54 QM_FLASH[flash]->tmg_ctrl &= ~QM_FLASH_WAIT_STATE_MASK;
56 QM_FLASH[flash]->tmg_ctrl &= ~QM_FLASH_CLK_SLOW;
61 QM_FLASH[flash]->tmg_ctrl =
62 (QM_FLASH[flash]->tmg_ctrl &
63 ~QM_FLASH_WAIT_STATE_MASK) |
64 (1 << QM_FLASH_WAIT_STATE_OFFSET);
75 uint32_t *sys_ticks_per_us,
80 *sys_ticks_per_us = SYS_TICKS_PER_US_32MHZ / BIT(div);
81 *trim = QM_FLASH_DATA_TRIM_CODE->osc_trim_32mhz;
85 *sys_ticks_per_us = SYS_TICKS_PER_US_16MHZ / BIT(div);
86 *trim = QM_FLASH_DATA_TRIM_CODE->osc_trim_16mhz;
90 *sys_ticks_per_us = SYS_TICKS_PER_US_8MHZ / BIT(div);
91 *trim = QM_FLASH_DATA_TRIM_CODE->osc_trim_8mhz;
95 *sys_ticks_per_us = SYS_TICKS_PER_US_4MHZ / BIT(div);
96 *trim = QM_FLASH_DATA_TRIM_CODE->osc_trim_4mhz;
100 *sys_ticks_per_us = 1;
104 *sys_ticks_per_us = SYS_TICKS_PER_US_XTAL / BIT(div);
111 QM_CHECK(div < CLK_SYS_DIV_NUM, -EINVAL);
116 uint32_t sys_ticks_per_us = 1;
122 uint32_t ccu_sys_clk_ctl =
123 QM_SCSS_CCU->ccu_sys_clk_ctl & CLK_SYS_CLK_DIV_DEF_MASK;
126 clk_sys_compute_new_frequency(mode, div, &sys_ticks_per_us, &trim);
134 apply_flash_timings(SYS_TICKS_PER_US_32MHZ);
166 if ((trim & QM_FLASH_TRIM_PRESENT_MASK) ==
167 QM_FLASH_TRIM_PRESENT) {
171 QM_SCSS_CCU->osc0_cfg1 &= ~OSC0_CFG1_SI_FREQ_SEL_MASK;
172 QM_SCSS_CCU->osc0_cfg1 |= (mode << OSC0_CFG1_SI_FREQ_SEL_OFFS);
174 QM_SCSS_CCU->osc0_cfg1 |= QM_OSC0_EN_SI_OSC;
176 while (!(QM_SCSS_CCU->osc0_stat1 & QM_OSC0_LOCK_SI)) {
179 QM_SCSS_CCU->osc0_cfg1 &= ~QM_OSC0_MODE_SEL;
181 QM_SCSS_CCU->ccu_sys_clk_ctl =
182 ccu_sys_clk_ctl | QM_CCU_SYS_CLK_SEL |
183 (div << QM_CCU_SYS_CLK_DIV_OFFSET);
185 QM_SCSS_CCU->osc0_cfg1 &= ~QM_OSC0_EN_CRYSTAL;
191 (QM_CCU_RTC_CLK_EN | (div << QM_CCU_SYS_CLK_DIV_OFFSET));
193 QM_SCSS_CCU->ccu_sys_clk_ctl =
194 (ccu_sys_clk_ctl & ~(QM_CCU_SYS_CLK_SEL));
198 QM_SCSS_CCU->osc0_cfg1 |= QM_OSC0_EN_CRYSTAL;
199 sys_ticks_per_us = SYS_TICKS_PER_US_XTAL / BIT(div);
200 while (!(QM_SCSS_CCU->osc0_stat1 & QM_OSC0_LOCK_XTAL)) {
202 QM_SCSS_CCU->osc0_cfg1 |= QM_OSC0_MODE_SEL;
203 QM_SCSS_CCU->ccu_sys_clk_ctl =
204 ccu_sys_clk_ctl | QM_CCU_SYS_CLK_SEL |
205 (div << QM_CCU_SYS_CLK_DIV_OFFSET);
206 QM_SCSS_CCU->osc0_cfg1 &= ~QM_OSC0_EN_SI_OSC;
210 QM_SCSS_CCU->ccu_sys_clk_ctl |= QM_CCU_SYS_CLK_DIV_EN;
211 ticks_per_us = (sys_ticks_per_us > 0 ? sys_ticks_per_us : 1);
216 apply_flash_timings(sys_ticks_per_us);
225 QM_CHECK(NULL != value, -EINVAL);
227 *value = (QM_SCSS_CCU->osc0_cfg1 & OSC0_CFG1_FTRIMOTP_MASK) >>
228 OSC0_CFG1_FTRIMOTP_OFFS;
236 QM_SCSS_CCU->osc0_cfg0 |= BIT(1);
239 QM_SCSS_CCU->osc0_cfg1 &= ~OSC0_CFG1_FTRIMOTP_MASK;
240 QM_SCSS_CCU->osc0_cfg1 |=
241 (value << OSC0_CFG1_FTRIMOTP_OFFS) & OSC0_CFG1_FTRIMOTP_MASK;
253 QM_SCSS_CCU->osc0_cfg0 &= ~BIT(1);
262 QM_SCSS_CCU->ccu_periph_clk_div_ctl0 =
263 (div << QM_CCU_PERIPH_PCLK_DIV_OFFSET);
265 QM_SCSS_CCU->ccu_periph_clk_div_ctl0 |= QM_CCU_PERIPH_PCLK_DIV_EN;
275 QM_SCSS_CCU->ccu_gpio_db_clk_ctl & CLK_GPIO_DB_DIV_DEF_MASK;
276 reg |= (div << QM_CCU_GPIO_DB_DIV_OFFSET);
277 QM_SCSS_CCU->ccu_gpio_db_clk_ctl = reg;
279 QM_SCSS_CCU->ccu_gpio_db_clk_ctl |= QM_CCU_GPIO_DB_CLK_DIV_EN;
288 uint32_t reg = QM_SCSS_CCU->ccu_ext_clock_ctl & CLK_EXTERN_DIV_DEF_MASK;
289 reg |= (div << QM_CCU_EXTERN_DIV_OFFSET);
290 QM_SCSS_CCU->ccu_ext_clock_ctl = reg;
292 QM_SCSS_CCU->ccu_ext_clock_ctl |= QM_CCU_EXT_CLK_DIV_EN;
301 uint32_t reg = QM_SCSS_CCU->ccu_sys_clk_ctl & CLK_RTC_DIV_DEF_MASK;
302 reg |= (div << QM_CCU_RTC_CLK_DIV_OFFSET);
303 QM_SCSS_CCU->ccu_sys_clk_ctl = reg;
305 QM_SCSS_CCU->ccu_sys_clk_ctl |= QM_CCU_RTC_CLK_DIV_EN;
314 QM_SCSS_CCU->ccu_periph_clk_gate_ctl |= clocks;
316 #if (HAS_SW_SOCWATCH)
328 QM_SCSS_CCU->ccu_periph_clk_gate_ctl &= ~clocks;
330 #if (HAS_SW_SOCWATCH)
344 uint32_t timeout = ticks_per_us * microseconds;
348 unsigned long long tsc_start;
350 tsc_start = get_ticks();
352 while (get_ticks() - tsc_start < timeout) {
365 QM_SCSS_CCU->ccu_mlayer_ahb_ctl |= QM_CCU_USB_CLK_EN;
368 QM_USB_PLL_CFG0 = QM_USB_PLL_CFG0_DEFAULT | QM_USB_PLL_PDLD;
374 while (!(QM_USB_PLL_CFG0 & QM_USB_PLL_LOCK) && timeout) {
389 QM_SCSS_CCU->ccu_mlayer_ahb_ctl &= ~QM_CCU_USB_CLK_EN;
392 QM_USB_PLL_CFG0 &= ~QM_USB_PLL_PDLD;
398 while ((QM_USB_PLL_CFG0 & QM_USB_PLL_LOCK) && timeout) {
412 QM_SCSS_CCU->ccu_mlayer_ahb_ctl |= QM_CCU_DMA_CLK_EN;
419 QM_SCSS_CCU->ccu_mlayer_ahb_ctl &= ~QM_CCU_DMA_CLK_EN;
432 ((QM_SCSS_CCU->ccu_periph_clk_div_ctl0 &
433 CLK_PERIPH_DIV_DEF_MASK) >>
434 QM_CCU_PERIPH_PCLK_DIV_OFFSET);
clk_sys_mode_t
System clock mode type.
int clk_sys_set_mode(const clk_sys_mode_t mode, const clk_sys_div_t div)
Set clock mode and divisor.
int clk_sys_usb_disable(void)
Disable the USB Clock mode.
Real Time Clock Divider = 32768.
int clk_rtc_set_div(const clk_rtc_div_t div)
Change divider value of RTC.
int clk_periph_enable(const clk_periph_t clocks)
Enable clocks for peripherals / registers.
Peripheral Clock Divider = 8.
uint32_t get_i2c_clk_freq_in_mhz(void)
Get I2C clock frequency in MHz.
int clk_gpio_db_set_div(const clk_gpio_db_div_t div)
Change divider value of GPIO debounce clock.
Crystal Oscillator Clock.
int clk_dma_enable(void)
Enable the DMA clock.
Quark D2000 peripherals Enable.
0x018 Perip Clock Gate Ctl.
clk_sys_div_t
System clock divider type.
16MHz Hybrid Oscillator Clock.
int clk_trim_read(uint32_t *const value)
Read the silicon oscillator trim code for the current frequency.
clk_periph_div_t
Peripheral clock divider type.
32MHz Hybrid Oscillator Clock.
GPIO Clock Debounce Divider = 128.
External Crystal Clock Divider = 8.
clk_gpio_db_div_t
GPIO clock debounce divider type.
clk_rtc_div_t
RTC clock divider type.
void clk_sys_udelay(uint32_t microseconds)
Idle loop the processor for at least the value given in microseconds.
8MHz Hybrid Oscillator Clock.
uint32_t clk_sys_get_ticks_per_us(void)
Get number of system ticks per micro second.
int clk_periph_disable(const clk_periph_t clocks)
Disable clocks for peripherals / registers.
int clk_periph_set_div(const clk_periph_div_t div)
Change divider value of peripheral clock.
int clk_trim_apply(const uint32_t value)
Apply silicon oscillator trim code.
int clk_ext_set_div(const clk_ext_div_t div)
Change divider value of external clock.
int clk_dma_disable(void)
Disable the DMA clock.
4MHz Hybrid Oscillator Clock.
clk_periph_t
Peripheral clock register map.
clk_ext_div_t
External crystal clock divider type.
int clk_sys_usb_enable(void)
Enable the USB Clock mode.