mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-02 02:36:44 +07:00
ARM: zynq: Add support for SOC_BUS
Provide information through SOC_BUS to user space. Silicon revision is provided through devcfg device. Signed-off-by: Michal Simek <michal.simek@xilinx.com>
This commit is contained in:
parent
c9eaa447e7
commit
00f7dc6363
@ -154,6 +154,11 @@ clkc: clkc@100 {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
devcfg: devcfg@f8007000 {
|
||||||
|
compatible = "xlnx,zynq-devcfg-1.0";
|
||||||
|
reg = <0xf8007000 0x100>;
|
||||||
|
} ;
|
||||||
|
|
||||||
global_timer: timer@f8f00200 {
|
global_timer: timer@f8f00200 {
|
||||||
compatible = "arm,cortex-a9-global-timer";
|
compatible = "arm,cortex-a9-global-timer";
|
||||||
reg = <0xf8f00200 0x20>;
|
reg = <0xf8f00200 0x20>;
|
||||||
|
@ -10,5 +10,6 @@ config ARCH_ZYNQ
|
|||||||
select CADENCE_TTC_TIMER
|
select CADENCE_TTC_TIMER
|
||||||
select ARM_GLOBAL_TIMER if !CPU_FREQ
|
select ARM_GLOBAL_TIMER if !CPU_FREQ
|
||||||
select MFD_SYSCON
|
select MFD_SYSCON
|
||||||
|
select SOC_BUS
|
||||||
help
|
help
|
||||||
Support for Xilinx Zynq ARM Cortex A9 Platform
|
Support for Xilinx Zynq ARM Cortex A9 Platform
|
||||||
|
@ -29,6 +29,8 @@
|
|||||||
#include <linux/memblock.h>
|
#include <linux/memblock.h>
|
||||||
#include <linux/irqchip.h>
|
#include <linux/irqchip.h>
|
||||||
#include <linux/irqchip/arm-gic.h>
|
#include <linux/irqchip/arm-gic.h>
|
||||||
|
#include <linux/slab.h>
|
||||||
|
#include <linux/sys_soc.h>
|
||||||
|
|
||||||
#include <asm/mach/arch.h>
|
#include <asm/mach/arch.h>
|
||||||
#include <asm/mach/map.h>
|
#include <asm/mach/map.h>
|
||||||
@ -37,10 +39,15 @@
|
|||||||
#include <asm/page.h>
|
#include <asm/page.h>
|
||||||
#include <asm/pgtable.h>
|
#include <asm/pgtable.h>
|
||||||
#include <asm/smp_scu.h>
|
#include <asm/smp_scu.h>
|
||||||
|
#include <asm/system_info.h>
|
||||||
#include <asm/hardware/cache-l2x0.h>
|
#include <asm/hardware/cache-l2x0.h>
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
|
#define ZYNQ_DEVCFG_MCTRL 0x80
|
||||||
|
#define ZYNQ_DEVCFG_PS_VERSION_SHIFT 28
|
||||||
|
#define ZYNQ_DEVCFG_PS_VERSION_MASK 0xF
|
||||||
|
|
||||||
void __iomem *zynq_scu_base;
|
void __iomem *zynq_scu_base;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -59,6 +66,38 @@ static struct platform_device zynq_cpuidle_device = {
|
|||||||
.name = "cpuidle-zynq",
|
.name = "cpuidle-zynq",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* zynq_get_revision - Get Zynq silicon revision
|
||||||
|
*
|
||||||
|
* Return: Silicon version or -1 otherwise
|
||||||
|
*/
|
||||||
|
static int __init zynq_get_revision(void)
|
||||||
|
{
|
||||||
|
struct device_node *np;
|
||||||
|
void __iomem *zynq_devcfg_base;
|
||||||
|
u32 revision;
|
||||||
|
|
||||||
|
np = of_find_compatible_node(NULL, NULL, "xlnx,zynq-devcfg-1.0");
|
||||||
|
if (!np) {
|
||||||
|
pr_err("%s: no devcfg node found\n", __func__);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
zynq_devcfg_base = of_iomap(np, 0);
|
||||||
|
if (!zynq_devcfg_base) {
|
||||||
|
pr_err("%s: Unable to map I/O memory\n", __func__);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
revision = readl(zynq_devcfg_base + ZYNQ_DEVCFG_MCTRL);
|
||||||
|
revision >>= ZYNQ_DEVCFG_PS_VERSION_SHIFT;
|
||||||
|
revision &= ZYNQ_DEVCFG_PS_VERSION_MASK;
|
||||||
|
|
||||||
|
iounmap(zynq_devcfg_base);
|
||||||
|
|
||||||
|
return revision;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* zynq_init_machine - System specific initialization, intended to be
|
* zynq_init_machine - System specific initialization, intended to be
|
||||||
* called from board specific initialization.
|
* called from board specific initialization.
|
||||||
@ -66,13 +105,43 @@ static struct platform_device zynq_cpuidle_device = {
|
|||||||
static void __init zynq_init_machine(void)
|
static void __init zynq_init_machine(void)
|
||||||
{
|
{
|
||||||
struct platform_device_info devinfo = { .name = "cpufreq-cpu0", };
|
struct platform_device_info devinfo = { .name = "cpufreq-cpu0", };
|
||||||
|
struct soc_device_attribute *soc_dev_attr;
|
||||||
|
struct soc_device *soc_dev;
|
||||||
|
struct device *parent = NULL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 64KB way size, 8-way associativity, parity disabled
|
* 64KB way size, 8-way associativity, parity disabled
|
||||||
*/
|
*/
|
||||||
l2x0_of_init(0x02060000, 0xF0F0FFFF);
|
l2x0_of_init(0x02060000, 0xF0F0FFFF);
|
||||||
|
|
||||||
of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
|
soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
|
||||||
|
if (!soc_dev_attr)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
system_rev = zynq_get_revision();
|
||||||
|
|
||||||
|
soc_dev_attr->family = kasprintf(GFP_KERNEL, "Xilinx Zynq");
|
||||||
|
soc_dev_attr->revision = kasprintf(GFP_KERNEL, "0x%x", system_rev);
|
||||||
|
soc_dev_attr->soc_id = kasprintf(GFP_KERNEL, "0x%x",
|
||||||
|
zynq_slcr_get_device_id());
|
||||||
|
|
||||||
|
soc_dev = soc_device_register(soc_dev_attr);
|
||||||
|
if (IS_ERR(soc_dev)) {
|
||||||
|
kfree(soc_dev_attr->family);
|
||||||
|
kfree(soc_dev_attr->revision);
|
||||||
|
kfree(soc_dev_attr->soc_id);
|
||||||
|
kfree(soc_dev_attr);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
parent = soc_device_to_device(soc_dev);
|
||||||
|
|
||||||
|
out:
|
||||||
|
/*
|
||||||
|
* Finished with the static registrations now; fill in the missing
|
||||||
|
* devices
|
||||||
|
*/
|
||||||
|
of_platform_populate(NULL, of_default_bus_match_table, NULL, parent);
|
||||||
|
|
||||||
platform_device_register(&zynq_cpuidle_device);
|
platform_device_register(&zynq_cpuidle_device);
|
||||||
platform_device_register_full(&devinfo);
|
platform_device_register_full(&devinfo);
|
||||||
|
@ -24,6 +24,7 @@ extern int zynq_early_slcr_init(void);
|
|||||||
extern void zynq_slcr_system_reset(void);
|
extern void zynq_slcr_system_reset(void);
|
||||||
extern void zynq_slcr_cpu_stop(int cpu);
|
extern void zynq_slcr_cpu_stop(int cpu);
|
||||||
extern void zynq_slcr_cpu_start(int cpu);
|
extern void zynq_slcr_cpu_start(int cpu);
|
||||||
|
extern u32 zynq_slcr_get_device_id(void);
|
||||||
|
|
||||||
#ifdef CONFIG_SMP
|
#ifdef CONFIG_SMP
|
||||||
extern void secondary_startup(void);
|
extern void secondary_startup(void);
|
||||||
|
@ -26,10 +26,13 @@
|
|||||||
#define SLCR_PS_RST_CTRL_OFFSET 0x200 /* PS Software Reset Control */
|
#define SLCR_PS_RST_CTRL_OFFSET 0x200 /* PS Software Reset Control */
|
||||||
#define SLCR_A9_CPU_RST_CTRL_OFFSET 0x244 /* CPU Software Reset Control */
|
#define SLCR_A9_CPU_RST_CTRL_OFFSET 0x244 /* CPU Software Reset Control */
|
||||||
#define SLCR_REBOOT_STATUS_OFFSET 0x258 /* PS Reboot Status */
|
#define SLCR_REBOOT_STATUS_OFFSET 0x258 /* PS Reboot Status */
|
||||||
|
#define SLCR_PSS_IDCODE 0x530 /* PS IDCODE */
|
||||||
|
|
||||||
#define SLCR_UNLOCK_MAGIC 0xDF0D
|
#define SLCR_UNLOCK_MAGIC 0xDF0D
|
||||||
#define SLCR_A9_CPU_CLKSTOP 0x10
|
#define SLCR_A9_CPU_CLKSTOP 0x10
|
||||||
#define SLCR_A9_CPU_RST 0x1
|
#define SLCR_A9_CPU_RST 0x1
|
||||||
|
#define SLCR_PSS_IDCODE_DEVICE_SHIFT 12
|
||||||
|
#define SLCR_PSS_IDCODE_DEVICE_MASK 0x1F
|
||||||
|
|
||||||
static void __iomem *zynq_slcr_base;
|
static void __iomem *zynq_slcr_base;
|
||||||
static struct regmap *zynq_slcr_regmap;
|
static struct regmap *zynq_slcr_regmap;
|
||||||
@ -82,6 +85,22 @@ static inline int zynq_slcr_unlock(void)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* zynq_slcr_get_device_id - Read device code id
|
||||||
|
*
|
||||||
|
* Return: Device code id
|
||||||
|
*/
|
||||||
|
u32 zynq_slcr_get_device_id(void)
|
||||||
|
{
|
||||||
|
u32 val;
|
||||||
|
|
||||||
|
zynq_slcr_read(&val, SLCR_PSS_IDCODE);
|
||||||
|
val >>= SLCR_PSS_IDCODE_DEVICE_SHIFT;
|
||||||
|
val &= SLCR_PSS_IDCODE_DEVICE_MASK;
|
||||||
|
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* zynq_slcr_system_reset - Reset the entire system.
|
* zynq_slcr_system_reset - Reset the entire system.
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user