162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * AXS101/AXS103 Software Development Platform
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Copyright (C) 2013-15 Synopsys, Inc. (www.synopsys.com)
662306a36Sopenharmony_ci */
762306a36Sopenharmony_ci
862306a36Sopenharmony_ci#include <linux/of_fdt.h>
962306a36Sopenharmony_ci#include <linux/libfdt.h>
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_ci#include <asm/asm-offsets.h>
1262306a36Sopenharmony_ci#include <asm/io.h>
1362306a36Sopenharmony_ci#include <asm/mach_desc.h>
1462306a36Sopenharmony_ci#include <soc/arc/mcip.h>
1562306a36Sopenharmony_ci
1662306a36Sopenharmony_ci#define AXS_MB_CGU		0xE0010000
1762306a36Sopenharmony_ci#define AXS_MB_CREG		0xE0011000
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_ci#define CREG_MB_IRQ_MUX		(AXS_MB_CREG + 0x214)
2062306a36Sopenharmony_ci#define CREG_MB_SW_RESET	(AXS_MB_CREG + 0x220)
2162306a36Sopenharmony_ci#define CREG_MB_VER		(AXS_MB_CREG + 0x230)
2262306a36Sopenharmony_ci#define CREG_MB_CONFIG		(AXS_MB_CREG + 0x234)
2362306a36Sopenharmony_ci
2462306a36Sopenharmony_ci#define AXC001_CREG		0xF0001000
2562306a36Sopenharmony_ci#define AXC001_GPIO_INTC	0xF0003000
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_cistatic void __init axs10x_enable_gpio_intc_wire(void)
2862306a36Sopenharmony_ci{
2962306a36Sopenharmony_ci	/*
3062306a36Sopenharmony_ci	 * Peripherals on CPU Card and Mother Board are wired to cpu intc via
3162306a36Sopenharmony_ci	 * intermediate DW APB GPIO blocks (mainly for debouncing)
3262306a36Sopenharmony_ci	 *
3362306a36Sopenharmony_ci	 *         ---------------------
3462306a36Sopenharmony_ci	 *        |  snps,arc700-intc |
3562306a36Sopenharmony_ci	 *        ---------------------
3662306a36Sopenharmony_ci	 *          | #7          | #15
3762306a36Sopenharmony_ci	 * -------------------   -------------------
3862306a36Sopenharmony_ci	 * | snps,dw-apb-gpio |  | snps,dw-apb-gpio |
3962306a36Sopenharmony_ci	 * -------------------   -------------------
4062306a36Sopenharmony_ci	 *        | #12                     |
4162306a36Sopenharmony_ci	 *        |                 [ Debug UART on cpu card ]
4262306a36Sopenharmony_ci	 *        |
4362306a36Sopenharmony_ci	 * ------------------------
4462306a36Sopenharmony_ci	 * | snps,dw-apb-intc (MB)|
4562306a36Sopenharmony_ci	 * ------------------------
4662306a36Sopenharmony_ci	 *  |      |       |      |
4762306a36Sopenharmony_ci	 * [eth] [uart]        [... other perip on Main Board]
4862306a36Sopenharmony_ci	 *
4962306a36Sopenharmony_ci	 * Current implementation of "irq-dw-apb-ictl" driver doesn't work well
5062306a36Sopenharmony_ci	 * with stacked INTCs. In particular problem happens if its master INTC
5162306a36Sopenharmony_ci	 * not yet instantiated. See discussion here -
5262306a36Sopenharmony_ci	 * https://lore.kernel.org/lkml/54F6FE2C.7020309@synopsys.com
5362306a36Sopenharmony_ci	 *
5462306a36Sopenharmony_ci	 * So setup the first gpio block as a passive pass thru and hide it from
5562306a36Sopenharmony_ci	 * DT hardware topology - connect MB intc directly to cpu intc
5662306a36Sopenharmony_ci	 * The GPIO "wire" needs to be init nevertheless (here)
5762306a36Sopenharmony_ci	 *
5862306a36Sopenharmony_ci	 * One side adv is that peripheral interrupt handling avoids one nested
5962306a36Sopenharmony_ci	 * intc ISR hop
6062306a36Sopenharmony_ci	 */
6162306a36Sopenharmony_ci#define GPIO_INTEN		(AXC001_GPIO_INTC + 0x30)
6262306a36Sopenharmony_ci#define GPIO_INTMASK		(AXC001_GPIO_INTC + 0x34)
6362306a36Sopenharmony_ci#define GPIO_INTTYPE_LEVEL	(AXC001_GPIO_INTC + 0x38)
6462306a36Sopenharmony_ci#define GPIO_INT_POLARITY	(AXC001_GPIO_INTC + 0x3c)
6562306a36Sopenharmony_ci#define MB_TO_GPIO_IRQ		12
6662306a36Sopenharmony_ci
6762306a36Sopenharmony_ci	iowrite32(~(1 << MB_TO_GPIO_IRQ), (void __iomem *) GPIO_INTMASK);
6862306a36Sopenharmony_ci	iowrite32(0, (void __iomem *) GPIO_INTTYPE_LEVEL);
6962306a36Sopenharmony_ci	iowrite32(~0, (void __iomem *) GPIO_INT_POLARITY);
7062306a36Sopenharmony_ci	iowrite32(1 << MB_TO_GPIO_IRQ, (void __iomem *) GPIO_INTEN);
7162306a36Sopenharmony_ci}
7262306a36Sopenharmony_ci
7362306a36Sopenharmony_cistatic void __init axs10x_print_board_ver(unsigned int creg, const char *str)
7462306a36Sopenharmony_ci{
7562306a36Sopenharmony_ci	union ver {
7662306a36Sopenharmony_ci		struct {
7762306a36Sopenharmony_ci#ifdef CONFIG_CPU_BIG_ENDIAN
7862306a36Sopenharmony_ci			unsigned int pad:11, y:12, m:4, d:5;
7962306a36Sopenharmony_ci#else
8062306a36Sopenharmony_ci			unsigned int d:5, m:4, y:12, pad:11;
8162306a36Sopenharmony_ci#endif
8262306a36Sopenharmony_ci		};
8362306a36Sopenharmony_ci		unsigned int val;
8462306a36Sopenharmony_ci	} board;
8562306a36Sopenharmony_ci
8662306a36Sopenharmony_ci	board.val = ioread32((void __iomem *)creg);
8762306a36Sopenharmony_ci	pr_info("AXS: %s FPGA Date: %u-%u-%u\n", str, board.d, board.m,
8862306a36Sopenharmony_ci		board.y);
8962306a36Sopenharmony_ci}
9062306a36Sopenharmony_ci
9162306a36Sopenharmony_cistatic void __init axs10x_early_init(void)
9262306a36Sopenharmony_ci{
9362306a36Sopenharmony_ci	int mb_rev;
9462306a36Sopenharmony_ci	char mb[32];
9562306a36Sopenharmony_ci
9662306a36Sopenharmony_ci	/* Determine motherboard version */
9762306a36Sopenharmony_ci	if (ioread32((void __iomem *) CREG_MB_CONFIG) & (1 << 28))
9862306a36Sopenharmony_ci		mb_rev = 3;	/* HT-3 (rev3.0) */
9962306a36Sopenharmony_ci	else
10062306a36Sopenharmony_ci		mb_rev = 2;	/* HT-2 (rev2.0) */
10162306a36Sopenharmony_ci
10262306a36Sopenharmony_ci	axs10x_enable_gpio_intc_wire();
10362306a36Sopenharmony_ci
10462306a36Sopenharmony_ci	scnprintf(mb, 32, "MainBoard v%d", mb_rev);
10562306a36Sopenharmony_ci	axs10x_print_board_ver(CREG_MB_VER, mb);
10662306a36Sopenharmony_ci}
10762306a36Sopenharmony_ci
10862306a36Sopenharmony_ci#ifdef CONFIG_AXS101
10962306a36Sopenharmony_ci
11062306a36Sopenharmony_ci#define CREG_CPU_ADDR_770	(AXC001_CREG + 0x20)
11162306a36Sopenharmony_ci#define CREG_CPU_ADDR_TUNN	(AXC001_CREG + 0x60)
11262306a36Sopenharmony_ci#define CREG_CPU_ADDR_770_UPD	(AXC001_CREG + 0x34)
11362306a36Sopenharmony_ci#define CREG_CPU_ADDR_TUNN_UPD	(AXC001_CREG + 0x74)
11462306a36Sopenharmony_ci
11562306a36Sopenharmony_ci#define CREG_CPU_ARC770_IRQ_MUX	(AXC001_CREG + 0x114)
11662306a36Sopenharmony_ci#define CREG_CPU_GPIO_UART_MUX	(AXC001_CREG + 0x120)
11762306a36Sopenharmony_ci
11862306a36Sopenharmony_ci/*
11962306a36Sopenharmony_ci * Set up System Memory Map for ARC cpu / peripherals controllers
12062306a36Sopenharmony_ci *
12162306a36Sopenharmony_ci * Each AXI master has a 4GB memory map specified as 16 apertures of 256MB, each
12262306a36Sopenharmony_ci * of which maps to a corresponding 256MB aperture in Target slave memory map.
12362306a36Sopenharmony_ci *
12462306a36Sopenharmony_ci * e.g. ARC cpu AXI Master's aperture 8 (0x8000_0000) is mapped to aperture 0
12562306a36Sopenharmony_ci * (0x0000_0000) of DDR Port 0 (slave #1)
12662306a36Sopenharmony_ci *
12762306a36Sopenharmony_ci * Access from cpu to MB controllers such as GMAC is setup using AXI Tunnel:
12862306a36Sopenharmony_ci * which has master/slaves on both ends.
12962306a36Sopenharmony_ci * e.g. aperture 14 (0xE000_0000) of ARC cpu is mapped to aperture 14
13062306a36Sopenharmony_ci * (0xE000_0000) of CPU Card AXI Tunnel slave (slave #3) which is mapped to
13162306a36Sopenharmony_ci * MB AXI Tunnel Master, which also has a mem map setup
13262306a36Sopenharmony_ci *
13362306a36Sopenharmony_ci * In the reverse direction, MB AXI Masters (e.g. GMAC) mem map is setup
13462306a36Sopenharmony_ci * to map to MB AXI Tunnel slave which connects to CPU Card AXI Tunnel Master
13562306a36Sopenharmony_ci */
13662306a36Sopenharmony_cistruct aperture {
13762306a36Sopenharmony_ci	unsigned int slave_sel:4, slave_off:4, pad:24;
13862306a36Sopenharmony_ci};
13962306a36Sopenharmony_ci
14062306a36Sopenharmony_ci/* CPU Card target slaves */
14162306a36Sopenharmony_ci#define AXC001_SLV_NONE			0
14262306a36Sopenharmony_ci#define AXC001_SLV_DDR_PORT0		1
14362306a36Sopenharmony_ci#define AXC001_SLV_SRAM			2
14462306a36Sopenharmony_ci#define AXC001_SLV_AXI_TUNNEL		3
14562306a36Sopenharmony_ci#define AXC001_SLV_AXI2APB		6
14662306a36Sopenharmony_ci#define AXC001_SLV_DDR_PORT1		7
14762306a36Sopenharmony_ci
14862306a36Sopenharmony_ci/* MB AXI Target slaves */
14962306a36Sopenharmony_ci#define AXS_MB_SLV_NONE			0
15062306a36Sopenharmony_ci#define AXS_MB_SLV_AXI_TUNNEL_CPU	1
15162306a36Sopenharmony_ci#define AXS_MB_SLV_AXI_TUNNEL_HAPS	2
15262306a36Sopenharmony_ci#define AXS_MB_SLV_SRAM			3
15362306a36Sopenharmony_ci#define AXS_MB_SLV_CONTROL		4
15462306a36Sopenharmony_ci
15562306a36Sopenharmony_ci/* MB AXI masters */
15662306a36Sopenharmony_ci#define AXS_MB_MST_TUNNEL_CPU		0
15762306a36Sopenharmony_ci#define AXS_MB_MST_USB_OHCI		10
15862306a36Sopenharmony_ci
15962306a36Sopenharmony_ci/*
16062306a36Sopenharmony_ci * memmap for ARC core on CPU Card
16162306a36Sopenharmony_ci */
16262306a36Sopenharmony_cistatic const struct aperture axc001_memmap[16] = {
16362306a36Sopenharmony_ci	{AXC001_SLV_AXI_TUNNEL,		0x0},
16462306a36Sopenharmony_ci	{AXC001_SLV_AXI_TUNNEL,		0x1},
16562306a36Sopenharmony_ci	{AXC001_SLV_SRAM,		0x0}, /* 0x2000_0000: Local SRAM */
16662306a36Sopenharmony_ci	{AXC001_SLV_NONE,		0x0},
16762306a36Sopenharmony_ci	{AXC001_SLV_NONE,		0x0},
16862306a36Sopenharmony_ci	{AXC001_SLV_NONE,		0x0},
16962306a36Sopenharmony_ci	{AXC001_SLV_NONE,		0x0},
17062306a36Sopenharmony_ci	{AXC001_SLV_NONE,		0x0},
17162306a36Sopenharmony_ci	{AXC001_SLV_DDR_PORT0,		0x0}, /* 0x8000_0000: DDR   0..256M */
17262306a36Sopenharmony_ci	{AXC001_SLV_DDR_PORT0,		0x1}, /* 0x9000_0000: DDR 256..512M */
17362306a36Sopenharmony_ci	{AXC001_SLV_DDR_PORT0,		0x2},
17462306a36Sopenharmony_ci	{AXC001_SLV_DDR_PORT0,		0x3},
17562306a36Sopenharmony_ci	{AXC001_SLV_NONE,		0x0},
17662306a36Sopenharmony_ci	{AXC001_SLV_AXI_TUNNEL,		0xD},
17762306a36Sopenharmony_ci	{AXC001_SLV_AXI_TUNNEL,		0xE}, /* MB: CREG, CGU... */
17862306a36Sopenharmony_ci	{AXC001_SLV_AXI2APB,		0x0}, /* CPU Card local CREG, CGU... */
17962306a36Sopenharmony_ci};
18062306a36Sopenharmony_ci
18162306a36Sopenharmony_ci/*
18262306a36Sopenharmony_ci * memmap for CPU Card AXI Tunnel Master (for access by MB controllers)
18362306a36Sopenharmony_ci * GMAC (MB) -> MB AXI Tunnel slave -> CPU Card AXI Tunnel Master -> DDR
18462306a36Sopenharmony_ci */
18562306a36Sopenharmony_cistatic const struct aperture axc001_axi_tunnel_memmap[16] = {
18662306a36Sopenharmony_ci	{AXC001_SLV_AXI_TUNNEL,		0x0},
18762306a36Sopenharmony_ci	{AXC001_SLV_AXI_TUNNEL,		0x1},
18862306a36Sopenharmony_ci	{AXC001_SLV_SRAM,		0x0},
18962306a36Sopenharmony_ci	{AXC001_SLV_NONE,		0x0},
19062306a36Sopenharmony_ci	{AXC001_SLV_NONE,		0x0},
19162306a36Sopenharmony_ci	{AXC001_SLV_NONE,		0x0},
19262306a36Sopenharmony_ci	{AXC001_SLV_NONE,		0x0},
19362306a36Sopenharmony_ci	{AXC001_SLV_NONE,		0x0},
19462306a36Sopenharmony_ci	{AXC001_SLV_DDR_PORT1,		0x0},
19562306a36Sopenharmony_ci	{AXC001_SLV_DDR_PORT1,		0x1},
19662306a36Sopenharmony_ci	{AXC001_SLV_DDR_PORT1,		0x2},
19762306a36Sopenharmony_ci	{AXC001_SLV_DDR_PORT1,		0x3},
19862306a36Sopenharmony_ci	{AXC001_SLV_NONE,		0x0},
19962306a36Sopenharmony_ci	{AXC001_SLV_AXI_TUNNEL,		0xD},
20062306a36Sopenharmony_ci	{AXC001_SLV_AXI_TUNNEL,		0xE},
20162306a36Sopenharmony_ci	{AXC001_SLV_AXI2APB,		0x0},
20262306a36Sopenharmony_ci};
20362306a36Sopenharmony_ci
20462306a36Sopenharmony_ci/*
20562306a36Sopenharmony_ci * memmap for MB AXI Masters
20662306a36Sopenharmony_ci * Same mem map for all perip controllers as well as MB AXI Tunnel Master
20762306a36Sopenharmony_ci */
20862306a36Sopenharmony_cistatic const struct aperture axs_mb_memmap[16] = {
20962306a36Sopenharmony_ci	{AXS_MB_SLV_SRAM,		0x0},
21062306a36Sopenharmony_ci	{AXS_MB_SLV_SRAM,		0x0},
21162306a36Sopenharmony_ci	{AXS_MB_SLV_NONE,		0x0},
21262306a36Sopenharmony_ci	{AXS_MB_SLV_NONE,		0x0},
21362306a36Sopenharmony_ci	{AXS_MB_SLV_NONE,		0x0},
21462306a36Sopenharmony_ci	{AXS_MB_SLV_NONE,		0x0},
21562306a36Sopenharmony_ci	{AXS_MB_SLV_NONE,		0x0},
21662306a36Sopenharmony_ci	{AXS_MB_SLV_NONE,		0x0},
21762306a36Sopenharmony_ci	{AXS_MB_SLV_AXI_TUNNEL_CPU,	0x8},	/* DDR on CPU Card */
21862306a36Sopenharmony_ci	{AXS_MB_SLV_AXI_TUNNEL_CPU,	0x9},	/* DDR on CPU Card */
21962306a36Sopenharmony_ci	{AXS_MB_SLV_AXI_TUNNEL_CPU,	0xA},
22062306a36Sopenharmony_ci	{AXS_MB_SLV_AXI_TUNNEL_CPU,	0xB},
22162306a36Sopenharmony_ci	{AXS_MB_SLV_NONE,		0x0},
22262306a36Sopenharmony_ci	{AXS_MB_SLV_AXI_TUNNEL_HAPS,	0xD},
22362306a36Sopenharmony_ci	{AXS_MB_SLV_CONTROL,		0x0},	/* MB Local CREG, CGU... */
22462306a36Sopenharmony_ci	{AXS_MB_SLV_AXI_TUNNEL_CPU,	0xF},
22562306a36Sopenharmony_ci};
22662306a36Sopenharmony_ci
22762306a36Sopenharmony_cistatic noinline void __init
22862306a36Sopenharmony_ciaxs101_set_memmap(void __iomem *base, const struct aperture map[16])
22962306a36Sopenharmony_ci{
23062306a36Sopenharmony_ci	unsigned int slave_select, slave_offset;
23162306a36Sopenharmony_ci	int i;
23262306a36Sopenharmony_ci
23362306a36Sopenharmony_ci	slave_select = slave_offset = 0;
23462306a36Sopenharmony_ci	for (i = 0; i < 8; i++) {
23562306a36Sopenharmony_ci		slave_select |= map[i].slave_sel << (i << 2);
23662306a36Sopenharmony_ci		slave_offset |= map[i].slave_off << (i << 2);
23762306a36Sopenharmony_ci	}
23862306a36Sopenharmony_ci
23962306a36Sopenharmony_ci	iowrite32(slave_select, base + 0x0);	/* SLV0 */
24062306a36Sopenharmony_ci	iowrite32(slave_offset, base + 0x8);	/* OFFSET0 */
24162306a36Sopenharmony_ci
24262306a36Sopenharmony_ci	slave_select = slave_offset = 0;
24362306a36Sopenharmony_ci	for (i = 0; i < 8; i++) {
24462306a36Sopenharmony_ci		slave_select |= map[i+8].slave_sel << (i << 2);
24562306a36Sopenharmony_ci		slave_offset |= map[i+8].slave_off << (i << 2);
24662306a36Sopenharmony_ci	}
24762306a36Sopenharmony_ci
24862306a36Sopenharmony_ci	iowrite32(slave_select, base + 0x4);	/* SLV1 */
24962306a36Sopenharmony_ci	iowrite32(slave_offset, base + 0xC);	/* OFFSET1 */
25062306a36Sopenharmony_ci}
25162306a36Sopenharmony_ci
25262306a36Sopenharmony_cistatic void __init axs101_early_init(void)
25362306a36Sopenharmony_ci{
25462306a36Sopenharmony_ci	int i;
25562306a36Sopenharmony_ci
25662306a36Sopenharmony_ci	/* ARC 770D memory view */
25762306a36Sopenharmony_ci	axs101_set_memmap((void __iomem *) CREG_CPU_ADDR_770, axc001_memmap);
25862306a36Sopenharmony_ci	iowrite32(1, (void __iomem *) CREG_CPU_ADDR_770_UPD);
25962306a36Sopenharmony_ci
26062306a36Sopenharmony_ci	/* AXI tunnel memory map (incoming traffic from MB into CPU Card */
26162306a36Sopenharmony_ci	axs101_set_memmap((void __iomem *) CREG_CPU_ADDR_TUNN,
26262306a36Sopenharmony_ci			      axc001_axi_tunnel_memmap);
26362306a36Sopenharmony_ci	iowrite32(1, (void __iomem *) CREG_CPU_ADDR_TUNN_UPD);
26462306a36Sopenharmony_ci
26562306a36Sopenharmony_ci	/* MB peripherals memory map */
26662306a36Sopenharmony_ci	for (i = AXS_MB_MST_TUNNEL_CPU; i <= AXS_MB_MST_USB_OHCI; i++)
26762306a36Sopenharmony_ci		axs101_set_memmap((void __iomem *) AXS_MB_CREG + (i << 4),
26862306a36Sopenharmony_ci				      axs_mb_memmap);
26962306a36Sopenharmony_ci
27062306a36Sopenharmony_ci	iowrite32(0x3ff, (void __iomem *) AXS_MB_CREG + 0x100); /* Update */
27162306a36Sopenharmony_ci
27262306a36Sopenharmony_ci	/* GPIO pins 18 and 19 are used as UART rx and tx, respectively. */
27362306a36Sopenharmony_ci	iowrite32(0x01, (void __iomem *) CREG_CPU_GPIO_UART_MUX);
27462306a36Sopenharmony_ci
27562306a36Sopenharmony_ci	/* Set up the MB interrupt system: mux interrupts to GPIO7) */
27662306a36Sopenharmony_ci	iowrite32(0x01, (void __iomem *) CREG_MB_IRQ_MUX);
27762306a36Sopenharmony_ci
27862306a36Sopenharmony_ci	/* reset ethernet and ULPI interfaces */
27962306a36Sopenharmony_ci	iowrite32(0x18, (void __iomem *) CREG_MB_SW_RESET);
28062306a36Sopenharmony_ci
28162306a36Sopenharmony_ci	/* map GPIO 14:10 to ARC 9:5 (IRQ mux change for MB v2 onwards) */
28262306a36Sopenharmony_ci	iowrite32(0x52, (void __iomem *) CREG_CPU_ARC770_IRQ_MUX);
28362306a36Sopenharmony_ci
28462306a36Sopenharmony_ci	axs10x_early_init();
28562306a36Sopenharmony_ci}
28662306a36Sopenharmony_ci
28762306a36Sopenharmony_ci#endif	/* CONFIG_AXS101 */
28862306a36Sopenharmony_ci
28962306a36Sopenharmony_ci#ifdef CONFIG_AXS103
29062306a36Sopenharmony_ci
29162306a36Sopenharmony_ci#define AXC003_CREG	0xF0001000
29262306a36Sopenharmony_ci#define AXC003_MST_AXI_TUNNEL	0
29362306a36Sopenharmony_ci#define AXC003_MST_HS38		1
29462306a36Sopenharmony_ci
29562306a36Sopenharmony_ci#define CREG_CPU_AXI_M0_IRQ_MUX	(AXC003_CREG + 0x440)
29662306a36Sopenharmony_ci#define CREG_CPU_GPIO_UART_MUX	(AXC003_CREG + 0x480)
29762306a36Sopenharmony_ci#define CREG_CPU_TUN_IO_CTRL	(AXC003_CREG + 0x494)
29862306a36Sopenharmony_ci
29962306a36Sopenharmony_ci
30062306a36Sopenharmony_cistatic void __init axs103_early_init(void)
30162306a36Sopenharmony_ci{
30262306a36Sopenharmony_ci#ifdef CONFIG_ARC_MCIP
30362306a36Sopenharmony_ci	/*
30462306a36Sopenharmony_ci	 * AXS103 configurations for SMP/QUAD configurations share device tree
30562306a36Sopenharmony_ci	 * which defaults to 100 MHz. However recent failures of Quad config
30662306a36Sopenharmony_ci	 * revealed P&R timing violations so clamp it down to safe 50 MHz
30762306a36Sopenharmony_ci	 * Instead of duplicating defconfig/DT for SMP/QUAD, add a small hack
30862306a36Sopenharmony_ci	 * of fudging the freq in DT
30962306a36Sopenharmony_ci	 */
31062306a36Sopenharmony_ci#define AXS103_QUAD_CORE_CPU_FREQ_HZ	50000000
31162306a36Sopenharmony_ci
31262306a36Sopenharmony_ci	unsigned int num_cores = (read_aux_reg(ARC_REG_MCIP_BCR) >> 16) & 0x3F;
31362306a36Sopenharmony_ci	if (num_cores > 2) {
31462306a36Sopenharmony_ci		u32 freq;
31562306a36Sopenharmony_ci		int off = fdt_path_offset(initial_boot_params, "/cpu_card/core_clk");
31662306a36Sopenharmony_ci		const struct fdt_property *prop;
31762306a36Sopenharmony_ci
31862306a36Sopenharmony_ci		prop = fdt_get_property(initial_boot_params, off,
31962306a36Sopenharmony_ci					"assigned-clock-rates", NULL);
32062306a36Sopenharmony_ci		freq = be32_to_cpu(*(u32 *)(prop->data));
32162306a36Sopenharmony_ci
32262306a36Sopenharmony_ci		/* Patching .dtb in-place with new core clock value */
32362306a36Sopenharmony_ci		if (freq != AXS103_QUAD_CORE_CPU_FREQ_HZ) {
32462306a36Sopenharmony_ci			freq = cpu_to_be32(AXS103_QUAD_CORE_CPU_FREQ_HZ);
32562306a36Sopenharmony_ci			fdt_setprop_inplace(initial_boot_params, off,
32662306a36Sopenharmony_ci					    "assigned-clock-rates", &freq, sizeof(freq));
32762306a36Sopenharmony_ci		}
32862306a36Sopenharmony_ci	}
32962306a36Sopenharmony_ci#endif
33062306a36Sopenharmony_ci
33162306a36Sopenharmony_ci	/* Memory maps already config in pre-bootloader */
33262306a36Sopenharmony_ci
33362306a36Sopenharmony_ci	/* set GPIO mux to UART */
33462306a36Sopenharmony_ci	iowrite32(0x01, (void __iomem *) CREG_CPU_GPIO_UART_MUX);
33562306a36Sopenharmony_ci
33662306a36Sopenharmony_ci	iowrite32((0x00100000U | 0x000C0000U | 0x00003322U),
33762306a36Sopenharmony_ci		  (void __iomem *) CREG_CPU_TUN_IO_CTRL);
33862306a36Sopenharmony_ci
33962306a36Sopenharmony_ci	/* Set up the AXS_MB interrupt system.*/
34062306a36Sopenharmony_ci	iowrite32(12, (void __iomem *) (CREG_CPU_AXI_M0_IRQ_MUX
34162306a36Sopenharmony_ci					 + (AXC003_MST_HS38 << 2)));
34262306a36Sopenharmony_ci
34362306a36Sopenharmony_ci	/* connect ICTL - Main Board with GPIO line */
34462306a36Sopenharmony_ci	iowrite32(0x01, (void __iomem *) CREG_MB_IRQ_MUX);
34562306a36Sopenharmony_ci
34662306a36Sopenharmony_ci	axs10x_print_board_ver(AXC003_CREG + 4088, "AXC003 CPU Card");
34762306a36Sopenharmony_ci
34862306a36Sopenharmony_ci	axs10x_early_init();
34962306a36Sopenharmony_ci}
35062306a36Sopenharmony_ci#endif
35162306a36Sopenharmony_ci
35262306a36Sopenharmony_ci#ifdef CONFIG_AXS101
35362306a36Sopenharmony_ci
35462306a36Sopenharmony_cistatic const char *axs101_compat[] __initconst = {
35562306a36Sopenharmony_ci	"snps,axs101",
35662306a36Sopenharmony_ci	NULL,
35762306a36Sopenharmony_ci};
35862306a36Sopenharmony_ci
35962306a36Sopenharmony_ciMACHINE_START(AXS101, "axs101")
36062306a36Sopenharmony_ci	.dt_compat	= axs101_compat,
36162306a36Sopenharmony_ci	.init_early	= axs101_early_init,
36262306a36Sopenharmony_ciMACHINE_END
36362306a36Sopenharmony_ci
36462306a36Sopenharmony_ci#endif	/* CONFIG_AXS101 */
36562306a36Sopenharmony_ci
36662306a36Sopenharmony_ci#ifdef CONFIG_AXS103
36762306a36Sopenharmony_ci
36862306a36Sopenharmony_cistatic const char *axs103_compat[] __initconst = {
36962306a36Sopenharmony_ci	"snps,axs103",
37062306a36Sopenharmony_ci	NULL,
37162306a36Sopenharmony_ci};
37262306a36Sopenharmony_ci
37362306a36Sopenharmony_ciMACHINE_START(AXS103, "axs103")
37462306a36Sopenharmony_ci	.dt_compat	= axs103_compat,
37562306a36Sopenharmony_ci	.init_early	= axs103_early_init,
37662306a36Sopenharmony_ciMACHINE_END
37762306a36Sopenharmony_ci
37862306a36Sopenharmony_ci/*
37962306a36Sopenharmony_ci * For the VDK OS-kit, to get the offset to pid and command fields
38062306a36Sopenharmony_ci */
38162306a36Sopenharmony_cichar coware_swa_pid_offset[TASK_PID];
38262306a36Sopenharmony_cichar coware_swa_comm_offset[TASK_COMM];
38362306a36Sopenharmony_ci
38462306a36Sopenharmony_ci#endif	/* CONFIG_AXS103 */
385