diff options
author | Arnd Bergmann | 2020-11-30 17:24:21 +0100 |
---|---|---|
committer | Arnd Bergmann | 2020-11-30 17:24:22 +0100 |
commit | 00c543f6f3f46ce02e300d76e22bb21a8a75e872 (patch) | |
tree | 51e506e6d1a5c09c3f7aeb142f29a5420b1db988 | |
parent | bbecede458d042a5b71d6f10eedd471615d9ee6c (diff) | |
parent | 4da595ddc06909d9ba8fcedcce0c4e1e0a4c3244 (diff) |
Merge tag 'aspeed-5.11-soc' of git://git.kernel.org/pub/scm/linux/kernel/git/joel/aspeed into arm/drivers
ASPEED soc driver updates for 5.11
New drivers:
- SoC info driver to expose revision information
New features:
- AST2600 support for the LPC control driver. This includes
setting the LPC2AHB bridge up in a backwards compatible manner.
Cleanups:
- LPC control
- Kconfig
- Bindings updates for AST2600 strings
* tag 'aspeed-5.11-soc' of git://git.kernel.org/pub/scm/linux/kernel/git/joel/aspeed:
soc: aspeed: Enable drivers with ARCH_ASPEED
soc: aspeed: Fix a reference leak in aspeed_socinfo_init()
soc: aspeed: remove unneeded semicolon
soc: aspeed-lpc-ctrl: Fix driver name
soc: aspeed-lpc-ctrl: Fix whitespace
soc: aspeed-lpc-ctrl: LPC to AHB mapping on ast2600
soc: aspeed-lpc-ctrl: Fail probe of lpc-ctrl if reserved memory is not aligned
soc: aspeed: lpc: Add AST2600 compatible strings
dt-bindings: aspeed-lpc: Add AST2600 compatible strings
ARM: dts: aspeed: Add silicon id node
soc: aspeed: Add soc info driver
dt-bindings: aspeed: Add silicon id node to SCU
soc: aspeed: Improve kconfig
Link: https://lore.kernel.org/r/CACPK8Xe=9ezhyWRMqVOEQr7SU1YoYfVBGGdGzjmE4SiBr--vJQ@mail.gmail.com
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
-rw-r--r-- | Documentation/devicetree/bindings/mfd/aspeed-lpc.txt | 8 | ||||
-rw-r--r-- | Documentation/devicetree/bindings/mfd/aspeed-scu.txt | 26 | ||||
-rw-r--r-- | arch/arm/boot/dts/aspeed-g4.dtsi | 5 | ||||
-rw-r--r-- | arch/arm/boot/dts/aspeed-g5.dtsi | 5 | ||||
-rw-r--r-- | arch/arm/boot/dts/aspeed-g6.dtsi | 5 | ||||
-rw-r--r-- | drivers/soc/Makefile | 2 | ||||
-rw-r--r-- | drivers/soc/aspeed/Kconfig | 47 | ||||
-rw-r--r-- | drivers/soc/aspeed/Makefile | 1 | ||||
-rw-r--r-- | drivers/soc/aspeed/aspeed-lpc-ctrl.c | 37 | ||||
-rw-r--r-- | drivers/soc/aspeed/aspeed-lpc-snoop.c | 2 | ||||
-rw-r--r-- | drivers/soc/aspeed/aspeed-socinfo.c | 135 |
11 files changed, 252 insertions, 21 deletions
diff --git a/Documentation/devicetree/bindings/mfd/aspeed-lpc.txt b/Documentation/devicetree/bindings/mfd/aspeed-lpc.txt index a92acf1dd491..d0a38ba8b9ce 100644 --- a/Documentation/devicetree/bindings/mfd/aspeed-lpc.txt +++ b/Documentation/devicetree/bindings/mfd/aspeed-lpc.txt @@ -46,6 +46,7 @@ Required properties - compatible: One of: "aspeed,ast2400-lpc", "simple-mfd" "aspeed,ast2500-lpc", "simple-mfd" + "aspeed,ast2600-lpc", "simple-mfd" - reg: contains the physical address and length values of the Aspeed LPC memory region. @@ -64,6 +65,7 @@ BMC Node - compatible: One of: "aspeed,ast2400-lpc-bmc" "aspeed,ast2500-lpc-bmc" + "aspeed,ast2600-lpc-bmc" - reg: contains the physical address and length values of the H8S/2168-compatible LPC controller memory region @@ -74,6 +76,7 @@ Host Node - compatible: One of: "aspeed,ast2400-lpc-host", "simple-mfd", "syscon" "aspeed,ast2500-lpc-host", "simple-mfd", "syscon" + "aspeed,ast2600-lpc-host", "simple-mfd", "syscon" - reg: contains the address and length values of the host-related register space for the Aspeed LPC controller @@ -128,6 +131,7 @@ Required properties: - compatible: One of: "aspeed,ast2400-lpc-ctrl"; "aspeed,ast2500-lpc-ctrl"; + "aspeed,ast2600-lpc-ctrl"; - reg: contains offset/length values of the host interface controller memory regions @@ -168,6 +172,7 @@ Required properties: - compatible: One of: "aspeed,ast2400-lhc"; "aspeed,ast2500-lhc"; + "aspeed,ast2600-lhc"; - reg: contains offset/length values of the LHC memory regions. In the AST2400 and AST2500 there are two regions. @@ -187,7 +192,8 @@ state of the LPC bus. Some systems may chose to modify this configuration. Required properties: - - compatible: "aspeed,ast2500-lpc-reset" or + - compatible: "aspeed,ast2600-lpc-reset" or + "aspeed,ast2500-lpc-reset" "aspeed,ast2400-lpc-reset" - reg: offset and length of the IP in the LHC memory region - #reset-controller indicates the number of reset cells expected diff --git a/Documentation/devicetree/bindings/mfd/aspeed-scu.txt b/Documentation/devicetree/bindings/mfd/aspeed-scu.txt index 4d92c0bb6687..857ee33f7329 100644 --- a/Documentation/devicetree/bindings/mfd/aspeed-scu.txt +++ b/Documentation/devicetree/bindings/mfd/aspeed-scu.txt @@ -20,3 +20,29 @@ syscon: syscon@1e6e2000 { #clock-cells = <1>; #reset-cells = <1>; }; + +Silicon ID +----------------- + +Families have unique hardware silicon identifiers within the SoC. + +Required properties: + + - compatible: "aspeed,silicon-id" or: + "aspeed,ast2400-silicon-id" or + "aspeed,ast2500-silicon-id" or + "aspeed,ast2600-silicon-id" + + - reg: offset and length of the silicon id information + optionally, a second offset and length describes the unique chip id + + The reg should be the unique silicon id register, and + not backwards compatible one in eg. the 2600. + +Example: + + +silicon-id@7c { + compatible = "aspeed,ast2500-silicon-id", "aspeed,silicon-id"; + reg = <0x7c 0x4 0x150 0x8>; +}; diff --git a/arch/arm/boot/dts/aspeed-g4.dtsi b/arch/arm/boot/dts/aspeed-g4.dtsi index 82f0213e3a3c..b3dafbc8caca 100644 --- a/arch/arm/boot/dts/aspeed-g4.dtsi +++ b/arch/arm/boot/dts/aspeed-g4.dtsi @@ -192,6 +192,11 @@ status = "disabled"; }; + silicon-id@7c { + compatible = "aspeed,ast2400-silicon-id", "aspeed,silicon-id"; + reg = <0x7c 0x4>; + }; + pinctrl: pinctrl@80 { reg = <0x80 0x18>, <0xa0 0x10>; compatible = "aspeed,ast2400-pinctrl"; diff --git a/arch/arm/boot/dts/aspeed-g5.dtsi b/arch/arm/boot/dts/aspeed-g5.dtsi index a93009aa2f04..5bc0de0f3365 100644 --- a/arch/arm/boot/dts/aspeed-g5.dtsi +++ b/arch/arm/boot/dts/aspeed-g5.dtsi @@ -239,6 +239,11 @@ status = "disabled"; }; + silicon-id@7c { + compatible = "aspeed,ast2500-silicon-id", "aspeed,silicon-id"; + reg = <0x7c 0x4 0x150 0x8>; + }; + pinctrl: pinctrl@80 { compatible = "aspeed,ast2500-pinctrl"; reg = <0x80 0x18>, <0xa0 0x10>; diff --git a/arch/arm/boot/dts/aspeed-g6.dtsi b/arch/arm/boot/dts/aspeed-g6.dtsi index b58220a49cbd..1ce3a1f06f7f 100644 --- a/arch/arm/boot/dts/aspeed-g6.dtsi +++ b/arch/arm/boot/dts/aspeed-g6.dtsi @@ -311,6 +311,11 @@ compatible = "aspeed,ast2600-pinctrl"; }; + silicon-id@14 { + compatible = "aspeed,ast2600-silicon-id", "aspeed,silicon-id"; + reg = <0x14 0x4 0x5b0 0x8>; + }; + smp-memram@180 { compatible = "aspeed,ast2600-smpmem"; reg = <0x180 0x40>; diff --git a/drivers/soc/Makefile b/drivers/soc/Makefile index 36452bed86ef..8fa43a2d17e7 100644 --- a/drivers/soc/Makefile +++ b/drivers/soc/Makefile @@ -4,7 +4,7 @@ # obj-$(CONFIG_ARCH_ACTIONS) += actions/ -obj-$(CONFIG_SOC_ASPEED) += aspeed/ +obj-y += aspeed/ obj-$(CONFIG_ARCH_AT91) += atmel/ obj-y += bcm/ obj-$(CONFIG_ARCH_DOVE) += dove/ diff --git a/drivers/soc/aspeed/Kconfig b/drivers/soc/aspeed/Kconfig index c95fa30f1a76..243ca196e6ad 100644 --- a/drivers/soc/aspeed/Kconfig +++ b/drivers/soc/aspeed/Kconfig @@ -1,32 +1,47 @@ # SPDX-License-Identifier: GPL-2.0-only -menu "Aspeed SoC drivers" -config SOC_ASPEED - def_bool y - depends on ARCH_ASPEED || COMPILE_TEST +if ARCH_ASPEED || COMPILE_TEST + +menu "ASPEED SoC drivers" config ASPEED_LPC_CTRL - depends on SOC_ASPEED && REGMAP && MFD_SYSCON - tristate "Aspeed ast2400/2500 HOST LPC to BMC bridge control" + tristate "ASPEED LPC firmware cycle control" + select REGMAP + select MFD_SYSCON + default ARCH_ASPEED help - Control Aspeed ast2400/2500 HOST LPC to BMC mappings through - ioctl()s, the driver also provides a read/write interface to a BMC ram - region where the host LPC read/write region can be buffered. + Control LPC firmware cycle mappings through ioctl()s. The driver + also provides a read/write interface to a BMC ram region where the + host LPC read/write region can be buffered. config ASPEED_LPC_SNOOP - tristate "Aspeed ast2500 HOST LPC snoop support" - depends on SOC_ASPEED && REGMAP && MFD_SYSCON + tristate "ASPEED LPC snoop support" + select REGMAP + select MFD_SYSCON + default ARCH_ASPEED help Provides a driver to control the LPC snoop interface which allows the BMC to listen on and save the data written by the host to an arbitrary LPC I/O port. config ASPEED_P2A_CTRL - depends on SOC_ASPEED && REGMAP && MFD_SYSCON - tristate "Aspeed ast2400/2500 HOST P2A VGA MMIO to BMC bridge control" + tristate "ASPEED P2A (VGA MMIO to BMC) bridge control" + select REGMAP + select MFD_SYSCON + default ARCH_ASPEED + help + Control ASPEED P2A VGA MMIO to BMC mappings through ioctl()s. The + driver also provides an interface for userspace mappings to a + pre-defined region. + +config ASPEED_SOCINFO + bool "ASPEED SoC Information driver" + default ARCH_ASPEED + select SOC_BUS + default ARCH_ASPEED help - Control Aspeed ast2400/2500 HOST P2A VGA MMIO to BMC mappings through - ioctl()s, the driver also provides an interface for userspace mappings to - a pre-defined region. + Say yes to support decoding of ASPEED BMC information. endmenu + +endif diff --git a/drivers/soc/aspeed/Makefile b/drivers/soc/aspeed/Makefile index b64be47f2b1f..fcab7192e1a4 100644 --- a/drivers/soc/aspeed/Makefile +++ b/drivers/soc/aspeed/Makefile @@ -2,3 +2,4 @@ obj-$(CONFIG_ASPEED_LPC_CTRL) += aspeed-lpc-ctrl.o obj-$(CONFIG_ASPEED_LPC_SNOOP) += aspeed-lpc-snoop.o obj-$(CONFIG_ASPEED_P2A_CTRL) += aspeed-p2a-ctrl.o +obj-$(CONFIG_ASPEED_SOCINFO) += aspeed-socinfo.o diff --git a/drivers/soc/aspeed/aspeed-lpc-ctrl.c b/drivers/soc/aspeed/aspeed-lpc-ctrl.c index 01ed21e8bfee..439bcd6b8c4a 100644 --- a/drivers/soc/aspeed/aspeed-lpc-ctrl.c +++ b/drivers/soc/aspeed/aspeed-lpc-ctrl.c @@ -4,6 +4,7 @@ */ #include <linux/clk.h> +#include <linux/log2.h> #include <linux/mfd/syscon.h> #include <linux/miscdevice.h> #include <linux/mm.h> @@ -21,6 +22,9 @@ #define HICR5_ENL2H BIT(8) #define HICR5_ENFWH BIT(10) +#define HICR6 0x4 +#define SW_FWH2AHB BIT(17) + #define HICR7 0x8 #define HICR8 0xc @@ -30,8 +34,9 @@ struct aspeed_lpc_ctrl { struct clk *clk; phys_addr_t mem_base; resource_size_t mem_size; - u32 pnor_size; - u32 pnor_base; + u32 pnor_size; + u32 pnor_base; + bool fwh2ahb; }; static struct aspeed_lpc_ctrl *file_aspeed_lpc_ctrl(struct file *file) @@ -177,6 +182,16 @@ static long aspeed_lpc_ctrl_ioctl(struct file *file, unsigned int cmd, return rc; /* + * Switch to FWH2AHB mode, AST2600 only. + * + * The other bits in this register are interrupt status bits + * that are cleared by writing 1. As we don't want to clear + * them, set only the bit of interest. + */ + if (lpc_ctrl->fwh2ahb) + regmap_write(lpc_ctrl->regmap, HICR6, SW_FWH2AHB); + + /* * Enable LPC FHW cycles. This is required for the host to * access the regions specified. */ @@ -241,6 +256,18 @@ static int aspeed_lpc_ctrl_probe(struct platform_device *pdev) lpc_ctrl->mem_size = resource_size(&resm); lpc_ctrl->mem_base = resm.start; + + if (!is_power_of_2(lpc_ctrl->mem_size)) { + dev_err(dev, "Reserved memory size must be a power of 2, got %u\n", + (unsigned int)lpc_ctrl->mem_size); + return -EINVAL; + } + + if (!IS_ALIGNED(lpc_ctrl->mem_base, lpc_ctrl->mem_size)) { + dev_err(dev, "Reserved memory must be naturally aligned for size %u\n", + (unsigned int)lpc_ctrl->mem_size); + return -EINVAL; + } } lpc_ctrl->regmap = syscon_node_to_regmap( @@ -261,6 +288,9 @@ static int aspeed_lpc_ctrl_probe(struct platform_device *pdev) return rc; } + if (of_device_is_compatible(dev->of_node, "aspeed,ast2600-lpc-ctrl")) + lpc_ctrl->fwh2ahb = true; + lpc_ctrl->miscdev.minor = MISC_DYNAMIC_MINOR; lpc_ctrl->miscdev.name = DEVICE_NAME; lpc_ctrl->miscdev.fops = &aspeed_lpc_ctrl_fops; @@ -291,6 +321,7 @@ static int aspeed_lpc_ctrl_remove(struct platform_device *pdev) static const struct of_device_id aspeed_lpc_ctrl_match[] = { { .compatible = "aspeed,ast2400-lpc-ctrl" }, { .compatible = "aspeed,ast2500-lpc-ctrl" }, + { .compatible = "aspeed,ast2600-lpc-ctrl" }, { }, }; @@ -308,4 +339,4 @@ module_platform_driver(aspeed_lpc_ctrl_driver); MODULE_DEVICE_TABLE(of, aspeed_lpc_ctrl_match); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Cyril Bur <cyrilbur@gmail.com>"); -MODULE_DESCRIPTION("Control for aspeed 2400/2500 LPC HOST to BMC mappings"); +MODULE_DESCRIPTION("Control for ASPEED LPC HOST to BMC mappings"); diff --git a/drivers/soc/aspeed/aspeed-lpc-snoop.c b/drivers/soc/aspeed/aspeed-lpc-snoop.c index f3d8d53ab84d..682ba0eb4eba 100644 --- a/drivers/soc/aspeed/aspeed-lpc-snoop.c +++ b/drivers/soc/aspeed/aspeed-lpc-snoop.c @@ -325,6 +325,8 @@ static const struct of_device_id aspeed_lpc_snoop_match[] = { .data = &ast2400_model_data }, { .compatible = "aspeed,ast2500-lpc-snoop", .data = &ast2500_model_data }, + { .compatible = "aspeed,ast2600-lpc-snoop", + .data = &ast2500_model_data }, { }, }; diff --git a/drivers/soc/aspeed/aspeed-socinfo.c b/drivers/soc/aspeed/aspeed-socinfo.c new file mode 100644 index 000000000000..773930e0cb10 --- /dev/null +++ b/drivers/soc/aspeed/aspeed-socinfo.c @@ -0,0 +1,135 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* Copyright 2019 IBM Corp. */ + +#include <linux/io.h> +#include <linux/of.h> +#include <linux/of_address.h> +#include <linux/of_platform.h> +#include <linux/platform_device.h> +#include <linux/slab.h> +#include <linux/sys_soc.h> + +static struct { + const char *name; + const u32 id; +} const rev_table[] = { + /* AST2400 */ + { "AST2400", 0x02000303 }, + { "AST1400", 0x02010103 }, + { "AST1250", 0x02010303 }, + /* AST2500 */ + { "AST2500", 0x04000303 }, + { "AST2510", 0x04000103 }, + { "AST2520", 0x04000203 }, + { "AST2530", 0x04000403 }, + /* AST2600 */ + { "AST2600", 0x05000303 }, + { "AST2620", 0x05010203 }, +}; + +static const char *siliconid_to_name(u32 siliconid) +{ + unsigned int id = siliconid & 0xff00ffff; + unsigned int i; + + for (i = 0 ; i < ARRAY_SIZE(rev_table) ; ++i) { + if (rev_table[i].id == id) + return rev_table[i].name; + } + + return "Unknown"; +} + +static const char *siliconid_to_rev(u32 siliconid) +{ + unsigned int rev = (siliconid >> 16) & 0xff; + + switch (rev) { + case 0: + return "A0"; + case 1: + return "A1"; + case 3: + return "A2"; + } + + return "??"; +} + +static int __init aspeed_socinfo_init(void) +{ + struct soc_device_attribute *attrs; + struct soc_device *soc_dev; + struct device_node *np; + void __iomem *reg; + bool has_chipid = false; + u32 siliconid; + u32 chipid[2]; + const char *machine = NULL; + + np = of_find_compatible_node(NULL, NULL, "aspeed,silicon-id"); + if (!of_device_is_available(np)) { + of_node_put(np); + return -ENODEV; + } + + reg = of_iomap(np, 0); + if (!reg) { + of_node_put(np); + return -ENODEV; + } + siliconid = readl(reg); + iounmap(reg); + + /* This is optional, the ast2400 does not have it */ + reg = of_iomap(np, 1); + if (reg) { + has_chipid = true; + chipid[0] = readl(reg); + chipid[1] = readl(reg + 4); + iounmap(reg); + } + of_node_put(np); + + attrs = kzalloc(sizeof(*attrs), GFP_KERNEL); + if (!attrs) + return -ENODEV; + + /* + * Machine: Romulus BMC + * Family: AST2500 + * Revision: A1 + * SoC ID: raw silicon revision id + * Serial Number: 64-bit chipid + */ + + np = of_find_node_by_path("/"); + of_property_read_string(np, "model", &machine); + if (machine) + attrs->machine = kstrdup(machine, GFP_KERNEL); + of_node_put(np); + + attrs->family = siliconid_to_name(siliconid); + attrs->revision = siliconid_to_rev(siliconid); + attrs->soc_id = kasprintf(GFP_KERNEL, "%08x", siliconid); + + if (has_chipid) + attrs->serial_number = kasprintf(GFP_KERNEL, "%08x%08x", + chipid[1], chipid[0]); + + soc_dev = soc_device_register(attrs); + if (IS_ERR(soc_dev)) { + kfree(attrs->soc_id); + kfree(attrs->serial_number); + kfree(attrs); + return PTR_ERR(soc_dev); + } + + pr_info("ASPEED %s rev %s (%s)\n", + attrs->family, + attrs->revision, + attrs->soc_id); + + return 0; +} +early_initcall(aspeed_socinfo_init); |