aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2020-04-16 17:14:44 -0400
committerTom Rini <trini@konsulko.com>2020-04-16 17:14:44 -0400
commit0f238dab6d17caabe4f9781d23aaa6087139f2bd (patch)
tree4c3aaa186537f37fe3bfd6240862a74b32ffd837
parentcf87f7cd8cdb35761103720a102df9bf5b88c1b2 (diff)
parent7b50db8242b62c85a19da9521b703faa858f4a63 (diff)
downloadu-boot-0f238dab6d17caabe4f9781d23aaa6087139f2bd.zip
u-boot-0f238dab6d17caabe4f9781d23aaa6087139f2bd.tar.gz
u-boot-0f238dab6d17caabe4f9781d23aaa6087139f2bd.tar.bz2
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.dts7
-rw-r--r--arch/arc/include/asm/cache.h7
-rw-r--r--arch/arc/lib/cache.c118
-rw-r--r--configs/hsdk_defconfig1
-rw-r--r--drivers/clk/clk-hsdk-cgu.c3
5 files changed, 126 insertions, 10 deletions
diff --git a/arch/arc/dts/hsdk.dts b/arch/arc/dts/hsdk.dts
index 34ef3a6..cf2ce8a 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 0fdcf2d..ab61846 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 1340776..8a1d678 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 4830158..84b22ed 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 4637b9f..6eaafde 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 },