code:
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __ASM_MACH_PXA910_H
#define __ASM_MACH_PXA910_H

extern void pxa910_timer_init(void);
extern void __init pxa910_init_irq(void);

#include <linux/i2c.h>
#include <linux/platform_data/i2c-pxa.h>
#include <linux/platform_data/mtd-nand-pxa3xx.h>
#include <video/mmp_disp.h>
#include <linux/irqchip/mmp.h>

#include "devices.h"

extern struct mmp_device_desc pxa910_device_uart1;
extern struct mmp_device_desc pxa910_device_uart2;
extern struct mmp_device_desc pxa910_device_twsi0;
extern struct mmp_device_desc pxa910_device_twsi1;
extern struct mmp_device_desc pxa910_device_pwm1;
extern struct mmp_device_desc pxa910_device_pwm2;
extern struct mmp_device_desc pxa910_device_pwm3;
extern struct mmp_device_desc pxa910_device_pwm4;
extern struct mmp_device_desc pxa910_device_nand;
extern struct platform_device pxa168_device_usb_phy;
extern struct platform_device pxa168_device_u2o;
extern struct platform_device pxa168_device_u2ootg;
extern struct platform_device pxa168_device_u2oehci;
extern struct mmp_device_desc pxa910_device_disp;
extern struct mmp_device_desc pxa910_device_fb;
extern struct mmp_device_desc pxa910_device_panel;
extern struct platform_device pxa910_device_gpio;
extern struct platform_device pxa910_device_rtc;

static inline int pxa910_add_uart(int id)
{
	struct mmp_device_desc *d = NULL;

	switch (id) {
	case 1: d = &pxa910_device_uart1; break;
	case 2: d = &pxa910_device_uart2; break;
	}

	if (d == NULL)
		return -EINVAL;

	return mmp_register_device(d, NULL, 0);
}

static inline int pxa910_add_twsi(int id, struct i2c_pxa_platform_data *data,
				  struct i2c_board_info *info, unsigned size)
{
	struct mmp_device_desc *d = NULL;
	int ret;

	switch (id) {
	case 0: d = &pxa910_device_twsi0; break;
	case 1: d = &pxa910_device_twsi1; break;
	default:
		return -EINVAL;
	}

	ret = i2c_register_board_info(id, info, size);
	if (ret)
		return ret;

	return mmp_register_device(d, data, sizeof(*data));
}

static inline int pxa910_add_pwm(int id)
{
	struct mmp_device_desc *d = NULL;

	switch (id) {
	case 1: d = &pxa910_device_pwm1; break;
	case 2: d = &pxa910_device_pwm2; break;
	case 3: d = &pxa910_device_pwm3; break;
	case 4: d = &pxa910_device_pwm4; break;
	default:
		return -EINVAL;
	}

	return mmp_register_device(d, NULL, 0);
}

static inline int pxa910_add_nand(struct pxa3xx_nand_platform_data *info)
{
	return mmp_register_device(&pxa910_device_nand, info, sizeof(*info));
}
#endif /* __ASM_MACH_PXA910_H */


code:
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 *   Application Peripheral Bus Clock Unit
 */

#ifndef __ASM_MACH_REGS_APBC_H
#define __ASM_MACH_REGS_APBC_H

#include "addr-map.h"

/* Common APB clock register bit definitions */
#define APBC_APBCLK	(1 << 0)  /* APB Bus Clock Enable */
#define APBC_FNCLK	(1 << 1)  /* Functional Clock Enable */
#define APBC_RST	(1 << 2)  /* Reset Generation */

/* Functional Clock Selection Mask */
#define APBC_FNCLKSEL(x)	(((x) & 0xf) << 4)

#endif /* __ASM_MACH_REGS_APBC_H */

repo_name: angery/linux


code:
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 *   Application Subsystem Power Management Unit
 */

#ifndef __ASM_MACH_REGS_APMU_H
#define __ASM_MACH_REGS_APMU_H

#include "addr-map.h"

#define APMU_FNCLK_EN	(1 << 4)
#define APMU_AXICLK_EN	(1 << 3)
#define APMU_FNRST_DIS	(1 << 1)
#define APMU_AXIRST_DIS	(1 << 0)

/* Wake Clear Register */
#define APMU_WAKE_CLR	APMU_REG(0x07c)

#define APMU_PXA168_KP_WAKE_CLR		(1 << 7)
#define APMU_PXA168_CFI_WAKE_CLR	(1 << 6)
#define APMU_PXA168_XD_WAKE_CLR		(1 << 5)
#define APMU_PXA168_MSP_WAKE_CLR	(1 << 4)
#define APMU_PXA168_SD4_WAKE_CLR	(1 << 3)
#define APMU_PXA168_SD3_WAKE_CLR	(1 << 2)
#define APMU_PXA168_SD2_WAKE_CLR	(1 << 1)
#define APMU_PXA168_SD1_WAKE_CLR	(1 << 0)

#endif /* __ASM_MACH_REGS_APMU_H */


code:
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 *   Interrupt Control Unit
 */

#ifndef __ASM_MACH_ICU_H
#define __ASM_MACH_ICU_H

#include "addr-map.h"

#define ICU_VIRT_BASE	(AXI_VIRT_BASE + 0x82000)
#define ICU_REG(x)	(ICU_VIRT_BASE + (x))

#define ICU2_VIRT_BASE	(AXI_VIRT_BASE + 0x84000)
#define ICU2_REG(x)	(ICU2_VIRT_BASE + (x))

#define ICU_INT_CONF(n)		ICU_REG((n) << 2)
#define ICU_INT_CONF_MASK	(0xf)

/************ PXA168/PXA910 (MMP) *********************/
#define ICU_INT_CONF_AP_INT	(1 << 6)
#define ICU_INT_CONF_CP_INT	(1 << 5)
#define ICU_INT_CONF_IRQ	(1 << 4)

#define ICU_AP_FIQ_SEL_INT_NUM	ICU_REG(0x108)	/* AP FIQ Selected Interrupt */
#define ICU_AP_IRQ_SEL_INT_NUM	ICU_REG(0x10C)	/* AP IRQ Selected Interrupt */
#define ICU_AP_GBL_IRQ_MSK	ICU_REG(0x114)	/* AP Global Interrupt Mask */
#define ICU_INT_STATUS_0	ICU_REG(0x128)	/* Interrupt Stuats 0 */
#define ICU_INT_STATUS_1	ICU_REG(0x12C)	/* Interrupt Status 1 */

/************************** MMP2 ***********************/

/*
 * IRQ0/FIQ0 is routed to SP IRQ/FIQ.
 * IRQ1 is routed to PJ4 IRQ, and IRQ2 is routes to PJ4 FIQ.
 */
#define ICU_INT_ROUTE_SP_IRQ		(1 << 4)
#define ICU_INT_ROUTE_PJ4_IRQ		(1 << 5)
#define ICU_INT_ROUTE_PJ4_FIQ		(1 << 6)

#define MMP2_ICU_PJ4_IRQ_STATUS0	ICU_REG(0x138)
#define MMP2_ICU_PJ4_IRQ_STATUS1	ICU_REG(0x13c)
#define MMP2_ICU_PJ4_FIQ_STATUS0	ICU_REG(0x140)
#define MMP2_ICU_PJ4_FIQ_STATUS1	ICU_REG(0x144)

#define MMP2_ICU_INT4_STATUS		ICU_REG(0x150)
#define MMP2_ICU_INT5_STATUS		ICU_REG(0x154)
#define MMP2_ICU_INT17_STATUS		ICU_REG(0x158)
#define MMP2_ICU_INT35_STATUS		ICU_REG(0x15c)
#define MMP2_ICU_INT51_STATUS		ICU_REG(0x160)

#define MMP2_ICU_INT4_MASK		ICU_REG(0x168)
#define MMP2_ICU_INT5_MASK		ICU_REG(0x16C)
#define MMP2_ICU_INT17_MASK		ICU_REG(0x170)
#define MMP2_ICU_INT35_MASK		ICU_REG(0x174)
#define MMP2_ICU_INT51_MASK		ICU_REG(0x178)

#define MMP2_ICU_SP_IRQ_SEL		ICU_REG(0x100)
#define MMP2_ICU_PJ4_IRQ_SEL		ICU_REG(0x104)
#define MMP2_ICU_PJ4_FIQ_SEL		ICU_REG(0x108)

#define MMP2_ICU_INVERT			ICU_REG(0x164)

#define MMP2_ICU_INV_PMIC		(1 << 0)
#define MMP2_ICU_INV_PERF		(1 << 1)
#define MMP2_ICU_INV_COMMTX		(1 << 2)
#define MMP2_ICU_INV_COMMRX		(1 << 3)

#endif /* __ASM_MACH_ICU_H */


code:
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 *   Timers Module
 */

#ifndef __ASM_MACH_REGS_TIMERS_H
#define __ASM_MACH_REGS_TIMERS_H

#include "addr-map.h"

#define TIMERS1_VIRT_BASE	(APB_VIRT_BASE + 0x14000)
#define TIMERS2_VIRT_BASE	(APB_VIRT_BASE + 0x16000)

#define TMR_CCR		(0x0000)
#define TMR_TN_MM(n, m)	(0x0004 + ((n) << 3) + (((n) + (m)) << 2))
#define TMR_CR(n)	(0x0028 + ((n) << 2))
#define TMR_SR(n)	(0x0034 + ((n) << 2))
#define TMR_IER(n)	(0x0040 + ((n) << 2))
#define TMR_PLVR(n)	(0x004c + ((n) << 2))
#define TMR_PLCR(n)	(0x0058 + ((n) << 2))
#define TMR_WMER	(0x0064)
#define TMR_WMR		(0x0068)
#define TMR_WVR		(0x006c)
#define TMR_WSR		(0x0070)
#define TMR_ICR(n)	(0x0074 + ((n) << 2))
#define TMR_WICR	(0x0080)
#define TMR_CER		(0x0084)
#define TMR_CMR		(0x0088)
#define TMR_ILR(n)	(0x008c + ((n) << 2))
#define TMR_WCR		(0x0098)
#define TMR_WFAR	(0x009c)
#define TMR_WSAR	(0x00A0)
#define TMR_CVWR(n)	(0x00A4 + ((n) << 2))

#define TMR_CCR_CS_0(x)	(((x) & 0x3) << 0)
#define TMR_CCR_CS_1(x)	(((x) & 0x7) << 2)
#define TMR_CCR_CS_2(x)	(((x) & 0x3) << 5)

#endif /* __ASM_MACH_REGS_TIMERS_H */


code:
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
 * Copyright (C) 2011 Marvell International Ltd. All rights reserved.
 */

#ifndef __ASM_ARCH_REGS_USB_H
#define __ASM_ARCH_REGS_USB_H

#define PXA168_U2O_REGBASE	(0xd4208000)
#define PXA168_U2O_PHYBASE	(0xd4207000)

#define PXA168_U2H_REGBASE      (0xd4209000)
#define PXA168_U2H_PHYBASE      (0xd4206000)

#define MMP3_HSIC1_REGBASE	(0xf0001000)
#define MMP3_HSIC1_PHYBASE	(0xf0001800)

#define MMP3_HSIC2_REGBASE	(0xf0002000)
#define MMP3_HSIC2_PHYBASE	(0xf0002800)

#define MMP3_FSIC_REGBASE	(0xf0003000)
#define MMP3_FSIC_PHYBASE	(0xf0003800)

#define USB_REG_RANGE		(0x1ff)
#define USB_PHY_RANGE		(0xff)

/* registers */
#define U2x_CAPREGS_OFFSET       0x100

/* phy regs */
#define UTMI_REVISION		0x0
#define UTMI_CTRL		0x4
#define UTMI_PLL		0x8
#define UTMI_TX			0xc
#define UTMI_RX			0x10
#define UTMI_IVREF		0x14
#define UTMI_T0			0x18
#define UTMI_T1			0x1c
#define UTMI_T2			0x20
#define UTMI_T3			0x24
#define UTMI_T4			0x28
#define UTMI_T5			0x2c
#define UTMI_RESERVE		0x30
#define UTMI_USB_INT		0x34
#define UTMI_DBG_CTL		0x38
#define UTMI_OTG_ADDON		0x3c

/* For UTMICTRL Register */
#define UTMI_CTRL_USB_CLK_EN                    (1 << 31)
/* pxa168 */
#define UTMI_CTRL_SUSPEND_SET1                  (1 << 30)
#define UTMI_CTRL_SUSPEND_SET2                  (1 << 29)
#define UTMI_CTRL_RXBUF_PDWN                    (1 << 24)
#define UTMI_CTRL_TXBUF_PDWN                    (1 << 11)

#define UTMI_CTRL_INPKT_DELAY_SHIFT             30
#define UTMI_CTRL_INPKT_DELAY_SOF_SHIFT		28
#define UTMI_CTRL_PU_REF_SHIFT			20
#define UTMI_CTRL_ARC_PULLDN_SHIFT              12
#define UTMI_CTRL_PLL_PWR_UP_SHIFT              1
#define UTMI_CTRL_PWR_UP_SHIFT                  0

/* For UTMI_PLL Register */
#define UTMI_PLL_PLLCALI12_SHIFT		29
#define UTMI_PLL_PLLCALI12_MASK			(0x3 << 29)

#define UTMI_PLL_PLLVDD18_SHIFT			27
#define UTMI_PLL_PLLVDD18_MASK			(0x3 << 27)

#define UTMI_PLL_PLLVDD12_SHIFT			25
#define UTMI_PLL_PLLVDD12_MASK			(0x3 << 25)

#define UTMI_PLL_CLK_BLK_EN_SHIFT               24
#define CLK_BLK_EN                              (0x1 << 24)
#define PLL_READY                               (0x1 << 23)
#define KVCO_EXT                                (0x1 << 22)
#define VCOCAL_START                            (0x1 << 21)

#define UTMI_PLL_KVCO_SHIFT			15
#define UTMI_PLL_KVCO_MASK                      (0x7 << 15)

#define UTMI_PLL_ICP_SHIFT			12
#define UTMI_PLL_ICP_MASK                       (0x7 << 12)

#define UTMI_PLL_FBDIV_SHIFT                    4
#define UTMI_PLL_FBDIV_MASK                     (0xFF << 4)

#define UTMI_PLL_REFDIV_SHIFT                   0
#define UTMI_PLL_REFDIV_MASK                    (0xF << 0)

/* For UTMI_TX Register */
#define UTMI_TX_REG_EXT_FS_RCAL_SHIFT		27
#define UTMI_TX_REG_EXT_FS_RCAL_MASK		(0xf << 27)

#define UTMI_TX_REG_EXT_FS_RCAL_EN_SHIFT	26
#define UTMI_TX_REG_EXT_FS_RCAL_EN_MASK		(0x1 << 26)

#define UTMI_TX_TXVDD12_SHIFT                   22
#define UTMI_TX_TXVDD12_MASK                    (0x3 << 22)

#define UTMI_TX_CK60_PHSEL_SHIFT                17
#define UTMI_TX_CK60_PHSEL_MASK                 (0xf << 17)

#define UTMI_TX_IMPCAL_VTH_SHIFT                14
#define UTMI_TX_IMPCAL_VTH_MASK                 (0x7 << 14)

#define REG_RCAL_START                          (0x1 << 12)

#define UTMI_TX_LOW_VDD_EN_SHIFT                11

#define UTMI_TX_AMP_SHIFT			0
#define UTMI_TX_AMP_MASK			(0x7 << 0)

/* For UTMI_RX Register */
#define UTMI_REG_SQ_LENGTH_SHIFT                15
#define UTMI_REG_SQ_LENGTH_MASK                 (0x3 << 15)

#define UTMI_RX_SQ_THRESH_SHIFT                 4
#define UTMI_RX_SQ_THRESH_MASK                  (0xf << 4)

#define UTMI_OTG_ADDON_OTG_ON			(1 << 0)

/* fsic registers */
#define FSIC_MISC			0x4
#define FSIC_INT			0x28
#define FSIC_CTRL			0x30

/* HSIC registers */
#define HSIC_PAD_CTRL			0x4

#define HSIC_CTRL			0x8
#define HSIC_CTRL_HSIC_ENABLE		(1<<7)
#define HSIC_CTRL_PLL_BYPASS		(1<<4)

#define TEST_GRP_0			0xc
#define TEST_GRP_1			0x10

#define HSIC_INT			0x14
#define HSIC_INT_READY_INT_EN		(1<<10)
#define HSIC_INT_CONNECT_INT_EN		(1<<9)
#define HSIC_INT_CORE_INT_EN		(1<<8)
#define HSIC_INT_HS_READY		(1<<2)
#define HSIC_INT_CONNECT		(1<<1)
#define HSIC_INT_CORE			(1<<0)

#define HSIC_CONFIG			0x18
#define USBHSIC_CTRL			0x20

#define HSIC_USB_CTRL			0x28
#define HSIC_USB_CTRL_CLKEN		1
#define	HSIC_USB_CLK_PHY		0x0
#define HSIC_USB_CLK_PMU		0x1

#endif /* __ASM_ARCH_PXA_U2O_H */


code:
// SPDX-License-Identifier: GPL-2.0-only
/*
 *  linux/arch/arm/mach-mmp/sram.c
 *
 *  based on mach-davinci/sram.c - DaVinci simple SRAM allocator
 *
 *  Copyright (c) 2011 Marvell Semiconductors Inc.
 *  All Rights Reserved
 *
 *  Add for mmp sram support - Leo Yan <leoy@marvell.com>
 */

#include <linux/module.h>
#include <linux/mod_devicetable.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/err.h>
#include <linux/slab.h>
#include <linux/genalloc.h>

#include <linux/platform_data/dma-mmp_tdma.h>

struct sram_bank_info {
	char *pool_name;
	struct gen_pool *gpool;
	int granularity;

	phys_addr_t sram_phys;
	void __iomem *sram_virt;
	u32 sram_size;

	struct list_head node;
};

static DEFINE_MUTEX(sram_lock);
static LIST_HEAD(sram_bank_list);

struct gen_pool *sram_get_gpool(char *pool_name)
{
	struct sram_bank_info *info = NULL;

	if (!pool_name)
		return NULL;

	mutex_lock(&sram_lock);

	list_for_each_entry(info, &sram_bank_list, node)
		if (!strcmp(pool_name, info->pool_name))
			break;

	mutex_unlock(&sram_lock);

	if (&info->node == &sram_bank_list)
		return NULL;

	return info->gpool;
}
EXPORT_SYMBOL(sram_get_gpool);

static int sram_probe(struct platform_device *pdev)
{
	struct sram_platdata *pdata = pdev->dev.platform_data;
	struct sram_bank_info *info;
	struct resource *res;
	int ret = 0;

	if (!pdata || !pdata->pool_name)
		return -ENODEV;

	info = kzalloc(sizeof(*info), GFP_KERNEL);
	if (!info)
		return -ENOMEM;

	platform_set_drvdata(pdev, info);

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (res == NULL) {
		dev_err(&pdev->dev, "no memory resource defined\n");
		ret = -ENODEV;
		goto out;
	}

	if (!resource_size(res))
		return 0;

	info->sram_phys   = (phys_addr_t)res->start;
	info->sram_size   = resource_size(res);
	info->sram_virt   = ioremap(info->sram_phys, info->sram_size);
	info->pool_name	  = kstrdup(pdata->pool_name, GFP_KERNEL);
	info->granularity = pdata->granularity;

	info->gpool = gen_pool_create(ilog2(info->granularity), -1);
	if (!info->gpool) {
		dev_err(&pdev->dev, "create pool failed\n");
		ret = -ENOMEM;
		goto create_pool_err;
	}

	ret = gen_pool_add_virt(info->gpool, (unsigned long)info->sram_virt,
				info->sram_phys, info->sram_size, -1);
	if (ret < 0) {
		dev_err(&pdev->dev, "add new chunk failed\n");
		ret = -ENOMEM;
		goto add_chunk_err;
	}

	mutex_lock(&sram_lock);
	list_add(&info->node, &sram_bank_list);
	mutex_unlock(&sram_lock);

	dev_info(&pdev->dev, "initialized\n");
	return 0;

add_chunk_err:
	gen_pool_destroy(info->gpool);
create_pool_err:
	iounmap(info->sram_virt);
	kfree(info->pool_name);
out:
	kfree(info);
	return ret;
}

static int sram_remove(struct platform_device *pdev)
{
	struct sram_bank_info *info;

	info = platform_get_drvdata(pdev);

	if (info->sram_size) {
		mutex_lock(&sram_lock);
		list_del(&info->node);
		mutex_unlock(&sram_lock);

		gen_pool_destroy(info->gpool);
		iounmap(info->sram_virt);
		kfree(info->pool_name);
	}

	kfree(info);

	return 0;
}

static const struct platform_device_id sram_id_table[] = {
	{ "asram", MMP_ASRAM },
	{ "isram", MMP_ISRAM },
	{ }
};

static struct platform_driver sram_driver = {
	.probe		= sram_probe,
	.remove		= sram_remove,
	.driver		= {
		.name	= "mmp-sram",
	},
	.id_table	= sram_id_table,
};

static int __init sram_init(void)
{
	return platform_driver_register(&sram_driver);
}
core_initcall(sram_init);

MODULE_LICENSE("GPL");


code:
// SPDX-License-Identifier: GPL-2.0-only
/*
 *  linux/arch/arm/mach-mmp/teton_bga.c
 *
 *  Support for the Marvell PXA168 Teton BGA Development Platform.
 *
 *  Author: Mark F. Brown <mark.brown314@gmail.com>
 *
 *  This code is based on aspenite.c
 */

#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <linux/gpio.h>
#include <linux/gpio-pxa.h>
#include <linux/input.h>
#include <linux/platform_data/keypad-pxa27x.h>
#include <linux/i2c.h>

#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include "addr-map.h"
#include "mfp-pxa168.h"
#include "pxa168.h"
#include "teton_bga.h"
#include "irqs.h"

#include "common.h"

static unsigned long teton_bga_pin_config[] __initdata = {
	/* UART1 */
	GPIO107_UART1_TXD,
	GPIO108_UART1_RXD,

	/* Keypad */
	GPIO109_KP_MKIN1,
	GPIO110_KP_MKIN0,
	GPIO111_KP_MKOUT7,
	GPIO112_KP_MKOUT6,

	/* I2C Bus */
	GPIO105_CI2C_SDA,
	GPIO106_CI2C_SCL,

	/* RTC */
	GPIO78_GPIO,
};

static struct pxa_gpio_platform_data pxa168_gpio_pdata = {
	.irq_base	= MMP_GPIO_TO_IRQ(0),
};

static unsigned int teton_bga_matrix_key_map[] = {
	KEY(0, 6, KEY_ESC),
	KEY(0, 7, KEY_ENTER),
	KEY(1, 6, KEY_LEFT),
	KEY(1, 7, KEY_RIGHT),
};

static struct matrix_keymap_data teton_bga_matrix_keymap_data = {
	.keymap			= teton_bga_matrix_key_map,
	.keymap_size		= ARRAY_SIZE(teton_bga_matrix_key_map),
};

static struct pxa27x_keypad_platform_data teton_bga_keypad_info __initdata = {
	.matrix_key_rows        = 2,
	.matrix_key_cols        = 8,
	.matrix_keymap_data	= &teton_bga_matrix_keymap_data,
	.debounce_interval      = 30,
};

static struct i2c_board_info teton_bga_i2c_info[] __initdata = {
	{
		I2C_BOARD_INFO("ds1337", 0x68),
		.irq = MMP_GPIO_TO_IRQ(RTC_INT_GPIO)
	},
};

static void __init teton_bga_init(void)
{
	mfp_config(ARRAY_AND_SIZE(teton_bga_pin_config));

	/* on-chip devices */
	pxa168_add_uart(1);
	pxa168_add_keypad(&teton_bga_keypad_info);
	pxa168_add_twsi(0, NULL, ARRAY_AND_SIZE(teton_bga_i2c_info));
	platform_device_add_data(&pxa168_device_gpio, &pxa168_gpio_pdata,
				 sizeof(struct pxa_gpio_platform_data));
	platform_device_register(&pxa168_device_gpio);
}

MACHINE_START(TETON_BGA, "PXA168-based Teton BGA Development Platform")
	.map_io		= mmp_map_io,
	.nr_irqs	= MMP_NR_IRQS,
	.init_irq       = pxa168_init_irq,
	.init_time	= pxa168_timer_init,
	.init_machine   = teton_bga_init,
	.restart	= pxa168_restart,
MACHINE_END


code:
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 *  Support for the Marvell PXA168 Teton BGA Development Platform.
 */
#ifndef __ASM_MACH_TETON_BGA_H
#define __ASM_MACH_TETON_BGA_H

/* GPIOs */
#define MMC_PWENA_GPIO		27
#define USBHPENB_GPIO		55
#define RTC_INT_GPIO		78
#define LCD_VBLK_EN_GPIO	79
#define LCD_DVDD_EN_GPIO	80
#define RST_WIFI_GPIO		81
#define CF_PWEN_GPIO		82
#define USB_OC_GPIO		83
#define PWM_GPIO		84
#define USBHPENA_GPIO		85
#define TS_INT_GPIO		86
#define CIR_GPIO		108

#endif /* __ASM_MACH_TETON_BGA_H */


code:
// SPDX-License-Identifier: GPL-2.0-only
/*
 * linux/arch/arm/mach-mmp/time.c
 *
 *   Support for clocksource and clockevents
 *
 * Copyright (C) 2008 Marvell International Ltd.
 * All rights reserved.
 *
 *   2008-04-11: Jason Chagas <Jason.chagas@marvell.com>
 *   2008-10-08: Bin Yang <bin.yang@marvell.com>
 *
 * The timers module actually includes three timers, each timer with up to
 * three match comparators. Timer #0 is used here in free-running mode as
 * the clock source, and match comparator #1 used as clock event device.
 */

#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/interrupt.h>
#include <linux/clockchips.h>
#include <linux/clk.h>

#include <linux/io.h>
#include <linux/irq.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/sched_clock.h>
#include <asm/mach/time.h>

#include "addr-map.h"
#include "regs-timers.h"
#include "regs-apbc.h"
#include "irqs.h"
#include <linux/soc/mmp/cputype.h>

#define TIMERS_VIRT_BASE	TIMERS1_VIRT_BASE

#define MAX_DELTA		(0xfffffffe)
#define MIN_DELTA		(16)

static void __iomem *mmp_timer_base = TIMERS_VIRT_BASE;

/*
 * Read the timer through the CVWR register. Delay is required after requesting
 * a read. The CR register cannot be directly read due to metastability issues
 * documented in the PXA168 software manual.
 */
static inline uint32_t timer_read(void)
{
	uint32_t val;
	int delay = 3;

	__raw_writel(1, mmp_timer_base + TMR_CVWR(1));

	while (delay--)
		val = __raw_readl(mmp_timer_base + TMR_CVWR(1));

	return val;
}

static u64 notrace mmp_read_sched_clock(void)
{
	return timer_read();
}

static irqreturn_t timer_interrupt(int irq, void *dev_id)
{
	struct clock_event_device *c = dev_id;

	/*
	 * Clear pending interrupt status.
	 */
	__raw_writel(0x01, mmp_timer_base + TMR_ICR(0));

	/*
	 * Disable timer 0.
	 */
	__raw_writel(0x02, mmp_timer_base + TMR_CER);

	c->event_handler(c);

	return IRQ_HANDLED;
}

static int timer_set_next_event(unsigned long delta,
				struct clock_event_device *dev)
{
	unsigned long flags;

	local_irq_save(flags);

	/*
	 * Disable timer 0.
	 */
	__raw_writel(0x02, mmp_timer_base + TMR_CER);

	/*
	 * Clear and enable timer match 0 interrupt.
	 */
	__raw_writel(0x01, mmp_timer_base + TMR_ICR(0));
	__raw_writel(0x01, mmp_timer_base + TMR_IER(0));

	/*
	 * Setup new clockevent timer value.
	 */
	__raw_writel(delta - 1, mmp_timer_base + TMR_TN_MM(0, 0));

	/*
	 * Enable timer 0.
	 */
	__raw_writel(0x03, mmp_timer_base + TMR_CER);

	local_irq_restore(flags);

	return 0;
}

static int timer_set_shutdown(struct clock_event_device *evt)
{
	unsigned long flags;

	local_irq_save(flags);
	/* disable the matching interrupt */
	__raw_writel(0x00, mmp_timer_base + TMR_IER(0));
	local_irq_restore(flags);

	return 0;
}

static struct clock_event_device ckevt = {
	.name			= "clockevent",
	.features		= CLOCK_EVT_FEAT_ONESHOT,
	.rating			= 200,
	.set_next_event		= timer_set_next_event,
	.set_state_shutdown	= timer_set_shutdown,
	.set_state_oneshot	= timer_set_shutdown,
};

static u64 clksrc_read(struct clocksource *cs)
{
	return timer_read();
}

static struct clocksource cksrc = {
	.name		= "clocksource",
	.rating		= 200,
	.read		= clksrc_read,
	.mask		= CLOCKSOURCE_MASK(32),
	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
};

static void __init timer_config(void)
{
	uint32_t ccr = __raw_readl(mmp_timer_base + TMR_CCR);

	__raw_writel(0x0, mmp_timer_base + TMR_CER); /* disable */

	ccr &= (cpu_is_mmp2() || cpu_is_mmp3()) ?
		(TMR_CCR_CS_0(0) | TMR_CCR_CS_1(0)) :
		(TMR_CCR_CS_0(3) | TMR_CCR_CS_1(3));
	__raw_writel(ccr, mmp_timer_base + TMR_CCR);

	/* set timer 0 to periodic mode, and timer 1 to free-running mode */
	__raw_writel(0x2, mmp_timer_base + TMR_CMR);

	__raw_writel(0x1, mmp_timer_base + TMR_PLCR(0)); /* periodic */
	__raw_writel(0x7, mmp_timer_base + TMR_ICR(0));  /* clear status */
	__raw_writel(0x0, mmp_timer_base + TMR_IER(0));

	__raw_writel(0x0, mmp_timer_base + TMR_PLCR(1)); /* free-running */
	__raw_writel(0x7, mmp_timer_base + TMR_ICR(1));  /* clear status */
	__raw_writel(0x0, mmp_timer_base + TMR_IER(1));

	/* enable timer 1 counter */
	__raw_writel(0x2, mmp_timer_base + TMR_CER);
}

void __init mmp_timer_init(int irq, unsigned long rate)
{
	timer_config();

	sched_clock_register(mmp_read_sched_clock, 32, rate);

	ckevt.cpumask = cpumask_of(0);

	if (request_irq(irq, timer_interrupt, IRQF_TIMER | IRQF_IRQPOLL,
			"timer", &ckevt))
		pr_err("Failed to request irq %d (timer)\n", irq);

	clocksource_register_hz(&cksrc, rate);
	clockevents_config_and_register(&ckevt, rate, MIN_DELTA, MAX_DELTA);
}

static int __init mmp_dt_init_timer(struct device_node *np)
{
	struct clk *clk;
	int irq, ret;
	unsigned long rate;

	clk = of_clk_get(np, 0);
	if (!IS_ERR(clk)) {
		ret = clk_prepare_enable(clk);
		if (ret)
			return ret;
		rate = clk_get_rate(clk);
	} else if (cpu_is_pj4()) {
		rate = 6500000;
	} else {
		rate = 3250000;
	}

	irq = irq_of_parse_and_map(np, 0);
	if (!irq)
		return -EINVAL;

	mmp_timer_base = of_iomap(np, 0);
	if (!mmp_timer_base)
		return -ENOMEM;

	mmp_timer_init(irq, rate);
	return 0;
}

TIMER_OF_DECLARE(mmp_timer, "mrvl,mmp-timer", mmp_dt_init_timer);


code:
// SPDX-License-Identifier: GPL-2.0-only
/*
 *  linux/arch/arm/mach-mmp/ttc_dkb.c
 *
 *  Support for the Marvell PXA910-based TTC_DKB Development Platform.
 */

#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/onenand.h>
#include <linux/interrupt.h>
#include <linux/platform_data/pca953x.h>
#include <linux/gpio.h>
#include <linux/gpio-pxa.h>
#include <linux/mfd/88pm860x.h>
#include <linux/platform_data/mv_usb.h>
#include <linux/spi/spi.h>
#include <linux/delay.h>

#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/mach/flash.h>
#include "addr-map.h"
#include "mfp-pxa910.h"
#include "pxa910.h"
#include "irqs.h"
#include "regs-usb.h"

#include "common.h"

#define TTCDKB_GPIO_EXT0(x)	(MMP_NR_BUILTIN_GPIO + ((x < 0) ? 0 :	\
				((x < 16) ? x : 15)))
#define TTCDKB_GPIO_EXT1(x)	(MMP_NR_BUILTIN_GPIO + 16 + ((x < 0) ? 0 : \
				((x < 16) ? x : 15)))

/*
 * 16 board interrupts -- MAX7312 GPIO expander
 * 16 board interrupts -- PCA9575 GPIO expander
 * 24 board interrupts -- 88PM860x PMIC
 */
#define TTCDKB_NR_IRQS		(MMP_NR_IRQS + 16 + 16 + 24)

static unsigned long ttc_dkb_pin_config[] __initdata = {
	/* UART2 */
	GPIO47_UART2_RXD,
	GPIO48_UART2_TXD,

	/* DFI */
	DF_IO0_ND_IO0,
	DF_IO1_ND_IO1,
	DF_IO2_ND_IO2,
	DF_IO3_ND_IO3,
	DF_IO4_ND_IO4,
	DF_IO5_ND_IO5,
	DF_IO6_ND_IO6,
	DF_IO7_ND_IO7,
	DF_IO8_ND_IO8,
	DF_IO9_ND_IO9,
	DF_IO10_ND_IO10,
	DF_IO11_ND_IO11,
	DF_IO12_ND_IO12,
	DF_IO13_ND_IO13,
	DF_IO14_ND_IO14,
	DF_IO15_ND_IO15,
	DF_nCS0_SM_nCS2_nCS0,
	DF_ALE_SM_WEn_ND_ALE,
	DF_CLE_SM_OEn_ND_CLE,
	DF_WEn_DF_WEn,
	DF_REn_DF_REn,
	DF_RDY0_DF_RDY0,
};

static struct pxa_gpio_platform_data pxa910_gpio_pdata = {
	.irq_base	= MMP_GPIO_TO_IRQ(0),
};

static struct mtd_partition ttc_dkb_onenand_partitions[] = {
	{
		.name		= "bootloader",
		.offset		= 0,
		.size		= SZ_1M,
		.mask_flags	= MTD_WRITEABLE,
	}, {
		.name		= "reserved",
		.offset		= MTDPART_OFS_APPEND,
		.size		= SZ_128K,
		.mask_flags	= MTD_WRITEABLE,
	}, {
		.name		= "reserved",
		.offset		= MTDPART_OFS_APPEND,
		.size		= SZ_8M,
		.mask_flags	= MTD_WRITEABLE,
	}, {
		.name		= "kernel",
		.offset		= MTDPART_OFS_APPEND,
		.size		= (SZ_2M + SZ_1M),
		.mask_flags	= 0,
	}, {
		.name		= "filesystem",
		.offset		= MTDPART_OFS_APPEND,
		.size		= SZ_32M + SZ_16M,
		.mask_flags	= 0,
	}
};

static struct onenand_platform_data ttc_dkb_onenand_info = {
	.parts		= ttc_dkb_onenand_partitions,
	.nr_parts	= ARRAY_SIZE(ttc_dkb_onenand_partitions),
};

static struct resource ttc_dkb_resource_onenand[] = {
	[0] = {
		.start	= SMC_CS0_PHYS_BASE,
		.end	= SMC_CS0_PHYS_BASE + SZ_1M,
		.flags	= IORESOURCE_MEM,
	},
};

static struct platform_device ttc_dkb_device_onenand = {
	.name		= "onenand-flash",
	.id		= -1,
	.resource	= ttc_dkb_resource_onenand,
	.num_resources	= ARRAY_SIZE(ttc_dkb_resource_onenand),
	.dev		= {
		.platform_data	= &ttc_dkb_onenand_info,
	},
};

static struct platform_device *ttc_dkb_devices[] = {
	&pxa910_device_gpio,
	&pxa910_device_rtc,
	&ttc_dkb_device_onenand,
};

static struct pca953x_platform_data max7312_data[] = {
	{
		.gpio_base	= TTCDKB_GPIO_EXT0(0),
		.irq_base	= MMP_NR_IRQS,
	},
};

static struct pm860x_platform_data ttc_dkb_pm8607_info = {
	.irq_base       = IRQ_BOARD_START,
};

static struct i2c_board_info ttc_dkb_i2c_info[] = {
	{
		.type           = "88PM860x",
		.addr           = 0x34,
		.platform_data  = &ttc_dkb_pm8607_info,
		.irq            = IRQ_PXA910_PMIC_INT,
	},
	{
		.type		= "max7312",
		.addr		= 0x23,
		.irq		= MMP_GPIO_TO_IRQ(80),
		.platform_data	= &max7312_data,
	},
};

#if IS_ENABLED(CONFIG_USB_SUPPORT)
#if IS_ENABLED(CONFIG_USB_MV_UDC) || IS_ENABLED(CONFIG_USB_EHCI_MV_U2O)

static struct mv_usb_platform_data ttc_usb_pdata = {
	.vbus		= NULL,
	.mode		= MV_USB_MODE_OTG,
	.otg_force_a_bus_req = 1,
	.phy_init	= pxa_usb_phy_init,
	.phy_deinit	= pxa_usb_phy_deinit,
	.set_vbus	= NULL,
};
#endif
#endif

#if IS_ENABLED(CONFIG_MTD_NAND_MARVELL)
static struct pxa3xx_nand_platform_data dkb_nand_info = {};
#endif

#if IS_ENABLED(CONFIG_MMP_DISP)
/* path config */
#define CFG_IOPADMODE(iopad)   (iopad)  /* 0x0 ~ 0xd */
#define SCLK_SOURCE_SELECT(x)  (x << 30) /* 0x0 ~ 0x3 */
/* link config */
#define CFG_DUMBMODE(mode)     (mode << 28) /* 0x0 ~ 0x6*/
static struct mmp_mach_path_config dkb_disp_config[] = {
	[0] = {
		.name = "mmp-parallel",
		.overlay_num = 2,
		.output_type = PATH_OUT_PARALLEL,
		.path_config = CFG_IOPADMODE(0x1)
			| SCLK_SOURCE_SELECT(0x1),
		.link_config = CFG_DUMBMODE(0x2),
	},
};

static struct mmp_mach_plat_info dkb_disp_info = {
	.name = "mmp-disp",
	.clk_name = "disp0",
	.path_num = 1,
	.paths = dkb_disp_config,
};

static struct mmp_buffer_driver_mach_info dkb_fb_info = {
	.name = "mmp-fb",
	.path_name = "mmp-parallel",
	.overlay_id = 0,
	.dmafetch_id = 1,
	.default_pixfmt = PIXFMT_RGB565,
};

static void dkb_tpo_panel_power(int on)
{
	int err;
	u32 spi_reset = mfp_to_gpio(MFP_PIN_GPIO106);

	if (on) {
		err = gpio_request(spi_reset, "TPO_LCD_SPI_RESET");
		if (err) {
			pr_err("failed to request GPIO for TPO LCD RESET\n");
			return;
		}
		gpio_direction_output(spi_reset, 0);
		udelay(100);
		gpio_set_value(spi_reset, 1);
		gpio_free(spi_reset);
	} else {
		err = gpio_request(spi_reset, "TPO_LCD_SPI_RESET");
		if (err) {
			pr_err("failed to request LCD RESET gpio\n");
			return;
		}
		gpio_set_value(spi_reset, 0);
		gpio_free(spi_reset);
	}
}

static struct mmp_mach_panel_info dkb_tpo_panel_info = {
	.name = "tpo-hvga",
	.plat_path_name = "mmp-parallel",
	.plat_set_onoff = dkb_tpo_panel_power,
};

static struct spi_board_info spi_board_info[] __initdata = {
	{
		.modalias       = "tpo-hvga",
		.platform_data  = &dkb_tpo_panel_info,
		.bus_num        = 5,
	}
};

static void __init add_disp(void)
{
	mmp_register_device(&pxa910_device_disp,
		&dkb_disp_info, sizeof(dkb_disp_info));
	spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
	mmp_register_device(&pxa910_device_fb,
		&dkb_fb_info, sizeof(dkb_fb_info));
	mmp_register_device(&pxa910_device_panel,
		&dkb_tpo_panel_info, sizeof(dkb_tpo_panel_info));
}
#endif

static void __init ttc_dkb_init(void)
{
	mfp_config(ARRAY_AND_SIZE(ttc_dkb_pin_config));

	/* on-chip devices */
	pxa910_add_uart(1);
#if IS_ENABLED(CONFIG_MTD_NAND_MARVELL)
	pxa910_add_nand(&dkb_nand_info);
#endif

	/* off-chip devices */
	pxa910_add_twsi(0, NULL, ARRAY_AND_SIZE(ttc_dkb_i2c_info));
	platform_device_add_data(&pxa910_device_gpio, &pxa910_gpio_pdata,
				 sizeof(struct pxa_gpio_platform_data));
	platform_add_devices(ARRAY_AND_SIZE(ttc_dkb_devices));

#if IS_ENABLED(CONFIG_USB_SUPPORT)
#if IS_ENABLED(CONFIG_PHY_PXA_USB)
	platform_device_register(&pxa168_device_usb_phy);
#endif

#if IS_ENABLED(CONFIG_USB_MV_UDC)
	pxa168_device_u2o.dev.platform_data = &ttc_usb_pdata;
	platform_device_register(&pxa168_device_u2o);
#endif

#if IS_ENABLED(CONFIG_USB_EHCI_MV_U2O)
	pxa168_device_u2oehci.dev.platform_data = &ttc_usb_pdata;
	platform_device_register(&pxa168_device_u2oehci);
#endif

#if IS_ENABLED(CONFIG_USB_MV_OTG)
	pxa168_device_u2ootg.dev.platform_data = &ttc_usb_pdata;
	platform_device_register(&pxa168_device_u2ootg);
#endif
#endif

#if IS_ENABLED(CONFIG_MMP_DISP)
	add_disp();
#endif
}

MACHINE_START(TTC_DKB, "PXA910-based TTC_DKB Development Platform")
	.map_io		= mmp_map_io,
	.nr_irqs	= TTCDKB_NR_IRQS,
	.init_irq       = pxa910_init_irq,
	.init_time	= pxa910_timer_init,
	.init_machine   = ttc_dkb_init,
	.restart	= mmp_restart,
MACHINE_END


code:
# SPDX-License-Identifier: GPL-2.0-only
menuconfig ARCH_MOXART
	bool "MOXA ART SoC"
	depends on ARCH_MULTI_V4
	depends on CPU_LITTLE_ENDIAN
	select CPU_FA526
	select ARM_DMA_MEM_BUFFERABLE
	select FARADAY_FTINTC010
	select FTTMR010_TIMER
	select GPIOLIB
	select PHYLIB if NETDEVICES
	help
	  Say Y here if you want to run your kernel on hardware with a
	  MOXA ART SoC.
	  The MOXA ART SoC is based on a Faraday FA526 ARMv4 32-bit
	  192 MHz CPU with MMU and 16KB/8KB D/I-cache (UC-7112-LX).
	  Used on models UC-7101, UC-7112/UC-7110, IA240/IA241, IA3341.

if ARCH_MOXART

config MACH_UC7112LX
	bool "MOXA UC-7112-LX"
	depends on ARCH_MOXART
	help
	  Say Y here if you intend to run this kernel on a MOXA
	  UC-7112-LX embedded computer.

endif

path: arch/arm/mach-moxart/Kconfig


code:
# SPDX-License-Identifier: GPL-2.0-only
# Object file lists.

obj-$(CONFIG_MACH_UC7112LX)	+= moxart.o

path: arch/arm/mach-moxart/Makefile


code:
// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * arch/arm/mach-moxart/moxart.c
 *
 * (C) Copyright 2013, Jonas Jensen <jonas.jensen@gmail.com>
 */


code:
menuconfig ARCH_MSTARV7
	bool "MStar/Sigmastar Armv7 SoC Support"
	depends on ARCH_MULTI_V7
	select ARM_ERRATA_814220
	select ARM_GIC
	select ARM_HEAVY_MB
	select HAVE_ARM_ARCH_TIMER
	select MST_IRQ
	select MSTAR_MSC313_MPLL
	help
	  Support for newer MStar/Sigmastar SoC families that are
	  based on Armv7 cores like the Cortex A7 and share the same
	  basic hardware like the infinity and mercury series.

if ARCH_MSTARV7

config MACH_INFINITY
	bool "MStar/Sigmastar infinity SoC support"
	default ARCH_MSTARV7
	help
	  Support for MStar/Sigmastar infinity IP camera SoCs.

config MACH_MERCURY
	bool "MStar/Sigmastar mercury SoC support"
	default ARCH_MSTARV7
	help
	  Support for MStar/Sigmastar mercury dash camera SoCs.
	  Note that older Mercury2 SoCs are ARM9 based and not supported.

endif

path: arch/arm/mach-mstar/Kconfig


code: obj-$(CONFIG_ARCH_MSTARV7) += mstarv7.o

path: arch/arm/mach-mstar/Makefile


code:
// SPDX-License-Identifier: GPL-2.0
/*
 * Device Tree support for MStar/Sigmastar Armv7 SoCs
 *
 * Copyright (c) 2020 thingy.jp
 * Author: Daniel Palmer <daniel@thingy.jp>
 */

#include <linux/init.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/io.h>

/*
 * In the u-boot code the area these registers are in is
 * called "L3 bridge" and there are register descriptions
 * for something in the same area called "AXI".
 *
 * It's not exactly known what this is but the vendor code
 * for both u-boot and linux share calls to "flush the miu pipe".
 * This seems to be to force pending CPU writes to memory so that
 * the state is right before DMA capable devices try to read
 * descriptors and data the CPU has prepared. Without doing this
 * ethernet doesn't work reliably for example.
 */

#define MSTARV7_L3BRIDGE_FLUSH		0x14
#define MSTARV7_L3BRIDGE_STATUS		0x40
#define MSTARV7_L3BRIDGE_FLUSH_TRIGGER	BIT(0)
#define MSTARV7_L3BRIDGE_STATUS_DONE	BIT(12)

#ifdef CONFIG_SMP
#define MSTARV7_CPU1_BOOT_ADDR_HIGH	0x4c
#define MSTARV7_CPU1_BOOT_ADDR_LOW	0x50
#define MSTARV7_CPU1_UNLOCK		0x58
#define MSTARV7_CPU1_UNLOCK_MAGIC	0xbabe
#endif

static void __iomem *l3bridge;

static const char * const mstarv7_board_dt_compat[] __initconst = {
	"mstar,infinity",
	"mstar,infinity2m",
	"mstar,infinity3",
	"mstar,mercury5",
	NULL,
};

/*
 * This may need locking to deal with situations where an interrupt
 * happens while we are in here and mb() gets called by the interrupt handler.
 *
 * The vendor code did have a spin lock but it doesn't seem to be needed and
 * removing it hasn't caused any side effects so far.
 *
 * [writel|readl]_relaxed have to be used here because otherwise
 * we'd end up right back in here.
 */
static void mstarv7_mb(void)
{
	/* toggle the flush miu pipe fire bit */
	writel_relaxed(0, l3bridge + MSTARV7_L3BRIDGE_FLUSH);
	writel_relaxed(MSTARV7_L3BRIDGE_FLUSH_TRIGGER, l3bridge
			+ MSTARV7_L3BRIDGE_FLUSH);
	while (!(readl_relaxed(l3bridge + MSTARV7_L3BRIDGE_STATUS)
			& MSTARV7_L3BRIDGE_STATUS_DONE)) {
		/* wait for flush to complete */
	}
}

#ifdef CONFIG_SMP
static int mstarv7_boot_secondary(unsigned int cpu, struct task_struct *idle)
{
	struct device_node *np;
	u32 bootaddr = (u32) __pa_symbol(secondary_startup_arm);
	void __iomem *smpctrl;

	/*
	 * right now we don't know how to boot anything except
	 * cpu 1.
	 */
	if (cpu != 1)
		return -EINVAL;

	np = of_find_compatible_node(NULL, NULL, "mstar,smpctrl");
	smpctrl = of_iomap(np, 0);

	if (!smpctrl)
		return -ENODEV;

	/* set the boot address for the second cpu */
	writew(bootaddr & 0xffff, smpctrl + MSTARV7_CPU1_BOOT_ADDR_LOW);
	writew((bootaddr >> 16) & 0xffff, smpctrl + MSTARV7_CPU1_BOOT_ADDR_HIGH);

	/* unlock the second cpu */
	writew(MSTARV7_CPU1_UNLOCK_MAGIC, smpctrl + MSTARV7_CPU1_UNLOCK);

	/* and away we go...*/
	arch_send_wakeup_ipi_mask(cpumask_of(cpu));

	iounmap(smpctrl);

	return 0;
}

static const struct smp_operations __initdata mstarv7_smp_ops = {
	.smp_boot_secondary = mstarv7_boot_secondary,
};
#endif

static void __init mstarv7_init(void)
{
	struct device_node *np;

	np = of_find_compatible_node(NULL, NULL, "mstar,l3bridge");
	l3bridge = of_iomap(np, 0);
	if (l3bridge)
		soc_mb = mstarv7_mb;
	else
		pr_warn("Failed to install memory barrier, DMA will be broken!\n");
}

DT_MACHINE_START(MSTARV7_DT, "MStar/Sigmastar Armv7 (Device Tree)")
	.dt_compat	= mstarv7_board_dt_compat,
	.init_machine	= mstarv7_init,
	.smp		= smp_ops(mstarv7_smp_ops),
MACHINE_END


code:
# SPDX-License-Identifier: GPL-2.0-only
menuconfig ARCH_MV78XX0
	bool "Marvell MV78xx0"
	depends on ARCH_MULTI_V5
	depends on CPU_LITTLE_ENDIAN
	depends on ATAGS && UNUSED_BOARD_FILES
	select CPU_FEROCEON
	select GPIOLIB
	select MVEBU_MBUS
	select FORCE_PCI
	select PLAT_ORION_LEGACY
	help
	  Support for the following Marvell MV78xx0 series SoCs:
	  MV781x0, MV782x0.

if ARCH_MV78XX0

config MACH_DB78X00_BP
	bool "Marvell DB-78x00-BP Development Board"
	help
	  Say 'Y' here if you want your kernel to support the
	  Marvell DB-78x00-BP Development Board.

config MACH_RD78X00_MASA
	bool "Marvell RD-78x00-mASA Reference Design"
	help
	  Say 'Y' here if you want your kernel to support the
	  Marvell RD-78x00-mASA Reference Design.

config MACH_TERASTATION_WXL
	bool "Buffalo WLX (Terastation Duo) NAS"
	help
	  Say 'Y' here if you want your kernel to support the
	  Buffalo WXL Nas.

endif


code:
# SPDX-License-Identifier: GPL-2.0
ccflags-y := -I$(srctree)/arch/arm/plat-orion/include

obj-y				+= common.o mpp.o irq.o pcie.o
obj-$(CONFIG_MACH_DB78X00_BP)	+= db78x00-bp-setup.o
obj-$(CONFIG_MACH_RD78X00_MASA)	+= rd78x00-masa-setup.o
obj-$(CONFIG_MACH_TERASTATION_WXL) += buffalo-wxl-setup.o


code:
/* SPDX-License-Identifier: GPL-2.0-only */

#ifndef __ASM_ARCH_BRIDGE_REGS_H
#define __ASM_ARCH_BRIDGE_REGS_H

#include "mv78xx0.h"

#define CPU_CONTROL		(BRIDGE_VIRT_BASE + 0x0104)
#define L2_WRITETHROUGH		0x00020000

#define RSTOUTn_MASK		(BRIDGE_VIRT_BASE + 0x0108)
#define RSTOUTn_MASK_PHYS	(BRIDGE_PHYS_BASE + 0x0108)
#define SOFT_RESET_OUT_EN	0x00000004

#define SYSTEM_SOFT_RESET	(BRIDGE_VIRT_BASE + 0x010c)
#define SOFT_RESET		0x00000001

#define BRIDGE_INT_TIMER1_CLR	(~0x0004)

#define IRQ_VIRT_BASE		(BRIDGE_VIRT_BASE + 0x0200)
#define IRQ_CAUSE_ERR_OFF	0x0000
#define IRQ_CAUSE_LOW_OFF	0x0004
#define IRQ_CAUSE_HIGH_OFF	0x0008
#define IRQ_MASK_ERR_OFF	0x000c
#define IRQ_MASK_LOW_OFF	0x0010
#define IRQ_MASK_HIGH_OFF	0x0014

#define TIMER_VIRT_BASE		(BRIDGE_VIRT_BASE + 0x0300)
#define TIMER_PHYS_BASE		(BRIDGE_PHYS_BASE + 0x0300)

#endif


code:
// SPDX-License-Identifier: GPL-2.0-only
/*
 * arch/arm/mach-mv78xx0/buffalo-wxl-setup.c
 *
 * Buffalo WXL (Terastation Duo) Setup routines
 *
 * sebastien requiem <sebastien@requiem.fr>
 */

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/ata_platform.h>
#include <linux/mv643xx_eth.h>
#include <linux/ethtool.h>
#include <linux/i2c.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include "mv78xx0.h"
#include "common.h"
#include "mpp.h"

/* This arch has 2 Giga Ethernet */

static struct mv643xx_eth_platform_data db78x00_ge00_data = {
	.phy_addr	= MV643XX_ETH_PHY_ADDR(0),
};

static struct mv643xx_eth_platform_data db78x00_ge01_data = {
	.phy_addr	= MV643XX_ETH_PHY_ADDR(8),
};

/* 2 SATA controller supporting HotPlug */

static struct mv_sata_platform_data db78x00_sata_data = {
	.n_ports	= 2,
};

static struct i2c_board_info __initdata db78x00_i2c_rtc = {
	I2C_BOARD_INFO("ds1338", 0x68),
};

static unsigned int wxl_mpp_config[] __initdata = {
	MPP0_GE1_TXCLK,
	MPP1_GE1_TXCTL,
	MPP2_GE1_RXCTL,
	MPP3_GE1_RXCLK,
	MPP4_GE1_TXD0,
	MPP5_GE1_TXD1,
	MPP6_GE1_TXD2,
	MPP7_GE1_TXD3,
	MPP8_GE1_RXD0,
	MPP9_GE1_RXD1,
	MPP10_GE1_RXD2,
	MPP11_GE1_RXD3,
	MPP12_GPIO,
	MPP13_SYSRST_OUTn,
	MPP14_SATA1_ACTn,
	MPP15_SATA0_ACTn,
	MPP16_GPIO,
	MPP17_GPIO,
	MPP18_GPIO,
	MPP19_GPIO,
	MPP20_GPIO,
	MPP21_GPIO,
	MPP22_GPIO,
	MPP23_GPIO,
	MPP24_UA2_TXD,
	MPP25_UA2_RXD,
	MPP26_UA2_CTSn,
	MPP27_UA2_RTSn,
	MPP28_GPIO,
	MPP29_SYSRST_OUTn,
	MPP30_GPIO,
	MPP31_GPIO,
	MPP32_GPIO,
	MPP33_GPIO,
	MPP34_GPIO,
	MPP35_GPIO,
	MPP36_GPIO,
	MPP37_GPIO,
	MPP38_GPIO,
	MPP39_GPIO,
	MPP40_UNUSED,
	MPP41_UNUSED,
	MPP42_UNUSED,
	MPP43_UNUSED,
	MPP44_UNUSED,
	MPP45_UNUSED,
	MPP46_UNUSED,
	MPP47_UNUSED,
	MPP48_SATA1_ACTn,
	MPP49_SATA0_ACTn,
	0
};

static void __init wxl_init(void)
{
	/*
	 * Basic MV78xx0 setup. Needs to be called early.
	 */
	mv78xx0_init();
	mv78xx0_mpp_conf(wxl_mpp_config);

	/*
	 * Partition on-chip peripherals between the two CPU cores.
	 */
	mv78xx0_ehci0_init();
	mv78xx0_ehci1_init();
	mv78xx0_ehci2_init();
	mv78xx0_ge00_init(&db78x00_ge00_data);
	mv78xx0_ge01_init(&db78x00_ge01_data);
	mv78xx0_sata_init(&db78x00_sata_data);
	mv78xx0_uart0_init();
	mv78xx0_uart1_init();
	mv78xx0_uart2_init();
	mv78xx0_uart3_init();
	mv78xx0_i2c_init();
	i2c_register_board_info(0, &db78x00_i2c_rtc, 1);
}

static int __init wxl_pci_init(void)
{
	if (machine_is_terastation_wxl()) {
		/*
		 * Assign the x16 PCIe slot on the board to CPU core
		 * #0, and let CPU core #1 have the four x1 slots.
		 */
		if (mv78xx0_core_index() == 0)
			mv78xx0_pcie_init(0, 1);
		else
			mv78xx0_pcie_init(1, 0);
	}

	return 0;
}
subsys_initcall(wxl_pci_init);

MACHINE_START(TERASTATION_WXL, "Buffalo Nas WXL")
	/* Maintainer: Sebastien Requiem <sebastien@requiem.fr> */
	.atag_offset	= 0x100,
	.nr_irqs	= MV78XX0_NR_IRQS,
	.init_machine	= wxl_init,
	.map_io		= mv78xx0_map_io,
	.init_early	= mv78xx0_init_early,
	.init_irq	= mv78xx0_init_irq,
	.init_time	= mv78xx0_timer_init,
	.restart	= mv78xx0_restart,
MACHINE_END


code:
// SPDX-License-Identifier: GPL-2.0-only
/*
 * arch/arm/mach-mv78xx0/common.c
 *
 * Core functions for Marvell MV78xx0 SoCs
 */

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/platform_device.h>
#include <linux/serial_8250.h>
#include <linux/ata_platform.h>
#include <linux/clk-provider.h>
#include <linux/ethtool.h>
#include <asm/hardware/cache-feroceon-l2.h>
#include <asm/mach/map.h>
#include <asm/mach/time.h>
#include <linux/platform_data/usb-ehci-orion.h>
#include <linux/platform_data/mtd-orion_nand.h>
#include <plat/time.h>
#include <plat/common.h>
#include <plat/addr-map.h>
#include "mv78xx0.h"
#include "bridge-regs.h"
#include "common.h"

static int get_tclk(void);

/*****************************************************************************
 * Common bits
 ****************************************************************************/
int mv78xx0_core_index(void)
{
	u32 extra;

	/*
	 * Read Extra Features register.
	 */
	__asm__("mrc p15, 1, %0, c15, c1, 0" : "=r" (extra));

	return !!(extra & 0x00004000);
}

static int get_hclk(void)
{
	int hclk;

	/*
	 * HCLK tick rate is configured by DEV_D[7:5] pins.
	 */
	switch ((readl(SAMPLE_AT_RESET_LOW) >> 5) & 7) {
	case 0:
		hclk = 166666667;
		break;
	case 1:
		hclk = 200000000;
		break;
	case 2:
		hclk = 266666667;
		break;
	case 3:
		hclk = 333333333;
		break;
	case 4:
		hclk = 400000000;
		break;
	default:
		panic("unknown HCLK PLL setting: %.8x\n",
			readl(SAMPLE_AT_RESET_LOW));
	}

	return hclk;
}

static void get_pclk_l2clk(int hclk, int core_index, int *pclk, int *l2clk)
{
	u32 cfg;

	/*
	 * Core #0 PCLK/L2CLK is configured by bits [13:8], core #1
	 * PCLK/L2CLK by bits [19:14].
	 */
	if (core_index == 0) {
		cfg = (readl(SAMPLE_AT_RESET_LOW) >> 8) & 0x3f;
	} else {
		cfg = (readl(SAMPLE_AT_RESET_LOW) >> 14) & 0x3f;
	}

	/*
	 * Bits [11:8] ([17:14] for core #1) configure the PCLK:HCLK
	 * ratio (1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5, 5, 5.5, 6).
	 */
	*pclk = ((u64)hclk * (2 + (cfg & 0xf))) >> 1;

	/*
	 * Bits [13:12] ([19:18] for core #1) configure the PCLK:L2CLK
	 * ratio (1, 2, 3).
	 */
	*l2clk = *pclk / (((cfg >> 4) & 3) + 1);
}

static int get_tclk(void)
{
	int tclk_freq;

	/*
	 * TCLK tick rate is configured by DEV_A[2:0] strap pins.
	 */
	switch ((readl(SAMPLE_AT_RESET_HIGH) >> 6) & 7) {
	case 1:
		tclk_freq = 166666667;
		break;
	case 3:
		tclk_freq = 200000000;
		break;
	default:
		panic("unknown TCLK PLL setting: %.8x\n",
			readl(SAMPLE_AT_RESET_HIGH));
	}

	return tclk_freq;
}

/*****************************************************************************
 * I/O Address Mapping
 ****************************************************************************/
static struct map_desc mv78xx0_io_desc[] __initdata = {
	{
		.virtual	= (unsigned long) MV78XX0_CORE_REGS_VIRT_BASE,
		.pfn		= 0,
		.length		= MV78XX0_CORE_REGS_SIZE,
		.type		= MT_DEVICE,
	}, {
		.virtual	= (unsigned long) MV78XX0_REGS_VIRT_BASE,
		.pfn		= __phys_to_pfn(MV78XX0_REGS_PHYS_BASE),
		.length		= MV78XX0_REGS_SIZE,
		.type		= MT_DEVICE,
	},
};

void __init mv78xx0_map_io(void)
{
	unsigned long phys;

	/*
	 * Map the right set of per-core registers depending on
	 * which core we are running on.
	 */
	if (mv78xx0_core_index() == 0) {
		phys = MV78XX0_CORE0_REGS_PHYS_BASE;
	} else {
		phys = MV78XX0_CORE1_REGS_PHYS_BASE;
	}
	mv78xx0_io_desc[0].pfn = __phys_to_pfn(phys);

	iotable_init(mv78xx0_io_desc, ARRAY_SIZE(mv78xx0_io_desc));
}

/*****************************************************************************
 * CLK tree
 ****************************************************************************/
static struct clk *tclk;

static void __init clk_init(void)
{
	tclk = clk_register_fixed_rate(NULL, "tclk", NULL, 0, get_tclk());

	orion_clkdev_init(tclk);
}

/*****************************************************************************
 * EHCI
 ****************************************************************************/
void __init mv78xx0_ehci0_init(void)
{
	orion_ehci_init(USB0_PHYS_BASE, IRQ_MV78XX0_USB_0, EHCI_PHY_NA);
}

/*****************************************************************************
 * EHCI1
 ****************************************************************************/
void __init mv78xx0_ehci1_init(void)
{
	orion_ehci_1_init(USB1_PHYS_BASE, IRQ_MV78XX0_USB_1);
}

/*****************************************************************************
 * EHCI2
 ****************************************************************************/
void __init mv78xx0_ehci2_init(void)
{
	orion_ehci_2_init(USB2_PHYS_BASE, IRQ_MV78XX0_USB_2);
}

/*****************************************************************************
 * GE00
 ****************************************************************************/
void __init mv78xx0_ge00_init(struct mv643xx_eth_platform_data *eth_data)
{
	orion_ge00_init(eth_data,
			GE00_PHYS_BASE, IRQ_MV78XX0_GE00_SUM,
			IRQ_MV78XX0_GE_ERR,
			MV643XX_TX_CSUM_DEFAULT_LIMIT);
}

/*****************************************************************************
 * GE01
 ****************************************************************************/
void __init mv78xx0_ge01_init(struct mv643xx_eth_platform_data *eth_data)
{
	orion_ge01_init(eth_data,
			GE01_PHYS_BASE, IRQ_MV78XX0_GE01_SUM,
			MV643XX_TX_CSUM_DEFAULT_LIMIT);
}

/*****************************************************************************
 * GE10
 ****************************************************************************/
void __init mv78xx0_ge10_init(struct mv643xx_eth_platform_data *eth_data)
{
	u32 dev, rev;

	/*
	 * On the Z0, ge10 and ge11 are internally connected back
	 * to back, and not brought out.
	 */
	mv78xx0_pcie_id(&dev, &rev);
	if (dev == MV78X00_Z0_DEV_ID) {
		eth_data->phy_addr = MV643XX_ETH_PHY_NONE;
		eth_data->speed = SPEED_1000;
		eth_data->duplex = DUPLEX_FULL;
	}

	orion_ge10_init(eth_data, GE10_PHYS_BASE, IRQ_MV78XX0_GE10_SUM);
}

/*****************************************************************************
 * GE11
 ****************************************************************************/
void __init mv78xx0_ge11_init(struct mv643xx_eth_platform_data *eth_data)
{
	u32 dev, rev;

	/*
	 * On the Z0, ge10 and ge11 are internally connected back
	 * to back, and not brought out.
	 */
	mv78xx0_pcie_id(&dev, &rev);
	if (dev == MV78X00_Z0_DEV_ID) {
		eth_data->phy_addr = MV643XX_ETH_PHY_NONE;
		eth_data->speed = SPEED_1000;
		eth_data->duplex = DUPLEX_FULL;
	}

	orion_ge11_init(eth_data, GE11_PHYS_BASE, IRQ_MV78XX0_GE11_SUM);
}

/*****************************************************************************
 * I2C
 ****************************************************************************/
void __init mv78xx0_i2c_init(void)
{
	orion_i2c_init(I2C_0_PHYS_BASE, IRQ_MV78XX0_I2C_0, 8);
	orion_i2c_1_init(I2C_1_PHYS_BASE, IRQ_MV78XX0_I2C_1, 8);
}

/*****************************************************************************
 * SATA
 ****************************************************************************/
void __init mv78xx0_sata_init(struct mv_sata_platform_data *sata_data)
{
	orion_sata_init(sata_data, SATA_PHYS_BASE, IRQ_MV78XX0_SATA);
}

/*****************************************************************************
 * UART0
 ****************************************************************************/
void __init mv78xx0_uart0_init(void)
{
	orion_uart0_init(UART0_VIRT_BASE, UART0_PHYS_BASE,
			 IRQ_MV78XX0_UART_0, tclk);
}

/*****************************************************************************
 * UART1
 ****************************************************************************/
void __init mv78xx0_uart1_init(void)
{
	orion_uart1_init(UART1_VIRT_BASE, UART1_PHYS_BASE,
			 IRQ_MV78XX0_UART_1, tclk);
}

/*****************************************************************************
 * UART2
 ****************************************************************************/
void __init mv78xx0_uart2_init(void)
{
	orion_uart2_init(UART2_VIRT_BASE, UART2_PHYS_BASE,
			 IRQ_MV78XX0_UART_2, tclk);
}

/*****************************************************************************
 * UART3
 ****************************************************************************/
void __init mv78xx0_uart3_init(void)
{
	orion_uart3_init(UART3_VIRT_BASE, UART3_PHYS_BASE,
			 IRQ_MV78XX0_UART_3, tclk);
}

/*****************************************************************************
 * Time handling
 ****************************************************************************/
void __init mv78xx0_init_early(void)
{
	orion_time_set_base(TIMER_VIRT_BASE);
	if (mv78xx0_core_index() == 0)
		mvebu_mbus_init("marvell,mv78xx0-mbus",
				BRIDGE_WINS_CPU0_BASE, BRIDGE_WINS_SZ,
				DDR_WINDOW_CPU0_BASE, DDR_WINDOW_CPU_SZ);
	else
		mvebu_mbus_init("marvell,mv78xx0-mbus",
				BRIDGE_WINS_CPU1_BASE, BRIDGE_WINS_SZ,
				DDR_WINDOW_CPU1_BASE, DDR_WINDOW_CPU_SZ);
}

void __ref mv78xx0_timer_init(void)
{
	orion_time_init(BRIDGE_VIRT_BASE, BRIDGE_INT_TIMER1_CLR,
			IRQ_MV78XX0_TIMER_1, get_tclk());
}

/*****************************************************************************
 * General
 ****************************************************************************/
static char * __init mv78xx0_id(void)
{
	u32 dev, rev;

	mv78xx0_pcie_id(&dev, &rev);

	if (dev == MV78X00_Z0_DEV_ID) {
		if (rev == MV78X00_REV_Z0)
			return "MV78X00-Z0";
		else
			return "MV78X00-Rev-Unsupported";
	} else if (dev == MV78100_DEV_ID) {
		if (rev == MV78100_REV_A0)
			return "MV78100-A0";
		else if (rev == MV78100_REV_A1)
			return "MV78100-A1";
		else
			return "MV78100-Rev-Unsupported";
	} else if (dev == MV78200_DEV_ID) {
		if (rev == MV78100_REV_A0)
			return "MV78200-A0";
		else
			return "MV78200-Rev-Unsupported";
	} else {
		return "Device-Unknown";
	}
}

static int __init is_l2_writethrough(void)
{
	return !!(readl(CPU_CONTROL) & L2_WRITETHROUGH);
}

void __init mv78xx0_init(void)
{
	int core_index;
	int hclk;
	int pclk;
	int l2clk;

	core_index = mv78xx0_core_index();
	hclk = get_hclk();
	get_pclk_l2clk(hclk, core_index, &pclk, &l2clk);

	printk(KERN_INFO "%s ", mv78xx0_id());
	printk("core #%d, ", core_index);
	printk("PCLK = %dMHz, ", (pclk + 499999) / 1000000);
	printk("L2 = %dMHz, ", (l2clk + 499999) / 1000000);
	printk("HCLK = %dMHz, ", (hclk + 499999) / 1000000);
	printk("TCLK = %dMHz\n", (get_tclk() + 499999) / 1000000);

	if (IS_ENABLED(CONFIG_CACHE_FEROCEON_L2))
		feroceon_l2_init(is_l2_writethrough());

	/* Setup root of clk tree */
	clk_init();
}

void mv78xx0_restart(enum reboot_mode mode, const char *cmd)
{
	/*
	 * Enable soft reset to assert RSTOUTn.
	 */
	writel(SOFT_RESET_OUT_EN, RSTOUTn_MASK);

	/*
	 * Assert soft reset.
	 */
	writel(SOFT_RESET, SYSTEM_SOFT_RESET);

	while (1)
		;
}


code:
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * arch/arm/mach-mv78xx0/common.h
 *
 * Core functions for Marvell MV78xx0 SoCs
 */

#ifndef __ARCH_MV78XX0_COMMON_H
#define __ARCH_MV78XX0_COMMON_H

#include <linux/reboot.h>

struct mv643xx_eth_platform_data;
struct mv_sata_platform_data;

/*
 * Basic MV78xx0 init functions used early by machine-setup.
 */
int mv78xx0_core_index(void);
void mv78xx0_map_io(void);
void mv78xx0_init(void);
void mv78xx0_init_early(void);
void mv78xx0_init_irq(void);

void mv78xx0_setup_cpu_mbus(void);
void mv78xx0_setup_pcie_io_win(int window, u32 base, u32 size,
			       int maj, int min);
void mv78xx0_setup_pcie_mem_win(int window, u32 base, u32 size,
				int maj, int min);

void mv78xx0_pcie_id(u32 *dev, u32 *rev);

void mv78xx0_ehci0_init(void);
void mv78xx0_ehci1_init(void);
void mv78xx0_ehci2_init(void);
void mv78xx0_ge00_init(struct mv643xx_eth_platform_data *eth_data);
void mv78xx0_ge01_init(struct mv643xx_eth_platform_data *eth_data);
void mv78xx0_ge10_init(struct mv643xx_eth_platform_data *eth_data);
void mv78xx0_ge11_init(struct mv643xx_eth_platform_data *eth_data);
void mv78xx0_pcie_init(int init_port0, int init_port1);
void mv78xx0_sata_init(struct mv_sata_platform_data *sata_data);
void mv78xx0_uart0_init(void);
void mv78xx0_uart1_init(void);
void mv78xx0_uart2_init(void);
void mv78xx0_uart3_init(void);
void mv78xx0_i2c_init(void);
void mv78xx0_restart(enum reboot_mode, const char *);

extern void mv78xx0_timer_init(void);

#endif


code:
// SPDX-License-Identifier: GPL-2.0-only
/*
 * arch/arm/mach-mv78xx0/db78x00-bp-setup.c
 *
 * Marvell DB-78x00-BP Development Board Setup
 */

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/ata_platform.h>
#include <linux/mv643xx_eth.h>
#include <linux/ethtool.h>
#include <linux/i2c.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include "mv78xx0.h"
#include "common.h"

static struct mv643xx_eth_platform_data db78x00_ge00_data = {
	.phy_addr	= MV643XX_ETH_PHY_ADDR(8),
};

static struct mv643xx_eth_platform_data db78x00_ge01_data = {
	.phy_addr	= MV643XX_ETH_PHY_ADDR(9),
};

static struct mv643xx_eth_platform_data db78x00_ge10_data = {
	.phy_addr	= MV643XX_ETH_PHY_ADDR(10),
};

static struct mv643xx_eth_platform_data db78x00_ge11_data = {
	.phy_addr	= MV643XX_ETH_PHY_ADDR(11),
};

static struct mv_sata_platform_data db78x00_sata_data = {
	.n_ports	= 2,
};

static struct i2c_board_info __initdata db78x00_i2c_rtc = {
	I2C_BOARD_INFO("ds1338", 0x68),
};

static void __init db78x00_init(void)
{
	/*
	 * Basic MV78xx0 setup. Needs to be called early.
	 */
	mv78xx0_init();

	/*
	 * Partition on-chip peripherals between the two CPU cores.
	 */
	if (mv78xx0_core_index() == 0) {
		mv78xx0_ehci0_init();
		mv78xx0_ehci1_init();
		mv78xx0_ehci2_init();
		mv78xx0_ge00_init(&db78x00_ge00_data);
		mv78xx0_ge01_init(&db78x00_ge01_data);
		mv78xx0_ge10_init(&db78x00_ge10_data);
		mv78xx0_ge11_init(&db78x00_ge11_data);
		mv78xx0_sata_init(&db78x00_sata_data);
		mv78xx0_uart0_init();
		mv78xx0_uart2_init();
		mv78xx0_i2c_init();
		i2c_register_board_info(0, &db78x00_i2c_rtc, 1);
	} else {
		mv78xx0_uart1_init();
		mv78xx0_uart3_init();
	}
}

static int __init db78x00_pci_init(void)
{
	if (machine_is_db78x00_bp()) {
		/*
		 * Assign the x16 PCIe slot on the board to CPU core
		 * #0, and let CPU core #1 have the four x1 slots.
		 */
		if (mv78xx0_core_index() == 0)
			mv78xx0_pcie_init(0, 1);
		else
			mv78xx0_pcie_init(1, 0);
	}

	return 0;
}
subsys_initcall(db78x00_pci_init);

MACHINE_START(DB78X00_BP, "Marvell DB-78x00-BP Development Board")
	/* Maintainer: Lennert Buytenhek <buytenh@marvell.com> */
	.atag_offset	= 0x100,
	.nr_irqs	= MV78XX0_NR_IRQS,
	.init_machine	= db78x00_init,
	.map_io		= mv78xx0_map_io,
	.init_early	= mv78xx0_init_early,
	.init_irq	= mv78xx0_init_irq,
	.init_time	= mv78xx0_timer_init,
	.restart	= mv78xx0_restart,
MACHINE_END


code:
// SPDX-License-Identifier: GPL-2.0-only
/*
 * arch/arm/mach-mv78xx0/irq.c
 *
 * MV78xx0 IRQ handling.
 */
#include <linux/gpio.h>
#include <linux/kernel.h>
#include <linux/irq.h>
#include <linux/io.h>
#include <asm/exception.h>
#include <plat/orion-gpio.h>
#include <plat/irq.h>
#include "bridge-regs.h"
#include "common.h"

static int __initdata gpio0_irqs[4] = {
	IRQ_MV78XX0_GPIO_0_7,
	IRQ_MV78XX0_GPIO_8_15,
	IRQ_MV78XX0_GPIO_16_23,
	IRQ_MV78XX0_GPIO_24_31,
};

static void __iomem *mv78xx0_irq_base = IRQ_VIRT_BASE;

static asmlinkage void
__exception_irq_entry mv78xx0_legacy_handle_irq(struct pt_regs *regs)
{
	u32 stat;

	stat = readl_relaxed(mv78xx0_irq_base + IRQ_CAUSE_LOW_OFF);
	stat &= readl_relaxed(mv78xx0_irq_base + IRQ_MASK_LOW_OFF);
	if (stat) {
		unsigned int hwirq = __fls(stat);
		handle_IRQ(hwirq, regs);
		return;
	}
	stat = readl_relaxed(mv78xx0_irq_base + IRQ_CAUSE_HIGH_OFF);
	stat &= readl_relaxed(mv78xx0_irq_base + IRQ_MASK_HIGH_OFF);
	if (stat) {
		unsigned int hwirq = 32 + __fls(stat);
		handle_IRQ(hwirq, regs);
		return;
	}
	stat = readl_relaxed(mv78xx0_irq_base + IRQ_CAUSE_ERR_OFF);
	stat &= readl_relaxed(mv78xx0_irq_base + IRQ_MASK_ERR_OFF);
	if (stat) {
		unsigned int hwirq = 64 + __fls(stat);
		handle_IRQ(hwirq, regs);
		return;
	}
}

void __init mv78xx0_init_irq(void)
{
	orion_irq_init(0, IRQ_VIRT_BASE + IRQ_MASK_LOW_OFF);
	orion_irq_init(32, IRQ_VIRT_BASE + IRQ_MASK_HIGH_OFF);
	orion_irq_init(64, IRQ_VIRT_BASE + IRQ_MASK_ERR_OFF);

	set_handle_irq(mv78xx0_legacy_handle_irq);

	/*
	 * Initialize gpiolib for GPIOs 0-31.  (The GPIO interrupt mask
	 * registers for core #1 are at an offset of 0x18 from those of
	 * core #0.)
	 */
	orion_gpio_init(0, 32, GPIO_VIRT_BASE, mv78xx0_core_index() ? 0x18 : 0,
			IRQ_MV78XX0_GPIO_START, gpio0_irqs);
}


code:
/* SPDX-License-Identifier: GPL-2.0-only */
/* IRQ definitions for Marvell MV78xx0 SoCs */

#ifndef __ASM_ARCH_IRQS_H
#define __ASM_ARCH_IRQS_H

/*
 * MV78xx0 Low Interrupt Controller
 */
#define IRQ_MV78XX0_ERR		0
#define IRQ_MV78XX0_SPI		1
#define IRQ_MV78XX0_I2C_0	2
#define IRQ_MV78XX0_I2C_1	3
#define IRQ_MV78XX0_IDMA_0	4
#define IRQ_MV78XX0_IDMA_1	5
#define IRQ_MV78XX0_IDMA_2	6
#define IRQ_MV78XX0_IDMA_3	7
#define IRQ_MV78XX0_TIMER_0	8
#define IRQ_MV78XX0_TIMER_1	9
#define IRQ_MV78XX0_TIMER_2	10
#define IRQ_MV78XX0_TIMER_3	11
#define IRQ_MV78XX0_UART_0	12
#define IRQ_MV78XX0_UART_1	13
#define IRQ_MV78XX0_UART_2	14
#define IRQ_MV78XX0_UART_3	15
#define IRQ_MV78XX0_USB_0	16
#define IRQ_MV78XX0_USB_1	17
#define IRQ_MV78XX0_USB_2	18
#define IRQ_MV78XX0_CRYPTO	19
#define IRQ_MV78XX0_SDIO_0	20
#define IRQ_MV78XX0_SDIO_1	21
#define IRQ_MV78XX0_XOR_0	22
#define IRQ_MV78XX0_XOR_1	23
#define IRQ_MV78XX0_I2S_0	24
#define IRQ_MV78XX0_I2S_1	25
#define IRQ_MV78XX0_SATA	26
#define IRQ_MV78XX0_TDMI	27

/*
 * MV78xx0 High Interrupt Controller
 */
#define IRQ_MV78XX0_PCIE_00	32
#define IRQ_MV78XX0_PCIE_01	33
#define IRQ_MV78XX0_PCIE_02	34
#define IRQ_MV78XX0_PCIE_03	35
#define IRQ_MV78XX0_PCIE_10	36
#define IRQ_MV78XX0_PCIE_11	37
#define IRQ_MV78XX0_PCIE_12	38
#define IRQ_MV78XX0_PCIE_13	39
#define IRQ_MV78XX0_GE00_SUM	40
#define IRQ_MV78XX0_GE00_RX	41
#define IRQ_MV78XX0_GE00_TX	42
#define IRQ_MV78XX0_GE00_MISC	43
#define IRQ_MV78XX0_GE01_SUM	44
#define IRQ_MV78XX0_GE01_RX	45
#define IRQ_MV78XX0_GE01_TX	46
#define IRQ_MV78XX0_GE01_MISC	47
#define IRQ_MV78XX0_GE10_SUM	48
#define IRQ_MV78XX0_GE10_RX	49
#define IRQ_MV78XX0_GE10_TX	50
#define IRQ_MV78XX0_GE10_MISC	51
#define IRQ_MV78XX0_GE11_SUM	52
#define IRQ_MV78XX0_GE11_RX	53
#define IRQ_MV78XX0_GE11_TX	54
#define IRQ_MV78XX0_GE11_MISC	55
#define IRQ_MV78XX0_GPIO_0_7	56
#define IRQ_MV78XX0_GPIO_8_15	57
#define IRQ_MV78XX0_GPIO_16_23	58
#define IRQ_MV78XX0_GPIO_24_31	59
#define IRQ_MV78XX0_DB_IN	60
#define IRQ_MV78XX0_DB_OUT	61

/*
 * MV78xx0 Error Interrupt Controller
 */
#define IRQ_MV78XX0_GE_ERR	70

/*
 * MV78XX0 General Purpose Pins
 */
#define IRQ_MV78XX0_GPIO_START	96
#define NR_GPIO_IRQS		32

#define MV78XX0_NR_IRQS		(IRQ_MV78XX0_GPIO_START + NR_GPIO_IRQS)

#endif


code:
// SPDX-License-Identifier: GPL-2.0-only
/*
 * arch/arm/mach-mv78x00/mpp.c
 *
 * MPP functions for Marvell MV78x00 SoCs
 */
#include <linux/gpio.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/io.h>
#include <plat/mpp.h>
#include "mv78xx0.h"
#include "common.h"
#include "mpp.h"

static unsigned int __init mv78xx0_variant(void)
{
	u32 dev, rev;

	mv78xx0_pcie_id(&dev, &rev);

	if (dev == MV78100_DEV_ID && rev >= MV78100_REV_A0)
		return MPP_78100_A0_MASK;

	printk(KERN_ERR "MPP setup: unknown mv78x00 variant "
			"(dev %#x rev %#x)\n", dev, rev);
	return 0;
}

void __init mv78xx0_mpp_conf(unsigned int *mpp_list)
{
	orion_mpp_conf(mpp_list, mv78xx0_variant(),
		       MPP_MAX, DEV_BUS_VIRT_BASE);
}


code:
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * linux/arch/arm/mach-mv78xx0/mpp.h -- Multi Purpose Pins
 *
 * sebastien requiem <sebastien@requiem.fr>
 */

#ifndef __MV78X00_MPP_H
#define __MV78X00_MPP_H

#define MPP(_num, _sel, _in, _out, _78100_A0) (\
    /* MPP number */        ((_num) & 0xff) | \
    /* MPP select value */        (((_sel) & 0xf) << 8) | \
    /* may be input signal */    ((!!(_in)) << 12) | \
    /* may be output signal */    ((!!(_out)) << 13) | \
    /* available on A0 */    ((!!(_78100_A0)) << 14))

                /*   num sel  i  o  78100_A0  */

#define MPP_78100_A0_MASK    MPP(0, 0x0, 0, 0, 1)

#define MPP0_GPIO        MPP(0, 0x0, 1, 1, 1)
#define MPP0_GE0_COL        MPP(0, 0x1, 0, 0, 1)
#define MPP0_GE1_TXCLK        MPP(0, 0x2, 0, 0, 1)
#define MPP0_UNUSED        MPP(0, 0x3, 0, 0, 1)

#define MPP1_GPIO        MPP(1, 0x0, 1, 1, 1)
#define MPP1_GE0_RXERR        MPP(1, 0x1, 0, 0, 1)
#define MPP1_GE1_TXCTL        MPP(1, 0x2, 0, 0, 1)
#define MPP1_UNUSED        MPP(1, 0x3, 0, 0, 1)

#define MPP2_GPIO        MPP(2, 0x0, 1, 1, 1)
#define MPP2_GE0_CRS        MPP(2, 0x1, 0, 0, 1)
#define MPP2_GE1_RXCTL        MPP(2, 0x2, 0, 0, 1)
#define MPP2_UNUSED        MPP(2, 0x3, 0, 0, 1)

#define MPP3_GPIO        MPP(3, 0x0, 1, 1, 1)
#define MPP3_GE0_TXERR        MPP(3, 0x1, 0, 0, 1)
#define MPP3_GE1_RXCLK        MPP(3, 0x2, 0, 0, 1)
#define MPP3_UNUSED        MPP(3, 0x3, 0, 0, 1)

#define MPP4_GPIO        MPP(4, 0x0, 1, 1, 1)
#define MPP4_GE0_TXD4        MPP(4, 0x1, 0, 0, 1)
#define MPP4_GE1_TXD0        MPP(4, 0x2, 0, 0, 1)
#define MPP4_UNUSED        MPP(4, 0x3, 0, 0, 1)

#define MPP5_GPIO        MPP(5, 0x0, 1, 1, 1)
#define MPP5_GE0_TXD5        MPP(5, 0x1, 0, 0, 1)
#define MPP5_GE1_TXD1        MPP(5, 0x2, 0, 0, 1)
#define MPP5_UNUSED        MPP(5, 0x3, 0, 0, 1)

#define MPP6_GPIO        MPP(6, 0x0, 1, 1, 1)
#define MPP6_GE0_TXD6        MPP(6, 0x1, 0, 0, 1)
#define MPP6_GE1_TXD2        MPP(6, 0x2, 0, 0, 1)
#define MPP6_UNUSED        MPP(6, 0x3, 0, 0, 1)

#define MPP7_GPIO        MPP(7, 0x0, 1, 1, 1)
#define MPP7_GE0_TXD7        MPP(7, 0x1, 0, 0, 1)
#define MPP7_GE1_TXD3        MPP(7, 0x2, 0, 0, 1)
#define MPP7_UNUSED        MPP(7, 0x3, 0, 0, 1)

#define MPP8_GPIO        MPP(8, 0x0, 1, 1, 1)
#define MPP8_GE0_RXD4        MPP(8, 0x1, 0, 0, 1)
#define MPP8_GE1_RXD0        MPP(8, 0x2, 0, 0, 1)
#define MPP8_UNUSED        MPP(8, 0x3, 0, 0, 1)

#define MPP9_GPIO        MPP(9, 0x0, 1, 1, 1)
#define MPP9_GE0_RXD5        MPP(9, 0x1, 0, 0, 1)
#define MPP9_GE1_RXD1        MPP(9, 0x2, 0, 0, 1)
#define MPP9_UNUSED        MPP(9, 0x3, 0, 0, 1)

#define MPP10_GPIO        MPP(10, 0x0, 1, 1, 1)
#define MPP10_GE0_RXD6        MPP(10, 0x1, 0, 0, 1)
#define MPP10_GE1_RXD2        MPP(10, 0x2, 0, 0, 1)
#define MPP10_UNUSED        MPP(10, 0x3, 0, 0, 1)

#define MPP11_GPIO        MPP(11, 0x0, 1, 1, 1)
#define MPP11_GE0_RXD7        MPP(11, 0x1, 0, 0, 1)
#define MPP11_GE1_RXD3        MPP(11, 0x2, 0, 0, 1)
#define MPP11_UNUSED        MPP(11, 0x3, 0, 0, 1)

#define MPP12_GPIO        MPP(12, 0x0, 1, 1, 1)
#define MPP12_M_BB        MPP(12, 0x3, 0, 0, 1)
#define MPP12_UA0_CTSn        MPP(12, 0x4, 0, 0, 1)
#define MPP12_NAND_FLASH_REn0    MPP(12, 0x5, 0, 0, 1)
#define MPP12_TDM0_SCSn        MPP(12, 0X6, 0, 0, 1)
#define MPP12_UNUSED        MPP(12, 0x1, 0, 0, 1)

#define MPP13_GPIO        MPP(13, 0x0, 1, 1, 1)
#define MPP13_SYSRST_OUTn    MPP(13, 0x3, 0, 0, 1)
#define MPP13_UA0_RTSn        MPP(13, 0x4, 0, 0, 1)
#define MPP13_NAN_FLASH_WEn0    MPP(13, 0x5, 0, 0, 1)
#define MPP13_TDM_SCLK        MPP(13, 0x6, 0, 0, 1)
#define MPP13_UNUSED        MPP(13, 0x1, 0, 0, 1)

#define MPP14_GPIO        MPP(14, 0x0, 1, 1, 1)
#define MPP14_SATA1_ACTn    MPP(14, 0x3, 0, 0, 1)
#define MPP14_UA1_CTSn        MPP(14, 0x4, 0, 0, 1)
#define MPP14_NAND_FLASH_REn1    MPP(14, 0x5, 0, 0, 1)
#define MPP14_TDM_SMOSI        MPP(14, 0x6, 0, 0, 1)
#define MPP14_UNUSED        MPP(14, 0x1, 0, 0, 1)

#define MPP15_GPIO        MPP(15, 0x0, 1, 1, 1)
#define MPP15_SATA0_ACTn    MPP(15, 0x3, 0, 0, 1)
#define MPP15_UA1_RTSn        MPP(15, 0x4, 0, 0, 1)
#define MPP15_NAND_FLASH_WEn1    MPP(15, 0x5, 0, 0, 1)
#define MPP15_TDM_SMISO        MPP(15, 0x6, 0, 0, 1)
#define MPP15_UNUSED        MPP(15, 0x1, 0, 0, 1)

#define MPP16_GPIO        MPP(16, 0x0, 1, 1, 1)
#define MPP16_SATA1_PRESENTn    MPP(16, 0x3, 0, 0, 1)
#define MPP16_UA2_TXD        MPP(16, 0x4, 0, 0, 1)
#define MPP16_NAND_FLASH_REn3    MPP(16, 0x5, 0, 0, 1)
#define MPP16_TDM_INTn        MPP(16, 0x6, 0, 0, 1)
#define MPP16_UNUSED        MPP(16, 0x1, 0, 0, 1)

#define MPP17_GPIO        MPP(17, 0x0, 1, 1, 1)
#define MPP17_SATA0_PRESENTn    MPP(17, 0x3, 0, 0, 1)
#define MPP17_UA2_RXD        MPP(17, 0x4, 0, 0, 1)
#define MPP17_NAND_FLASH_WEn3    MPP(17, 0x5, 0, 0, 1)
#define MPP17_TDM_RSTn        MPP(17, 0x6, 0, 0, 1)
#define MPP17_UNUSED        MPP(17, 0x1, 0, 0, 1)

#define MPP18_GPIO        MPP(18, 0x0, 1, 1, 1)
#define MPP18_UA0_CTSn        MPP(18, 0x4, 0, 0, 1)
#define MPP18_BOOT_FLASH_REn    MPP(18, 0x5, 0, 0, 1)
#define MPP18_UNUSED        MPP(18, 0x1, 0, 0, 1)

#define MPP19_GPIO        MPP(19, 0x0, 1, 1, 1)
#define MPP19_UA0_CTSn        MPP(19, 0x4, 0, 0, 1)
#define MPP19_BOOT_FLASH_WEn    MPP(19, 0x5, 0, 0, 1)
#define MPP19_UNUSED        MPP(19, 0x1, 0, 0, 1)

#define MPP20_GPIO        MPP(20, 0x0, 1, 1, 1)
#define MPP20_UA1_CTSs        MPP(20, 0x4, 0, 0, 1)
#define MPP20_TDM_PCLK        MPP(20, 0x6, 0, 0, 0)
#define MPP20_UNUSED        MPP(20, 0x1, 0, 0, 1)

#define MPP21_GPIO        MPP(21, 0x0, 1, 1, 1)
#define MPP21_UA1_CTSs        MPP(21, 0x4, 0, 0, 1)
#define MPP21_TDM_FSYNC        MPP(21, 0x6, 0, 0, 0)
#define MPP21_UNUSED        MPP(21, 0x1, 0, 0, 1)

#define MPP22_GPIO        MPP(22, 0x0, 1, 1, 1)
#define MPP22_UA3_TDX        MPP(22, 0x4, 0, 0, 1)
#define MPP22_NAND_FLASH_REn2    MPP(22, 0x5, 0, 0, 1)
#define MPP22_TDM_DRX        MPP(22, 0x6, 0, 0, 1)
#define MPP22_UNUSED        MPP(22, 0x1, 0, 0, 1)

#define MPP23_GPIO        MPP(23, 0x0, 1, 1, 1)
#define MPP23_UA3_RDX        MPP(23, 0x4, 0, 0, 1)
#define MPP23_NAND_FLASH_WEn2    MPP(23, 0x5, 0, 0, 1)
#define MPP23_TDM_DTX        MPP(23, 0x6, 0, 0, 1)
#define MPP23_UNUSED        MPP(23, 0x1, 0, 0, 1)

#define MPP24_GPIO        MPP(24, 0x0, 1, 1, 1)
#define MPP24_UA2_TXD        MPP(24, 0x4, 0, 0, 1)
#define MPP24_TDM_INTn        MPP(24, 0x6, 0, 0, 1)
#define MPP24_UNUSED        MPP(24, 0x1, 0, 0, 1)

#define MPP25_GPIO        MPP(25, 0x0, 1, 1, 1)
#define MPP25_UA2_RXD        MPP(25, 0x4, 0, 0, 1)
#define MPP25_TDM_RSTn        MPP(25, 0x6, 0, 0, 1)
#define MPP25_UNUSED        MPP(25, 0x1, 0, 0, 1)

#define MPP26_GPIO        MPP(26, 0x0, 1, 1, 1)
#define MPP26_UA2_CTSn        MPP(26, 0x4, 0, 0, 1)
#define MPP26_TDM_PCLK        MPP(26, 0x6, 0, 0, 1)
#define MPP26_UNUSED        MPP(26, 0x1, 0, 0, 1)

#define MPP27_GPIO        MPP(27, 0x0, 1, 1, 1)
#define MPP27_UA2_RTSn        MPP(27, 0x4, 0, 0, 1)
#define MPP27_TDM_FSYNC        MPP(27, 0x6, 0, 0, 1)
#define MPP27_UNUSED        MPP(27, 0x1, 0, 0, 1)

#define MPP28_GPIO        MPP(28, 0x0, 1, 1, 1)
#define MPP28_UA3_TXD        MPP(28, 0x4, 0, 0, 1)
#define MPP28_TDM_DRX        MPP(28, 0x6, 0, 0, 1)
#define MPP28_UNUSED        MPP(28, 0x1, 0, 0, 1)

#define MPP29_GPIO        MPP(29, 0x0, 1, 1, 1)
#define MPP29_UA3_RXD        MPP(29, 0x4, 0, 0, 1)
#define MPP29_SYSRST_OUTn    MPP(29, 0x5, 0, 0, 1)
#define MPP29_TDM_DTX        MPP(29, 0x6, 0, 0, 1)
#define MPP29_UNUSED        MPP(29, 0x1, 0, 0, 1)

#define MPP30_GPIO        MPP(30, 0x0, 1, 1, 1)
#define MPP30_UA3_CTSn        MPP(30, 0x4, 0, 0, 1)
#define MPP30_UNUSED        MPP(30, 0x1, 0, 0, 1)

#define MPP31_GPIO        MPP(31, 0x0, 1, 1, 1)
#define MPP31_UA3_RTSn        MPP(31, 0x4, 0, 0, 1)
#define MPP31_TDM1_SCSn        MPP(31, 0x6, 0, 0, 1)
#define MPP31_UNUSED        MPP(31, 0x1, 0, 0, 1)

#define MPP32_GPIO        MPP(32, 0x1, 1, 1, 1)
#define MPP32_UA3_TDX        MPP(32, 0x4, 0, 0, 1)
#define MPP32_SYSRST_OUTn    MPP(32, 0x5, 0, 0, 1)
#define MPP32_TDM0_RXQ        MPP(32, 0x6, 0, 0, 1)
#define MPP32_UNUSED        MPP(32, 0x3, 0, 0, 1)

#define MPP33_GPIO        MPP(33, 0x1, 1, 1, 1)
#define MPP33_UA3_RDX        MPP(33, 0x4, 0, 0, 1)
#define MPP33_TDM0_TXQ        MPP(33, 0x6, 0, 0, 1)
#define MPP33_UNUSED        MPP(33, 0x3, 0, 0, 1)

#define MPP34_GPIO        MPP(34, 0x1, 1, 1, 1)
#define MPP34_UA2_TDX        MPP(34, 0x4, 0, 0, 1)
#define MPP34_TDM1_RXQ        MPP(34, 0x6, 0, 0, 1)
#define MPP34_UNUSED        MPP(34, 0x3, 0, 0, 1)

#define MPP35_GPIO        MPP(35, 0x1, 1, 1, 1)
#define MPP35_UA2_RDX        MPP(35, 0x4, 0, 0, 1)
#define MPP35_TDM1_TXQ        MPP(35, 0x6, 0, 0, 1)
#define MPP35_UNUSED        MPP(35, 0x3, 0, 0, 1)

#define MPP36_GPIO        MPP(36, 0x1, 1, 1, 1)
#define MPP36_UA0_CTSn        MPP(36, 0x2, 0, 0, 1)
#define MPP36_UA2_TDX        MPP(36, 0x4, 0, 0, 1)
#define MPP36_TDM0_SCSn        MPP(36, 0x6, 0, 0, 1)
#define MPP36_UNUSED        MPP(36, 0x3, 0, 0, 1)

#define MPP37_GPIO        MPP(37, 0x1, 1, 1, 1)
#define MPP37_UA0_RTSn        MPP(37, 0x2, 0, 0, 1)
#define MPP37_UA2_RXD        MPP(37, 0x4, 0, 0, 1)
#define MPP37_SYSRST_OUTn    MPP(37, 0x5, 0, 0, 1)
#define MPP37_TDM_SCLK        MPP(37, 0x6, 0, 0, 1)
#define MPP37_UNUSED        MPP(37, 0x3, 0, 0, 1)

#define MPP38_GPIO        MPP(38, 0x1, 1, 1, 1)
#define MPP38_UA1_CTSn        MPP(38, 0x2, 0, 0, 1)
#define MPP38_UA3_TXD        MPP(38, 0x4, 0, 0, 1)
#define MPP38_SYSRST_OUTn    MPP(38, 0x5, 0, 0, 1)
#define MPP38_TDM_SMOSI        MPP(38, 0x6, 0, 0, 1)
#define MPP38_UNUSED        MPP(38, 0x3, 0, 0, 1)

#define MPP39_GPIO        MPP(39, 0x1, 1, 1, 1)
#define MPP39_UA1_RTSn        MPP(39, 0x2, 0, 0, 1)
#define MPP39_UA3_RXD        MPP(39, 0x4, 0, 0, 1)
#define MPP39_SYSRST_OUTn    MPP(39, 0x5, 0, 0, 1)
#define MPP39_TDM_SMISO        MPP(39, 0x6, 0, 0, 1)
#define MPP39_UNUSED        MPP(39, 0x3, 0, 0, 1)

#define MPP40_GPIO        MPP(40, 0x1, 1, 1, 1)
#define MPP40_TDM_INTn        MPP(40, 0x6, 0, 0, 1)
#define MPP40_UNUSED        MPP(40, 0x0, 0, 0, 1)

#define MPP41_GPIO        MPP(41, 0x1, 1, 1, 1)
#define MPP41_TDM_RSTn        MPP(41, 0x6, 0, 0, 1)
#define MPP41_UNUSED        MPP(41, 0x0, 0, 0, 1)

#define MPP42_GPIO        MPP(42, 0x1, 1, 1, 1)
#define MPP42_TDM_PCLK        MPP(42, 0x6, 0, 0, 1)
#define MPP42_UNUSED        MPP(42, 0x0, 0, 0, 1)

#define MPP43_GPIO        MPP(43, 0x1, 1, 1, 1)
#define MPP43_TDM_FSYNC        MPP(43, 0x6, 0, 0, 1)
#define MPP43_UNUSED        MPP(43, 0x0, 0, 0, 1)

#define MPP44_GPIO        MPP(44, 0x1, 1, 1, 1)
#define MPP44_TDM_DRX        MPP(44, 0x6, 0, 0, 1)
#define MPP44_UNUSED        MPP(44, 0x0, 0, 0, 1)

#define MPP45_GPIO        MPP(45, 0x1, 1, 1, 1)
#define MPP45_SATA0_ACTn    MPP(45, 0x3, 0, 0, 1)
#define MPP45_TDM_DRX        MPP(45, 0x6, 0, 0, 1)
#define MPP45_UNUSED        MPP(45, 0x0, 0, 0, 1)

#define MPP46_GPIO        MPP(46, 0x1, 1, 1, 1)
#define MPP46_TDM_SCSn        MPP(46, 0x6, 0, 0, 1)
#define MPP46_UNUSED        MPP(46, 0x0, 0, 0, 1)

#define MPP47_GPIO        MPP(47, 0x1, 1, 1, 1)
#define MPP47_UNUSED        MPP(47, 0x0, 0, 0, 1)

#define MPP48_GPIO        MPP(48, 0x1, 1, 1, 1)
#define MPP48_SATA1_ACTn    MPP(48, 0x3, 0, 0, 1)
#define MPP48_UNUSED        MPP(48, 0x2, 0, 0, 1)

#define MPP49_GPIO        MPP(49, 0x1, 1, 1, 1)
#define MPP49_SATA0_ACTn    MPP(49, 0x3, 0, 0, 1)
#define MPP49_M_BB        MPP(49, 0x4, 0, 0, 1)
#define MPP49_UNUSED        MPP(49, 0x2, 0, 0, 1)

#define MPP_MAX            49

void mv78xx0_mpp_conf(unsigned int *mpp_list);

#endif


code:
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Generic definitions for Marvell MV78xx0 SoC flavors:
 *  MV781x0 and MV782x0.
 */

#ifndef __ASM_ARCH_MV78XX0_H
#define __ASM_ARCH_MV78XX0_H

#include "irqs.h"

/*
 * Marvell MV78xx0 address maps.
 *
 * phys
 * c0000000	PCIe Memory space
 * f0800000	PCIe #0 I/O space
 * f0900000	PCIe #1 I/O space
 * f0a00000	PCIe #2 I/O space
 * f0b00000	PCIe #3 I/O space
 * f0c00000	PCIe #4 I/O space
 * f0d00000	PCIe #5 I/O space
 * f0e00000	PCIe #6 I/O space
 * f0f00000	PCIe #7 I/O space
 * f1000000	on-chip peripheral registers
 *
 * virt		phys		size
 * fe400000	f102x000	16K	core-specific peripheral registers
 * fee00000	f0800000	64K	PCIe #0 I/O space
 * fee10000	f0900000	64K	PCIe #1 I/O space
 * fee20000	f0a00000	64K	PCIe #2 I/O space
 * fee30000	f0b00000	64K	PCIe #3 I/O space
 * fee40000	f0c00000	64K	PCIe #4 I/O space
 * fee50000	f0d00000	64K	PCIe #5 I/O space
 * fee60000	f0e00000	64K	PCIe #6 I/O space
 * fee70000	f0f00000	64K	PCIe #7 I/O space
 * fec00000	f1000000	1M	on-chip peripheral registers
 */
#define MV78XX0_CORE0_REGS_PHYS_BASE	0xf1020000
#define MV78XX0_CORE1_REGS_PHYS_BASE	0xf1024000
#define MV78XX0_CORE_REGS_VIRT_BASE	IOMEM(0xfe400000)
#define MV78XX0_CORE_REGS_PHYS_BASE	0xfe400000
#define MV78XX0_CORE_REGS_SIZE		SZ_16K

#define MV78XX0_PCIE_IO_PHYS_BASE(i)	(0xf0800000 + ((i) << 20))
#define MV78XX0_PCIE_IO_SIZE		SZ_1M

#define MV78XX0_REGS_PHYS_BASE		0xf1000000
#define MV78XX0_REGS_VIRT_BASE		IOMEM(0xfec00000)
#define MV78XX0_REGS_SIZE		SZ_1M

#define MV78XX0_PCIE_MEM_PHYS_BASE	0xc0000000
#define MV78XX0_PCIE_MEM_SIZE		0x30000000

/*
 * Core-specific peripheral registers.
 */
#define BRIDGE_VIRT_BASE	(MV78XX0_CORE_REGS_VIRT_BASE)
#define BRIDGE_PHYS_BASE	(MV78XX0_CORE_REGS_PHYS_BASE)
#define  BRIDGE_WINS_CPU0_BASE  (MV78XX0_CORE0_REGS_PHYS_BASE)
#define  BRIDGE_WINS_CPU1_BASE  (MV78XX0_CORE1_REGS_PHYS_BASE)
#define  BRIDGE_WINS_SZ         (0xA000)

/*
 * Register Map
 */
#define DDR_VIRT_BASE		(MV78XX0_REGS_VIRT_BASE + 0x00000)
#define DDR_PHYS_BASE           (MV78XX0_REGS_PHYS_BASE + 0x00000)
#define  DDR_WINDOW_CPU0_BASE	(DDR_PHYS_BASE + 0x1500)
#define  DDR_WINDOW_CPU1_BASE	(DDR_PHYS_BASE + 0x1570)
#define  DDR_WINDOW_CPU_SZ      (0x20)

#define DEV_BUS_PHYS_BASE	(MV78XX0_REGS_PHYS_BASE + 0x10000)
#define DEV_BUS_VIRT_BASE	(MV78XX0_REGS_VIRT_BASE + 0x10000)
#define  SAMPLE_AT_RESET_LOW	(DEV_BUS_VIRT_BASE + 0x0030)
#define  SAMPLE_AT_RESET_HIGH	(DEV_BUS_VIRT_BASE + 0x0034)
#define  GPIO_VIRT_BASE		(DEV_BUS_VIRT_BASE + 0x0100)
#define  I2C_0_PHYS_BASE	(DEV_BUS_PHYS_BASE + 0x1000)
#define  I2C_1_PHYS_BASE	(DEV_BUS_PHYS_BASE + 0x1100)
#define  UART0_PHYS_BASE	(DEV_BUS_PHYS_BASE + 0x2000)
#define  UART0_VIRT_BASE	(DEV_BUS_VIRT_BASE + 0x2000)
#define  UART1_PHYS_BASE	(DEV_BUS_PHYS_BASE + 0x2100)
#define  UART1_VIRT_BASE	(DEV_BUS_VIRT_BASE + 0x2100)
#define  UART2_PHYS_BASE	(DEV_BUS_PHYS_BASE + 0x2200)
#define  UART2_VIRT_BASE	(DEV_BUS_VIRT_BASE + 0x2200)
#define  UART3_PHYS_BASE	(DEV_BUS_PHYS_BASE + 0x2300)
#define  UART3_VIRT_BASE	(DEV_BUS_VIRT_BASE + 0x2300)

#define GE10_PHYS_BASE		(MV78XX0_REGS_PHYS_BASE + 0x30000)
#define GE11_PHYS_BASE		(MV78XX0_REGS_PHYS_BASE + 0x34000)

#define PCIE00_VIRT_BASE	(MV78XX0_REGS_VIRT_BASE + 0x40000)
#define PCIE01_VIRT_BASE	(MV78XX0_REGS_VIRT_BASE + 0x44000)
#define PCIE02_VIRT_BASE	(MV78XX0_REGS_VIRT_BASE + 0x48000)
#define PCIE03_VIRT_BASE	(MV78XX0_REGS_VIRT_BASE + 0x4c000)

#define USB0_PHYS_BASE		(MV78XX0_REGS_PHYS_BASE + 0x50000)
#define USB1_PHYS_BASE		(MV78XX0_REGS_PHYS_BASE + 0x51000)
#define USB2_PHYS_BASE		(MV78XX0_REGS_PHYS_BASE + 0x52000)

#define GE00_PHYS_BASE		(MV78XX0_REGS_PHYS_BASE + 0x70000)
#define GE01_PHYS_BASE		(MV78XX0_REGS_PHYS_BASE + 0x74000)

#define PCIE10_VIRT_BASE	(MV78XX0_REGS_VIRT_BASE + 0x80000)
#define PCIE11_VIRT_BASE	(MV78XX0_REGS_VIRT_BASE + 0x84000)
#define PCIE12_VIRT_BASE	(MV78XX0_REGS_VIRT_BASE + 0x88000)
#define PCIE13_VIRT_BASE	(MV78XX0_REGS_VIRT_BASE + 0x8c000)

#define SATA_PHYS_BASE		(MV78XX0_REGS_PHYS_BASE + 0xa0000)

/*
 * Supported devices and revisions.
 */
#define MV78X00_Z0_DEV_ID	0x6381
#define MV78X00_REV_Z0		1

#define MV78100_DEV_ID		0x7810
#define MV78100_REV_A0		1
#define MV78100_REV_A1		2

#define MV78200_DEV_ID		0x7820
#define MV78200_REV_A0		1

#endif


code:
// SPDX-License-Identifier: GPL-2.0-only
/*
 * arch/arm/mach-mv78xx0/pcie.c
 *
 * PCIe functions for Marvell MV78xx0 SoCs
 */

#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/mbus.h>
#include <video/vga.h>
#include <asm/irq.h>
#include <asm/mach/pci.h>
#include <plat/pcie.h>
#include "mv78xx0.h"
#include "common.h"

#define MV78XX0_MBUS_PCIE_MEM_TARGET(port, lane) ((port) ? 8 : 4)
#define MV78XX0_MBUS_PCIE_MEM_ATTR(port, lane)   (0xf8 & ~(0x10 << (lane)))
#define MV78XX0_MBUS_PCIE_IO_TARGET(port, lane)  ((port) ? 8 : 4)
#define MV78XX0_MBUS_PCIE_IO_ATTR(port, lane)    (0xf0 & ~(0x10 << (lane)))

struct pcie_port {
	u8			maj;
	u8			min;
	u8			root_bus_nr;
	void __iomem		*base;
	spinlock_t		conf_lock;
	char			mem_space_name[20];
	struct resource		res;
};

static struct pcie_port pcie_port[8];
static int num_pcie_ports;
static struct resource pcie_io_space;

void __init mv78xx0_pcie_id(u32 *dev, u32 *rev)
{
	*dev = orion_pcie_dev_id(PCIE00_VIRT_BASE);
	*rev = orion_pcie_rev(PCIE00_VIRT_BASE);
}

u32 pcie_port_size[8] = {
	0,
	0x30000000,
	0x10000000,
	0x10000000,
	0x08000000,
	0x08000000,
	0x08000000,
	0x04000000,
};

static void __init mv78xx0_pcie_preinit(void)
{
	int i;
	u32 size_each;
	u32 start;

	pcie_io_space.name = "PCIe I/O Space";
	pcie_io_space.start = MV78XX0_PCIE_IO_PHYS_BASE(0);
	pcie_io_space.end =
		MV78XX0_PCIE_IO_PHYS_BASE(0) + MV78XX0_PCIE_IO_SIZE * 8 - 1;
	pcie_io_space.flags = IORESOURCE_MEM;
	if (request_resource(&iomem_resource, &pcie_io_space))
		panic("can't allocate PCIe I/O space");

	if (num_pcie_ports > 7)
		panic("invalid number of PCIe ports");

	size_each = pcie_port_size[num_pcie_ports];

	start = MV78XX0_PCIE_MEM_PHYS_BASE;
	for (i = 0; i < num_pcie_ports; i++) {
		struct pcie_port *pp = pcie_port + i;

		snprintf(pp->mem_space_name, sizeof(pp->mem_space_name),
			"PCIe %d.%d MEM", pp->maj, pp->min);
		pp->mem_space_name[sizeof(pp->mem_space_name) - 1] = 0;
		pp->res.name = pp->mem_space_name;
		pp->res.flags = IORESOURCE_MEM;
		pp->res.start = start;
		pp->res.end = start + size_each - 1;
		start += size_each;

		if (request_resource(&iomem_resource, &pp->res))
			panic("can't allocate PCIe MEM sub-space");

		mvebu_mbus_add_window_by_id(MV78XX0_MBUS_PCIE_MEM_TARGET(pp->maj, pp->min),
					    MV78XX0_MBUS_PCIE_MEM_ATTR(pp->maj, pp->min),
					    pp->res.start, resource_size(&pp->res));
		mvebu_mbus_add_window_remap_by_id(MV78XX0_MBUS_PCIE_IO_TARGET(pp->maj, pp->min),
						  MV78XX0_MBUS_PCIE_IO_ATTR(pp->maj, pp->min),
						  i * SZ_64K, SZ_64K, 0);
	}
}

static int __init mv78xx0_pcie_setup(int nr, struct pci_sys_data *sys)
{
	struct pcie_port *pp;
	struct resource realio;

	if (nr >= num_pcie_ports)
		return 0;

	pp = &pcie_port[nr];
	sys->private_data = pp;
	pp->root_bus_nr = sys->busnr;

	/*
	 * Generic PCIe unit setup.
	 */
	orion_pcie_set_local_bus_nr(pp->base, sys->busnr);
	orion_pcie_setup(pp->base);

	realio.start = nr * SZ_64K;
	realio.end = realio.start + SZ_64K - 1;
	pci_remap_iospace(&realio, MV78XX0_PCIE_IO_PHYS_BASE(nr));

	pci_add_resource_offset(&sys->resources, &pp->res, sys->mem_offset);

	return 1;
}

static int pcie_valid_config(struct pcie_port *pp, int bus, int dev)
{
	/*
	 * Don't go out when trying to access nonexisting devices
	 * on the local bus.
	 */
	if (bus == pp->root_bus_nr && dev > 1)
		return 0;

	return 1;
}

static int pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
			int size, u32 *val)
{
	struct pci_sys_data *sys = bus->sysdata;
	struct pcie_port *pp = sys->private_data;
	unsigned long flags;
	int ret;

	if (pcie_valid_config(pp, bus->number, PCI_SLOT(devfn)) == 0) {
		*val = 0xffffffff;
		return PCIBIOS_DEVICE_NOT_FOUND;
	}

	spin_lock_irqsave(&pp->conf_lock, flags);
	ret = orion_pcie_rd_conf(pp->base, bus, devfn, where, size, val);
	spin_unlock_irqrestore(&pp->conf_lock, flags);

	return ret;
}

static int pcie_wr_conf(struct pci_bus *bus, u32 devfn,
			int where, int size, u32 val)
{
	struct pci_sys_data *sys = bus->sysdata;
	struct pcie_port *pp = sys->private_data;
	unsigned long flags;
	int ret;

	if (pcie_valid_config(pp, bus->number, PCI_SLOT(devfn)) == 0)
		return PCIBIOS_DEVICE_NOT_FOUND;

	spin_lock_irqsave(&pp->conf_lock, flags);
	ret = orion_pcie_wr_conf(pp->base, bus, devfn, where, size, val);
	spin_unlock_irqrestore(&pp->conf_lock, flags);

	return ret;
}

static struct pci_ops pcie_ops = {
	.read = pcie_rd_conf,
	.write = pcie_wr_conf,
};

/*
 * The root complex has a hardwired class of PCI_CLASS_MEMORY_OTHER, when it
 * is operating as a root complex this needs to be switched to
 * PCI_CLASS_BRIDGE_HOST or Linux will errantly try to process the BAR's on
 * the device. Decoding setup is handled by the orion code.
 */
static void rc_pci_fixup(struct pci_dev *dev)
{
	if (dev->bus->parent == NULL && dev->devfn == 0) {
		int i;

		dev->class &= 0xff;
		dev->class |= PCI_CLASS_BRIDGE_HOST << 8;
		for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
			dev->resource[i].start = 0;
			dev->resource[i].end   = 0;
			dev->resource[i].flags = 0;
		}
	}
}
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL, PCI_ANY_ID, rc_pci_fixup);

static int __init mv78xx0_pcie_scan_bus(int nr, struct pci_host_bridge *bridge)
{
	struct pci_sys_data *sys = pci_host_bridge_priv(bridge);

	if (nr >= num_pcie_ports) {
		BUG();
		return -EINVAL;
	}

	list_splice_init(&sys->resources, &bridge->windows);
	bridge->dev.parent = NULL;
	bridge->sysdata = sys;
	bridge->busnr = sys->busnr;
	bridge->ops = &pcie_ops;

	return pci_scan_root_bus_bridge(bridge);
}

static int __init mv78xx0_pcie_map_irq(const struct pci_dev *dev, u8 slot,
	u8 pin)
{
	struct pci_sys_data *sys = dev->bus->sysdata;
	struct pcie_port *pp = sys->private_data;

	return IRQ_MV78XX0_PCIE_00 + (pp->maj << 2) + pp->min;
}

static struct hw_pci mv78xx0_pci __initdata = {
	.nr_controllers	= 8,
	.preinit	= mv78xx0_pcie_preinit,
	.setup		= mv78xx0_pcie_setup,
	.scan		= mv78xx0_pcie_scan_bus,
	.map_irq	= mv78xx0_pcie_map_irq,
};

static void __init add_pcie_port(int maj, int min, void __iomem *base)
{
	printk(KERN_INFO "MV78xx0 PCIe port %d.%d: ", maj, min);

	if (orion_pcie_link_up(base)) {
		struct pcie_port *pp = &pcie_port[num_pcie_ports++];

		printk("link up\n");

		pp->maj = maj;
		pp->min = min;
		pp->root_bus_nr = -1;
		pp->base = base;
		spin_lock_init(&pp->conf_lock);
		memset(&pp->res, 0, sizeof(pp->res));
	} else {
		printk("link down, ignoring\n");
	}
}

void __init mv78xx0_pcie_init(int init_port0, int init_port1)
{
	vga_base = MV78XX0_PCIE_MEM_PHYS_BASE;

	if (init_port0) {
		add_pcie_port(0, 0, PCIE00_VIRT_BASE);
		if (!orion_pcie_x4_mode(PCIE00_VIRT_BASE)) {
			add_pcie_port(0, 1, PCIE01_VIRT_BASE);
			add_pcie_port(0, 2, PCIE02_VIRT_BASE);
			add_pcie_port(0, 3, PCIE03_VIRT_BASE);
		}
	}

	if (init_port1) {
		add_pcie_port(1, 0, PCIE10_VIRT_BASE);
		if (!orion_pcie_x4_mode((void __iomem *)PCIE10_VIRT_BASE)) {
			add_pcie_port(1, 1, PCIE11_VIRT_BASE);
			add_pcie_port(1, 2, PCIE12_VIRT_BASE);
			add_pcie_port(1, 3, PCIE13_VIRT_BASE);
		}
	}

	pci_common_init(&mv78xx0_pci);
}


code:
// SPDX-License-Identifier: GPL-2.0-only
/*
 * arch/arm/mach-mv78x00/rd78x00-masa-setup.c
 *
 * Marvell RD-78x00-mASA Development Board Setup
 */

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/ata_platform.h>
#include <linux/mv643xx_eth.h>
#include <linux/ethtool.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include "mv78xx0.h"
#include "common.h"

static struct mv643xx_eth_platform_data rd78x00_masa_ge00_data = {
	.phy_addr	= MV643XX_ETH_PHY_ADDR(8),
};

static struct mv643xx_eth_platform_data rd78x00_masa_ge01_data = {
	.phy_addr	= MV643XX_ETH_PHY_ADDR(9),
};

static struct mv643xx_eth_platform_data rd78x00_masa_ge10_data = {
};

static struct mv643xx_eth_platform_data rd78x00_masa_ge11_data = {
};

static struct mv_sata_platform_data rd78x00_masa_sata_data = {
	.n_ports	= 2,
};

static void __init rd78x00_masa_init(void)
{
	/*
	 * Basic MV78x00 setup. Needs to be called early.
	 */
	mv78xx0_init();

	/*
	 * Partition on-chip peripherals between the two CPU cores.
	 */
	if (mv78xx0_core_index() == 0) {
		mv78xx0_ehci0_init();
		mv78xx0_ehci1_init();
		mv78xx0_ge00_init(&rd78x00_masa_ge00_data);
		mv78xx0_ge10_init(&rd78x00_masa_ge10_data);
		mv78xx0_sata_init(&rd78x00_masa_sata_data);
		mv78xx0_uart0_init();
		mv78xx0_uart2_init();
	} else {
		mv78xx0_ehci2_init();
		mv78xx0_ge01_init(&rd78x00_masa_ge01_data);
		mv78xx0_ge11_init(&rd78x00_masa_ge11_data);
		mv78xx0_uart1_init();
		mv78xx0_uart3_init();
	}
}

static int __init rd78x00_pci_init(void)
{
	/*
	 * Assign all PCIe devices to CPU core #0.
	 */
	if (machine_is_rd78x00_masa() && mv78xx0_core_index() == 0)
		mv78xx0_pcie_init(1, 1);

	return 0;
}
subsys_initcall(rd78x00_pci_init);

MACHINE_START(RD78X00_MASA, "Marvell RD-78x00-MASA Development Board")
	/* Maintainer: Lennert Buytenhek <buytenh@marvell.com> */
	.atag_offset	= 0x100,
	.nr_irqs	= MV78XX0_NR_IRQS,
	.init_machine	= rd78x00_masa_init,
	.map_io		= mv78xx0_map_io,
	.init_early	= mv78xx0_init_early,
	.init_irq	= mv78xx0_init_irq,
	.init_time	= mv78xx0_timer_init,
	.restart	= mv78xx0_restart,
MACHINE_END


code:
# SPDX-License-Identifier: GPL-2.0-only
menuconfig ARCH_MVEBU
	bool "Marvell Engineering Business Unit (MVEBU) SoCs"
	depends on ARCH_MULTI_V7 || (ARCH_MULTI_V5 && CPU_LITTLE_ENDIAN)
	select CLKSRC_MMIO
	select PINCTRL
	select PLAT_ORION
	select SOC_BUS
	select MVEBU_MBUS
	select ZONE_DMA if ARM_LPAE
	select GPIOLIB
	select PCI_QUIRKS if PCI

if ARCH_MVEBU

config MACH_MVEBU_ANY
	bool

config MACH_MVEBU_V7
	bool
	select ARMADA_370_XP_TIMER
	select CACHE_L2X0
	select ARM_CPU_SUSPEND
	select MACH_MVEBU_ANY
	select MVEBU_CLK_COREDIV

config MACH_ARMADA_370
	bool "Marvell Armada 370 boards"
	depends on ARCH_MULTI_V7
	select ARMADA_370_CLK
	select ARMADA_370_XP_IRQ
	select CPU_PJ4B
	select MACH_MVEBU_V7
	select PINCTRL_ARMADA_370
	help
	  Say 'Y' here if you want your kernel to support boards based
	  on the Marvell Armada 370 SoC with device tree.

config MACH_ARMADA_375
	bool "Marvell Armada 375 boards"
	depends on ARCH_MULTI_V7
	select ARMADA_370_XP_IRQ
	select ARM_ERRATA_720789
	select PL310_ERRATA_753970
	select ARM_GIC
	select ARMADA_375_CLK
	select HAVE_ARM_SCU
	select HAVE_ARM_TWD if SMP
	select MACH_MVEBU_V7
	select PINCTRL_ARMADA_375
	help
	  Say 'Y' here if you want your kernel to support boards based
	  on the Marvell Armada 375 SoC with device tree.

config MACH_ARMADA_38X
	bool "Marvell Armada 380/385 boards"
	depends on ARCH_MULTI_V7
	select ARM_ERRATA_720789
	select PL310_ERRATA_753970
	select ARM_GIC
	select ARM_GLOBAL_TIMER
	select CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK
	select ARMADA_370_XP_IRQ
	select ARMADA_38X_CLK
	select HAVE_ARM_SCU
	select HAVE_ARM_TWD if SMP
	select MACH_MVEBU_V7
	select PINCTRL_ARMADA_38X
	help
	  Say 'Y' here if you want your kernel to support boards based
	  on the Marvell Armada 380/385 SoC with device tree.

config MACH_ARMADA_39X
	bool "Marvell Armada 39x boards"
	depends on ARCH_MULTI_V7
	select ARM_GIC
	select ARMADA_370_XP_IRQ
	select ARMADA_39X_CLK
	select CACHE_L2X0
	select HAVE_ARM_SCU
	select HAVE_ARM_TWD if SMP
	select MACH_MVEBU_V7
	select PINCTRL_ARMADA_39X
	help
	  Say 'Y' here if you want your kernel to support boards based
	  on the Marvell Armada 39x SoC with device tree.

config MACH_ARMADA_XP
	bool "Marvell Armada XP boards"
	depends on ARCH_MULTI_V7
	select ARMADA_370_XP_IRQ
	select ARMADA_XP_CLK
	select CPU_PJ4B
	select MACH_MVEBU_V7
	select PINCTRL_ARMADA_XP
	help
	  Say 'Y' here if you want your kernel to support boards based
	  on the Marvell Armada XP SoC with device tree.

config MACH_DOVE
	bool "Marvell Dove boards"
	depends on ARCH_MULTI_V7
	select CACHE_L2X0
	select CPU_PJ4
	select DOVE_CLK
	select MACH_MVEBU_ANY
	select ORION_IRQCHIP
	select ORION_TIMER
	select PM_GENERIC_DOMAINS if PM
	select PINCTRL_DOVE
	help
	  Say 'Y' here if you want your kernel to support the
	  Marvell Dove using flattened device tree.

config MACH_KIRKWOOD
	bool "Marvell Kirkwood boards"
	depends on ARCH_MULTI_V5
	select CPU_FEROCEON
	select GPIOLIB
	select KIRKWOOD_CLK
	select MACH_MVEBU_ANY
	select ORION_IRQCHIP
	select ORION_TIMER
	select FORCE_PCI
	select PCI_QUIRKS
	select PINCTRL_KIRKWOOD
	help
	  Say 'Y' here if you want your kernel to support boards based
	  on the Marvell Kirkwood device tree.

endif

path: arch/arm/mach-mvebu/Kconfig


code:
# SPDX-License-Identifier: GPL-2.0
ccflags-y := -I$(srctree)/arch/arm/plat-orion/include

obj-$(CONFIG_MACH_MVEBU_ANY)	 += system-controller.o mvebu-soc-id.o

ifeq ($(CONFIG_MACH_MVEBU_V7),y)
obj-y				 += cpu-reset.o board-v7.o coherency.o coherency_ll.o pmsu.o pmsu_ll.o

obj-$(CONFIG_PM)		 += pm.o pm-board.o
obj-$(CONFIG_SMP)		 += platsmp.o headsmp.o platsmp-a9.o headsmp-a9.o
endif

obj-$(CONFIG_MACH_DOVE)		 += dove.o

ifeq ($(CONFIG_MACH_KIRKWOOD),y)
obj-y				 += kirkwood.o
obj-$(CONFIG_PM)		 += kirkwood-pm.o
endif

path: arch/arm/mach-mvebu/Makefile


code:
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Generic definitions for Marvell Armada_370_XP SoCs
 *
 * Copyright (C) 2012 Marvell
 *
 * Lior Amsalem <alior@marvell.com>
 * Gregory CLEMENT <gregory.clement@free-electrons.com>
 * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
 */

#ifndef __MACH_ARMADA_370_XP_H
#define __MACH_ARMADA_370_XP_H

#ifdef CONFIG_SMP
void armada_xp_secondary_startup(void);
extern const struct smp_operations armada_xp_smp_ops;
#endif

#endif /* __MACH_ARMADA_370_XP_H */


code:
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Device Tree support for Armada 370 and XP platforms.
 *
 * Copyright (C) 2012 Marvell
 *
 * Lior Amsalem <alior@marvell.com>
 * Gregory CLEMENT <gregory.clement@free-electrons.com>
 * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
 */

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/of_address.h>
#include <linux/of_fdt.h>
#include <linux/io.h>
#include <linux/clocksource.h>
#include <linux/dma-mapping.h>
#include <linux/memblock.h>
#include <linux/mbus.h>
#include <linux/slab.h>
#include <linux/irqchip.h>
#include <asm/hardware/cache-l2x0.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <asm/mach/time.h>
#include <asm/smp_scu.h>
#include "armada-370-xp.h"
#include "common.h"
#include "coherency.h"
#include "mvebu-soc-id.h"

static void __iomem *scu_base;

/*
 * Enables the SCU when available. Obviously, this is only useful on
 * Cortex-A based SOCs, not on PJ4B based ones.
 */
static void __init mvebu_scu_enable(void)
{
	struct device_node *np =
		of_find_compatible_node(NULL, NULL, "arm,cortex-a9-scu");
	if (np) {
		scu_base = of_iomap(np, 0);
		scu_enable(scu_base);
		of_node_put(np);
	}
}

void __iomem *mvebu_get_scu_base(void)
{
	return scu_base;
}

/*
 * When returning from suspend, the platform goes through the
 * bootloader, which executes its DDR3 training code. This code has
 * the unfortunate idea of using the first 10 KB of each DRAM bank to
 * exercise the RAM and calculate the optimal timings. Therefore, this
 * area of RAM is overwritten, and shouldn't be used by the kernel if
 * suspend/resume is supported.
 */

#ifdef CONFIG_SUSPEND
#define MVEBU_DDR_TRAINING_AREA_SZ (10 * SZ_1K)
static int __init mvebu_scan_mem(unsigned long node, const char *uname,
				 int depth, void *data)
{
	const char *type = of_get_flat_dt_prop(node, "device_type", NULL);
	const __be32 *reg, *endp;
	int l;

	if (type == NULL || strcmp(type, "memory"))
		return 0;

	reg = of_get_flat_dt_prop(node, "linux,usable-memory", &l);
	if (reg == NULL)
		reg = of_get_flat_dt_prop(node, "reg", &l);
	if (reg == NULL)
		return 0;

	endp = reg + (l / sizeof(__be32));
	while ((endp - reg) >= (dt_root_addr_cells + dt_root_size_cells)) {
		u64 base, size;

		base = dt_mem_next_cell(dt_root_addr_cells, &reg);
		size = dt_mem_next_cell(dt_root_size_cells, &reg);

		memblock_reserve(base, MVEBU_DDR_TRAINING_AREA_SZ);
	}

	return 0;
}

static void __init mvebu_memblock_reserve(void)
{
	of_scan_flat_dt(mvebu_scan_mem, NULL);
}
#else
static void __init mvebu_memblock_reserve(void) {}
#endif

static void __init mvebu_init_irq(void)
{
	irqchip_init();
	mvebu_scu_enable();
	coherency_init();
	BUG_ON(mvebu_mbus_dt_init(coherency_available()));
}

static void __init i2c_quirk(void)
{
	struct device_node *np;
	u32 dev, rev;

	/*
	 * Only revisons more recent than A0 support the offload
	 * mechanism. We can exit only if we are sure that we can
	 * get the SoC revision and it is more recent than A0.
	 */
	if (mvebu_get_soc_id(&dev, &rev) == 0 && rev > MV78XX0_A0_REV)
		return;

	for_each_compatible_node(np, NULL, "marvell,mv78230-i2c") {
		struct property *new_compat;

		new_compat = kzalloc(sizeof(*new_compat), GFP_KERNEL);

		new_compat->name = kstrdup("compatible", GFP_KERNEL);
		new_compat->length = sizeof("marvell,mv78230-a0-i2c");
		new_compat->value = kstrdup("marvell,mv78230-a0-i2c",
						GFP_KERNEL);

		of_update_property(np, new_compat);
	}
}

static void __init mvebu_dt_init(void)
{
	if (of_machine_is_compatible("marvell,armadaxp"))
		i2c_quirk();
}

static void __init armada_370_xp_dt_fixup(void)
{
#ifdef CONFIG_SMP
	smp_set_ops(smp_ops(armada_xp_smp_ops));
#endif
}

static const char * const armada_370_xp_dt_compat[] __initconst = {
	"marvell,armada-370-xp",
	NULL,
};

DT_MACHINE_START(ARMADA_370_XP_DT, "Marvell Armada 370/XP (Device Tree)")
	.l2c_aux_val	= 0,
	.l2c_aux_mask	= ~0,
	.init_machine	= mvebu_dt_init,
	.init_irq       = mvebu_init_irq,
	.restart	= mvebu_restart,
	.reserve        = mvebu_memblock_reserve,
	.dt_compat	= armada_370_xp_dt_compat,
	.dt_fixup	= armada_370_xp_dt_fixup,
MACHINE_END

static const char * const armada_375_dt_compat[] __initconst = {
	"marvell,armada375",
	NULL,
};

DT_MACHINE_START(ARMADA_375_DT, "Marvell Armada 375 (Device Tree)")
	.l2c_aux_val	= 0,
	.l2c_aux_mask	= ~0,
	.init_irq       = mvebu_init_irq,
	.init_machine	= mvebu_dt_init,
	.restart	= mvebu_restart,
	.dt_compat	= armada_375_dt_compat,
MACHINE_END

static const char * const armada_38x_dt_compat[] __initconst = {
	"marvell,armada380",
	"marvell,armada385",
	NULL,
};

DT_MACHINE_START(ARMADA_38X_DT, "Marvell Armada 380/385 (Device Tree)")
	.l2c_aux_val	= 0,
	.l2c_aux_mask	= ~0,
	.init_irq       = mvebu_init_irq,
	.restart	= mvebu_restart,
	.dt_compat	= armada_38x_dt_compat,
MACHINE_END

static const char * const armada_39x_dt_compat[] __initconst = {
	"marvell,armada390",
	"marvell,armada398",
	NULL,
};

DT_MACHINE_START(ARMADA_39X_DT, "Marvell Armada 39x (Device Tree)")
	.l2c_aux_val	= 0,
	.l2c_aux_mask	= ~0,
	.init_irq       = mvebu_init_irq,
	.restart	= mvebu_restart,
	.dt_compat	= armada_39x_dt_compat,
MACHINE_END