From mboxrd@z Thu Jan 1 00:00:00 1970 From: Ley Foon Tan Date: Fri, 17 Feb 2017 16:56:57 +0800 Subject: [U-Boot] [PATCH v4 25/28] arm: socfpga: arria10: Added drivers for Arria10 clock manager In-Reply-To: References: <1484025641-5412-1-git-send-email-tien.fong.chee@intel.com> <1484025641-5412-26-git-send-email-tien.fong.chee@intel.com> Message-ID: List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: u-boot@lists.denx.de On Mon, Jan 23, 2017 at 12:18 PM, Marek Vasut wrote: > On 01/10/2017 06:20 AM, Chee Tien Fong wrote: >> From: Tien Fong Chee >> >> The drivers is restructured such common functions, gen5 functions, and >> arria10 functions are moved to clock_manager.c, clock_manager_gen5 and >> clock_manager_arria10 respectively. >> >> Signed-off-by: Tien Fong Chee >> Cc: Marek Vasut >> Cc: Dinh Nguyen >> Cc: Ching Liang See >> Cc: Tien Fong >> --- >> arch/arm/mach-socfpga/clock_manager.c | 752 +++++++--------- >> arch/arm/mach-socfpga/clock_manager_arria10.c | 954 +++++++++++++++++++++ >> .../{clock_manager.c => clock_manager_gen5.c} | 240 +----- >> arch/arm/mach-socfpga/include/mach/clock_manager.h | 356 ++++++-- >> 4 files changed, 1573 insertions(+), 729 deletions(-) >> create mode 100644 arch/arm/mach-socfpga/clock_manager_arria10.c >> copy arch/arm/mach-socfpga/{clock_manager.c => clock_manager_gen5.c} (62%) >> >> diff --git a/arch/arm/mach-socfpga/clock_manager.c b/arch/arm/mach-socfpga/clock_manager.c >> index aa71636..d209f7d 100644 >> --- a/arch/arm/mach-socfpga/clock_manager.c >> +++ b/arch/arm/mach-socfpga/clock_manager.c >> @@ -1,5 +1,5 @@ >> /* >> - * Copyright (C) 2013 Altera Corporation >> + * Copyright (C) 2013-2016 Altera Corporation >> * >> * SPDX-License-Identifier: GPL-2.0+ >> */ >> @@ -7,416 +7,287 @@ >> #include >> #include >> #include >> +#include >> >> DECLARE_GLOBAL_DATA_PTR; >> >> +/* Function prototypes */ >> +/* Common prototypes */ >> +unsigned int cm_get_l4_sp_clk_hz(void); >> +unsigned int cm_get_qspi_controller_clk_hz(void); >> +unsigned int cm_get_mmc_controller_clk_hz(void); >> +unsigned int cm_get_spi_controller_clk_hz(void); >> +static void cm_print_clock_quick_summary(void); >> +int do_showclocks(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]); >> +void cm_wait_for_lock(uint32_t mask); >> +void cm_wait_for_fsm(void); >> +unsigned int cm_get_main_vco_clk_hz(void); >> +unsigned int cm_get_per_vco_clk_hz(void); >> +unsigned long cm_get_mpu_clk_hz(void); >> + >> static const struct socfpga_clock_manager *clock_manager_base = >> (struct socfpga_clock_manager *)SOCFPGA_CLKMGR_ADDRESS; >> >> -static void cm_wait_for_lock(uint32_t mask) >> +/* Common functions */ >> +int set_cpu_clk_info(void) >> { >> - register uint32_t inter_val; >> - uint32_t retry = 0; >> - do { >> - inter_val = readl(&clock_manager_base->inter) & mask; >> - if (inter_val == mask) >> - retry++; >> - else >> - retry = 0; >> - if (retry >= 10) >> - break; >> - } while (1); >> -} >> + /* Calculate the clock frequencies required for drivers */ >> + cm_get_l4_sp_clk_hz(); >> + cm_get_mmc_controller_clk_hz(); >> >> -/* function to poll in the fsm busy bit */ >> -static void cm_wait_for_fsm(void) >> -{ >> - while (readl(&clock_manager_base->stat) & CLKMGR_STAT_BUSY) >> - ; >> -} >> + gd->bd->bi_arm_freq = cm_get_mpu_clk_hz() / 1000000; >> + gd->bd->bi_dsp_freq = 0; >> >> -/* >> - * function to write the bypass register which requires a poll of the >> - * busy bit >> - */ >> -static void cm_write_bypass(uint32_t val) >> -{ >> - writel(val, &clock_manager_base->bypass); >> - cm_wait_for_fsm(); >> -} >> +#if defined(CONFIG_TARGET_SOCFPGA_GEN5) >> + gd->bd->bi_ddr_freq = cm_get_sdram_clk_hz() / 1000000; >> +#elif defined(CONFIG_TARGET_SOCFPGA_ARRIA10) >> + gd->bd->bi_ddr_freq = 0; > > What ? This cannot work ... For A10, ddr controller is on fpga side and we don't need the ddr freq for ddr setup. > >> +#endif >> >> -/* function to write the ctrl register which requires a poll of the busy bit */ >> -static void cm_write_ctrl(uint32_t val) >> -{ >> - writel(val, &clock_manager_base->ctrl); >> - cm_wait_for_fsm(); >> + return 0; >> } >> >> -/* function to write a clock register that has phase information */ >> -static void cm_write_with_phase(uint32_t value, >> - uint32_t reg_address, uint32_t mask) >> +unsigned int cm_get_spi_controller_clk_hz(void) >> { >> - /* poll until phase is zero */ >> - while (readl(reg_address) & mask) >> - ; >> + uint32_t clock = 0; >> >> - writel(value, reg_address); >> +#if defined(CONFIG_TARGET_SOCFPGA_GEN5) >> + uint32_t reg; >> + clock = cm_get_per_vco_clk_hz(); >> >> - while (readl(reg_address) & mask) >> - ; >> -} >> + /* get the clock prior L4 SP divider (periph_base_clk) */ >> + reg = readl(&clock_manager_base->per_pll.perbaseclk); >> + clock /= (reg + 1); >> +#elif defined(CONFIG_TARGET_SOCFPGA_ARRIA10) >> + clock = cm_get_l4_noc_hz(CLKMGR_MAINPLL_NOCDIV_L4MPCLK_LSB); >> +#endif > > You might want to consider separate clock manager for A10 and Gen5 to > avoid the massive ifdeffery. Yes, I will separate them to separate files. > >> -/* >> - * Setup clocks while making no assumptions about previous state of the clocks. >> - * >> - * Start by being paranoid and gate all sw managed clocks >> - * Put all plls in bypass >> - * Put all plls VCO registers back to reset value (bandgap power down). >> - * Put peripheral and main pll src to reset value to avoid glitch. >> - * Delay 5 us. >> - * Deassert bandgap power down and set numerator and denominator >> - * Start 7 us timer. >> - * set internal dividers >> - * Wait for 7 us timer. >> - * Enable plls >> - * Set external dividers while plls are locking >> - * Wait for pll lock >> - * Assert/deassert outreset all. >> - * Take all pll's out of bypass >> - * Clear safe mode >> - * set source main and peripheral clocks >> - * Ungate clocks >> - */ >> + return clock; >> +} >> Regards Ley Foon