Commit 7e32c605 authored by Olof Johansson's avatar Olof Johansson

Merge tag 'arm-soc/for-4.16/drivers' of http://github.com/Broadcom/stblinux into next/drivers

This pull request contains Broadcom ARM/ARM64 based SoCs drivers changes for
4.16, please pull the following:

- Arnd provides an update to the Raspberry Pi firmware interface and uses time64_t to
  print the time to make it more future proof

- Florian provides a set of updates to make the Broadcom STB Bus Interface Unit code
  work on newer ARM64-based chips, as well as perform the correct interface tuning
  for these chips to reach the expected performance

* tag 'arm-soc/for-4.16/drivers' of http://github.com/Broadcom/stblinux:
  soc: brcmstb: biuctrl: Move to early_initcall
  soc: brcmstb: Split initialization
  soc: brcmstb: biuctrl: Fine tune B53 MCP interface settings
  soc: brcmstb: biuctrl: Wire-up new registers
  soc: brcmstb: biuctrl: Prepare for saving/restoring other registers
  soc: brcmstb: Correct CPU_CREDIT_REG offset for Brahma-B53 CPUs
  soc: brcmstb: Make CPU credit offset more parameterized
  dt-bindings: arm: brcmstb: Correct BIUCTRL node documentation
  dt-bindings: arm: Add entry for Broadcom Brahma-B53
  firmware: raspberrypi: print time using time64_t
