diff --git a/cpu/stm32/dist/clk_conf/clk_conf.c b/cpu/stm32/dist/clk_conf/clk_conf.c index 37455bcb9a..f21da30647 100644 --- a/cpu/stm32/dist/clk_conf/clk_conf.c +++ b/cpu/stm32/dist/clk_conf/clk_conf.c @@ -188,6 +188,10 @@ static void usage(char **argv) int main(int argc, char **argv) { + int char_offset = 0; + const unsigned int* stm32_model_p = stm32_f_model; + const clk_cfg_t* stm32_clk_cfg_p = stm32_f_clk_cfg; + int model_max = MODEL_F_MAX; if (argc < 2) { usage(argv); return 1; @@ -199,23 +203,36 @@ int main(int argc, char **argv) || !isdigit(argv[1][8]) || ((argv[1][5] != 'f') && (argv[1][5] != 'F') /* && (argv[1][5] != 'l') && (argv[1][5] != 'L') */)) { - fprintf(stderr, "Invalid model : %s\n", argv[1]); - return 1; + if (strlen(argv[1]) < 10 + || !isdigit(argv[1][7]) + || !isdigit(argv[1][8]) + || !isdigit(argv[1][9]) + || ((argv[1][5] != 'm') && (argv[1][5] != 'M')) + || ((argv[1][6] != 'p') && (argv[1][5] != 'p')) + ) { + fprintf(stderr, "Invalid model : %s\n", argv[1]); + return 1; + } + + char_offset = 1; + stm32_model_p = stm32_model_mp; + stm32_clk_cfg_p = stm32_mp_clk_cfg; + model_max = MODEL_MP_MAX; } - int model = atoi(argv[1] + 6); + int model = atoi(argv[1] + 6 + char_offset); int i; - for (i = 0; i < MODEL_MAX; i++) { - if (stm32_model[i] == model) { + for (i = 0; i < model_max; i++) { + if (stm32_model_p[i] == model) { break; } } - if (i == MODEL_MAX) { + if (i == model_max) { fprintf(stderr, "Unsupported CPU model %s\n", argv[1]); return 1; } - const clk_cfg_t *cfg = &stm32_clk_cfg[i]; + const clk_cfg_t *cfg = &stm32_clk_cfg_p[i]; /* print help for given cpu */ if (argc < 5) { @@ -399,6 +416,7 @@ int main(int argc, char **argv) /* APB prescalers */ unsigned apb1_pre; unsigned apb2_pre; + unsigned apb3_pre; for (apb1_pre = 1; apb1_pre <= 16; apb1_pre <<= 1) { if (coreclock / apb1_pre <= cfg->max_apb1) { @@ -412,6 +430,13 @@ int main(int argc, char **argv) } } } + if (cfg->family == STM32MP1) { + for (apb3_pre = 1; apb3_pre <= 16; apb3_pre <<= 1) { + if (coreclock / apb3_pre <= cfg->max_apb3) { + break; + } + } + } /* Print constants */ @@ -435,14 +460,32 @@ int main(int argc, char **argv) " * 1: external crystal available (always 32.768kHz) */\n" "#define CLOCK_LSE (%uU)\n", is_lse); printf("/* peripheral clock setup */\n"); + + if (cfg->family != STM32MP1) { printf("#define CLOCK_AHB_DIV RCC_CFGR_HPRE_DIV1\n" "#define CLOCK_AHB (CLOCK_CORECLOCK / 1)\n"); + } if (cfg->family == STM32F0) { printf("#define CLOCK_APB1_DIV RCC_CFGR_PPRE_DIV%u /* max %uMHz */\n" "#define CLOCK_APB1 (CLOCK_CORECLOCK / %u)\n", apb1_pre, cfg->max_apb1 / 1000000U, apb1_pre); printf("#define CLOCK_APB2 (CLOCK_APB1)\n"); } + else if (cfg->family == STM32MP1) { + /* TODO: Set to 1 by default, conf_clk is not able to handle this parameter */ + printf("#define CLOCK_MCU_DIV RCC_MCUDIVR_MCUDIV_1 /* max %uMHz */\n" + "#define CLOCK_MCU (CLOCK_CORECLOCK / 1)\n", + cfg->max_coreclock / 1000000U); + printf("#define CLOCK_APB1_DIV RCC_APB1DIVR_APB1DIV_%u /* max %uMHz */\n" + "#define CLOCK_APB1 (CLOCK_CORECLOCK / %u)\n", + apb1_pre, cfg->max_apb1 / 1000000U, apb1_pre); + printf("#define CLOCK_APB2_DIV RCC_APB2DIVR_APB2DIV_%u /* max %uMHz */\n" + "#define CLOCK_APB2 (CLOCK_CORECLOCK / %u)\n", + apb2_pre, cfg->max_apb2 / 1000000U, apb2_pre); + printf("#define CLOCK_APB3_DIV RCC_APB3DIVR_APB3DIV_%u /* max %uMHz */\n" + "#define CLOCK_APB3 (CLOCK_CORECLOCK / %u)\n", + apb3_pre, cfg->max_apb3 / 1000000U, apb3_pre); + } else { printf("#define CLOCK_APB1_DIV RCC_CFGR_PPRE1_DIV%u /* max %uMHz */\n" "#define CLOCK_APB1 (CLOCK_CORECLOCK / %u)\n", diff --git a/cpu/stm32/dist/clk_conf/clk_conf.h b/cpu/stm32/dist/clk_conf/clk_conf.h index 06b37b9214..844419dd8a 100644 --- a/cpu/stm32/dist/clk_conf/clk_conf.h +++ b/cpu/stm32/dist/clk_conf/clk_conf.h @@ -35,6 +35,7 @@ enum fam { STM32F3, STM32F4, STM32F7, + STM32MP1, FAM_MAX, }; /** @} */ @@ -106,8 +107,15 @@ enum { STM32F777, STM32F779, - MODEL_MAX, + MODEL_F_MAX, }; + +enum { + STM32MP157, + + MODEL_MP_MAX, +}; + /** @} */ /** @@ -167,6 +175,7 @@ typedef struct { unsigned max_coreclock; /**< Max coreclock */ unsigned max_apb1; /**< Max APB1 clock */ unsigned max_apb2; /**< Max APB2 clock */ + unsigned max_apb3; /**< Max APB3 clock */ unsigned hsi; /**< HSI frequency */ @@ -200,7 +209,7 @@ typedef struct { #define STM32F0(x) [STM32F0##x] = x /** List of supported models */ -static const unsigned stm32_model[] = { +static const unsigned stm32_f_model[] = { STM32F0(30), STM32F0(70), STM32F0(31), @@ -264,6 +273,13 @@ static const unsigned stm32_model[] = { STM32F(779), }; +#define STM32MP(x) [STM32MP##x] = x + +/** List of supported models */ +static const unsigned stm32_model_mp[] = { + STM32MP(157), +}; + /** STM32F2xx / STM32F401 PLL config */ #define stm32f2_4_192_pll_cfg { \ .min_vco_input = 1000000U, \ @@ -304,10 +320,30 @@ static const unsigned stm32_model[] = { .inc_q = 1, \ } +/** STM32MP1 PLL config */ +#define stm32mp1_pll_cfg { \ + .min_vco_input = 4000000U, \ + .max_vco_input = 16000000U, \ + .min_vco_output = 400000000U, \ + .max_vco_output = 800000000U, \ + .min_n = 25, \ + .max_n = 100, \ + .inc_n = 1, \ + .min_m = 2, \ + .max_m = 63, \ + .inc_m = 1, \ + .min_p = 2, \ + .max_p = 127, \ + .inc_p = 1, \ + .min_q = 2, \ + .max_q = 127, \ + .inc_q = 1, \ +} + /** * @brief Clock config for supported cpu */ -static const clk_cfg_t stm32_clk_cfg[] = { +static const clk_cfg_t stm32_f_clk_cfg[] = { [STM32F030 ... STM32F098] = { .family = STM32F0, .max_coreclock = 48000000U, @@ -595,6 +631,28 @@ static const clk_cfg_t stm32_clk_cfg[] = { }, }; + /** + * @brief Clock config for supported cpu + */ +static const clk_cfg_t stm32_mp_clk_cfg[] = { + [STM32MP157] = { + .family = STM32MP1, + .max_coreclock = 209000000U, + .max_apb1 = 104500000U, + .max_apb2 = 104500000U, + .max_apb3 = 104500000U, + .hsi = 64000000U, + .pll = stm32mp1_pll_cfg, + .has_pll_i2s = false, + .has_pll_sai = false, + .has_pll_i2s_m = false, + .has_pll_sai_m = false, + .has_pll_i2s_alt_input = false, + .has_alt_48MHz = 0, + .need_48MHz = true, + }, +}; + #ifdef __cplusplus } #endif