summaryrefslogtreecommitdiff
path: root/platform/kendryte
diff options
context:
space:
mode:
authorDamien Le Moal <damien.lemoal@wdc.com>2019-01-03 08:32:25 +0300
committerDamien Le Moal <damien.lemoal@wdc.com>2019-01-03 08:32:25 +0300
commitc37a8508d14dae5b0d09c74b5de905bc585abbe3 (patch)
treeecc447160fb368affdc0dee0c99c7201a9cb6b6b /platform/kendryte
parent4079df63a7a081c649a350eafd92af51d99df448 (diff)
downloadopensbi-c37a8508d14dae5b0d09c74b5de905bc585abbe3.tar.xz
platform: kendryte/k210: Simplify sysctl code
Simplify sysctl.c code to only the used CPU freqency function. This reduces the size of the final firmware by 4KB. Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com>
Diffstat (limited to 'platform/kendryte')
-rw-r--r--platform/kendryte/k210/sysctl.c1766
-rw-r--r--platform/kendryte/k210/sysctl.h161
-rw-r--r--platform/kendryte/k210/uarths.c2
3 files changed, 20 insertions, 1909 deletions
diff --git a/platform/kendryte/k210/sysctl.c b/platform/kendryte/k210/sysctl.c
index 90aa0e2..5977e33 100644
--- a/platform/kendryte/k210/sysctl.c
+++ b/platform/kendryte/k210/sysctl.c
@@ -15,959 +15,18 @@
#include <sbi/riscv_encoding.h>
#include "sysctl.h"
-#define SYSCTRL_CLOCK_FREQ_IN0 (26000000UL)
-
-const u8 get_select_pll2[] = {
- [SYSCTL_SOURCE_IN0] = 0,
- [SYSCTL_SOURCE_PLL0] = 1,
- [SYSCTL_SOURCE_PLL1] = 2,
-};
-
-const u8 get_source_pll2[] = {
- [0] = SYSCTL_SOURCE_IN0,
- [1] = SYSCTL_SOURCE_PLL0,
- [2] = SYSCTL_SOURCE_PLL1,
-};
-
-const u8 get_select_aclk[] = {
- [SYSCTL_SOURCE_IN0] = 0,
- [SYSCTL_SOURCE_PLL0] = 1,
-};
-
-const u8 get_source_aclk[] = {
- [0] = SYSCTL_SOURCE_IN0,
- [1] = SYSCTL_SOURCE_PLL0,
-};
-
volatile sysctl_t *const sysctl = (volatile sysctl_t *)SYSCTL_BASE_ADDR;
-u32 sysctl_get_git_id(void)
-{
- return sysctl->git_id.git_id;
-}
-
-u32 sysctl_get_freq(void)
-{
- return sysctl->clk_freq.clk_freq;
-}
-
-static void sysctl_reset_ctl(sysctl_reset_t reset, u8 rst_value)
-{
- switch (reset) {
- case SYSCTL_RESET_SOC:
- sysctl->soft_reset.soft_reset = rst_value;
- break;
- case SYSCTL_RESET_ROM:
- sysctl->peri_reset.rom_reset = rst_value;
- break;
- case SYSCTL_RESET_DMA:
- sysctl->peri_reset.dma_reset = rst_value;
- break;
- case SYSCTL_RESET_AI:
- sysctl->peri_reset.ai_reset = rst_value;
- break;
- case SYSCTL_RESET_DVP:
- sysctl->peri_reset.dvp_reset = rst_value;
- break;
- case SYSCTL_RESET_FFT:
- sysctl->peri_reset.fft_reset = rst_value;
- break;
- case SYSCTL_RESET_GPIO:
- sysctl->peri_reset.gpio_reset = rst_value;
- break;
- case SYSCTL_RESET_SPI0:
- sysctl->peri_reset.spi0_reset = rst_value;
- break;
- case SYSCTL_RESET_SPI1:
- sysctl->peri_reset.spi1_reset = rst_value;
- break;
- case SYSCTL_RESET_SPI2:
- sysctl->peri_reset.spi2_reset = rst_value;
- break;
- case SYSCTL_RESET_SPI3:
- sysctl->peri_reset.spi3_reset = rst_value;
- break;
- case SYSCTL_RESET_I2S0:
- sysctl->peri_reset.i2s0_reset = rst_value;
- break;
- case SYSCTL_RESET_I2S1:
- sysctl->peri_reset.i2s1_reset = rst_value;
- break;
- case SYSCTL_RESET_I2S2:
- sysctl->peri_reset.i2s2_reset = rst_value;
- break;
- case SYSCTL_RESET_I2C0:
- sysctl->peri_reset.i2c0_reset = rst_value;
- break;
- case SYSCTL_RESET_I2C1:
- sysctl->peri_reset.i2c1_reset = rst_value;
- break;
- case SYSCTL_RESET_I2C2:
- sysctl->peri_reset.i2c2_reset = rst_value;
- break;
- case SYSCTL_RESET_UART1:
- sysctl->peri_reset.uart1_reset = rst_value;
- break;
- case SYSCTL_RESET_UART2:
- sysctl->peri_reset.uart2_reset = rst_value;
- break;
- case SYSCTL_RESET_UART3:
- sysctl->peri_reset.uart3_reset = rst_value;
- break;
- case SYSCTL_RESET_AES:
- sysctl->peri_reset.aes_reset = rst_value;
- break;
- case SYSCTL_RESET_FPIOA:
- sysctl->peri_reset.fpioa_reset = rst_value;
- break;
- case SYSCTL_RESET_TIMER0:
- sysctl->peri_reset.timer0_reset = rst_value;
- break;
- case SYSCTL_RESET_TIMER1:
- sysctl->peri_reset.timer1_reset = rst_value;
- break;
- case SYSCTL_RESET_TIMER2:
- sysctl->peri_reset.timer2_reset = rst_value;
- break;
- case SYSCTL_RESET_WDT0:
- sysctl->peri_reset.wdt0_reset = rst_value;
- break;
- case SYSCTL_RESET_WDT1:
- sysctl->peri_reset.wdt1_reset = rst_value;
- break;
- case SYSCTL_RESET_SHA:
- sysctl->peri_reset.sha_reset = rst_value;
- break;
- case SYSCTL_RESET_RTC:
- sysctl->peri_reset.rtc_reset = rst_value;
- break;
-
- default:
- break;
- }
-}
-
-void sysctl_reset(sysctl_reset_t reset)
-{
- sysctl_reset_ctl(reset, 1);
- sysctl_reset_ctl(reset, 0);
-}
-
-static int sysctl_clock_bus_en(sysctl_clock_t clock, u8 en)
-{
- /*
- * The timer is under APB0, to prevent apb0_clk_en1 and apb0_clk_en0
- * on same register, we split it to peripheral and central two
- * registers, to protect CPU close apb0 clock accidentally.
- *
- * The apb0_clk_en0 and apb0_clk_en1 have same function,
- * one of them set, the APB0 clock enable.
- */
-
- /* The APB clock should carefully disable */
- if (en) {
- switch (clock) {
- /*
- * These peripheral devices are under APB0
- * GPIO, UART1, UART2, UART3, SPI_SLAVE, I2S0, I2S1,
- * I2S2, I2C0, I2C1, I2C2, FPIOA, SHA256, TIMER0,
- * TIMER1, TIMER2
- */
- case SYSCTL_CLOCK_GPIO:
- case SYSCTL_CLOCK_SPI2:
- case SYSCTL_CLOCK_I2S0:
- case SYSCTL_CLOCK_I2S1:
- case SYSCTL_CLOCK_I2S2:
- case SYSCTL_CLOCK_I2C0:
- case SYSCTL_CLOCK_I2C1:
- case SYSCTL_CLOCK_I2C2:
- case SYSCTL_CLOCK_UART1:
- case SYSCTL_CLOCK_UART2:
- case SYSCTL_CLOCK_UART3:
- case SYSCTL_CLOCK_FPIOA:
- case SYSCTL_CLOCK_TIMER0:
- case SYSCTL_CLOCK_TIMER1:
- case SYSCTL_CLOCK_TIMER2:
- case SYSCTL_CLOCK_SHA:
- sysctl->clk_en_cent.apb0_clk_en = en;
- break;
-
- /*
- * These peripheral devices are under APB1
- * WDT, AES, OTP, DVP, SYSCTL
- */
- case SYSCTL_CLOCK_AES:
- case SYSCTL_CLOCK_WDT0:
- case SYSCTL_CLOCK_WDT1:
- case SYSCTL_CLOCK_OTP:
- case SYSCTL_CLOCK_RTC:
- sysctl->clk_en_cent.apb1_clk_en = en;
- break;
-
- /*
- * These peripheral devices are under APB2
- * SPI0, SPI1
- */
- case SYSCTL_CLOCK_SPI0:
- case SYSCTL_CLOCK_SPI1:
- sysctl->clk_en_cent.apb2_clk_en = en;
- break;
-
- default:
- break;
- }
- }
-
- return 0;
-}
-
-static int sysctl_clock_device_en(sysctl_clock_t clock, u8 en)
-{
- switch (clock) {
- /*
- * These devices are PLL
- */
- case SYSCTL_CLOCK_PLL0:
- sysctl->pll0.pll_out_en0 = en;
- break;
- case SYSCTL_CLOCK_PLL1:
- sysctl->pll1.pll_out_en1 = en;
- break;
- case SYSCTL_CLOCK_PLL2:
- sysctl->pll2.pll_out_en2 = en;
- break;
-
- /*
- * These devices are CPU, SRAM, APB bus, ROM, DMA, AI
- */
- case SYSCTL_CLOCK_CPU:
- sysctl->clk_en_cent.cpu_clk_en = en;
- break;
- case SYSCTL_CLOCK_SRAM0:
- sysctl->clk_en_cent.sram0_clk_en = en;
- break;
- case SYSCTL_CLOCK_SRAM1:
- sysctl->clk_en_cent.sram1_clk_en = en;
- break;
- case SYSCTL_CLOCK_APB0:
- sysctl->clk_en_cent.apb0_clk_en = en;
- break;
- case SYSCTL_CLOCK_APB1:
- sysctl->clk_en_cent.apb1_clk_en = en;
- break;
- case SYSCTL_CLOCK_APB2:
- sysctl->clk_en_cent.apb2_clk_en = en;
- break;
- case SYSCTL_CLOCK_ROM:
- sysctl->clk_en_peri.rom_clk_en = en;
- break;
- case SYSCTL_CLOCK_DMA:
- sysctl->clk_en_peri.dma_clk_en = en;
- break;
- case SYSCTL_CLOCK_AI:
- sysctl->clk_en_peri.ai_clk_en = en;
- break;
- case SYSCTL_CLOCK_DVP:
- sysctl->clk_en_peri.dvp_clk_en = en;
- break;
- case SYSCTL_CLOCK_FFT:
- sysctl->clk_en_peri.fft_clk_en = en;
- break;
- case SYSCTL_CLOCK_SPI3:
- sysctl->clk_en_peri.spi3_clk_en = en;
- break;
-
- /*
- * These peripheral devices are under APB0
- * GPIO, UART1, UART2, UART3, SPI_SLAVE, I2S0, I2S1,
- * I2S2, I2C0, I2C1, I2C2, FPIOA, SHA256, TIMER0,
- * TIMER1, TIMER2
- */
- case SYSCTL_CLOCK_GPIO:
- sysctl->clk_en_peri.gpio_clk_en = en;
- break;
- case SYSCTL_CLOCK_SPI2:
- sysctl->clk_en_peri.spi2_clk_en = en;
- break;
- case SYSCTL_CLOCK_I2S0:
- sysctl->clk_en_peri.i2s0_clk_en = en;
- break;
- case SYSCTL_CLOCK_I2S1:
- sysctl->clk_en_peri.i2s1_clk_en = en;
- break;
- case SYSCTL_CLOCK_I2S2:
- sysctl->clk_en_peri.i2s2_clk_en = en;
- break;
- case SYSCTL_CLOCK_I2C0:
- sysctl->clk_en_peri.i2c0_clk_en = en;
- break;
- case SYSCTL_CLOCK_I2C1:
- sysctl->clk_en_peri.i2c1_clk_en = en;
- break;
- case SYSCTL_CLOCK_I2C2:
- sysctl->clk_en_peri.i2c2_clk_en = en;
- break;
- case SYSCTL_CLOCK_UART1:
- sysctl->clk_en_peri.uart1_clk_en = en;
- break;
- case SYSCTL_CLOCK_UART2:
- sysctl->clk_en_peri.uart2_clk_en = en;
- break;
- case SYSCTL_CLOCK_UART3:
- sysctl->clk_en_peri.uart3_clk_en = en;
- break;
- case SYSCTL_CLOCK_FPIOA:
- sysctl->clk_en_peri.fpioa_clk_en = en;
- break;
- case SYSCTL_CLOCK_TIMER0:
- sysctl->clk_en_peri.timer0_clk_en = en;
- break;
- case SYSCTL_CLOCK_TIMER1:
- sysctl->clk_en_peri.timer1_clk_en = en;
- break;
- case SYSCTL_CLOCK_TIMER2:
- sysctl->clk_en_peri.timer2_clk_en = en;
- break;
- case SYSCTL_CLOCK_SHA:
- sysctl->clk_en_peri.sha_clk_en = en;
- break;
-
- /*
- * These peripheral devices are under APB1
- * WDT, AES, OTP, DVP, SYSCTL
- */
- case SYSCTL_CLOCK_AES:
- sysctl->clk_en_peri.aes_clk_en = en;
- break;
- case SYSCTL_CLOCK_WDT0:
- sysctl->clk_en_peri.wdt0_clk_en = en;
- break;
- case SYSCTL_CLOCK_WDT1:
- sysctl->clk_en_peri.wdt1_clk_en = en;
- break;
- case SYSCTL_CLOCK_OTP:
- sysctl->clk_en_peri.otp_clk_en = en;
- break;
- case SYSCTL_CLOCK_RTC:
- sysctl->clk_en_peri.rtc_clk_en = en;
- break;
-
- /*
- * These peripheral devices are under APB2
- * SPI0, SPI1
- */
- case SYSCTL_CLOCK_SPI0:
- sysctl->clk_en_peri.spi0_clk_en = en;
- break;
- case SYSCTL_CLOCK_SPI1:
- sysctl->clk_en_peri.spi1_clk_en = en;
- break;
-
- default:
- break;
- }
-
- return 0;
-}
-
-int sysctl_clock_enable(sysctl_clock_t clock)
-{
- if (clock >= SYSCTL_CLOCK_MAX)
- return -1;
-
- sysctl_clock_bus_en(clock, 1);
- sysctl_clock_device_en(clock, 1);
-
- return 0;
-}
-
-int sysctl_clock_disable(sysctl_clock_t clock)
-{
- if (clock >= SYSCTL_CLOCK_MAX)
- return -1;
-
- sysctl_clock_bus_en(clock, 0);
- sysctl_clock_device_en(clock, 0);
-
- return 0;
-}
-
-int sysctl_clock_set_threshold(sysctl_threshold_t which, int threshold)
-{
- int result = 0;
-
- switch (which) {
- /*
- * These threshold is 2 bit width
- */
- case SYSCTL_THRESHOLD_ACLK:
- sysctl->clk_sel0.aclk_divider_sel = (u8)threshold & 0x03;
- break;
-
- /*
- * These threshold is 3 bit width
- */
- case SYSCTL_THRESHOLD_APB0:
- sysctl->clk_sel0.apb0_clk_sel = (u8)threshold & 0x07;
- break;
- case SYSCTL_THRESHOLD_APB1:
- sysctl->clk_sel0.apb1_clk_sel = (u8)threshold & 0x07;
- break;
- case SYSCTL_THRESHOLD_APB2:
- sysctl->clk_sel0.apb2_clk_sel = (u8)threshold & 0x07;
- break;
-
- /*
- * These threshold is 4 bit width
- */
- case SYSCTL_THRESHOLD_SRAM0:
- sysctl->clk_th0.sram0_gclk_threshold = (u8)threshold & 0x0F;
- break;
- case SYSCTL_THRESHOLD_SRAM1:
- sysctl->clk_th0.sram1_gclk_threshold = (u8)threshold & 0x0F;
- break;
- case SYSCTL_THRESHOLD_AI:
- sysctl->clk_th0.ai_gclk_threshold = (u8)threshold & 0x0F;
- break;
- case SYSCTL_THRESHOLD_DVP:
- sysctl->clk_th0.dvp_gclk_threshold = (u8)threshold & 0x0F;
- break;
- case SYSCTL_THRESHOLD_ROM:
- sysctl->clk_th0.rom_gclk_threshold = (u8)threshold & 0x0F;
- break;
-
- /*
- * These threshold is 8 bit width
- */
- case SYSCTL_THRESHOLD_SPI0:
- sysctl->clk_th1.spi0_clk_threshold = (u8)threshold;
- break;
- case SYSCTL_THRESHOLD_SPI1:
- sysctl->clk_th1.spi1_clk_threshold = (u8)threshold;
- break;
- case SYSCTL_THRESHOLD_SPI2:
- sysctl->clk_th1.spi2_clk_threshold = (u8)threshold;
- break;
- case SYSCTL_THRESHOLD_SPI3:
- sysctl->clk_th1.spi3_clk_threshold = (u8)threshold;
- break;
- case SYSCTL_THRESHOLD_TIMER0:
- sysctl->clk_th2.timer0_clk_threshold = (u8)threshold;
- break;
- case SYSCTL_THRESHOLD_TIMER1:
- sysctl->clk_th2.timer1_clk_threshold = (u8)threshold;
- break;
- case SYSCTL_THRESHOLD_TIMER2:
- sysctl->clk_th2.timer2_clk_threshold = (u8)threshold;
- break;
- case SYSCTL_THRESHOLD_I2S0_M:
- sysctl->clk_th4.i2s0_mclk_threshold = (u8)threshold;
- break;
- case SYSCTL_THRESHOLD_I2S1_M:
- sysctl->clk_th4.i2s1_mclk_threshold = (u8)threshold;
- break;
- case SYSCTL_THRESHOLD_I2S2_M:
- sysctl->clk_th5.i2s2_mclk_threshold = (u8)threshold;
- break;
- case SYSCTL_THRESHOLD_I2C0:
- sysctl->clk_th5.i2c0_clk_threshold = (u8)threshold;
- break;
- case SYSCTL_THRESHOLD_I2C1:
- sysctl->clk_th5.i2c1_clk_threshold = (u8)threshold;
- break;
- case SYSCTL_THRESHOLD_I2C2:
- sysctl->clk_th5.i2c2_clk_threshold = (u8)threshold;
- break;
- case SYSCTL_THRESHOLD_WDT0:
- sysctl->clk_th6.wdt0_clk_threshold = (u8)threshold;
- break;
- case SYSCTL_THRESHOLD_WDT1:
- sysctl->clk_th6.wdt1_clk_threshold = (u8)threshold;
- break;
-
- /*
- * These threshold is 16 bit width
- */
- case SYSCTL_THRESHOLD_I2S0:
- sysctl->clk_th3.i2s0_clk_threshold = (u16)threshold;
- break;
- case SYSCTL_THRESHOLD_I2S1:
- sysctl->clk_th3.i2s1_clk_threshold = (u16)threshold;
- break;
- case SYSCTL_THRESHOLD_I2S2:
- sysctl->clk_th4.i2s2_clk_threshold = (u16)threshold;
- break;
-
- default:
- result = -1;
- break;
- }
-
- return result;
-}
-
-int sysctl_clock_get_threshold(sysctl_threshold_t which)
-{
- int threshold = 0;
-
- switch (which) {
- /*
- * Select and get threshold value
- */
- case SYSCTL_THRESHOLD_ACLK:
- threshold = (int)sysctl->clk_sel0.aclk_divider_sel;
- break;
- case SYSCTL_THRESHOLD_APB0:
- threshold = (int)sysctl->clk_sel0.apb0_clk_sel;
- break;
- case SYSCTL_THRESHOLD_APB1:
- threshold = (int)sysctl->clk_sel0.apb1_clk_sel;
- break;
- case SYSCTL_THRESHOLD_APB2:
- threshold = (int)sysctl->clk_sel0.apb2_clk_sel;
- break;
- case SYSCTL_THRESHOLD_SRAM0:
- threshold = (int)sysctl->clk_th0.sram0_gclk_threshold;
- break;
- case SYSCTL_THRESHOLD_SRAM1:
- threshold = (int)sysctl->clk_th0.sram1_gclk_threshold;
- break;
- case SYSCTL_THRESHOLD_AI:
- threshold = (int)sysctl->clk_th0.ai_gclk_threshold;
- break;
- case SYSCTL_THRESHOLD_DVP:
- threshold = (int)sysctl->clk_th0.dvp_gclk_threshold;
- break;
- case SYSCTL_THRESHOLD_ROM:
- threshold = (int)sysctl->clk_th0.rom_gclk_threshold;
- break;
- case SYSCTL_THRESHOLD_SPI0:
- threshold = (int)sysctl->clk_th1.spi0_clk_threshold;
- break;
- case SYSCTL_THRESHOLD_SPI1:
- threshold = (int)sysctl->clk_th1.spi1_clk_threshold;
- break;
- case SYSCTL_THRESHOLD_SPI2:
- threshold = (int)sysctl->clk_th1.spi2_clk_threshold;
- break;
- case SYSCTL_THRESHOLD_SPI3:
- threshold = (int)sysctl->clk_th1.spi3_clk_threshold;
- break;
- case SYSCTL_THRESHOLD_TIMER0:
- threshold = (int)sysctl->clk_th2.timer0_clk_threshold;
- break;
- case SYSCTL_THRESHOLD_TIMER1:
- threshold = (int)sysctl->clk_th2.timer1_clk_threshold;
- break;
- case SYSCTL_THRESHOLD_TIMER2:
- threshold = (int)sysctl->clk_th2.timer2_clk_threshold;
- break;
- case SYSCTL_THRESHOLD_I2S0:
- threshold = (int)sysctl->clk_th3.i2s0_clk_threshold;
- break;
- case SYSCTL_THRESHOLD_I2S1:
- threshold = (int)sysctl->clk_th3.i2s1_clk_threshold;
- break;
- case SYSCTL_THRESHOLD_I2S2:
- threshold = (int)sysctl->clk_th4.i2s2_clk_threshold;
- break;
- case SYSCTL_THRESHOLD_I2S0_M:
- threshold = (int)sysctl->clk_th4.i2s0_mclk_threshold;
- break;
- case SYSCTL_THRESHOLD_I2S1_M:
- threshold = (int)sysctl->clk_th4.i2s1_mclk_threshold;
- break;
- case SYSCTL_THRESHOLD_I2S2_M:
- threshold = (int)sysctl->clk_th5.i2s2_mclk_threshold;
- break;
- case SYSCTL_THRESHOLD_I2C0:
- threshold = (int)sysctl->clk_th5.i2c0_clk_threshold;
- break;
- case SYSCTL_THRESHOLD_I2C1:
- threshold = (int)sysctl->clk_th5.i2c1_clk_threshold;
- break;
- case SYSCTL_THRESHOLD_I2C2:
- threshold = (int)sysctl->clk_th5.i2c2_clk_threshold;
- break;
- case SYSCTL_THRESHOLD_WDT0:
- threshold = (int)sysctl->clk_th6.wdt0_clk_threshold;
- break;
- case SYSCTL_THRESHOLD_WDT1:
- threshold = (int)sysctl->clk_th6.wdt1_clk_threshold;
- break;
-
- default:
- break;
- }
-
- return threshold;
-}
-
-int sysctl_clock_set_clock_select(sysctl_clock_select_t which, int select)
-{
- int result = 0;
-
- switch (which) {
- /*
- * These clock select is 1 bit width
- */
- case SYSCTL_CLOCK_SELECT_PLL0_BYPASS:
- sysctl->pll0.pll_bypass0 = select & 0x01;
- break;
- case SYSCTL_CLOCK_SELECT_PLL1_BYPASS:
- sysctl->pll1.pll_bypass1 = select & 0x01;
- break;
- case SYSCTL_CLOCK_SELECT_PLL2_BYPASS:
- sysctl->pll2.pll_bypass2 = select & 0x01;
- break;
- case SYSCTL_CLOCK_SELECT_ACLK:
- sysctl->clk_sel0.aclk_sel = select & 0x01;
- break;
- case SYSCTL_CLOCK_SELECT_SPI3:
- sysctl->clk_sel0.spi3_clk_sel = select & 0x01;
- break;
- case SYSCTL_CLOCK_SELECT_TIMER0:
- sysctl->clk_sel0.timer0_clk_sel = select & 0x01;
- break;
- case SYSCTL_CLOCK_SELECT_TIMER1:
- sysctl->clk_sel0.timer1_clk_sel = select & 0x01;
- break;
- case SYSCTL_CLOCK_SELECT_TIMER2:
- sysctl->clk_sel0.timer2_clk_sel = select & 0x01;
- break;
- case SYSCTL_CLOCK_SELECT_SPI3_SAMPLE:
- sysctl->clk_sel1.spi3_sample_clk_sel = select & 0x01;
- break;
-
- /*
- * These clock select is 2 bit width
- */
- case SYSCTL_CLOCK_SELECT_PLL2:
- sysctl->pll2.pll_ckin_sel2 = select & 0x03;
- break;
-
- default:
- result = -1;
- break;
- }
-
- return result;
-}
-
-int sysctl_clock_get_clock_select(sysctl_clock_select_t which)
-{
- int clock_select = 0;
-
- switch (which) {
- /*
- * Select and get clock select value
- */
- case SYSCTL_CLOCK_SELECT_PLL0_BYPASS:
- clock_select = (int)sysctl->pll0.pll_bypass0;
- break;
- case SYSCTL_CLOCK_SELECT_PLL1_BYPASS:
- clock_select = (int)sysctl->pll1.pll_bypass1;
- break;
- case SYSCTL_CLOCK_SELECT_PLL2_BYPASS:
- clock_select = (int)sysctl->pll2.pll_bypass2;
- break;
- case SYSCTL_CLOCK_SELECT_PLL2:
- clock_select = (int)sysctl->pll2.pll_ckin_sel2;
- break;
- case SYSCTL_CLOCK_SELECT_ACLK:
- clock_select = (int)sysctl->clk_sel0.aclk_sel;
- break;
- case SYSCTL_CLOCK_SELECT_SPI3:
- clock_select = (int)sysctl->clk_sel0.spi3_clk_sel;
- break;
- case SYSCTL_CLOCK_SELECT_TIMER0:
- clock_select = (int)sysctl->clk_sel0.timer0_clk_sel;
- break;
- case SYSCTL_CLOCK_SELECT_TIMER1:
- clock_select = (int)sysctl->clk_sel0.timer1_clk_sel;
- break;
- case SYSCTL_CLOCK_SELECT_TIMER2:
- clock_select = (int)sysctl->clk_sel0.timer2_clk_sel;
- break;
- case SYSCTL_CLOCK_SELECT_SPI3_SAMPLE:
- clock_select = (int)sysctl->clk_sel1.spi3_sample_clk_sel;
- break;
-
- default:
- break;
- }
-
- return clock_select;
-}
-
-u32 sysctl_clock_source_get_freq(sysctl_clock_source_t input)
-{
- u32 result;
-
- switch (input) {
- case SYSCTL_SOURCE_IN0:
- result = SYSCTRL_CLOCK_FREQ_IN0;
- break;
- case SYSCTL_SOURCE_PLL0:
- result = sysctl_pll_get_freq(SYSCTL_PLL0);
- break;
- case SYSCTL_SOURCE_PLL1:
- result = sysctl_pll_get_freq(SYSCTL_PLL1);
- break;
- case SYSCTL_SOURCE_PLL2:
- result = sysctl_pll_get_freq(SYSCTL_PLL2);
- break;
- case SYSCTL_SOURCE_ACLK:
- result = sysctl_clock_get_freq(SYSCTL_CLOCK_ACLK);
- break;
- default:
- result = 0;
- break;
- }
-
- return result;
-}
-
-static int sysctl_pll_is_lock(sysctl_pll_t pll)
-{
- /*
- * All bit enable means PLL lock
- *
- * struct pll_lock_t
- * {
- * u8 overflow : 1;
- * u8 rfslip : 1;
- * u8 fbslip : 1;
- * };
- *
- */
-
- if (pll >= SYSCTL_PLL_MAX)
- return 0;
-
- switch (pll) {
- case SYSCTL_PLL0:
- return sysctl->pll_lock.pll_lock0 == 3;
-
- case SYSCTL_PLL1:
- return sysctl->pll_lock.pll_lock1 & 1;
-
- case SYSCTL_PLL2:
- return sysctl->pll_lock.pll_lock2 & 1;
-
- default:
- break;
- }
-
- return 0;
-}
-
-static int sysctl_pll_clear_slip(sysctl_pll_t pll)
-{
- if (pll >= SYSCTL_PLL_MAX)
- return -1;
-
- switch (pll) {
- case SYSCTL_PLL0:
- sysctl->pll_lock.pll_slip_clear0 = 1;
- break;
-
- case SYSCTL_PLL1:
- sysctl->pll_lock.pll_slip_clear1 = 1;
- break;
-
- case SYSCTL_PLL2:
- sysctl->pll_lock.pll_slip_clear2 = 1;
- break;
-
- default:
- break;
- }
-
- return sysctl_pll_is_lock(pll) ? 0 : -1;
-}
-
-int sysctl_pll_enable(sysctl_pll_t pll)
-{
- /*
- * ---+
- * PWRDN |
- * +-------------------------------------------------------------
- * ^
- * |
- * |
- * t1
- * +------------------+
- * RESET | |
- * ----------+ +-----------------------------------
- * ^ ^ ^
- * |<----- t_rst ---->|<---------- t_lock ---------->|
- * | | |
- * t2 t3 t4
- */
-
- if (pll >= SYSCTL_PLL_MAX)
- return -1;
-
- switch (pll) {
- case SYSCTL_PLL0:
- /* Do not bypass PLL */
- sysctl->pll0.pll_bypass0 = 0;
- /*
- * Power on the PLL, negtive from PWRDN
- * 0 is power off
- * 1 is power on
- */
- sysctl->pll0.pll_pwrd0 = 1;
- /*
- * Reset trigger of the PLL, connected RESET
- * 0 is free
- * 1 is reset
- */
- sysctl->pll0.pll_reset0 = 0;
- sysctl->pll0.pll_reset0 = 1;
- asm volatile ("nop");
- asm volatile ("nop");
- sysctl->pll0.pll_reset0 = 0;
- break;
-
- case SYSCTL_PLL1:
- /* Do not bypass PLL */
- sysctl->pll1.pll_bypass1 = 0;
- /*
- * Power on the PLL, negtive from PWRDN
- * 0 is power off
- * 1 is power on
- */
- sysctl->pll1.pll_pwrd1 = 1;
- /*
- * Reset trigger of the PLL, connected RESET
- * 0 is free
- * 1 is reset
- */
- sysctl->pll1.pll_reset1 = 0;
- sysctl->pll1.pll_reset1 = 1;
- asm volatile ("nop");
- asm volatile ("nop");
- sysctl->pll1.pll_reset1 = 0;
- break;
-
- case SYSCTL_PLL2:
- /* Do not bypass PLL */
- sysctl->pll2.pll_bypass2 = 0;
- /*
- * Power on the PLL, negtive from PWRDN
- * 0 is power off
- * 1 is power on
- */
- sysctl->pll2.pll_pwrd2 = 1;
- /*
- * Reset trigger of the PLL, connected RESET
- * 0 is free
- * 1 is reset
- */
- sysctl->pll2.pll_reset2 = 0;
- sysctl->pll2.pll_reset2 = 1;
- asm volatile ("nop");
- asm volatile ("nop");
- sysctl->pll2.pll_reset2 = 0;
- break;
-
- default:
- break;
- }
-
- return 0;
-}
-
-int sysctl_pll_disable(sysctl_pll_t pll)
-{
- if (pll >= SYSCTL_PLL_MAX)
- return -1;
-
- switch (pll) {
- case SYSCTL_PLL0:
- /* Bypass PLL */
- sysctl->pll0.pll_bypass0 = 1;
- /*
- * Power on the PLL, negtive from PWRDN
- * 0 is power off
- * 1 is power on
- */
- sysctl->pll0.pll_pwrd0 = 0;
- break;
-
- case SYSCTL_PLL1:
- /* Bypass PLL */
- sysctl->pll1.pll_bypass1 = 1;
- /*
- * Power on the PLL, negtive from PWRDN
- * 0 is power off
- * 1 is power on
- */
- sysctl->pll1.pll_pwrd1 = 0;
- break;
-
- case SYSCTL_PLL2:
- /* Bypass PLL */
- sysctl->pll2.pll_bypass2 = 1;
- /*
- * Power on the PLL, negtive from PWRDN
- * 0 is power off
- * 1 is power on
- */
- sysctl->pll2.pll_pwrd2 = 0;
- break;
-
- default:
- break;
- }
-
- return 0;
-}
+#define SYSCTRL_CLOCK_FREQ_IN0 (26000000UL)
-u32 sysctl_pll_get_freq(sysctl_pll_t pll)
+static u32 sysctl_pll0_get_freq(void)
{
- u32 freq_in = 0;
- u32 nr = 0, nf = 0, od = 0;
- u8 select = 0;
-
- if (pll >= SYSCTL_PLL_MAX)
- return 0;
+ u32 freq_in, nr, nf, od;
- switch (pll) {
- case SYSCTL_PLL0:
- freq_in = sysctl_clock_source_get_freq(SYSCTL_SOURCE_IN0);
- nr = sysctl->pll0.clkr0 + 1;
- nf = sysctl->pll0.clkf0 + 1;
- od = sysctl->pll0.clkod0 + 1;
- break;
-
- case SYSCTL_PLL1:
- freq_in = sysctl_clock_source_get_freq(SYSCTL_SOURCE_IN0);
- nr = sysctl->pll1.clkr1 + 1;
- nf = sysctl->pll1.clkf1 + 1;
- od = sysctl->pll1.clkod1 + 1;
- break;
-
- case SYSCTL_PLL2:
- /*
- * Get input freq accroding select register
- */
- select = sysctl->pll2.pll_ckin_sel2;
- if (select < sizeof(get_source_pll2))
- freq_in = sysctl_clock_source_get_freq(get_source_pll2[select]);
- else
- return 0;
-
- nr = sysctl->pll2.clkr2 + 1;
- nf = sysctl->pll2.clkf2 + 1;
- od = sysctl->pll2.clkod2 + 1;
- break;
-
- default:
- break;
- }
+ freq_in = SYSCTRL_CLOCK_FREQ_IN0;
+ nr = sysctl->pll0.clkr0 + 1;
+ nf = sysctl->pll0.clkf0 + 1;
+ od = sysctl->pll0.clkod0 + 1;
/*
* Get final PLL output freq
@@ -977,812 +36,19 @@ u32 sysctl_pll_get_freq(sysctl_pll_t pll)
return ((u64)freq_in * (u64)nf) / ((u64)nr * (u64)od);
}
-#if 0
-static u32 sysctl_pll_source_set_freq(sysctl_pll_t pll,
- sysctl_clock_source_t source, u32 freq)
-{
-
- const double vco_min = 3.5e+08;
- const double vco_max = 1.75e+09;
- const double ref_min = 1.36719e+07;
- const double ref_max = 1.75e+09;
- const int nr_min = 1;
- const int nr_max = 16;
- const int nf_min = 1;
- const int nf_max = 64;
- const int no_min = 1;
- const int no_max = 16;
- const int nb_min = 1;
- const int nb_max = 64;
- const int max_vco = 1;
- const int ref_rng = 1;
- int nr = 0;
- int nrx = 0;
- int nf = 0;
- int nfi = 0;
- int no = 0;
- int noe = 0;
- int not = 0;
- int nor = 0;
- int nore = 0;
- int nb = 0;
- int first = 0;
- int firstx = 0;
- int found = 0;
- long long nfx = 0;
- double fin = 0, fout = 0, fvco = 0;
- double val = 0, nval = 0, err = 0, merr = 0, terr = 0;
- int x_nrx = 0, x_no = 0, x_nb = 0;
- long long x_nfx = 0;
- double x_fvco = 0, x_err = 0;
- sysctl_pll0_t pll0;
- sysctl_pll1_t pll1;
- sysctl_pll2_t pll2;
- u32 freq_in = 0;
-
- if (pll >= SYSCTL_PLL_MAX)
- return 0;
-
- if (source >= SYSCTL_SOURCE_MAX)
- return 0;
-
- switch (pll) {
- case SYSCTL_PLL0:
- case SYSCTL_PLL1:
- /*
- * Check input clock source
- */
- if (source != SYSCTL_SOURCE_IN0)
- return 0;
- freq_in = sysctl_clock_source_get_freq(SYSCTL_SOURCE_IN0);
- /*
- * Check input clock freq
- */
- if (freq_in == 0)
- return 0;
- break;
-
- case SYSCTL_PLL2:
- /*
- * Check input clock source
- */
- if (source < sizeof(get_select_pll2))
- freq_in = sysctl_clock_source_get_freq(source);
- /*
- * Check input clock freq
- */
- if (freq_in == 0)
- return 0;
- break;
-
- default:
- return 0;
- }
-
- /*
- * Begin calculate PLL registers' value
- */
- fin = freq_in;
- fout = freq;
- val = fout / fin;
- terr = 0.5 / ((double)(nf_max / 2));
- first = firstx = 1;
- if (terr != -2) {
- first = 0;
- if (terr == 0)
- terr = 1e-16;
- merr = fabs(terr);
- }
- found = 0;
- for (nfi = val; nfi < nf_max; ++nfi) {
- nr = rint(((double)nfi) / val);
- if (nr == 0)
- continue;
- if ((ref_rng) && (nr < nr_min))
- continue;
- if (fin / ((double)nr) > ref_max)
- continue;
- nrx = nr;
- nf = nfx = nfi;
- nval = ((double)nfx) / ((double)nr);
- if (nf == 0)
- nf = 1;
- err = 1 - nval / val;
-
- if ((first) || (fabs(err) < merr * (1 + 1e-6)) || (fabs(err) < 1e-16)) {
- not = floor(vco_max / fout);
- for (no = (not > no_max) ? no_max : not; no > no_min; --no) {
- if ((ref_rng) && ((nr / no) < nr_min))
- continue;
- if ((nr % no) == 0)
- break;
- }
- if ((nr % no) != 0)
- continue;
- nor = ((not > no_max) ? no_max : not) / no;
- nore = nf_max / nf;
- if (nor > nore)
- nor = nore;
- noe = ceil(vco_min / fout);
- if (!max_vco) {
- nore = (noe - 1) / no + 1;
- nor = nore;
- not = 0; /* force next if to fail */
- }
- if ((((no * nor) < (not >> 1)) || ((no * nor) < noe)) && ((no * nor) < (nf_max / nf))) {
- no = nf_max / nf;
- if (no > no_max)
- no = no_max;
- if (no > not)
- no = not;
- nfx *= no;
- nf *= no;
- if ((no > 1) && (!firstx))
- continue;
- /* wait for larger nf in later iterations */
- } else {
- nrx /= no;
- nfx *= nor;
- nf *= nor;
- no *= nor;
- if (no > no_max)
- continue;
- if ((nor > 1) && (!firstx))
- continue;
- /* wait for larger nf in later iterations */
- }
-
- nb = nfx;
- if (nb < nb_min)
- nb = nb_min;
- if (nb > nb_max)
- continue;
-
- fvco = fin / ((double)nrx) * ((double)nfx);
- if (fvco < vco_min)
- continue;
- if (fvco > vco_max)
- continue;
- if (nf < nf_min)
- continue;
- if ((ref_rng) && (fin / ((double)nrx) < ref_min))
- continue;
- if ((ref_rng) && (nrx > nr_max))
- continue;
- if (!(((firstx) && (terr < 0)) || (fabs(err) < merr * (1 - 1e-6)) || ((max_vco) && (no > x_no))))
- continue;
- if ((!firstx) && (terr >= 0) && (nrx > x_nrx))
- continue;
-
- found = 1;
- x_no = no;
- x_nrx = nrx;
- x_nfx = nfx;
- x_nb = nb;
- x_fvco = fvco;
- x_err = err;
- first = firstx = 0;
- merr = fabs(err);
- if (terr != -1)
- continue;
- }
- }
-
- if (!found)
- return 0;
-
- nrx = x_nrx;
- nfx = x_nfx;
- no = x_no;
- nb = x_nb;
- fvco = x_fvco;
- err = x_err;
- if ((terr != -2) && (fabs(err) >= terr * (1 - 1e-6)))
- return 0;
-
- /*
- * Begin write PLL registers' value,
- * Using atomic write method.
- */
- switch (pll) {
- case SYSCTL_PLL0:
- /* Read register from bus */
- pll0 = sysctl->pll0;
- /* Set register temporary value */
- pll0.clkr0 = nrx - 1;
- pll0.clkf0 = nfx - 1;
- pll0.clkod0 = no - 1;
- pll0.bwadj0 = nb - 1;
- /* Write register back to bus */
- sysctl->pll0 = pll0;
- break;
-
- case SYSCTL_PLL1:
- /* Read register from bus */
- pll1 = sysctl->pll1;
- /* Set register temporary value */
- pll1.clkr1 = nrx - 1;
- pll1.clkf1 = nfx - 1;
- pll1.clkod1 = no - 1;
- pll1.bwadj1 = nb - 1;
- /* Write register back to bus */
- sysctl->pll1 = pll1;
- break;
-
- case SYSCTL_PLL2:
- /* Read register from bus */
- pll2 = sysctl->pll2;
- /* Set register temporary value */
- if (source < sizeof(get_select_pll2))
- pll2.pll_ckin_sel2 = get_select_pll2[source];
-
- pll2.clkr2 = nrx - 1;
- pll2.clkf2 = nfx - 1;
- pll2.clkod2 = no - 1;
- pll2.bwadj2 = nb - 1;
- /* Write register back to bus */
- sysctl->pll2 = pll2;
- break;
-
- default:
- return 0;
- }
-
- return sysctl_pll_get_freq(pll);
-}
-#endif
-
-u32 sysctl_clock_get_freq(sysctl_clock_t clock)
-{
- u32 source = 0;
- u32 result = 0;
-
- switch (clock) {
- /*
- * The clock IN0
- */
- case SYSCTL_CLOCK_IN0:
- source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_IN0);
- result = source;
- break;
-
- /*
- * These clock directly under PLL clock domain
- * They are using gated divider.
- */
- case SYSCTL_CLOCK_PLL0:
- source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_PLL0);
- result = source;
- break;
- case SYSCTL_CLOCK_PLL1:
- source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_PLL1);
- result = source;
- break;
- case SYSCTL_CLOCK_PLL2:
- source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_PLL2);
- result = source;
- break;
-
- /*
- * These clock directly under ACLK clock domain
- */
- case SYSCTL_CLOCK_CPU:
- switch (sysctl_clock_get_clock_select(SYSCTL_CLOCK_SELECT_ACLK)) {
- case 0:
- source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_IN0);
- break;
- case 1:
- source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_PLL0) /
- (2ULL << sysctl_clock_get_threshold(SYSCTL_THRESHOLD_ACLK));
- break;
- default:
- break;
- }
- result = source;
- break;
- case SYSCTL_CLOCK_DMA:
- switch (sysctl_clock_get_clock_select(SYSCTL_CLOCK_SELECT_ACLK)) {
- case 0:
- source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_IN0);
- break;
- case 1:
- source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_PLL0) /
- (2ULL << sysctl_clock_get_threshold(SYSCTL_THRESHOLD_ACLK));
- break;
- default:
- break;
- }
- result = source;
- break;
- case SYSCTL_CLOCK_FFT:
- switch (sysctl_clock_get_clock_select(SYSCTL_CLOCK_SELECT_ACLK)) {
- case 0:
- source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_IN0);
- break;
- case 1:
- source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_PLL0) /
- (2ULL << sysctl_clock_get_threshold(SYSCTL_THRESHOLD_ACLK));
- break;
- default:
- break;
- }
- result = source;
- break;
- case SYSCTL_CLOCK_ACLK:
- switch (sysctl_clock_get_clock_select(SYSCTL_CLOCK_SELECT_ACLK)) {
- case 0:
- source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_IN0);
- break;
- case 1:
- source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_PLL0) /
- (2ULL << sysctl_clock_get_threshold(SYSCTL_THRESHOLD_ACLK));
- break;
- default:
- break;
- }
- result = source;
- break;
- case SYSCTL_CLOCK_HCLK:
- switch (sysctl_clock_get_clock_select(SYSCTL_CLOCK_SELECT_ACLK)) {
- case 0:
- source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_IN0);
- break;
- case 1:
- source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_PLL0) /
- (2ULL << sysctl_clock_get_threshold(SYSCTL_THRESHOLD_ACLK));
- break;
- default:
- break;
- }
- result = source;
- break;
-
- /*
- * These clock under ACLK clock domain.
- * They are using gated divider.
- */
- case SYSCTL_CLOCK_SRAM0:
- source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_ACLK);
- result = source / (sysctl_clock_get_threshold(SYSCTL_THRESHOLD_SRAM0) + 1);
- break;
- case SYSCTL_CLOCK_SRAM1:
- source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_ACLK);
- result = source / (sysctl_clock_get_threshold(SYSCTL_THRESHOLD_SRAM1) + 1);
- break;
- case SYSCTL_CLOCK_ROM:
- source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_ACLK);
- result = source / (sysctl_clock_get_threshold(SYSCTL_THRESHOLD_ROM) + 1);
- break;
- case SYSCTL_CLOCK_DVP:
- source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_ACLK);
- result = source / (sysctl_clock_get_threshold(SYSCTL_THRESHOLD_DVP) + 1);
- break;
-
- /*
- * These clock under ACLK clock domain.
- * They are using even divider.
- */
- case SYSCTL_CLOCK_APB0:
- source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_ACLK);
- result = source / (sysctl_clock_get_threshold(SYSCTL_THRESHOLD_APB0) + 1);
- break;
- case SYSCTL_CLOCK_APB1:
- source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_ACLK);
- result = source / (sysctl_clock_get_threshold(SYSCTL_THRESHOLD_APB1) + 1);
- break;
- case SYSCTL_CLOCK_APB2:
- source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_ACLK);
- result = source / (sysctl_clock_get_threshold(SYSCTL_THRESHOLD_APB2) + 1);
- break;
-
- /*
- * These clock under AI clock domain.
- * They are using gated divider.
- */
- case SYSCTL_CLOCK_AI:
- source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_PLL1);
- result = source / (sysctl_clock_get_threshold(SYSCTL_THRESHOLD_AI) + 1);
- break;
-
- /*
- * These clock under I2S clock domain.
- * They are using even divider.
- */
- case SYSCTL_CLOCK_I2S0:
- source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_PLL2);
- result = source / ((sysctl_clock_get_threshold(SYSCTL_THRESHOLD_I2S0) + 1) * 2);
- break;
- case SYSCTL_CLOCK_I2S1:
- source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_PLL2);
- result = source / ((sysctl_clock_get_threshold(SYSCTL_THRESHOLD_I2S1) + 1) * 2);
- break;
- case SYSCTL_CLOCK_I2S2:
- source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_PLL2);
- result = source / ((sysctl_clock_get_threshold(SYSCTL_THRESHOLD_I2S2) + 1) * 2);
- break;
-
- /*
- * These clock under WDT clock domain.
- * They are using even divider.
- */
- case SYSCTL_CLOCK_WDT0:
- source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_IN0);
- result = source / ((sysctl_clock_get_threshold(SYSCTL_THRESHOLD_WDT0) + 1) * 2);
- break;
- case SYSCTL_CLOCK_WDT1:
- source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_IN0);
- result = source / ((sysctl_clock_get_threshold(SYSCTL_THRESHOLD_WDT1) + 1) * 2);
- break;
-
- /*
- * These clock under PLL0 clock domain.
- * They are using even divider.
- */
- case SYSCTL_CLOCK_SPI0:
- source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_PLL0);
- result = source / ((sysctl_clock_get_threshold(SYSCTL_THRESHOLD_SPI0) + 1) * 2);
- break;
- case SYSCTL_CLOCK_SPI1:
- source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_PLL0);
- result = source / ((sysctl_clock_get_threshold(SYSCTL_THRESHOLD_SPI1) + 1) * 2);
- break;
- case SYSCTL_CLOCK_SPI2:
- source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_PLL0);
- result = source / ((sysctl_clock_get_threshold(SYSCTL_THRESHOLD_SPI2) + 1) * 2);
- break;
- case SYSCTL_CLOCK_I2C0:
- source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_PLL0);
- result = source / ((sysctl_clock_get_threshold(SYSCTL_THRESHOLD_I2C0) + 1) * 2);
- break;
- case SYSCTL_CLOCK_I2C1:
- source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_PLL0);
- result = source / ((sysctl_clock_get_threshold(SYSCTL_THRESHOLD_I2C1) + 1) * 2);
- break;
- case SYSCTL_CLOCK_I2C2:
- source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_PLL0);
- result = source / ((sysctl_clock_get_threshold(SYSCTL_THRESHOLD_I2C2) + 1) * 2);
- break;
-
- /*
- * These clock under PLL0_SEL clock domain.
- * They are using even divider.
- */
- case SYSCTL_CLOCK_SPI3:
- switch (sysctl_clock_get_clock_select(SYSCTL_CLOCK_SELECT_SPI3)) {
- case 0:
- source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_IN0);
- break;
- case 1:
- source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_PLL0);
- break;
- default:
- break;
- }
-
- result = source / ((sysctl_clock_get_threshold(SYSCTL_THRESHOLD_SPI3) + 1) * 2);
- break;
- case SYSCTL_CLOCK_TIMER0:
- switch (sysctl_clock_get_clock_select(SYSCTL_CLOCK_SELECT_TIMER0)) {
- case 0:
- source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_IN0);
- break;
- case 1:
- source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_PLL0);
- break;
- default:
- break;
- }
-
- result = source / ((sysctl_clock_get_threshold(SYSCTL_THRESHOLD_TIMER0) + 1) * 2);
- break;
- case SYSCTL_CLOCK_TIMER1:
- switch (sysctl_clock_get_clock_select(SYSCTL_CLOCK_SELECT_TIMER1)) {
- case 0:
- source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_IN0);
- break;
- case 1:
- source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_PLL0);
- break;
- default:
- break;
- }
-
- result = source / ((sysctl_clock_get_threshold(SYSCTL_THRESHOLD_TIMER1) + 1) * 2);
- break;
- case SYSCTL_CLOCK_TIMER2:
- switch (sysctl_clock_get_clock_select(SYSCTL_CLOCK_SELECT_TIMER2)) {
- case 0:
- source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_IN0);
- break;
- case 1:
- source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_PLL0);
- break;
- default:
- break;
- }
-
- result = source / ((sysctl_clock_get_threshold(SYSCTL_THRESHOLD_TIMER2) + 1) * 2);
- break;
-
- /*
- * These clock under MISC clock domain.
- * They are using even divider.
- */
-
- /*
- * These clock under APB0 clock domain.
- * They are using even divider.
- */
- case SYSCTL_CLOCK_GPIO:
- source = sysctl_clock_get_freq(SYSCTL_CLOCK_APB0);
- result = source;
- break;
- case SYSCTL_CLOCK_UART1:
- source = sysctl_clock_get_freq(SYSCTL_CLOCK_APB0);
- result = source;
- break;
- case SYSCTL_CLOCK_UART2:
- source = sysctl_clock_get_freq(SYSCTL_CLOCK_APB0);
- result = source;
- break;
- case SYSCTL_CLOCK_UART3:
- source = sysctl_clock_get_freq(SYSCTL_CLOCK_APB0);
- result = source;
- break;
- case SYSCTL_CLOCK_FPIOA:
- source = sysctl_clock_get_freq(SYSCTL_CLOCK_APB0);
- result = source;
- break;
- case SYSCTL_CLOCK_SHA:
- source = sysctl_clock_get_freq(SYSCTL_CLOCK_APB0);
- result = source;
- break;
-
- /*
- * These clock under APB1 clock domain.
- * They are using even divider.
- */
- case SYSCTL_CLOCK_AES:
- source = sysctl_clock_get_freq(SYSCTL_CLOCK_APB1);
- result = source;
- break;
- case SYSCTL_CLOCK_OTP:
- source = sysctl_clock_get_freq(SYSCTL_CLOCK_APB1);
- result = source;
- break;
- case SYSCTL_CLOCK_RTC:
- source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_IN0);
- result = source;
- break;
-
- /*
- * These clock under APB2 clock domain.
- * They are using even divider.
- */
- default:
- break;
- }
-
- return result;
-}
-
-int sysctl_dma_select(sysctl_dma_channel_t channel, sysctl_dma_select_t select)
-{
- sysctl_dma_sel0_t dma_sel0;
- sysctl_dma_sel1_t dma_sel1;
-
- /* Read register from bus */
- dma_sel0 = sysctl->dma_sel0;
- dma_sel1 = sysctl->dma_sel1;
- switch (channel) {
- case SYSCTL_DMA_CHANNEL_0:
- dma_sel0.dma_sel0 = select;
- break;
-
- case SYSCTL_DMA_CHANNEL_1:
- dma_sel0.dma_sel1 = select;
- break;
-
- case SYSCTL_DMA_CHANNEL_2:
- dma_sel0.dma_sel2 = select;
- break;
-
- case SYSCTL_DMA_CHANNEL_3:
- dma_sel0.dma_sel3 = select;
- break;
-
- case SYSCTL_DMA_CHANNEL_4:
- dma_sel0.dma_sel4 = select;
- break;
-
- case SYSCTL_DMA_CHANNEL_5:
- dma_sel1.dma_sel5 = select;
- break;
-
- default:
- return -1;
- }
-
- /* Write register back to bus */
- sysctl->dma_sel0 = dma_sel0;
- sysctl->dma_sel1 = dma_sel1;
-
- return 0;
-}
-
-u32 sysctl_pll_fast_enable_pll(void)
-{
- sysctl_pll0_t pll0;
- sysctl_pll1_t pll1;
- sysctl_pll2_t pll2;
-
- /* Read register from bus */
- pll0 = sysctl->pll0;
- pll1 = sysctl->pll1;
- pll2 = sysctl->pll2;
-
- /*
- * Begin write PLL registers' value,
- * Using atomic write method.
- */
- /* PLL VCO MAX freq: 1.8GHz */
-
- /* PLL0: 26M reference clk get 793M output clock */
- pll0.clkr0 = 0;
- pll0.clkf0 = 60;
- pll0.clkod0 = 1;
- pll0.bwadj0 = 60;
-
- /* PLL1: 26M reference clk get 390M output clock */
- pll1.clkr1 = 0;
- pll1.clkf1 = 59;
- pll1.clkod1 = 3;
- pll1.bwadj1 = 59;
-
- /* PLL2: 26M reference clk get 390M output clock */
- pll2.clkr2 = 0;
- pll2.clkf2 = 59;
- pll2.clkod2 = 3;
- pll2.bwadj2 = 59;
-
- /* Write register to bus */
- sysctl->pll0 = pll0;
- sysctl->pll1 = pll1;
- sysctl->pll2 = pll2;
-
- sysctl_pll_enable(SYSCTL_PLL0);
- sysctl_pll_enable(SYSCTL_PLL1);
- sysctl_pll_enable(SYSCTL_PLL2);
-
- while (sysctl_pll_is_lock(SYSCTL_PLL0) == 0)
- sysctl_pll_clear_slip(SYSCTL_PLL0);
- while (sysctl_pll_is_lock(SYSCTL_PLL1) == 0)
- sysctl_pll_clear_slip(SYSCTL_PLL1);
- while (sysctl_pll_is_lock(SYSCTL_PLL2) == 0)
- sysctl_pll_clear_slip(SYSCTL_PLL2);
-
- sysctl_clock_enable(SYSCTL_CLOCK_PLL0);
- sysctl_clock_enable(SYSCTL_CLOCK_PLL1);
- sysctl_clock_enable(SYSCTL_CLOCK_PLL2);
-
- /* Set ACLK to PLL0 */
- sysctl_clock_set_clock_select(SYSCTL_CLOCK_SELECT_ACLK, SYSCTL_SOURCE_PLL0);
-
- return 0;
-}
-
-u32 sysctl_set_spi0_dvp_data(u8 en)
+u32 sysctl_get_cpu_freq(void)
{
- sysctl->misc.spi_dvp_data_enable = en;
- return 0;
-}
+ int clock_source;
-void sysctl_set_power_mode(sysctl_power_bank_t power_bank, sysctl_io_power_mode_t io_power_mode)
-{
- if(io_power_mode)
- *((u32 *)(&sysctl->power_sel)) |= (1 << power_bank);
- else
- *((u32 *)(&sysctl->power_sel)) &= ~(1 << power_bank);
-}
-
-#if 0
-u32 sysctl_pll_set_freq(sysctl_pll_t pll, u32 pll_freq)
-{
- u32 result;
-
- if(pll_freq == 0)
- return 0;
-
- volatile sysctl_general_pll_t *v_pll_t;
- switch(pll) {
- case SYSCTL_PLL0:
- v_pll_t = (sysctl_general_pll_t *)(&sysctl->pll0);
- break;
- case SYSCTL_PLL1:
- v_pll_t = (sysctl_general_pll_t *)(&sysctl->pll1);
- break;
- case SYSCTL_PLL2:
- v_pll_t = (sysctl_general_pll_t *)(&sysctl->pll2);
- break;
+ clock_source = (int)sysctl->clk_sel0.aclk_sel;
+ switch (clock_source) {
+ case 0:
+ return SYSCTRL_CLOCK_FREQ_IN0;
+ case 1:
+ return sysctl_pll0_get_freq() /
+ (2ULL << (int)sysctl->clk_sel0.aclk_divider_sel);
default:
return 0;
- break;
}
-
- /* 1. Change CPU CLK to XTAL */
- if (pll == SYSCTL_PLL0)
- sysctl_clock_set_clock_select(SYSCTL_CLOCK_SELECT_ACLK, SYSCTL_SOURCE_IN0);
-
- /* 2. Disable PLL output */
- v_pll_t->pll_out_en = 0;
-
- /* 3. Turn off PLL */
- v_pll_t->pll_pwrd = 0;
-
- /* 4. Set PLL new value */
- if (pll == SYSCTL_PLL2)
- result = sysctl_pll_source_set_freq(pll, v_pll_t->pll_ckin_sel, pll_freq);
- else
- result = sysctl_pll_source_set_freq(pll, SYSCTL_SOURCE_IN0, pll_freq);
-
- /* 5. Power on PLL */
- v_pll_t->pll_pwrd = 1;
- /* wait >100ns */
- sysctl_usleep(1);
-
- /* 6. Reset PLL then Release Reset*/
- v_pll_t->pll_reset = 0;
- v_pll_t->pll_reset = 1;
- /* wait >100ns */
- sysctl_usleep(1);
- v_pll_t->pll_reset = 0;
-
- /* 7. Get lock status, wait PLL stable */
- while (sysctl_pll_is_lock(pll) == 0)
- sysctl_pll_clear_slip(pll);
-
- /* 8. Enable PLL output */
- v_pll_t->pll_out_en = 1;
-
- /* 9. Change CPU CLK to PLL */
- if (pll == SYSCTL_PLL0)
- sysctl_clock_set_clock_select(SYSCTL_CLOCK_SELECT_ACLK, SYSCTL_SOURCE_PLL0);
-
- return result;
-}
-
-u32 sysctl_cpu_set_freq(u32 freq)
-{
- if (freq == 0)
- return 0;
-
- return sysctl_pll_set_freq(SYSCTL_PLL0, (sysctl->clk_sel0.aclk_divider_sel + 1) * 2 * freq);
-}
-#endif
-
-void sysctl_enable_irq(void)
-{
- csr_read_set(mie, MIP_MEIP);
- csr_read_set(mstatus, MSTATUS_MIE);
}
-void sysctl_disable_irq(void)
-{
- csr_read_clear(mie, MIP_MEIP);
- csr_read_clear(mstatus, MSTATUS_MIE);
-}
-
-u64 sysctl_get_time_us(void)
-{
- u64 v_cycle = read_cycle();
-
- return v_cycle * 1000000 / sysctl_clock_get_freq(SYSCTL_CLOCK_CPU);
-}
-
-void sysctl_usleep(u64 usec)
-{
- u64 nop_all = usec * sysctl_clock_get_freq(SYSCTL_CLOCK_CPU) / 1000000UL;
- u64 cycle = read_cycle();
-
- while (read_cycle() - cycle < nop_all);
-}
diff --git a/platform/kendryte/k210/sysctl.h b/platform/kendryte/k210/sysctl.h
index 09d81ae..aa95d62 100644
--- a/platform/kendryte/k210/sysctl.h
+++ b/platform/kendryte/k210/sysctl.h
@@ -782,164 +782,9 @@ typedef struct _sysctl_general_pll {
} __attribute__((packed, aligned(4))) sysctl_general_pll_t;
/**
- * System controller object instanse
+ * Get frequency of CPU
+ * @return The frequency of the CPU
*/
-extern volatile sysctl_t *const sysctl;
-
-/**
- * Enable clock for peripheral
- * @param[in] clock The clock to be enable
- * @return result
- * - 0 Success
- * - Other Fail
- */
-int sysctl_clock_enable(sysctl_clock_t clock);
-
-/**
- * Enable clock for peripheral
- * @param[in] clock The clock to be disable
- * @return result
- * - 0 Success
- * - Other Fail
- */
-int sysctl_clock_disable(sysctl_clock_t clock);
-
-/**
- * Sysctl clock set threshold
- * @param[in] which Which threshold to set
- * @param[in] threshold The threshold value
- * @return result
- * - 0 Success
- * - Other Fail
- */
-int sysctl_clock_set_threshold(sysctl_threshold_t which, int threshold);
-
-/**
- * Sysctl clock get threshold
- * @param[in] which Which threshold to get
- * @return The threshold value
- * - Other Value of threshold
- * - -1 Fail
- */
-int sysctl_clock_get_threshold(sysctl_threshold_t which);
-
-/**
- * Sysctl clock set clock select
- * @param[in] which Which clock select to set
- * @param[in] select The clock select value
- * @return result
- * - 0 Success
- * - Other Fail
- */
-int sysctl_clock_set_clock_select(sysctl_clock_select_t which, int select);
-
-/**
- * Sysctl clock get clock select
- * @param[in] which Which clock select to get
- * @return The clock select value
- * - Other Value of clock select
- * - -1 Fail
- */
-int sysctl_clock_get_clock_select(sysctl_clock_select_t which);
-
-/**
- * Get PLL frequency
- * @param[in] pll The PLL id
- * @return The frequency of PLL
- */
-u32 sysctl_pll_get_freq(sysctl_pll_t pll);
-
-/**
- * Get base clock frequency by clock id
- * @param[in] clock The clock id
- * @return The clock frequency
- */
-u32 sysctl_clock_get_freq(sysctl_clock_t clock);
-
-/**
- * Reset device by reset controller
- * @param[in] reset The reset signal
- */
-void sysctl_reset(sysctl_reset_t reset);
-
-/**
- * Enable the PLL and power on with reset
- * @param[in] pll The pll id
- * @return Result
- * - 0 Success
- * - Other Fail
- */
-int sysctl_pll_enable(sysctl_pll_t pll);
-
-/**
- * Disable the PLL and power off
- * @param[in] pll The pll id
- * @return Result
- * - 0 Success
- * - Other Fail
- */
-int sysctl_pll_disable(sysctl_pll_t pll);
-
-/**
- * Select DMA channel handshake peripheral signal
- * @param[in] channel The DMA channel
- * @param[in] select The peripheral select
- * @return Result
- * - 0 Success
- * - Other Fail
- */
-int sysctl_dma_select(sysctl_dma_channel_t channel, sysctl_dma_select_t select);
-
-/**
- * Set SPI0_D0-D7 DVP_D0-D7 as spi and dvp data pin
- * @param[in] en Enable or not
- * @return Result
- * - 0 Success
- * - Other Fail
- */
-u32 sysctl_set_spi0_dvp_data(u8 en);
-
-/**
- * Set io power mode
- * @param[in] power_bank IO power bank
- * @param[in] io_power_mode Set power mode 3.3v or 1.8
- * @return Result
- * - 0 Success
- * - Other Fail
- */
-void sysctl_set_power_mode(sysctl_power_bank_t power_bank, sysctl_io_power_mode_t io_power_mode);
-
-/**
- * Set frequency of CPU
- * @param[in] freq The desired frequency in Hz
- * @return The actual frequency of CPU after set
- */
-u32 sysctl_cpu_set_freq(u32 freq);
-
-/**
- * Init PLL freqency
- * @param[in] pll The PLL id
- * @param[in] pll_freq The desired frequency in Hz
-
- */
-u32 sysctl_pll_set_freq(sysctl_pll_t pll, u32 pll_freq);
-
-/**
- * Enable interrupt
- */
-void sysctl_enable_irq(void);
-
-/**
- * Disable interrupt
- */
-void sysctl_disable_irq(void);
-
-/**
- * Get the time start up to now
- * @return The time of microsecond
- */
-u64 sysctl_get_time_us(void);
-
-void sysctl_usleep(u64 usec);
+u32 sysctl_get_cpu_freq(void);
#endif /* _K210_SYSCTL_H_ */
diff --git a/platform/kendryte/k210/uarths.c b/platform/kendryte/k210/uarths.c
index 6551de7..2a189aa 100644
--- a/platform/kendryte/k210/uarths.c
+++ b/platform/kendryte/k210/uarths.c
@@ -21,7 +21,7 @@ static volatile struct uarths *const uarths =
void uarths_init(u32 baud_rate, enum uarths_stopbit stopbit)
{
- u32 freq = sysctl_clock_get_freq(SYSCTL_CLOCK_CPU);
+ u32 freq = sysctl_get_cpu_freq();
u16 div = freq / baud_rate - 1;
/* Set UART registers */