Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 00f7dc63 authored by Michal Simek's avatar Michal Simek
Browse files

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: default avatarMichal Simek <michal.simek@xilinx.com>
parent c9eaa447
Loading
Loading
Loading
Loading
+5 −0
Original line number Original line Diff line number Diff line
@@ -154,6 +154,11 @@
			};
			};
		};
		};


		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>;
+1 −0
Original line number Original line Diff line number Diff line
@@ -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
+70 −1
Original line number Original line Diff line number Diff line
@@ -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);
+1 −0
Original line number Original line Diff line number Diff line
@@ -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);
+19 −0
Original line number Original line Diff line number Diff line
@@ -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.
 */
 */