diff options
author | Tom Rini <trini@konsulko.com> | 2020-04-16 17:14:44 -0400 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2020-04-16 17:14:44 -0400 |
commit | 0f238dab6d17caabe4f9781d23aaa6087139f2bd (patch) | |
tree | 4c3aaa186537f37fe3bfd6240862a74b32ffd837 | |
parent | cf87f7cd8cdb35761103720a102df9bf5b88c1b2 (diff) | |
parent | 7b50db8242b62c85a19da9521b703faa858f4a63 (diff) | |
download | u-boot-0f238dab6d17caabe4f9781d23aaa6087139f2bd.tar.gz |
Merge tag 'arc-fixes-for-2020.07-rc1' of https://gitlab.denx.de/u-boot/custodians/u-boot-arc
This is pretty minor set of changes mostly touching HSDK board:
* Enable on-chip reset controller on HSDK
* Add possibility to turn-on & off L2$ on more
recent ARC HS processors.
* AXI tunnel clock calculation on HSDK
-rw-r--r-- | arch/arc/dts/hsdk.dts | 7 | ||||
-rw-r--r-- | arch/arc/include/asm/cache.h | 7 | ||||
-rw-r--r-- | arch/arc/lib/cache.c | 118 | ||||
-rw-r--r-- | configs/hsdk_defconfig | 1 | ||||
-rw-r--r-- | drivers/clk/clk-hsdk-cgu.c | 3 |
5 files changed, 126 insertions, 10 deletions
diff --git a/arch/arc/dts/hsdk.dts b/arch/arc/dts/hsdk.dts index 34ef3a620a..cf2ce8a1f6 100644 --- a/arch/arc/dts/hsdk.dts +++ b/arch/arc/dts/hsdk.dts @@ -6,6 +6,7 @@ #include "skeleton.dtsi" #include "dt-bindings/clock/snps,hsdk-cgu.h" +#include "dt-bindings/reset/snps,hsdk-reset.h" / { model = "snps,hsdk"; @@ -62,6 +63,12 @@ #clock-cells = <1>; }; + cgu_rst: reset-controller@f00008a0 { + compatible = "snps,hsdk-reset"; + #reset-cells = <1>; + reg = <0xf00008a0 0x4>, <0xf0000ff0 0x4>; + }; + uart0: serial0@f0005000 { compatible = "snps,dw-apb-uart"; reg = <0xf0005000 0x1000>; diff --git a/arch/arc/include/asm/cache.h b/arch/arc/include/asm/cache.h index 0fdcf2d2dd..ab61846b5a 100644 --- a/arch/arc/include/asm/cache.h +++ b/arch/arc/include/asm/cache.h @@ -40,6 +40,13 @@ static const inline int is_ioc_enabled(void) return IS_ENABLED(CONFIG_ARC_DBG_IOC_ENABLE); } +/* + * We export SLC control functions to use them in platform configuration code. + * They maust not be used in any generic code! + */ +void slc_enable(void); +void slc_disable(void); + #endif /* __ASSEMBLY__ */ #endif /* __ASM_ARC_CACHE_H */ diff --git a/arch/arc/lib/cache.c b/arch/arc/lib/cache.c index 1340776c66..8a1d67870a 100644 --- a/arch/arc/lib/cache.c +++ b/arch/arc/lib/cache.c @@ -89,8 +89,7 @@ * * [ NOTE 2 ]: * As of today we only support the following cache configurations on ARC. - * Other configurations may exist in HW (for example, since version 3.0 HS - * supports SL$ (L2 system level cache) disable) but we don't support it in SW. + * Other configurations may exist in HW but we don't support it in SW. * Configuration 1: * ______________________ * | | @@ -120,7 +119,8 @@ * | | * | L2 (SL$) | * |______________________| - * always must be on + * always on (ARCv2, HS < 3.0) + * on/off (ARCv2, HS >= 3.0) * ___|______________|____ * | | * | main memory | @@ -178,6 +178,8 @@ DECLARE_GLOBAL_DATA_PTR; static inlined_cachefunc void __ic_entire_invalidate(void); static inlined_cachefunc void __dc_entire_op(const int cacheop); +static inlined_cachefunc void __slc_entire_op(const int op); +static inlined_cachefunc bool ioc_enabled(void); static inline bool pae_exists(void) { @@ -238,6 +240,70 @@ static inlined_cachefunc bool slc_exists(void) return false; } +enum slc_dis_status { + ST_SLC_MISSING = 0, + ST_SLC_NO_DISABLE_CTRL, + ST_SLC_DISABLE_CTRL +}; + +/* + * ARCv1 -> ST_SLC_MISSING + * ARCv2 && SLC absent -> ST_SLC_MISSING + * ARCv2 && SLC exists && SLC version <= 2 -> ST_SLC_NO_DISABLE_CTRL + * ARCv2 && SLC exists && SLC version > 2 -> ST_SLC_DISABLE_CTRL + */ +static inlined_cachefunc enum slc_dis_status slc_disable_supported(void) +{ + if (is_isa_arcv2()) { + union bcr_generic sbcr; + + sbcr.word = read_aux_reg(ARC_BCR_SLC); + if (sbcr.fields.ver == 0) + return ST_SLC_MISSING; + else if (sbcr.fields.ver <= 2) + return ST_SLC_NO_DISABLE_CTRL; + else + return ST_SLC_DISABLE_CTRL; + } + + return ST_SLC_MISSING; +} + +static inlined_cachefunc bool __slc_enabled(void) +{ + return !(read_aux_reg(ARC_AUX_SLC_CTRL) & SLC_CTRL_DIS); +} + +static inlined_cachefunc void __slc_enable(void) +{ + unsigned int ctrl; + + ctrl = read_aux_reg(ARC_AUX_SLC_CTRL); + ctrl &= ~SLC_CTRL_DIS; + write_aux_reg(ARC_AUX_SLC_CTRL, ctrl); +} + +static inlined_cachefunc void __slc_disable(void) +{ + unsigned int ctrl; + + ctrl = read_aux_reg(ARC_AUX_SLC_CTRL); + ctrl |= SLC_CTRL_DIS; + write_aux_reg(ARC_AUX_SLC_CTRL, ctrl); +} + +static inlined_cachefunc bool slc_enabled(void) +{ + enum slc_dis_status slc_status = slc_disable_supported(); + + if (slc_status == ST_SLC_MISSING) + return false; + else if (slc_status == ST_SLC_NO_DISABLE_CTRL) + return true; + else + return __slc_enabled(); +} + static inlined_cachefunc bool slc_data_bypass(void) { /* @@ -247,7 +313,40 @@ static inlined_cachefunc bool slc_data_bypass(void) return !dcache_enabled(); } -static inline bool ioc_exists(void) +void slc_enable(void) +{ + if (slc_disable_supported() != ST_SLC_DISABLE_CTRL) + return; + + if (__slc_enabled()) + return; + + __slc_enable(); +} + +/* TODO: warn if we are not able to disable SLC */ +void slc_disable(void) +{ + if (slc_disable_supported() != ST_SLC_DISABLE_CTRL) + return; + + /* we don't support SLC disabling if we use IOC */ + if (ioc_enabled()) + return; + + if (!__slc_enabled()) + return; + + /* + * We need to flush L1D$ to guarantee that we won't have any + * writeback operations during SLC disabling. + */ + __dc_entire_op(OP_FLUSH); + __slc_entire_op(OP_FLUSH_N_INV); + __slc_disable(); +} + +static inlined_cachefunc bool ioc_exists(void) { if (is_isa_arcv2()) { union bcr_clust_cfg cbcr; @@ -259,7 +358,7 @@ static inline bool ioc_exists(void) return false; } -static inline bool ioc_enabled(void) +static inlined_cachefunc bool ioc_enabled(void) { /* * We check only CONFIG option instead of IOC HW state check as IOC @@ -275,7 +374,7 @@ static inlined_cachefunc void __slc_entire_op(const int op) { unsigned int ctrl; - if (!slc_exists()) + if (!slc_enabled()) return; ctrl = read_aux_reg(ARC_AUX_SLC_CTRL); @@ -324,7 +423,7 @@ static void __slc_rgn_op(unsigned long paddr, unsigned long sz, const int op) unsigned int ctrl; unsigned long end; - if (!slc_exists()) + if (!slc_enabled()) return; /* @@ -382,6 +481,9 @@ static void arc_ioc_setup(void) if (!slc_exists()) panic("Try to enable IOC but SLC is not present"); + if (!slc_enabled()) + panic("Try to enable IOC but SLC is disabled"); + /* Unsupported configuration. See [ NOTE 2 ] for more details. */ if (!dcache_enabled()) panic("Try to enable IOC but L1 D$ is disabled"); @@ -517,8 +619,6 @@ void invalidate_icache_all(void) /* * If SL$ is bypassed for data it is used only for instructions, * so we need to invalidate it too. - * TODO: HS 3.0 supports SLC disable so we need to check slc - * enable/disable status here. */ if (is_isa_arcv2() && slc_data_bypass()) __slc_entire_op(OP_INV); diff --git a/configs/hsdk_defconfig b/configs/hsdk_defconfig index 4830158d55..84b22ed7c0 100644 --- a/configs/hsdk_defconfig +++ b/configs/hsdk_defconfig @@ -47,6 +47,7 @@ CONFIG_SPI_FLASH_SST=y CONFIG_DM_ETH=y CONFIG_ETH_DESIGNWARE=y CONFIG_MII=y +CONFIG_DM_RESET=y CONFIG_DM_SERIAL=y CONFIG_DEBUG_UART_SHIFT=2 CONFIG_DEBUG_UART_ANNOUNCE=y diff --git a/drivers/clk/clk-hsdk-cgu.c b/drivers/clk/clk-hsdk-cgu.c index 4637b9fdf1..6eaafdeaf9 100644 --- a/drivers/clk/clk-hsdk-cgu.c +++ b/drivers/clk/clk-hsdk-cgu.c @@ -144,7 +144,7 @@ struct hsdk_tun_clk_cfg { static const struct hsdk_tun_clk_cfg tun_clk_cfg = { { 25000000, 50000000, 75000000, 100000000, 125000000, 150000000 }, - { 600000000, 600000000, 600000000, 600000000, 700000000, 600000000 }, { + { 600000000, 600000000, 600000000, 600000000, 750000000, 600000000 }, { { CGU_TUN_IDIV_TUN, { 24, 12, 8, 6, 6, 4 } }, { CGU_TUN_IDIV_ROM, { 4, 4, 4, 4, 5, 4 } }, { CGU_TUN_IDIV_PWM, { 8, 8, 8, 8, 10, 8 } } @@ -205,6 +205,7 @@ static const struct hsdk_pll_cfg asdt_pll_cfg[] = { { 500000000, 0, 14, 1, 0 }, { 600000000, 0, 17, 1, 0 }, { 700000000, 0, 20, 1, 0 }, + { 750000000, 1, 44, 1, 0 }, { 800000000, 0, 23, 1, 0 }, { 900000000, 1, 26, 0, 0 }, { 1000000000, 1, 29, 0, 0 }, |