Commit 00c543f6 authored by Arnd Bergmann's avatar Arnd Bergmann

Merge tag 'aspeed-5.11-soc' of...

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.comSigned-off-by: default avatarArnd Bergmann <arnd@arndb.de>
parents bbecede4 4da595dd
......@@ -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
......
......@@ -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>;
};
......@@ -192,6 +192,11 @@ p2a: p2a-control@2c {
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";
......
......@@ -239,6 +239,11 @@ p2a: p2a-control@2c {
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>;
......
......@@ -311,6 +311,11 @@ pinctrl: pinctrl {
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>;
......
......@@ -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/
......
# 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
......@@ -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
......@@ -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)
......@@ -176,6 +181,16 @@ static long aspeed_lpc_ctrl_ioctl(struct file *file, unsigned int cmd,
if (rc)
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");
......@@ -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 },
{ },
};
......
// 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);
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