From 2fcf414549a860fbab619df0be75c85ad0c8cd95 Mon Sep 17 00:00:00 2001 From: Zbigniew Bodek Date: Tue, 18 Apr 2017 10:39:14 +0000 Subject: [PATCH] Optimize Armada38x low-level MBUS settings Add early init handler, which comprises various internal bus optimisations for Armada 38x SoC's. Magic values used due to undocumented registers. Submitted by: Marcin Wojtas , Arnaud Ysmal Obtained from: Semihalf, Stormshield Sponsored by: Stormshield Differential revision: https://reviews.freebsd.org/D10219 --- sys/arm/mv/armada38x/armada38x.c | 45 ++++++++++++++++++++++++++++++++ sys/arm/mv/mv_machdep.c | 3 +++ sys/arm/mv/mvreg.h | 5 ++++ 3 files changed, 53 insertions(+) diff --git a/sys/arm/mv/armada38x/armada38x.c b/sys/arm/mv/armada38x/armada38x.c index ae4d459ec774..ebb9fdc720e5 100644 --- a/sys/arm/mv/armada38x/armada38x.c +++ b/sys/arm/mv/armada38x/armada38x.c @@ -41,6 +41,7 @@ __FBSDID("$FreeBSD$"); int armada38x_open_bootrom_win(void); int armada38x_scu_enable(void); int armada38x_win_set_iosync_barrier(void); +int armada38x_mbus_optimization(void); uint32_t get_tclk(void) @@ -114,6 +115,50 @@ armada38x_open_bootrom_win(void) return (rv); } +int +armada38x_mbus_optimization(void) +{ + bus_space_handle_t vaddr_iowind; + int rv; + + rv = bus_space_map(fdtbus_bs_tag, (bus_addr_t)MV_MBUS_CTRL_BASE, + MV_MBUS_CTRL_REGS_LEN, 0, &vaddr_iowind); + if (rv != 0) + return (rv); + + /* + * MBUS Units Priority Control Register - Prioritize XOR, + * PCIe and GbEs (ID=4,6,3,7,8) DRAM access + * GbE is High and others are Medium. + */ + bus_space_write_4(fdtbus_bs_tag, vaddr_iowind, 0, 0x19180); + + /* + * Fabric Units Priority Control Register - + * Prioritize CPUs requests. + */ + bus_space_write_4(fdtbus_bs_tag, vaddr_iowind, 0x4, 0x3000A); + + /* + * MBUS Units Prefetch Control Register - + * Pre-fetch enable for all IO masters. + */ + bus_space_write_4(fdtbus_bs_tag, vaddr_iowind, 0x8, 0xFFFF); + + /* + * Fabric Units Prefetch Control Register - + * Enable the CPUs Instruction and Data prefetch. + */ + bus_space_write_4(fdtbus_bs_tag, vaddr_iowind, 0xc, 0x303); + + bus_space_barrier(fdtbus_bs_tag, vaddr_iowind, 0, MV_MBUS_CTRL_REGS_LEN, + BUS_SPACE_BARRIER_WRITE); + + bus_space_unmap(fdtbus_bs_tag, vaddr_iowind, MV_MBUS_CTRL_REGS_LEN); + + return (rv); +} + int armada38x_scu_enable(void) { diff --git a/sys/arm/mv/mv_machdep.c b/sys/arm/mv/mv_machdep.c index f4dc0e105a29..26f1ddfc0675 100644 --- a/sys/arm/mv/mv_machdep.c +++ b/sys/arm/mv/mv_machdep.c @@ -77,6 +77,7 @@ void armadaxp_l2_init(void); int armada38x_win_set_iosync_barrier(void); int armada38x_scu_enable(void); int armada38x_open_bootrom_win(void); +int armada38x_mbus_optimization(void); #endif #define MPP_PIN_MAX 68 @@ -259,6 +260,8 @@ platform_late_init(void) /* Set IO Sync Barrier bit for all Mbus devices */ if (armada38x_win_set_iosync_barrier() != 0) printf("WARNING: could not map CPU Subsystem registers\n"); + if (armada38x_mbus_optimization() != 0) + printf("WARNING: could not enable mbus optimization\n"); if (armada38x_scu_enable() != 0) printf("WARNING: could not enable SCU\n"); #ifdef SMP diff --git a/sys/arm/mv/mvreg.h b/sys/arm/mv/mvreg.h index 547a0648937d..275ad572133c 100644 --- a/sys/arm/mv/mvreg.h +++ b/sys/arm/mv/mvreg.h @@ -447,4 +447,9 @@ #define CPU_RESET_ASSERT 0x1 #endif +#if defined(SOC_MV_ARMADA38X) +#define MV_MBUS_CTRL_BASE (MV_BASE + 0x20420) +#define MV_MBUS_CTRL_REGS_LEN 0x10 +#endif + #endif /* _MVREG_H_ */