diff --git a/bsp/artinchip/hal/cmu/aic_hal_pll_clk.c b/bsp/artinchip/hal/cmu/aic_hal_pll_clk.c index b70b37d3..28bcdf17 100644 --- a/bsp/artinchip/hal/cmu/aic_hal_pll_clk.c +++ b/bsp/artinchip/hal/cmu/aic_hal_pll_clk.c @@ -92,6 +92,34 @@ static int clk_pll_is_enable(struct aic_clk_comm_cfg *comm_cfg) return 0; } +static void clk_pll_enable_sdm(struct aic_clk_pll_cfg *pll, unsigned long parent_rate, u32 factor_n) +{ + u32 reg_val, ppm_max, sdm_amp; + u64 sdm_step; + + ppm_max = 1000000 / (factor_n + 1); + /* 1% spread */ + if (ppm_max < PLL_SDM_SPREAD_PPM) + sdm_amp = 0; + else + sdm_amp = PLL_SDM_AMP_MAX - + PLL_SDM_SPREAD_PPM * PLL_SDM_AMP_MAX / ppm_max; + + /* SDM uses triangular wave, 33KHz by default */ + sdm_step = (u64)(PLL_SDM_AMP_MAX - sdm_amp) * 2 * PLL_SDM_SPREAD_FREQ; + do_div(sdm_step, parent_rate); + if (sdm_step > 511) + sdm_step = 511; + + reg_val = (1UL << PLL_SDM_EN_BIT) | + (2 << PLL_SDM_MODE_BIT) | + (sdm_step << PLL_SDM_STEP_BIT) | + (3 << PLL_SDM_FREQ_BIT) | + (sdm_amp << PLL_SDM_AMP_BIT); + + writel(reg_val, cmu_reg(pll->offset_sdm)); +} + static unsigned long clk_pll_recalc_rate(struct aic_clk_comm_cfg *comm_cfg, unsigned long parent_rate) { @@ -99,7 +127,7 @@ static unsigned long clk_pll_recalc_rate(struct aic_clk_comm_cfg *comm_cfg, u32 factor_n, factor_m, factor_p, fra_in; u64 rate, rate_int, rate_fra; u8 fra_en = 0; - u32 sdm_en = 0; + u32 reg_val, sdm_en, sdm_bot; /* PLL output mux is CLK_24M */ if (!((readl(cmu_reg(pll->offset_gen)) >> PLL_OUT_MUX) & 0x1)) @@ -126,14 +154,17 @@ static unsigned long clk_pll_recalc_rate(struct aic_clk_comm_cfg *comm_cfg, } if (pll->type == AIC_PLL_SDM) { - sdm_en = readl(cmu_reg(pll->offset_sdm)); - sdm_en >>= 31; + reg_val = readl(cmu_reg(pll->offset_sdm)); + sdm_en = reg_val >> 31; + sdm_bot = reg_val & 0xFFFF; - /* Pll is SDM mode, but SDM is not enable - * Create a small deviation, let sys setup again + /* + * When the PLL is fractional PLL, SDM_EN will also be set to 1, + * so SDM_BOT is needed to help determine whether the spreading function + * has been enabled. */ - if (sdm_en == 0) - rate += 1; + if (!sdm_en || !sdm_bot) + clk_pll_enable_sdm(pll, parent_rate, factor_n); } #ifdef FPGA_BOARD_ARTINCHIP rate = fpga_board_rate[pll->id]; @@ -192,9 +223,8 @@ static int clk_pll_set_rate(struct aic_clk_comm_cfg *comm_cfg, u32 factor_n, factor_m, factor_p, reg_val; u64 val, fra_in = 0; u8 fra_en, factor_m_en; + u32 sdm_en; unsigned long vco_rate, pll_vco_min, pll_vco_max; - u32 ppm_max, sdm_amp, sdm_en = 0; - u64 sdm_step; struct aic_clk_pll_cfg *pll = to_clk_pll(comm_cfg); if (pll->flag & CLK_NO_CHANGE) @@ -266,32 +296,7 @@ static int clk_pll_set_rate(struct aic_clk_comm_cfg *comm_cfg, sdm_en = (1UL << PLL_SDM_EN_BIT) | (2UL << PLL_SDM_MODE_BIT); writel(sdm_en, cmu_reg(pll->offset_sdm)); } else if (pll->type == AIC_PLL_SDM) { - sdm_en = readl(cmu_reg(pll->offset_sdm)); - sdm_en >>= 31; - - ppm_max = 1000000 / (factor_n + 1); - /* 1% spread */ - if (ppm_max < PLL_SDM_SPREAD_PPM) - sdm_amp = 0; - else - sdm_amp = PLL_SDM_AMP_MAX - - PLL_SDM_SPREAD_PPM * - PLL_SDM_AMP_MAX / ppm_max; - - /* SDM uses triangular wave, 33KHz by default */ - sdm_step = (u64)(PLL_SDM_AMP_MAX - sdm_amp) * 2 * - PLL_SDM_SPREAD_FREQ; - do_div(sdm_step, parent_rate); - if (sdm_step > 511) - sdm_step = 511; - - reg_val = (1UL << PLL_SDM_EN_BIT) | - (2 << PLL_SDM_MODE_BIT) | - (sdm_step << PLL_SDM_STEP_BIT) | - (3 << PLL_SDM_FREQ_BIT) | - (sdm_amp << PLL_SDM_AMP_BIT); - - writel(reg_val, cmu_reg(pll->offset_sdm)); + clk_pll_enable_sdm(pll, parent_rate, factor_n); } reg_val = readl(cmu_reg(pll->offset_gen)); diff --git a/packages/artinchip/userid/spinand_bare.c b/packages/artinchip/userid/spinand_bare.c index 066cd8d1..b957d800 100644 --- a/packages/artinchip/userid/spinand_bare.c +++ b/packages/artinchip/userid/spinand_bare.c @@ -37,7 +37,7 @@ static int read_userid(struct mtd_dev *mtd, size_t offset, u8 *buf, size_t size) if (mtd->erasesize < USERID_MAX_SIZE) remain = mtd->erasesize; else - remain = USERID_MAX_SIZE; + remain = size; ptr = buf; while ((remain > 0) && (offset < end)) { diff --git a/packages/artinchip/userid/spinand_rtt.c b/packages/artinchip/userid/spinand_rtt.c index 59dda0a6..3a28c7ee 100644 --- a/packages/artinchip/userid/spinand_rtt.c +++ b/packages/artinchip/userid/spinand_rtt.c @@ -42,7 +42,7 @@ static int read_userid(struct rt_mtd_nand_device *mtd, size_t offset, u8 *buf, s if (erasesize < USERID_MAX_SIZE) remain = erasesize; else - remain = USERID_MAX_SIZE; + remain = size; ptr = buf; while ((remain > 0) && (offset < end)) { diff --git a/patches/20241204/CMU-PLL-PSRAM-instablity.tgz b/patches/20241204/CMU-PLL-PSRAM-instablity.tgz new file mode 100644 index 00000000..7c9e4e40 Binary files /dev/null and b/patches/20241204/CMU-PLL-PSRAM-instablity.tgz differ diff --git a/patches/20241204/userid-fix-heap-corrupt-by-buf-overflow-issue.tgz b/patches/20241204/userid-fix-heap-corrupt-by-buf-overflow-issue.tgz new file mode 100644 index 00000000..33568e9b Binary files /dev/null and b/patches/20241204/userid-fix-heap-corrupt-by-buf-overflow-issue.tgz differ