Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2)  * System controller support for Armada 370, 375 and XP platforms.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  * Copyright (C) 2012 Marvell
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  * Lior Amsalem <alior@marvell.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  * Gregory CLEMENT <gregory.clement@free-electrons.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  * This file is licensed under the terms of the GNU General Public
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)  * License version 2.  This program is licensed "as is" without any
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12)  * warranty of any kind, whether express or implied.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14)  * The Armada 370, 375 and Armada XP SoCs have a range of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15)  * miscellaneous registers, that do not belong to a particular device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16)  * but rather provide system-level features. This basic
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17)  * system-controller driver provides a device tree binding for those
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18)  * registers, and implements utility functions offering various
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19)  * features related to those registers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21)  * For now, the feature set is limited to restarting the platform by a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22)  * soft-reset, but it might be extended in the future.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) #include <linux/of_address.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) #include <linux/reboot.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) #include "common.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) #include "mvebu-soc-id.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) #include "pmsu.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) #define ARMADA_375_CRYPT0_ENG_TARGET 41
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) #define ARMADA_375_CRYPT0_ENG_ATTR    1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) static void __iomem *system_controller_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) static phys_addr_t system_controller_phys_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) struct mvebu_system_controller {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 	u32 rstoutn_mask_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 	u32 system_soft_reset_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 	u32 rstoutn_mask_reset_out_en;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	u32 system_soft_reset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 	u32 resume_boot_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 	u32 dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 	u32 rev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) static struct mvebu_system_controller *mvebu_sc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) static const struct mvebu_system_controller armada_370_xp_system_controller = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 	.rstoutn_mask_offset = 0x60,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	.system_soft_reset_offset = 0x64,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 	.rstoutn_mask_reset_out_en = 0x1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	.system_soft_reset = 0x1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 	.dev_id = 0x38,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 	.rev_id = 0x3c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) static const struct mvebu_system_controller armada_375_system_controller = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	.rstoutn_mask_offset = 0x54,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	.system_soft_reset_offset = 0x58,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	.rstoutn_mask_reset_out_en = 0x1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	.system_soft_reset = 0x1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	.resume_boot_addr = 0xd4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	.dev_id = 0x38,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	.rev_id = 0x3c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) static const struct mvebu_system_controller orion_system_controller = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	.rstoutn_mask_offset = 0x108,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	.system_soft_reset_offset = 0x10c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	.rstoutn_mask_reset_out_en = 0x4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	.system_soft_reset = 0x1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) static const struct of_device_id of_system_controller_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 		.compatible = "marvell,orion-system-controller",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 		.data = (void *) &orion_system_controller,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	}, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 		.compatible = "marvell,armada-370-xp-system-controller",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 		.data = (void *) &armada_370_xp_system_controller,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	}, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 		.compatible = "marvell,armada-375-system-controller",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 		.data = (void *) &armada_375_system_controller,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	{ /* end of list */ },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) void mvebu_restart(enum reboot_mode mode, const char *cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	if (!system_controller_base) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 		pr_err("Cannot restart, system-controller not available: check the device tree\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 		 * Enable soft reset to assert RSTOUTn.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 		writel(mvebu_sc->rstoutn_mask_reset_out_en,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 			system_controller_base +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 			mvebu_sc->rstoutn_mask_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 		 * Assert soft reset.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 		writel(mvebu_sc->system_soft_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 			system_controller_base +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 			mvebu_sc->system_soft_reset_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 	while (1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 		;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) int mvebu_system_controller_get_soc_id(u32 *dev, u32 *rev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	if (of_machine_is_compatible("marvell,armada380") &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 		system_controller_base) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 		*dev = readl(system_controller_base + mvebu_sc->dev_id) >> 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 		*rev = (readl(system_controller_base + mvebu_sc->rev_id) >> 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 			& 0xF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) #if defined(CONFIG_SMP) && defined(CONFIG_MACH_MVEBU_V7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) static void mvebu_armada375_smp_wa_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	u32 dev, rev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	phys_addr_t resume_addr_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 	if (mvebu_get_soc_id(&dev, &rev) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 	if (rev != ARMADA_375_Z1_REV)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 	resume_addr_reg = system_controller_phys_base +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 		mvebu_sc->resume_boot_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	mvebu_setup_boot_addr_wa(ARMADA_375_CRYPT0_ENG_TARGET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 				 ARMADA_375_CRYPT0_ENG_ATTR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 				 resume_addr_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) void mvebu_system_controller_set_cpu_boot_addr(void *boot_addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	BUG_ON(system_controller_base == NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	BUG_ON(mvebu_sc->resume_boot_addr == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	if (of_machine_is_compatible("marvell,armada375"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 		mvebu_armada375_smp_wa_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 	writel(__pa_symbol(boot_addr), system_controller_base +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 	       mvebu_sc->resume_boot_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) static int __init mvebu_system_controller_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 	const struct of_device_id *match;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	struct device_node *np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	np = of_find_matching_node_and_match(NULL, of_system_controller_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 					     &match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	if (np) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 		struct resource res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 		system_controller_base = of_iomap(np, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 		of_address_to_resource(np, 0, &res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 		system_controller_phys_base = res.start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 		mvebu_sc = (struct mvebu_system_controller *)match->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 		of_node_put(np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) early_initcall(mvebu_system_controller_init);