Signed-off-by: default avatarOlof Johansson <olof@lixom.net>
parents f681e08f f780429a
...@@ -17,21 +17,23 @@ Further, syscon nodes that map platform-specific registers used for general ...@@ -17,21 +17,23 @@ Further, syscon nodes that map platform-specific registers used for general
system control is required: system control is required:
- compatible: "brcm,bcm<chip_id>-sun-top-ctrl", "syscon" - compatible: "brcm,bcm<chip_id>-sun-top-ctrl", "syscon"
- compatible: "brcm,bcm<chip_id>-hif-cpubiuctrl", "syscon" - compatible: "brcm,bcm<chip_id>-cpu-biu-ctrl",
"brcm,brcmstb-cpu-biu-ctrl",
"syscon"
- compatible: "brcm,bcm<chip_id>-hif-continuation", "syscon" - compatible: "brcm,bcm<chip_id>-hif-continuation", "syscon"
hif-cpubiuctrl node cpu-biu-ctrl node
------------------- -------------------
SoCs with Broadcom Brahma15 ARM-based CPUs have a specific Bus Interface Unit SoCs with Broadcom Brahma15 ARM-based and Brahma53 ARM64-based CPUs have a
(BIU) block which controls and interfaces the CPU complex to the different specific Bus Interface Unit (BIU) block which controls and interfaces the CPU
Memory Controller Ports (MCP), one per memory controller (MEMC). This BIU block complex to the different Memory Controller Ports (MCP), one per memory
offers a feature called Write Pairing which consists in collapsing two adjacent controller (MEMC). This BIU block offers a feature called Write Pairing which
cache lines into a single (bursted) write transaction towards the memory consists in collapsing two adjacent cache lines into a single (bursted) write
controller (MEMC) to maximize write bandwidth. transaction towards the memory controller (MEMC) to maximize write bandwidth.
Required properties: Required properties:
- compatible: must be "brcm,bcm7445-hif-cpubiuctrl", "syscon" - compatible: must be "brcm,bcm7445-cpu-biu-ctrl", "brcm,brcmstb-cpu-biu-ctrl", "syscon"
Optional properties: Optional properties:
...@@ -52,7 +54,7 @@ example: ...@@ -52,7 +54,7 @@ example:
}; };
hif_cpubiuctrl: syscon@3e2400 { hif_cpubiuctrl: syscon@3e2400 {
compatible = "brcm,bcm7445-hif-cpubiuctrl", "syscon"; compatible = "brcm,bcm7445-cpu-biu-ctrl", "brcm,brcmstb-cpu-biu-ctrl", "syscon";
reg = <0x3e2400 0x5b4>; reg = <0x3e2400 0x5b4>;
brcm,write-pairing; brcm,write-pairing;
}; };
......
...@@ -169,6 +169,7 @@ described below. ...@@ -169,6 +169,7 @@ described below.
"arm,cortex-r5" "arm,cortex-r5"
"arm,cortex-r7" "arm,cortex-r7"
"brcm,brahma-b15" "brcm,brahma-b15"
"brcm,brahma-b53"
"brcm,vulcan" "brcm,vulcan"
"cavium,thunder" "cavium,thunder"
"cavium,thunder2" "cavium,thunder2"
......
...@@ -14,7 +14,6 @@ ...@@ -14,7 +14,6 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/irqchip.h> #include <linux/irqchip.h>
#include <linux/of_platform.h> #include <linux/of_platform.h>
#include <linux/soc/brcmstb/brcmstb.h>
#include <asm/mach-types.h> #include <asm/mach-types.h>
#include <asm/mach/arch.h> #include <asm/mach/arch.h>
...@@ -38,7 +37,6 @@ u32 brcmstb_uart_config[3] = { ...@@ -38,7 +37,6 @@ u32 brcmstb_uart_config[3] = {
static void __init brcmstb_init_irq(void) static void __init brcmstb_init_irq(void)
{ {
irqchip_init(); irqchip_init();
brcmstb_biuctrl_init();
} }
static const char *const brcmstb_match[] __initconst = { static const char *const brcmstb_match[] __initconst = {
......
...@@ -174,7 +174,7 @@ rpi_firmware_print_firmware_revision(struct rpi_firmware *fw) ...@@ -174,7 +174,7 @@ rpi_firmware_print_firmware_revision(struct rpi_firmware *fw)
if (ret == 0) { if (ret == 0) {
struct tm tm; struct tm tm;
time_to_tm(packet, 0, &tm); time64_to_tm(packet, 0, &tm);
dev_info(fw->cl.dev, dev_info(fw->cl.dev,
"Attached to firmware from %04ld-%02d-%02d %02d:%02d\n", "Attached to firmware from %04ld-%02d-%02d %02d:%02d\n",
......
...@@ -21,11 +21,70 @@ ...@@ -21,11 +21,70 @@
#include <linux/syscore_ops.h> #include <linux/syscore_ops.h>
#include <linux/soc/brcmstb/brcmstb.h> #include <linux/soc/brcmstb/brcmstb.h>
#define CPU_CREDIT_REG_OFFSET 0x184
#define CPU_CREDIT_REG_MCPx_WR_PAIRING_EN_MASK 0x70000000 #define CPU_CREDIT_REG_MCPx_WR_PAIRING_EN_MASK 0x70000000
#define CPU_CREDIT_REG_MCPx_READ_CRED_MASK 0xf
#define CPU_CREDIT_REG_MCPx_WRITE_CRED_MASK 0xf
#define CPU_CREDIT_REG_MCPx_READ_CRED_SHIFT(x) ((x) * 8)
#define CPU_CREDIT_REG_MCPx_WRITE_CRED_SHIFT(x) (((x) * 8) + 4)
#define CPU_MCP_FLOW_REG_MCPx_RDBUFF_CRED_SHIFT(x) ((x) * 8)
#define CPU_MCP_FLOW_REG_MCPx_RDBUFF_CRED_MASK 0xff
#define CPU_WRITEBACK_CTRL_REG_WB_THROTTLE_THRESHOLD_MASK 0xf
#define CPU_WRITEBACK_CTRL_REG_WB_THROTTLE_TIMEOUT_MASK 0xf
#define CPU_WRITEBACK_CTRL_REG_WB_THROTTLE_TIMEOUT_SHIFT 4
#define CPU_WRITEBACK_CTRL_REG_WB_THROTTLE_ENABLE BIT(8)
static void __iomem *cpubiuctrl_base; static void __iomem *cpubiuctrl_base;
static bool mcp_wr_pairing_en; static bool mcp_wr_pairing_en;
static const int *cpubiuctrl_regs;
static inline u32 cbc_readl(int reg)
{
int offset = cpubiuctrl_regs[reg];
if (offset == -1)
return (u32)-1;
return readl_relaxed(cpubiuctrl_base + offset);
}
static inline void cbc_writel(u32 val, int reg)
{
int offset = cpubiuctrl_regs[reg];
if (offset == -1)
return;
writel_relaxed(val, cpubiuctrl_base + offset);
}
enum cpubiuctrl_regs {
CPU_CREDIT_REG = 0,
CPU_MCP_FLOW_REG,
CPU_WRITEBACK_CTRL_REG
};
static const int b15_cpubiuctrl_regs[] = {
[CPU_CREDIT_REG] = 0x184,
[CPU_MCP_FLOW_REG] = -1,
[CPU_WRITEBACK_CTRL_REG] = -1,
};
/* Odd cases, e.g: 7260 */
static const int b53_cpubiuctrl_no_wb_regs[] = {
[CPU_CREDIT_REG] = 0x0b0,
[CPU_MCP_FLOW_REG] = 0x0b4,
[CPU_WRITEBACK_CTRL_REG] = -1,
};
static const int b53_cpubiuctrl_regs[] = {
[CPU_CREDIT_REG] = 0x0b0,
[CPU_MCP_FLOW_REG] = 0x0b4,
[CPU_WRITEBACK_CTRL_REG] = 0x22c,
};
#define NUM_CPU_BIUCTRL_REGS 3
static int __init mcp_write_pairing_set(void) static int __init mcp_write_pairing_set(void)
{ {
...@@ -34,15 +93,15 @@ static int __init mcp_write_pairing_set(void) ...@@ -34,15 +93,15 @@ static int __init mcp_write_pairing_set(void)
if (!cpubiuctrl_base) if (!cpubiuctrl_base)
return -1; return -1;
creds = readl_relaxed(cpubiuctrl_base + CPU_CREDIT_REG_OFFSET); creds = cbc_readl(CPU_CREDIT_REG);
if (mcp_wr_pairing_en) { if (mcp_wr_pairing_en) {
pr_info("MCP: Enabling write pairing\n"); pr_info("MCP: Enabling write pairing\n");
writel_relaxed(creds | CPU_CREDIT_REG_MCPx_WR_PAIRING_EN_MASK, cbc_writel(creds | CPU_CREDIT_REG_MCPx_WR_PAIRING_EN_MASK,
cpubiuctrl_base + CPU_CREDIT_REG_OFFSET); CPU_CREDIT_REG);
} else if (creds & CPU_CREDIT_REG_MCPx_WR_PAIRING_EN_MASK) { } else if (creds & CPU_CREDIT_REG_MCPx_WR_PAIRING_EN_MASK) {
pr_info("MCP: Disabling write pairing\n"); pr_info("MCP: Disabling write pairing\n");
writel_relaxed(creds & ~CPU_CREDIT_REG_MCPx_WR_PAIRING_EN_MASK, cbc_writel(creds & ~CPU_CREDIT_REG_MCPx_WR_PAIRING_EN_MASK,
cpubiuctrl_base + CPU_CREDIT_REG_OFFSET); CPU_CREDIT_REG);
} else { } else {
pr_info("MCP: Write pairing already disabled\n"); pr_info("MCP: Write pairing already disabled\n");
} }
...@@ -50,9 +109,62 @@ static int __init mcp_write_pairing_set(void) ...@@ -50,9 +109,62 @@ static int __init mcp_write_pairing_set(void)
return 0; return 0;
} }
static const u32 b53_mach_compat[] = {
0x7268,
0x7271,
0x7278,
};
static void __init mcp_b53_set(void)
{
unsigned int i;
u32 reg;
reg = brcmstb_get_family_id();
for (i = 0; i < ARRAY_SIZE(b53_mach_compat); i++) {
if (BRCM_ID(reg) == b53_mach_compat[i])
break;
}
if (i == ARRAY_SIZE(b53_mach_compat))
return;
/* Set all 3 MCP interfaces to 8 credits */
reg = cbc_readl(CPU_CREDIT_REG);
for (i = 0; i < 3; i++) {
reg &= ~(CPU_CREDIT_REG_MCPx_WRITE_CRED_MASK <<
CPU_CREDIT_REG_MCPx_WRITE_CRED_SHIFT(i));
reg &= ~(CPU_CREDIT_REG_MCPx_READ_CRED_MASK <<
CPU_CREDIT_REG_MCPx_READ_CRED_SHIFT(i));
reg |= 8 << CPU_CREDIT_REG_MCPx_WRITE_CRED_SHIFT(i);
reg |= 8 << CPU_CREDIT_REG_MCPx_READ_CRED_SHIFT(i);
}
cbc_writel(reg, CPU_CREDIT_REG);
/* Max out the number of in-flight Jwords reads on the MCP interface */
reg = cbc_readl(CPU_MCP_FLOW_REG);
for (i = 0; i < 3; i++)
reg |= CPU_MCP_FLOW_REG_MCPx_RDBUFF_CRED_MASK <<
CPU_MCP_FLOW_REG_MCPx_RDBUFF_CRED_SHIFT(i);
cbc_writel(reg, CPU_MCP_FLOW_REG);
/* Enable writeback throttling, set timeout to 128 cycles, 256 cycles
* threshold
*/
reg = cbc_readl(CPU_WRITEBACK_CTRL_REG);
reg |= CPU_WRITEBACK_CTRL_REG_WB_THROTTLE_ENABLE;
reg &= ~CPU_WRITEBACK_CTRL_REG_WB_THROTTLE_THRESHOLD_MASK;
reg &= ~(CPU_WRITEBACK_CTRL_REG_WB_THROTTLE_TIMEOUT_MASK <<
CPU_WRITEBACK_CTRL_REG_WB_THROTTLE_TIMEOUT_SHIFT);
reg |= 8;
reg |= 7 << CPU_WRITEBACK_CTRL_REG_WB_THROTTLE_TIMEOUT_SHIFT;
cbc_writel(reg, CPU_WRITEBACK_CTRL_REG);
}
static int __init setup_hifcpubiuctrl_regs(void) static int __init setup_hifcpubiuctrl_regs(void)
{ {
struct device_node *np; struct device_node *np, *cpu_dn;
int ret = 0; int ret = 0;
np = of_find_compatible_node(NULL, NULL, "brcm,brcmstb-cpu-biu-ctrl"); np = of_find_compatible_node(NULL, NULL, "brcm,brcmstb-cpu-biu-ctrl");
...@@ -69,27 +181,56 @@ static int __init setup_hifcpubiuctrl_regs(void) ...@@ -69,27 +181,56 @@ static int __init setup_hifcpubiuctrl_regs(void)
} }
mcp_wr_pairing_en = of_property_read_bool(np, "brcm,write-pairing"); mcp_wr_pairing_en = of_property_read_bool(np, "brcm,write-pairing");
cpu_dn = of_get_cpu_node(0, NULL);
if (!cpu_dn) {
pr_err("failed to obtain CPU device node\n");
ret = -ENODEV;
goto out;
}
if (of_device_is_compatible(cpu_dn, "brcm,brahma-b15"))
cpubiuctrl_regs = b15_cpubiuctrl_regs;
else if (of_device_is_compatible(cpu_dn, "brcm,brahma-b53"))
cpubiuctrl_regs = b53_cpubiuctrl_regs;
else {
pr_err("unsupported CPU\n");
ret = -EINVAL;
}
of_node_put(cpu_dn);
if (BRCM_ID(brcmstb_get_family_id()) == 0x7260)
cpubiuctrl_regs = b53_cpubiuctrl_no_wb_regs;
out: out:
of_node_put(np); of_node_put(np);
return ret; return ret;
} }
#ifdef CONFIG_PM_SLEEP #ifdef CONFIG_PM_SLEEP
static u32 cpu_credit_reg_dump; /* for save/restore */ static u32 cpubiuctrl_reg_save[NUM_CPU_BIUCTRL_REGS];
static int brcmstb_cpu_credit_reg_suspend(void) static int brcmstb_cpu_credit_reg_suspend(void)
{ {
if (cpubiuctrl_base) unsigned int i;
cpu_credit_reg_dump =
readl_relaxed(cpubiuctrl_base + CPU_CREDIT_REG_OFFSET); if (!cpubiuctrl_base)
return 0;
for (i = 0; i < NUM_CPU_BIUCTRL_REGS; i++)
cpubiuctrl_reg_save[i] = cbc_readl(i);
return 0; return 0;
} }
static void brcmstb_cpu_credit_reg_resume(void) static void brcmstb_cpu_credit_reg_resume(void)
{ {
if (cpubiuctrl_base) unsigned int i;
writel_relaxed(cpu_credit_reg_dump,
cpubiuctrl_base + CPU_CREDIT_REG_OFFSET); if (!cpubiuctrl_base)
return;
for (i = 0; i < NUM_CPU_BIUCTRL_REGS; i++)
cbc_writel(cpubiuctrl_reg_save[i], i);
} }
static struct syscore_ops brcmstb_cpu_credit_syscore_ops = { static struct syscore_ops brcmstb_cpu_credit_syscore_ops = {
...@@ -99,7 +240,7 @@ static struct syscore_ops brcmstb_cpu_credit_syscore_ops = { ...@@ -99,7 +240,7 @@ static struct syscore_ops brcmstb_cpu_credit_syscore_ops = {
#endif #endif
void __init brcmstb_biuctrl_init(void) static int __init brcmstb_biuctrl_init(void)
{ {
int ret; int ret;
...@@ -108,10 +249,13 @@ void __init brcmstb_biuctrl_init(void) ...@@ -108,10 +249,13 @@ void __init brcmstb_biuctrl_init(void)
ret = mcp_write_pairing_set(); ret = mcp_write_pairing_set();
if (ret) { if (ret) {
pr_err("MCP: Unable to disable write pairing!\n"); pr_err("MCP: Unable to disable write pairing!\n");
return; return ret;
} }
mcp_b53_set();
#ifdef CONFIG_PM_SLEEP #ifdef CONFIG_PM_SLEEP
register_syscore_ops(&brcmstb_cpu_credit_syscore_ops); register_syscore_ops(&brcmstb_cpu_credit_syscore_ops);
#endif #endif
return 0;
} }
early_initcall(brcmstb_biuctrl_init);
...@@ -66,13 +66,10 @@ static const struct of_device_id sun_top_ctrl_match[] = { ...@@ -66,13 +66,10 @@ static const struct of_device_id sun_top_ctrl_match[] = {
{ } { }
}; };
static int __init brcmstb_soc_device_init(void) static int __init brcmstb_soc_device_early_init(void)
{ {
struct soc_device_attribute *soc_dev_attr;
struct soc_device *soc_dev;
struct device_node *sun_top_ctrl; struct device_node *sun_top_ctrl;
void __iomem *sun_top_ctrl_base; void __iomem *sun_top_ctrl_base;
int ret = 0;
sun_top_ctrl = of_find_matching_node(NULL, sun_top_ctrl_match); sun_top_ctrl = of_find_matching_node(NULL, sun_top_ctrl_match);
if (!sun_top_ctrl) if (!sun_top_ctrl)
...@@ -84,12 +81,19 @@ static int __init brcmstb_soc_device_init(void) ...@@ -84,12 +81,19 @@ static int __init brcmstb_soc_device_init(void)
family_id = readl(sun_top_ctrl_base); family_id = readl(sun_top_ctrl_base);
product_id = readl(sun_top_ctrl_base + 0x4); product_id = readl(sun_top_ctrl_base + 0x4);
iounmap(sun_top_ctrl_base);
return 0;
}
early_initcall(brcmstb_soc_device_early_init);
static int __init brcmstb_soc_device_init(void)
{
struct soc_device_attribute *soc_dev_attr;
struct soc_device *soc_dev;
soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL); soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
if (!soc_dev_attr) { if (!soc_dev_attr)
ret = -ENOMEM; return -ENOMEM;
goto out;
}
soc_dev_attr->family = kasprintf(GFP_KERNEL, "%x", soc_dev_attr->family = kasprintf(GFP_KERNEL, "%x",
family_id >> 28 ? family_id >> 28 ?
...@@ -107,14 +111,9 @@ static int __init brcmstb_soc_device_init(void) ...@@ -107,14 +111,9 @@ static int __init brcmstb_soc_device_init(void)
kfree(soc_dev_attr->soc_id); kfree(soc_dev_attr->soc_id);
kfree(soc_dev_attr->revision); kfree(soc_dev_attr->revision);
kfree(soc_dev_attr); kfree(soc_dev_attr);
ret = -ENODEV; return -ENOMEM;
goto out;
} }
return 0; return 0;
out:
iounmap(sun_top_ctrl_base);
return ret;
} }
arch_initcall(brcmstb_soc_device_init); arch_initcall(brcmstb_soc_device_init);
...@@ -12,12 +12,6 @@ static inline u32 BRCM_REV(u32 reg) ...@@ -12,12 +12,6 @@ static inline u32 BRCM_REV(u32 reg)
return reg & 0xff; return reg & 0xff;
} }
/*
* Bus Interface Unit control register setup, must happen early during boot,
* before SMP is brought up, called by machine entry point.
*/
void brcmstb_biuctrl_init(void);
/* /*
* Helper functions for getting family or product id from the * Helper functions for getting family or product id from the
* SoC driver. * SoC driver.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment