162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * ARC HSDK Platform support code
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Copyright (C) 2017 Synopsys, Inc. (www.synopsys.com)
662306a36Sopenharmony_ci */
762306a36Sopenharmony_ci
862306a36Sopenharmony_ci#include <linux/init.h>
962306a36Sopenharmony_ci#include <linux/of_fdt.h>
1062306a36Sopenharmony_ci#include <linux/libfdt.h>
1162306a36Sopenharmony_ci#include <linux/smp.h>
1262306a36Sopenharmony_ci#include <asm/arcregs.h>
1362306a36Sopenharmony_ci#include <asm/io.h>
1462306a36Sopenharmony_ci#include <asm/mach_desc.h>
1562306a36Sopenharmony_ci
1662306a36Sopenharmony_ciint arc_hsdk_axi_dmac_coherent __section(".data") = 0;
1762306a36Sopenharmony_ci
1862306a36Sopenharmony_ci#define ARC_CCM_UNUSED_ADDR	0x60000000
1962306a36Sopenharmony_ci
2062306a36Sopenharmony_ci
2162306a36Sopenharmony_ci#define ARC_PERIPHERAL_BASE	0xf0000000
2262306a36Sopenharmony_ci#define CREG_BASE		(ARC_PERIPHERAL_BASE + 0x1000)
2362306a36Sopenharmony_ci
2462306a36Sopenharmony_ci#define SDIO_BASE		(ARC_PERIPHERAL_BASE + 0xA000)
2562306a36Sopenharmony_ci#define SDIO_UHS_REG_EXT	(SDIO_BASE + 0x108)
2662306a36Sopenharmony_ci#define SDIO_UHS_REG_EXT_DIV_2	(2 << 30)
2762306a36Sopenharmony_ci
2862306a36Sopenharmony_ci#define HSDK_GPIO_INTC          (ARC_PERIPHERAL_BASE + 0x3000)
2962306a36Sopenharmony_ci
3062306a36Sopenharmony_cistatic void __init hsdk_enable_gpio_intc_wire(void)
3162306a36Sopenharmony_ci{
3262306a36Sopenharmony_ci	/*
3362306a36Sopenharmony_ci	 * Peripherals on CPU Card are wired to cpu intc via intermediate
3462306a36Sopenharmony_ci	 * DW APB GPIO blocks (mainly for debouncing)
3562306a36Sopenharmony_ci	 *
3662306a36Sopenharmony_ci	 *         ---------------------
3762306a36Sopenharmony_ci	 *        |  snps,archs-intc  |
3862306a36Sopenharmony_ci	 *        ---------------------
3962306a36Sopenharmony_ci	 *                  |
4062306a36Sopenharmony_ci	 *        ----------------------
4162306a36Sopenharmony_ci	 *        | snps,archs-idu-intc |
4262306a36Sopenharmony_ci	 *        ----------------------
4362306a36Sopenharmony_ci	 *         |   |     |   |    |
4462306a36Sopenharmony_ci	 *         | [eth] [USB]    [... other peripherals]
4562306a36Sopenharmony_ci	 *         |
4662306a36Sopenharmony_ci	 * -------------------
4762306a36Sopenharmony_ci	 * | snps,dw-apb-intc |
4862306a36Sopenharmony_ci	 * -------------------
4962306a36Sopenharmony_ci	 *  |      |   |   |
5062306a36Sopenharmony_ci	 * [Bt] [HAPS]   [... other peripherals]
5162306a36Sopenharmony_ci	 *
5262306a36Sopenharmony_ci	 * Current implementation of "irq-dw-apb-ictl" driver doesn't work well
5362306a36Sopenharmony_ci	 * with stacked INTCs. In particular problem happens if its master INTC
5462306a36Sopenharmony_ci	 * not yet instantiated. See discussion here -
5562306a36Sopenharmony_ci	 * https://lore.kernel.org/lkml/54F6FE2C.7020309@synopsys.com
5662306a36Sopenharmony_ci	 *
5762306a36Sopenharmony_ci	 * So setup the first gpio block as a passive pass thru and hide it from
5862306a36Sopenharmony_ci	 * DT hardware topology - connect intc directly to cpu intc
5962306a36Sopenharmony_ci	 * The GPIO "wire" needs to be init nevertheless (here)
6062306a36Sopenharmony_ci	 *
6162306a36Sopenharmony_ci	 * One side adv is that peripheral interrupt handling avoids one nested
6262306a36Sopenharmony_ci	 * intc ISR hop
6362306a36Sopenharmony_ci	 *
6462306a36Sopenharmony_ci	 * According to HSDK User's Manual [1], "Table 2 Interrupt Mapping"
6562306a36Sopenharmony_ci	 * we have the following GPIO input lines used as sources of interrupt:
6662306a36Sopenharmony_ci	 * - GPIO[0] - Bluetooth interrupt of RS9113 module
6762306a36Sopenharmony_ci	 * - GPIO[2] - HAPS interrupt (on HapsTrak 3 connector)
6862306a36Sopenharmony_ci	 * - GPIO[3] - Audio codec (MAX9880A) interrupt
6962306a36Sopenharmony_ci	 * - GPIO[8-23] - Available on Arduino and PMOD_x headers
7062306a36Sopenharmony_ci	 * For now there's no use of Arduino and PMOD_x headers in Linux
7162306a36Sopenharmony_ci	 * use-case so we only enable lines 0, 2 and 3.
7262306a36Sopenharmony_ci	 *
7362306a36Sopenharmony_ci	 * [1] https://github.com/foss-for-synopsys-dwc-arc-processors/ARC-Development-Systems-Forum/wiki/docs/ARC_HSDK_User_Guide.pdf
7462306a36Sopenharmony_ci	 */
7562306a36Sopenharmony_ci#define GPIO_INTEN              (HSDK_GPIO_INTC + 0x30)
7662306a36Sopenharmony_ci#define GPIO_INTMASK            (HSDK_GPIO_INTC + 0x34)
7762306a36Sopenharmony_ci#define GPIO_INTTYPE_LEVEL      (HSDK_GPIO_INTC + 0x38)
7862306a36Sopenharmony_ci#define GPIO_INT_POLARITY       (HSDK_GPIO_INTC + 0x3c)
7962306a36Sopenharmony_ci#define GPIO_INT_CONNECTED_MASK	0x0d
8062306a36Sopenharmony_ci
8162306a36Sopenharmony_ci	iowrite32(0xffffffff, (void __iomem *) GPIO_INTMASK);
8262306a36Sopenharmony_ci	iowrite32(~GPIO_INT_CONNECTED_MASK, (void __iomem *) GPIO_INTMASK);
8362306a36Sopenharmony_ci	iowrite32(0x00000000, (void __iomem *) GPIO_INTTYPE_LEVEL);
8462306a36Sopenharmony_ci	iowrite32(0xffffffff, (void __iomem *) GPIO_INT_POLARITY);
8562306a36Sopenharmony_ci	iowrite32(GPIO_INT_CONNECTED_MASK, (void __iomem *) GPIO_INTEN);
8662306a36Sopenharmony_ci}
8762306a36Sopenharmony_ci
8862306a36Sopenharmony_cistatic int __init hsdk_tweak_node_coherency(const char *path, bool coherent)
8962306a36Sopenharmony_ci{
9062306a36Sopenharmony_ci	void *fdt = initial_boot_params;
9162306a36Sopenharmony_ci	const void *prop;
9262306a36Sopenharmony_ci	int node, ret;
9362306a36Sopenharmony_ci	bool dt_coh_set;
9462306a36Sopenharmony_ci
9562306a36Sopenharmony_ci	node = fdt_path_offset(fdt, path);
9662306a36Sopenharmony_ci	if (node < 0)
9762306a36Sopenharmony_ci		goto tweak_fail;
9862306a36Sopenharmony_ci
9962306a36Sopenharmony_ci	prop = fdt_getprop(fdt, node, "dma-coherent", &ret);
10062306a36Sopenharmony_ci	if (!prop && ret != -FDT_ERR_NOTFOUND)
10162306a36Sopenharmony_ci		goto tweak_fail;
10262306a36Sopenharmony_ci
10362306a36Sopenharmony_ci	dt_coh_set = ret != -FDT_ERR_NOTFOUND;
10462306a36Sopenharmony_ci	ret = 0;
10562306a36Sopenharmony_ci
10662306a36Sopenharmony_ci	/* need to remove "dma-coherent" property */
10762306a36Sopenharmony_ci	if (dt_coh_set && !coherent)
10862306a36Sopenharmony_ci		ret = fdt_delprop(fdt, node, "dma-coherent");
10962306a36Sopenharmony_ci
11062306a36Sopenharmony_ci	/* need to set "dma-coherent" property */
11162306a36Sopenharmony_ci	if (!dt_coh_set && coherent)
11262306a36Sopenharmony_ci		ret = fdt_setprop(fdt, node, "dma-coherent", NULL, 0);
11362306a36Sopenharmony_ci
11462306a36Sopenharmony_ci	if (ret < 0)
11562306a36Sopenharmony_ci		goto tweak_fail;
11662306a36Sopenharmony_ci
11762306a36Sopenharmony_ci	return 0;
11862306a36Sopenharmony_ci
11962306a36Sopenharmony_citweak_fail:
12062306a36Sopenharmony_ci	pr_err("failed to tweak %s to %scoherent\n", path, coherent ? "" : "non");
12162306a36Sopenharmony_ci	return -EFAULT;
12262306a36Sopenharmony_ci}
12362306a36Sopenharmony_ci
12462306a36Sopenharmony_cienum hsdk_axi_masters {
12562306a36Sopenharmony_ci	M_HS_CORE = 0,
12662306a36Sopenharmony_ci	M_HS_RTT,
12762306a36Sopenharmony_ci	M_AXI_TUN,
12862306a36Sopenharmony_ci	M_HDMI_VIDEO,
12962306a36Sopenharmony_ci	M_HDMI_AUDIO,
13062306a36Sopenharmony_ci	M_USB_HOST,
13162306a36Sopenharmony_ci	M_ETHERNET,
13262306a36Sopenharmony_ci	M_SDIO,
13362306a36Sopenharmony_ci	M_GPU,
13462306a36Sopenharmony_ci	M_DMAC_0,
13562306a36Sopenharmony_ci	M_DMAC_1,
13662306a36Sopenharmony_ci	M_DVFS
13762306a36Sopenharmony_ci};
13862306a36Sopenharmony_ci
13962306a36Sopenharmony_ci#define UPDATE_VAL	1
14062306a36Sopenharmony_ci
14162306a36Sopenharmony_ci/*
14262306a36Sopenharmony_ci * This is modified configuration of AXI bridge. Default settings
14362306a36Sopenharmony_ci * are specified in "Table 111 CREG Address Decoder register reset values".
14462306a36Sopenharmony_ci *
14562306a36Sopenharmony_ci * AXI_M_m_SLV{0|1} - Slave Select register for master 'm'.
14662306a36Sopenharmony_ci * Possible slaves are:
14762306a36Sopenharmony_ci *  - 0  => no slave selected
14862306a36Sopenharmony_ci *  - 1  => DDR controller port #1
14962306a36Sopenharmony_ci *  - 2  => SRAM controller
15062306a36Sopenharmony_ci *  - 3  => AXI tunnel
15162306a36Sopenharmony_ci *  - 4  => EBI controller
15262306a36Sopenharmony_ci *  - 5  => ROM controller
15362306a36Sopenharmony_ci *  - 6  => AXI2APB bridge
15462306a36Sopenharmony_ci *  - 7  => DDR controller port #2
15562306a36Sopenharmony_ci *  - 8  => DDR controller port #3
15662306a36Sopenharmony_ci *  - 9  => HS38x4 IOC
15762306a36Sopenharmony_ci *  - 10 => HS38x4 DMI
15862306a36Sopenharmony_ci * AXI_M_m_OFFSET{0|1} - Addr Offset register for master 'm'
15962306a36Sopenharmony_ci *
16062306a36Sopenharmony_ci * Please read ARC HS Development IC Specification, section 17.2 for more
16162306a36Sopenharmony_ci * information about apertures configuration.
16262306a36Sopenharmony_ci *
16362306a36Sopenharmony_ci * m	master		AXI_M_m_SLV0	AXI_M_m_SLV1	AXI_M_m_OFFSET0	AXI_M_m_OFFSET1
16462306a36Sopenharmony_ci * 0	HS (CBU)	0x11111111	0x63111111	0xFEDCBA98	0x0E543210
16562306a36Sopenharmony_ci * 1	HS (RTT)	0x77777777	0x77777777	0xFEDCBA98	0x76543210
16662306a36Sopenharmony_ci * 2	AXI Tunnel	0x88888888	0x88888888	0xFEDCBA98	0x76543210
16762306a36Sopenharmony_ci * 3	HDMI-VIDEO	0x77777777	0x77777777	0xFEDCBA98	0x76543210
16862306a36Sopenharmony_ci * 4	HDMI-ADUIO	0x77777777	0x77777777	0xFEDCBA98	0x76543210
16962306a36Sopenharmony_ci * 5	USB-HOST	0x77777777	0x77999999	0xFEDCBA98	0x76DCBA98
17062306a36Sopenharmony_ci * 6	ETHERNET	0x77777777	0x77999999	0xFEDCBA98	0x76DCBA98
17162306a36Sopenharmony_ci * 7	SDIO		0x77777777	0x77999999	0xFEDCBA98	0x76DCBA98
17262306a36Sopenharmony_ci * 8	GPU		0x77777777	0x77777777	0xFEDCBA98	0x76543210
17362306a36Sopenharmony_ci * 9	DMAC (port #1)	0x77777777	0x77777777	0xFEDCBA98	0x76543210
17462306a36Sopenharmony_ci * 10	DMAC (port #2)	0x77777777	0x77777777	0xFEDCBA98	0x76543210
17562306a36Sopenharmony_ci * 11	DVFS		0x00000000	0x60000000	0x00000000	0x00000000
17662306a36Sopenharmony_ci */
17762306a36Sopenharmony_ci
17862306a36Sopenharmony_ci#define CREG_AXI_M_SLV0(m)  ((void __iomem *)(CREG_BASE + 0x20 * (m)))
17962306a36Sopenharmony_ci#define CREG_AXI_M_SLV1(m)  ((void __iomem *)(CREG_BASE + 0x20 * (m) + 0x04))
18062306a36Sopenharmony_ci#define CREG_AXI_M_OFT0(m)  ((void __iomem *)(CREG_BASE + 0x20 * (m) + 0x08))
18162306a36Sopenharmony_ci#define CREG_AXI_M_OFT1(m)  ((void __iomem *)(CREG_BASE + 0x20 * (m) + 0x0C))
18262306a36Sopenharmony_ci#define CREG_AXI_M_UPDT(m)  ((void __iomem *)(CREG_BASE + 0x20 * (m) + 0x14))
18362306a36Sopenharmony_ci
18462306a36Sopenharmony_ci#define CREG_AXI_M_HS_CORE_BOOT	((void __iomem *)(CREG_BASE + 0x010))
18562306a36Sopenharmony_ci
18662306a36Sopenharmony_ci#define CREG_PAE		((void __iomem *)(CREG_BASE + 0x180))
18762306a36Sopenharmony_ci#define CREG_PAE_UPDT		((void __iomem *)(CREG_BASE + 0x194))
18862306a36Sopenharmony_ci
18962306a36Sopenharmony_cistatic void __init hsdk_init_memory_bridge_axi_dmac(void)
19062306a36Sopenharmony_ci{
19162306a36Sopenharmony_ci	bool coherent = !!arc_hsdk_axi_dmac_coherent;
19262306a36Sopenharmony_ci	u32 axi_m_slv1, axi_m_oft1;
19362306a36Sopenharmony_ci
19462306a36Sopenharmony_ci	/*
19562306a36Sopenharmony_ci	 * Don't tweak memory bridge configuration if we failed to tweak DTB
19662306a36Sopenharmony_ci	 * as we will end up in a inconsistent state.
19762306a36Sopenharmony_ci	 */
19862306a36Sopenharmony_ci	if (hsdk_tweak_node_coherency("/soc/dmac@80000", coherent))
19962306a36Sopenharmony_ci		return;
20062306a36Sopenharmony_ci
20162306a36Sopenharmony_ci	if (coherent) {
20262306a36Sopenharmony_ci		axi_m_slv1 = 0x77999999;
20362306a36Sopenharmony_ci		axi_m_oft1 = 0x76DCBA98;
20462306a36Sopenharmony_ci	} else {
20562306a36Sopenharmony_ci		axi_m_slv1 = 0x77777777;
20662306a36Sopenharmony_ci		axi_m_oft1 = 0x76543210;
20762306a36Sopenharmony_ci	}
20862306a36Sopenharmony_ci
20962306a36Sopenharmony_ci	writel(0x77777777, CREG_AXI_M_SLV0(M_DMAC_0));
21062306a36Sopenharmony_ci	writel(0xFEDCBA98, CREG_AXI_M_OFT0(M_DMAC_0));
21162306a36Sopenharmony_ci	writel(axi_m_slv1, CREG_AXI_M_SLV1(M_DMAC_0));
21262306a36Sopenharmony_ci	writel(axi_m_oft1, CREG_AXI_M_OFT1(M_DMAC_0));
21362306a36Sopenharmony_ci	writel(UPDATE_VAL, CREG_AXI_M_UPDT(M_DMAC_0));
21462306a36Sopenharmony_ci
21562306a36Sopenharmony_ci	writel(0x77777777, CREG_AXI_M_SLV0(M_DMAC_1));
21662306a36Sopenharmony_ci	writel(0xFEDCBA98, CREG_AXI_M_OFT0(M_DMAC_1));
21762306a36Sopenharmony_ci	writel(axi_m_slv1, CREG_AXI_M_SLV1(M_DMAC_1));
21862306a36Sopenharmony_ci	writel(axi_m_oft1, CREG_AXI_M_OFT1(M_DMAC_1));
21962306a36Sopenharmony_ci	writel(UPDATE_VAL, CREG_AXI_M_UPDT(M_DMAC_1));
22062306a36Sopenharmony_ci}
22162306a36Sopenharmony_ci
22262306a36Sopenharmony_cistatic void __init hsdk_init_memory_bridge(void)
22362306a36Sopenharmony_ci{
22462306a36Sopenharmony_ci	u32 reg;
22562306a36Sopenharmony_ci
22662306a36Sopenharmony_ci	/*
22762306a36Sopenharmony_ci	 * M_HS_CORE has one unique register - BOOT.
22862306a36Sopenharmony_ci	 * We need to clean boot mirror (BOOT[1:0]) bits in them to avoid first
22962306a36Sopenharmony_ci	 * aperture to be masked by 'boot mirror'.
23062306a36Sopenharmony_ci	 */
23162306a36Sopenharmony_ci	reg = readl(CREG_AXI_M_HS_CORE_BOOT) & (~0x3);
23262306a36Sopenharmony_ci	writel(reg, CREG_AXI_M_HS_CORE_BOOT);
23362306a36Sopenharmony_ci	writel(0x11111111, CREG_AXI_M_SLV0(M_HS_CORE));
23462306a36Sopenharmony_ci	writel(0x63111111, CREG_AXI_M_SLV1(M_HS_CORE));
23562306a36Sopenharmony_ci	writel(0xFEDCBA98, CREG_AXI_M_OFT0(M_HS_CORE));
23662306a36Sopenharmony_ci	writel(0x0E543210, CREG_AXI_M_OFT1(M_HS_CORE));
23762306a36Sopenharmony_ci	writel(UPDATE_VAL, CREG_AXI_M_UPDT(M_HS_CORE));
23862306a36Sopenharmony_ci
23962306a36Sopenharmony_ci	writel(0x77777777, CREG_AXI_M_SLV0(M_HS_RTT));
24062306a36Sopenharmony_ci	writel(0x77777777, CREG_AXI_M_SLV1(M_HS_RTT));
24162306a36Sopenharmony_ci	writel(0xFEDCBA98, CREG_AXI_M_OFT0(M_HS_RTT));
24262306a36Sopenharmony_ci	writel(0x76543210, CREG_AXI_M_OFT1(M_HS_RTT));
24362306a36Sopenharmony_ci	writel(UPDATE_VAL, CREG_AXI_M_UPDT(M_HS_RTT));
24462306a36Sopenharmony_ci
24562306a36Sopenharmony_ci	writel(0x88888888, CREG_AXI_M_SLV0(M_AXI_TUN));
24662306a36Sopenharmony_ci	writel(0x88888888, CREG_AXI_M_SLV1(M_AXI_TUN));
24762306a36Sopenharmony_ci	writel(0xFEDCBA98, CREG_AXI_M_OFT0(M_AXI_TUN));
24862306a36Sopenharmony_ci	writel(0x76543210, CREG_AXI_M_OFT1(M_AXI_TUN));
24962306a36Sopenharmony_ci	writel(UPDATE_VAL, CREG_AXI_M_UPDT(M_AXI_TUN));
25062306a36Sopenharmony_ci
25162306a36Sopenharmony_ci	writel(0x77777777, CREG_AXI_M_SLV0(M_HDMI_VIDEO));
25262306a36Sopenharmony_ci	writel(0x77777777, CREG_AXI_M_SLV1(M_HDMI_VIDEO));
25362306a36Sopenharmony_ci	writel(0xFEDCBA98, CREG_AXI_M_OFT0(M_HDMI_VIDEO));
25462306a36Sopenharmony_ci	writel(0x76543210, CREG_AXI_M_OFT1(M_HDMI_VIDEO));
25562306a36Sopenharmony_ci	writel(UPDATE_VAL, CREG_AXI_M_UPDT(M_HDMI_VIDEO));
25662306a36Sopenharmony_ci
25762306a36Sopenharmony_ci	writel(0x77777777, CREG_AXI_M_SLV0(M_HDMI_AUDIO));
25862306a36Sopenharmony_ci	writel(0x77777777, CREG_AXI_M_SLV1(M_HDMI_AUDIO));
25962306a36Sopenharmony_ci	writel(0xFEDCBA98, CREG_AXI_M_OFT0(M_HDMI_AUDIO));
26062306a36Sopenharmony_ci	writel(0x76543210, CREG_AXI_M_OFT1(M_HDMI_AUDIO));
26162306a36Sopenharmony_ci	writel(UPDATE_VAL, CREG_AXI_M_UPDT(M_HDMI_AUDIO));
26262306a36Sopenharmony_ci
26362306a36Sopenharmony_ci	writel(0x77777777, CREG_AXI_M_SLV0(M_USB_HOST));
26462306a36Sopenharmony_ci	writel(0x77999999, CREG_AXI_M_SLV1(M_USB_HOST));
26562306a36Sopenharmony_ci	writel(0xFEDCBA98, CREG_AXI_M_OFT0(M_USB_HOST));
26662306a36Sopenharmony_ci	writel(0x76DCBA98, CREG_AXI_M_OFT1(M_USB_HOST));
26762306a36Sopenharmony_ci	writel(UPDATE_VAL, CREG_AXI_M_UPDT(M_USB_HOST));
26862306a36Sopenharmony_ci
26962306a36Sopenharmony_ci	writel(0x77777777, CREG_AXI_M_SLV0(M_ETHERNET));
27062306a36Sopenharmony_ci	writel(0x77999999, CREG_AXI_M_SLV1(M_ETHERNET));
27162306a36Sopenharmony_ci	writel(0xFEDCBA98, CREG_AXI_M_OFT0(M_ETHERNET));
27262306a36Sopenharmony_ci	writel(0x76DCBA98, CREG_AXI_M_OFT1(M_ETHERNET));
27362306a36Sopenharmony_ci	writel(UPDATE_VAL, CREG_AXI_M_UPDT(M_ETHERNET));
27462306a36Sopenharmony_ci
27562306a36Sopenharmony_ci	writel(0x77777777, CREG_AXI_M_SLV0(M_SDIO));
27662306a36Sopenharmony_ci	writel(0x77999999, CREG_AXI_M_SLV1(M_SDIO));
27762306a36Sopenharmony_ci	writel(0xFEDCBA98, CREG_AXI_M_OFT0(M_SDIO));
27862306a36Sopenharmony_ci	writel(0x76DCBA98, CREG_AXI_M_OFT1(M_SDIO));
27962306a36Sopenharmony_ci	writel(UPDATE_VAL, CREG_AXI_M_UPDT(M_SDIO));
28062306a36Sopenharmony_ci
28162306a36Sopenharmony_ci	writel(0x77777777, CREG_AXI_M_SLV0(M_GPU));
28262306a36Sopenharmony_ci	writel(0x77777777, CREG_AXI_M_SLV1(M_GPU));
28362306a36Sopenharmony_ci	writel(0xFEDCBA98, CREG_AXI_M_OFT0(M_GPU));
28462306a36Sopenharmony_ci	writel(0x76543210, CREG_AXI_M_OFT1(M_GPU));
28562306a36Sopenharmony_ci	writel(UPDATE_VAL, CREG_AXI_M_UPDT(M_GPU));
28662306a36Sopenharmony_ci
28762306a36Sopenharmony_ci	writel(0x00000000, CREG_AXI_M_SLV0(M_DVFS));
28862306a36Sopenharmony_ci	writel(0x60000000, CREG_AXI_M_SLV1(M_DVFS));
28962306a36Sopenharmony_ci	writel(0x00000000, CREG_AXI_M_OFT0(M_DVFS));
29062306a36Sopenharmony_ci	writel(0x00000000, CREG_AXI_M_OFT1(M_DVFS));
29162306a36Sopenharmony_ci	writel(UPDATE_VAL, CREG_AXI_M_UPDT(M_DVFS));
29262306a36Sopenharmony_ci
29362306a36Sopenharmony_ci	hsdk_init_memory_bridge_axi_dmac();
29462306a36Sopenharmony_ci
29562306a36Sopenharmony_ci	/*
29662306a36Sopenharmony_ci	 * PAE remapping for DMA clients does not work due to an RTL bug, so
29762306a36Sopenharmony_ci	 * CREG_PAE register must be programmed to all zeroes, otherwise it
29862306a36Sopenharmony_ci	 * will cause problems with DMA to/from peripherals even if PAE40 is
29962306a36Sopenharmony_ci	 * not used.
30062306a36Sopenharmony_ci	 */
30162306a36Sopenharmony_ci	writel(0x00000000, CREG_PAE);
30262306a36Sopenharmony_ci	writel(UPDATE_VAL, CREG_PAE_UPDT);
30362306a36Sopenharmony_ci}
30462306a36Sopenharmony_ci
30562306a36Sopenharmony_cistatic void __init hsdk_init_early(void)
30662306a36Sopenharmony_ci{
30762306a36Sopenharmony_ci	hsdk_init_memory_bridge();
30862306a36Sopenharmony_ci
30962306a36Sopenharmony_ci	/*
31062306a36Sopenharmony_ci	 * Switch SDIO external ciu clock divider from default div-by-8 to
31162306a36Sopenharmony_ci	 * minimum possible div-by-2.
31262306a36Sopenharmony_ci	 */
31362306a36Sopenharmony_ci	iowrite32(SDIO_UHS_REG_EXT_DIV_2, (void __iomem *) SDIO_UHS_REG_EXT);
31462306a36Sopenharmony_ci
31562306a36Sopenharmony_ci	hsdk_enable_gpio_intc_wire();
31662306a36Sopenharmony_ci}
31762306a36Sopenharmony_ci
31862306a36Sopenharmony_cistatic const char *hsdk_compat[] __initconst = {
31962306a36Sopenharmony_ci	"snps,hsdk",
32062306a36Sopenharmony_ci	NULL,
32162306a36Sopenharmony_ci};
32262306a36Sopenharmony_ci
32362306a36Sopenharmony_ciMACHINE_START(SIMULATION, "hsdk")
32462306a36Sopenharmony_ci	.dt_compat	= hsdk_compat,
32562306a36Sopenharmony_ci	.init_early     = hsdk_init_early,
32662306a36Sopenharmony_ciMACHINE_END
327