diff --git a/bsp/allwinner_tina/drivers/drv_clock.c b/bsp/allwinner_tina/drivers/drv_clock.c index ad0d829683..b55cd6af4c 100644 --- a/bsp/allwinner_tina/drivers/drv_clock.c +++ b/bsp/allwinner_tina/drivers/drv_clock.c @@ -525,3 +525,89 @@ rt_err_t bus_software_reset_enalbe(enum bus_gate bus) return RT_EOK; } +rt_err_t mmc_set_clk(enum mmc_clk_id clk_id, int hz) +{ + unsigned int pll, pll_hz, div, n, oclk_dly, sclk_dly; + volatile rt_uint32_t *mmc_clk = (clk_id == SDMMC0) ? \ + (&CCU->sdmmc0_clk) : (&CCU->sdmmc1_clk); + + if (hz < 0) + { + return RT_EINVAL; + } + + if (hz == 0) + { + *mmc_clk &= ~(0x1 << 31); + return RT_EOK; + } + + if (hz <= 24000000) + { + pll = (0x0 << 24); + pll_hz = 24000000; + } + else + { + pll = (0x1 << 24); + pll_hz = periph_get_pll_clk(); + } + + div = pll_hz / hz; + if (pll_hz % hz) + { + div++; + } + + n = 0; + while (div > 16) + { + n++; + div = (div + 1) / 2; + } + + if (n > 3) + { + return -1; + } + + /* determine delays */ + if (hz <= 400000) + { + oclk_dly = 0; + sclk_dly = 0; + } + else if (hz <= 25000000) + { + oclk_dly = 0; + sclk_dly = 5; + } + else if (hz <= 50000000) + { + oclk_dly = 3; + sclk_dly = 4; + } + else + { + /* hz > 50000000 */ + oclk_dly = 1; + sclk_dly = 4; + } + + *mmc_clk = (0x1 << 31) | pll | (sclk_dly << 20) | \ + (n << 16) | (oclk_dly << 8) | (div - 1); + + return RT_EOK; +} + +rt_err_t dram_gate_clk_enable(enum dram_gate dram_gate) +{ + CCU->dram_gating |= (0x01 << dram_gate); + return RT_EOK; +} + +rt_err_t dram_gate_clk_disable(enum dram_gate dram_gate) +{ + CCU->dram_gating &= ~(0x01 << dram_gate); + return RT_EOK; +} diff --git a/bsp/allwinner_tina/drivers/drv_clock.h b/bsp/allwinner_tina/drivers/drv_clock.h index 7b71d77fa0..c1cb87af0a 100644 --- a/bsp/allwinner_tina/drivers/drv_clock.h +++ b/bsp/allwinner_tina/drivers/drv_clock.h @@ -34,13 +34,6 @@ #define CLK_PLL_SRC (0x02) #define PRE_DIV_SRC (0x03) -/* */ -#define BE_GATING_DRAM (0x1<<26) -#define FE_GATING_DRAM (0x1<<24) -#define TVD_GATING_DRAM (0x1<<3) -#define DEINTERLACE_GATING_DRAM (0x1<<2) -#define CSI_GATING_DRAM (0x1<<1) -#define VE_GATING_DRAM (0x1<<0) /* */ #define TCON_PLL_VIDEO_X1 (0x000) @@ -142,6 +135,21 @@ enum bus_gate AUDIO_CODEC_GATING = (0x00 | (0x2 << BUS_GATE_OFFSET_BIT)), }; +enum dram_gate +{ + BE_GATING_DRAM = 26, + FE_GATING_DRAM = 24, + TVD_GATING_DRAM = 3, + DEINTERLACE_GATING_DRAM = 2, + CSI_GATING_DRAM = 1, + VE_GATING_DRAM = 0 +}; +enum mmc_clk_id +{ + SDMMC0, + SDMMC1, +}; + struct tina_ccu { volatile rt_uint32_t pll_cpu_ctrl; /* 0x000 */ @@ -240,4 +248,8 @@ rt_err_t bus_gate_clk_disalbe(enum bus_gate bus); rt_err_t bus_software_reset_enalbe(enum bus_gate bus); rt_err_t bus_software_reset_disalbe(enum bus_gate bus); +rt_err_t dram_gate_clk_enable(enum dram_gate dram_gate); +rt_err_t dram_gate_clk_disable(enum dram_gate dram_gate); + +rt_err_t mmc_set_clk(enum mmc_clk_id clk_id, int hz); #endif \ No newline at end of file