code:
// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * arch/arm/mach-lpc32xx/common.c
 *
 * Author: Kevin Wells <kevin.wells@nxp.com>
 *
 * Copyright (C) 2010 NXP Semiconductors
 */

#include <linux/init.h>
#include <linux/soc/nxp/lpc32xx-misc.h>

#include <asm/mach/map.h>
#include <asm/system_info.h>

#include "lpc32xx.h"
#include "common.h"

/*
 * Returns the unique ID for the device
 */
void lpc32xx_get_uid(u32 devid[4])
{
	int i;

	for (i = 0; i < 4; i++)
		devid[i] = __raw_readl(LPC32XX_CLKPWR_DEVID(i << 2));
}

/*
 * Detects and returns IRAM size for the device variation
 */
#define LPC32XX_IRAM_BANK_SIZE SZ_128K
static u32 iram_size;
u32 lpc32xx_return_iram(void __iomem **mapbase, dma_addr_t *dmaaddr)
{
	if (iram_size == 0) {
		u32 savedval1, savedval2;
		void __iomem *iramptr1, *iramptr2;

		iramptr1 = io_p2v(LPC32XX_IRAM_BASE);
		iramptr2 = io_p2v(LPC32XX_IRAM_BASE + LPC32XX_IRAM_BANK_SIZE);
		savedval1 = __raw_readl(iramptr1);
		savedval2 = __raw_readl(iramptr2);

		if (savedval1 == savedval2) {
			__raw_writel(savedval2 + 1, iramptr2);
			if (__raw_readl(iramptr1) == savedval2 + 1)
				iram_size = LPC32XX_IRAM_BANK_SIZE;
			else
				iram_size = LPC32XX_IRAM_BANK_SIZE * 2;
			__raw_writel(savedval2, iramptr2);
		} else
			iram_size = LPC32XX_IRAM_BANK_SIZE * 2;
	}
	if (dmaaddr)
		*dmaaddr = LPC32XX_IRAM_BASE;
	if (mapbase)
		*mapbase = io_p2v(LPC32XX_IRAM_BASE);

	return iram_size;
}
EXPORT_SYMBOL_GPL(lpc32xx_return_iram);

void lpc32xx_set_phy_interface_mode(phy_interface_t mode)
{
	u32 tmp = __raw_readl(LPC32XX_CLKPWR_MACCLK_CTRL);
	tmp &= ~LPC32XX_CLKPWR_MACCTRL_PINS_MSK;
	if (mode == PHY_INTERFACE_MODE_MII)
		tmp |= LPC32XX_CLKPWR_MACCTRL_USE_MII_PINS;
	else
		tmp |= LPC32XX_CLKPWR_MACCTRL_USE_RMII_PINS;
	__raw_writel(tmp, LPC32XX_CLKPWR_MACCLK_CTRL);
}
EXPORT_SYMBOL_GPL(lpc32xx_set_phy_interface_mode);

static struct map_desc lpc32xx_io_desc[] __initdata = {
	{
		.virtual	= (unsigned long)IO_ADDRESS(LPC32XX_AHB0_START),
		.pfn		= __phys_to_pfn(LPC32XX_AHB0_START),
		.length		= LPC32XX_AHB0_SIZE,
		.type		= MT_DEVICE
	},
	{
		.virtual	= (unsigned long)IO_ADDRESS(LPC32XX_AHB1_START),
		.pfn		= __phys_to_pfn(LPC32XX_AHB1_START),
		.length		= LPC32XX_AHB1_SIZE,
		.type		= MT_DEVICE
	},
	{
		.virtual	= (unsigned long)IO_ADDRESS(LPC32XX_FABAPB_START),
		.pfn		= __phys_to_pfn(LPC32XX_FABAPB_START),
		.length		= LPC32XX_FABAPB_SIZE,
		.type		= MT_DEVICE
	},
	{
		.virtual	= (unsigned long)IO_ADDRESS(LPC32XX_IRAM_BASE),
		.pfn		= __phys_to_pfn(LPC32XX_IRAM_BASE),
		.length		= (LPC32XX_IRAM_BANK_SIZE * 2),
		.type		= MT_DEVICE
	},
};

void __init lpc32xx_map_io(void)
{
	iotable_init(lpc32xx_io_desc, ARRAY_SIZE(lpc32xx_io_desc));
}

static int __init lpc32xx_check_uid(void)
{
	u32 uid[4];

	lpc32xx_get_uid(uid);

	printk(KERN_INFO "LPC32XX unique ID: %08x%08x%08x%08x\n",
		uid[3], uid[2], uid[1], uid[0]);

	if (!system_serial_low && !system_serial_high) {
		system_serial_low = uid[0];
		system_serial_high = uid[1];
	}

	return 1;
}
arch_initcall(lpc32xx_check_uid);


code:
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
 * arch/arm/mach-lpc32xx/common.h
 *
 * Author: Kevin Wells <kevin.wells@nxp.com>
 *
 * Copyright (C) 2009-2010 NXP Semiconductors
 */

#ifndef __LPC32XX_COMMON_H
#define __LPC32XX_COMMON_H

#include <linux/init.h>

/*
 * Other arch specific structures and functions
 */
extern void __init lpc32xx_map_io(void);
extern void __init lpc32xx_serial_init(void);

/*
 * Returns the LPC32xx unique 128-bit chip ID
 */
extern void lpc32xx_get_uid(u32 devid[4]);

/*
 * Pointers used for sizing and copying suspend function data
 */
extern int lpc32xx_sys_suspend(void);
extern int lpc32xx_sys_suspend_sz;

#endif

repo_name: angery/linux


code:
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
 * arch/arm/mach-lpc32xx/include/mach/platform.h
 *
 * Author: Kevin Wells <kevin.wells@nxp.com>
 *
 * Copyright (C) 2010 NXP Semiconductors
 */

#ifndef __ARM_LPC32XX_H
#define __ARM_LPC32XX_H

#define _SBF(f, v)				((v) << (f))
#define _BIT(n)					_SBF(n, 1)

/*
 * AHB 0 physical base addresses
 */
#define LPC32XX_SLC_BASE			0x20020000
#define LPC32XX_SSP0_BASE			0x20084000
#define LPC32XX_SPI1_BASE			0x20088000
#define LPC32XX_SSP1_BASE			0x2008C000
#define LPC32XX_SPI2_BASE			0x20090000
#define LPC32XX_I2S0_BASE			0x20094000
#define LPC32XX_SD_BASE				0x20098000
#define LPC32XX_I2S1_BASE			0x2009C000
#define LPC32XX_MLC_BASE			0x200A8000
#define LPC32XX_AHB0_START			LPC32XX_SLC_BASE
#define LPC32XX_AHB0_SIZE			0x00089000

/*
 * AHB 1 physical base addresses
 */
#define LPC32XX_DMA_BASE			0x31000000
#define LPC32XX_USB_BASE			0x31020000
#define LPC32XX_USBH_BASE			0x31020000
#define LPC32XX_USB_OTG_BASE			0x31020000
#define LPC32XX_OTG_I2C_BASE			0x31020300
#define LPC32XX_LCD_BASE			0x31040000
#define LPC32XX_ETHERNET_BASE			0x31060000
#define LPC32XX_EMC_BASE			0x31080000
#define LPC32XX_ETB_CFG_BASE			0x310C0000
#define LPC32XX_ETB_DATA_BASE			0x310E0000
#define LPC32XX_AHB1_START			LPC32XX_DMA_BASE
#define LPC32XX_AHB1_SIZE			0x000E1000

/*
 * FAB physical base addresses
 */
#define LPC32XX_CLK_PM_BASE			0x40004000
#define LPC32XX_MIC_BASE			0x40008000
#define LPC32XX_SIC1_BASE			0x4000C000
#define LPC32XX_SIC2_BASE			0x40010000
#define LPC32XX_HS_UART1_BASE			0x40014000
#define LPC32XX_HS_UART2_BASE			0x40018000
#define LPC32XX_HS_UART7_BASE			0x4001C000
#define LPC32XX_RTC_BASE			0x40024000
#define LPC32XX_RTC_RAM_BASE			0x40024080
#define LPC32XX_GPIO_BASE			0x40028000
#define LPC32XX_PWM3_BASE			0x4002C000
#define LPC32XX_PWM4_BASE			0x40030000
#define LPC32XX_MSTIM_BASE			0x40034000
#define LPC32XX_HSTIM_BASE			0x40038000
#define LPC32XX_WDTIM_BASE			0x4003C000
#define LPC32XX_DEBUG_CTRL_BASE			0x40040000
#define LPC32XX_TIMER0_BASE			0x40044000
#define LPC32XX_ADC_BASE			0x40048000
#define LPC32XX_TIMER1_BASE			0x4004C000
#define LPC32XX_KSCAN_BASE			0x40050000
#define LPC32XX_UART_CTRL_BASE			0x40054000
#define LPC32XX_TIMER2_BASE			0x40058000
#define LPC32XX_PWM1_BASE			0x4005C000
#define LPC32XX_PWM2_BASE			0x4005C004
#define LPC32XX_TIMER3_BASE			0x40060000

/*
 * APB physical base addresses
 */
#define LPC32XX_UART3_BASE			0x40080000
#define LPC32XX_UART4_BASE			0x40088000
#define LPC32XX_UART5_BASE			0x40090000
#define LPC32XX_UART6_BASE			0x40098000
#define LPC32XX_I2C1_BASE			0x400A0000
#define LPC32XX_I2C2_BASE			0x400A8000

/*
 * FAB and APB base and sizing
 */
#define LPC32XX_FABAPB_START			LPC32XX_CLK_PM_BASE
#define LPC32XX_FABAPB_SIZE			0x000A5000

/*
 * Internal memory bases and sizes
 */
#define LPC32XX_IRAM_BASE			0x08000000
#define LPC32XX_IROM_BASE			0x0C000000

/*
 * External Static Memory Bank Address Space Bases
 */
#define LPC32XX_EMC_CS0_BASE			0xE0000000
#define LPC32XX_EMC_CS1_BASE			0xE1000000
#define LPC32XX_EMC_CS2_BASE			0xE2000000
#define LPC32XX_EMC_CS3_BASE			0xE3000000

/*
 * External SDRAM Memory Bank Address Space Bases
 */
#define LPC32XX_EMC_DYCS0_BASE			0x80000000
#define LPC32XX_EMC_DYCS1_BASE			0xA0000000

/*
 * Clock and crystal information
 */
#define LPC32XX_MAIN_OSC_FREQ			13000000
#define LPC32XX_CLOCK_OSC_FREQ			32768

/*
 * Clock and Power control register offsets
 */
#define _PMREG(x)				io_p2v(LPC32XX_CLK_PM_BASE +\
						(x))
#define LPC32XX_CLKPWR_DEBUG_CTRL		_PMREG(0x000)
#define LPC32XX_CLKPWR_BOOTMAP			_PMREG(0x014)
#define LPC32XX_CLKPWR_P01_ER			_PMREG(0x018)
#define LPC32XX_CLKPWR_USBCLK_PDIV		_PMREG(0x01C)
#define LPC32XX_CLKPWR_INT_ER			_PMREG(0x020)
#define LPC32XX_CLKPWR_INT_RS			_PMREG(0x024)
#define LPC32XX_CLKPWR_INT_SR			_PMREG(0x028)
#define LPC32XX_CLKPWR_INT_AP			_PMREG(0x02C)
#define LPC32XX_CLKPWR_PIN_ER			_PMREG(0x030)
#define LPC32XX_CLKPWR_PIN_RS			_PMREG(0x034)
#define LPC32XX_CLKPWR_PIN_SR			_PMREG(0x038)
#define LPC32XX_CLKPWR_PIN_AP			_PMREG(0x03C)
#define LPC32XX_CLKPWR_HCLK_DIV			_PMREG(0x040)
#define LPC32XX_CLKPWR_PWR_CTRL			_PMREG(0x044)
#define LPC32XX_CLKPWR_PLL397_CTRL		_PMREG(0x048)
#define LPC32XX_CLKPWR_MAIN_OSC_CTRL		_PMREG(0x04C)
#define LPC32XX_CLKPWR_SYSCLK_CTRL		_PMREG(0x050)
#define LPC32XX_CLKPWR_LCDCLK_CTRL		_PMREG(0x054)
#define LPC32XX_CLKPWR_HCLKPLL_CTRL		_PMREG(0x058)
#define LPC32XX_CLKPWR_ADC_CLK_CTRL_1		_PMREG(0x060)
#define LPC32XX_CLKPWR_USB_CTRL			_PMREG(0x064)
#define LPC32XX_CLKPWR_SDRAMCLK_CTRL		_PMREG(0x068)
#define LPC32XX_CLKPWR_DDR_LAP_NOM		_PMREG(0x06C)
#define LPC32XX_CLKPWR_DDR_LAP_COUNT		_PMREG(0x070)
#define LPC32XX_CLKPWR_DDR_LAP_DELAY		_PMREG(0x074)
#define LPC32XX_CLKPWR_SSP_CLK_CTRL		_PMREG(0x078)
#define LPC32XX_CLKPWR_I2S_CLK_CTRL		_PMREG(0x07C)
#define LPC32XX_CLKPWR_MS_CTRL			_PMREG(0x080)
#define LPC32XX_CLKPWR_MACCLK_CTRL		_PMREG(0x090)
#define LPC32XX_CLKPWR_TEST_CLK_SEL		_PMREG(0x0A4)
#define LPC32XX_CLKPWR_SFW_INT			_PMREG(0x0A8)
#define LPC32XX_CLKPWR_I2C_CLK_CTRL		_PMREG(0x0AC)
#define LPC32XX_CLKPWR_KEY_CLK_CTRL		_PMREG(0x0B0)
#define LPC32XX_CLKPWR_ADC_CLK_CTRL		_PMREG(0x0B4)
#define LPC32XX_CLKPWR_PWM_CLK_CTRL		_PMREG(0x0B8)
#define LPC32XX_CLKPWR_TIMER_CLK_CTRL		_PMREG(0x0BC)
#define LPC32XX_CLKPWR_TIMERS_PWMS_CLK_CTRL_1	_PMREG(0x0C0)
#define LPC32XX_CLKPWR_SPI_CLK_CTRL		_PMREG(0x0C4)
#define LPC32XX_CLKPWR_NAND_CLK_CTRL		_PMREG(0x0C8)
#define LPC32XX_CLKPWR_UART3_CLK_CTRL		_PMREG(0x0D0)
#define LPC32XX_CLKPWR_UART4_CLK_CTRL		_PMREG(0x0D4)
#define LPC32XX_CLKPWR_UART5_CLK_CTRL		_PMREG(0x0D8)
#define LPC32XX_CLKPWR_UART6_CLK_CTRL		_PMREG(0x0DC)
#define LPC32XX_CLKPWR_IRDA_CLK_CTRL		_PMREG(0x0E0)
#define LPC32XX_CLKPWR_UART_CLK_CTRL		_PMREG(0x0E4)
#define LPC32XX_CLKPWR_DMA_CLK_CTRL		_PMREG(0x0E8)
#define LPC32XX_CLKPWR_AUTOCLOCK		_PMREG(0x0EC)
#define LPC32XX_CLKPWR_DEVID(x)			_PMREG(0x130 + (x))

/*
 * clkpwr_debug_ctrl register definitions
*/
#define LPC32XX_CLKPWR_VFP_CLOCK_ENABLE_BIT	_BIT(4)

/*
 * clkpwr_bootmap register definitions
 */
#define LPC32XX_CLKPWR_BOOTMAP_SEL_BIT		_BIT(1)

/*
 * clkpwr_start_gpio register bit definitions
 */
#define LPC32XX_CLKPWR_GPIOSRC_P1IO23_BIT	_BIT(31)
#define LPC32XX_CLKPWR_GPIOSRC_P1IO22_BIT	_BIT(30)
#define LPC32XX_CLKPWR_GPIOSRC_P1IO21_BIT	_BIT(29)
#define LPC32XX_CLKPWR_GPIOSRC_P1IO20_BIT	_BIT(28)
#define LPC32XX_CLKPWR_GPIOSRC_P1IO19_BIT	_BIT(27)
#define LPC32XX_CLKPWR_GPIOSRC_P1IO18_BIT	_BIT(26)
#define LPC32XX_CLKPWR_GPIOSRC_P1IO17_BIT	_BIT(25)
#define LPC32XX_CLKPWR_GPIOSRC_P1IO16_BIT	_BIT(24)
#define LPC32XX_CLKPWR_GPIOSRC_P1IO15_BIT	_BIT(23)
#define LPC32XX_CLKPWR_GPIOSRC_P1IO14_BIT	_BIT(22)
#define LPC32XX_CLKPWR_GPIOSRC_P1IO13_BIT	_BIT(21)
#define LPC32XX_CLKPWR_GPIOSRC_P1IO12_BIT	_BIT(20)
#define LPC32XX_CLKPWR_GPIOSRC_P1IO11_BIT	_BIT(19)
#define LPC32XX_CLKPWR_GPIOSRC_P1IO10_BIT	_BIT(18)
#define LPC32XX_CLKPWR_GPIOSRC_P1IO9_BIT	_BIT(17)
#define LPC32XX_CLKPWR_GPIOSRC_P1IO8_BIT	_BIT(16)
#define LPC32XX_CLKPWR_GPIOSRC_P1IO7_BIT	_BIT(15)
#define LPC32XX_CLKPWR_GPIOSRC_P1IO6_BIT	_BIT(14)
#define LPC32XX_CLKPWR_GPIOSRC_P1IO5_BIT	_BIT(13)
#define LPC32XX_CLKPWR_GPIOSRC_P1IO4_BIT	_BIT(12)
#define LPC32XX_CLKPWR_GPIOSRC_P1IO3_BIT	_BIT(11)
#define LPC32XX_CLKPWR_GPIOSRC_P1IO2_BIT	_BIT(10)
#define LPC32XX_CLKPWR_GPIOSRC_P1IO1_BIT	_BIT(9)
#define LPC32XX_CLKPWR_GPIOSRC_P1IO0_BIT	_BIT(8)
#define LPC32XX_CLKPWR_GPIOSRC_P0IO7_BIT	_BIT(7)
#define LPC32XX_CLKPWR_GPIOSRC_P0IO6_BIT	_BIT(6)
#define LPC32XX_CLKPWR_GPIOSRC_P0IO5_BIT	_BIT(5)
#define LPC32XX_CLKPWR_GPIOSRC_P0IO4_BIT	_BIT(4)
#define LPC32XX_CLKPWR_GPIOSRC_P0IO3_BIT	_BIT(3)
#define LPC32XX_CLKPWR_GPIOSRC_P0IO2_BIT	_BIT(2)
#define LPC32XX_CLKPWR_GPIOSRC_P0IO1_BIT	_BIT(1)
#define LPC32XX_CLKPWR_GPIOSRC_P0IO0_BIT	_BIT(0)

/*
 * clkpwr_usbclk_pdiv register definitions
 */
#define LPC32XX_CLKPWR_USBPDIV_PLL_MASK		0xF

/*
 * clkpwr_start_int, clkpwr_start_raw_sts_int, clkpwr_start_sts_int,
 * clkpwr_start_pol_int, register bit definitions
 */
#define LPC32XX_CLKPWR_INTSRC_ADC_BIT		_BIT(31)
#define LPC32XX_CLKPWR_INTSRC_TS_P_BIT		_BIT(30)
#define LPC32XX_CLKPWR_INTSRC_TS_AUX_BIT	_BIT(29)
#define LPC32XX_CLKPWR_INTSRC_USBAHNEEDCLK_BIT	_BIT(26)
#define LPC32XX_CLKPWR_INTSRC_MSTIMER_BIT	_BIT(25)
#define LPC32XX_CLKPWR_INTSRC_RTC_BIT		_BIT(24)
#define LPC32XX_CLKPWR_INTSRC_USBNEEDCLK_BIT	_BIT(23)
#define LPC32XX_CLKPWR_INTSRC_USB_BIT		_BIT(22)
#define LPC32XX_CLKPWR_INTSRC_I2C_BIT		_BIT(21)
#define LPC32XX_CLKPWR_INTSRC_USBOTGTIMER_BIT	_BIT(20)
#define LPC32XX_CLKPWR_INTSRC_USBATXINT_BIT	_BIT(19)
#define LPC32XX_CLKPWR_INTSRC_KEY_BIT		_BIT(16)
#define LPC32XX_CLKPWR_INTSRC_MAC_BIT		_BIT(7)
#define LPC32XX_CLKPWR_INTSRC_P0P1_BIT		_BIT(6)
#define LPC32XX_CLKPWR_INTSRC_GPIO_05_BIT	_BIT(5)
#define LPC32XX_CLKPWR_INTSRC_GPIO_04_BIT	_BIT(4)
#define LPC32XX_CLKPWR_INTSRC_GPIO_03_BIT	_BIT(3)
#define LPC32XX_CLKPWR_INTSRC_GPIO_02_BIT	_BIT(2)
#define LPC32XX_CLKPWR_INTSRC_GPIO_01_BIT	_BIT(1)
#define LPC32XX_CLKPWR_INTSRC_GPIO_00_BIT	_BIT(0)

/*
 * clkpwr_start_pin, clkpwr_start_raw_sts_pin, clkpwr_start_sts_pin,
 * clkpwr_start_pol_pin register bit definitions
 */
#define LPC32XX_CLKPWR_EXTSRC_U7_RX_BIT		_BIT(31)
#define LPC32XX_CLKPWR_EXTSRC_U7_HCTS_BIT	_BIT(30)
#define LPC32XX_CLKPWR_EXTSRC_U6_IRRX_BIT	_BIT(28)
#define LPC32XX_CLKPWR_EXTSRC_U5_RX_BIT		_BIT(26)
#define LPC32XX_CLKPWR_EXTSRC_GPI_28_BIT	_BIT(25)
#define LPC32XX_CLKPWR_EXTSRC_U3_RX_BIT		_BIT(24)
#define LPC32XX_CLKPWR_EXTSRC_U2_HCTS_BIT	_BIT(23)
#define LPC32XX_CLKPWR_EXTSRC_U2_RX_BIT		_BIT(22)
#define LPC32XX_CLKPWR_EXTSRC_U1_RX_BIT		_BIT(21)
#define LPC32XX_CLKPWR_EXTSRC_MSDIO_INT_BIT	_BIT(18)
#define LPC32XX_CLKPWR_EXTSRC_MSDIO_SRT_BIT	_BIT(17)
#define LPC32XX_CLKPWR_EXTSRC_GPI_06_BIT	_BIT(16)
#define LPC32XX_CLKPWR_EXTSRC_GPI_05_BIT	_BIT(15)
#define LPC32XX_CLKPWR_EXTSRC_GPI_04_BIT	_BIT(14)
#define LPC32XX_CLKPWR_EXTSRC_GPI_03_BIT	_BIT(13)
#define LPC32XX_CLKPWR_EXTSRC_GPI_02_BIT	_BIT(12)
#define LPC32XX_CLKPWR_EXTSRC_GPI_01_BIT	_BIT(11)
#define LPC32XX_CLKPWR_EXTSRC_GPI_00_BIT	_BIT(10)
#define LPC32XX_CLKPWR_EXTSRC_SYSCLKEN_BIT	_BIT(9)
#define LPC32XX_CLKPWR_EXTSRC_SPI1_DATIN_BIT	_BIT(8)
#define LPC32XX_CLKPWR_EXTSRC_GPI_07_BIT	_BIT(7)
#define LPC32XX_CLKPWR_EXTSRC_SPI2_DATIN_BIT	_BIT(6)
#define LPC32XX_CLKPWR_EXTSRC_GPI_19_BIT	_BIT(5)
#define LPC32XX_CLKPWR_EXTSRC_GPI_09_BIT	_BIT(4)
#define LPC32XX_CLKPWR_EXTSRC_GPI_08_BIT	_BIT(3)

/*
 * clkpwr_hclk_div register definitions
 */
#define LPC32XX_CLKPWR_HCLKDIV_DDRCLK_STOP	(0x0 << 7)
#define LPC32XX_CLKPWR_HCLKDIV_DDRCLK_NORM	(0x1 << 7)
#define LPC32XX_CLKPWR_HCLKDIV_DDRCLK_HALF	(0x2 << 7)
#define LPC32XX_CLKPWR_HCLKDIV_PCLK_DIV(n)	(((n) & 0x1F) << 2)
#define LPC32XX_CLKPWR_HCLKDIV_DIV_2POW(n)	((n) & 0x3)

/*
 * clkpwr_pwr_ctrl register definitions
 */
#define LPC32XX_CLKPWR_CTRL_FORCE_PCLK		_BIT(10)
#define LPC32XX_CLKPWR_SDRAM_SELF_RFSH		_BIT(9)
#define LPC32XX_CLKPWR_UPD_SDRAM_SELF_RFSH	_BIT(8)
#define LPC32XX_CLKPWR_AUTO_SDRAM_SELF_RFSH	_BIT(7)
#define LPC32XX_CLKPWR_HIGHCORE_STATE_BIT	_BIT(5)
#define LPC32XX_CLKPWR_SYSCLKEN_STATE_BIT	_BIT(4)
#define LPC32XX_CLKPWR_SYSCLKEN_GPIO_EN		_BIT(3)
#define LPC32XX_CLKPWR_SELECT_RUN_MODE		_BIT(2)
#define LPC32XX_CLKPWR_HIGHCORE_GPIO_EN		_BIT(1)
#define LPC32XX_CLKPWR_STOP_MODE_CTRL		_BIT(0)

/*
 * clkpwr_pll397_ctrl register definitions
 */
#define LPC32XX_CLKPWR_PLL397_MSLOCK_STS	_BIT(10)
#define LPC32XX_CLKPWR_PLL397_BYPASS		_BIT(9)
#define LPC32XX_CLKPWR_PLL397_BIAS_NORM		0x000
#define LPC32XX_CLKPWR_PLL397_BIAS_N12_5	0x040
#define LPC32XX_CLKPWR_PLL397_BIAS_N25		0x080
#define LPC32XX_CLKPWR_PLL397_BIAS_N37_5	0x0C0
#define LPC32XX_CLKPWR_PLL397_BIAS_P12_5	0x100
#define LPC32XX_CLKPWR_PLL397_BIAS_P25		0x140
#define LPC32XX_CLKPWR_PLL397_BIAS_P37_5	0x180
#define LPC32XX_CLKPWR_PLL397_BIAS_P50		0x1C0
#define LPC32XX_CLKPWR_PLL397_BIAS_MASK		0x1C0
#define LPC32XX_CLKPWR_SYSCTRL_PLL397_DIS	_BIT(1)
#define LPC32XX_CLKPWR_SYSCTRL_PLL397_STS	_BIT(0)

/*
 * clkpwr_main_osc_ctrl register definitions
 */
#define LPC32XX_CLKPWR_MOSC_ADD_CAP(n)		(((n) & 0x7F) << 2)
#define LPC32XX_CLKPWR_MOSC_CAP_MASK		(0x7F << 2)
#define LPC32XX_CLKPWR_TEST_MODE		_BIT(1)
#define LPC32XX_CLKPWR_MOSC_DISABLE		_BIT(0)

/*
 * clkpwr_sysclk_ctrl register definitions
 */
#define LPC32XX_CLKPWR_SYSCTRL_BP_TRIG(n)	(((n) & 0x3FF) << 2)
#define LPC32XX_CLKPWR_SYSCTRL_BP_MASK		(0x3FF << 2)
#define LPC32XX_CLKPWR_SYSCTRL_USEPLL397	_BIT(1)
#define LPC32XX_CLKPWR_SYSCTRL_SYSCLKMUX	_BIT(0)

/*
 * clkpwr_lcdclk_ctrl register definitions
 */
#define LPC32XX_CLKPWR_LCDCTRL_LCDTYPE_TFT12	0x000
#define LPC32XX_CLKPWR_LCDCTRL_LCDTYPE_TFT16	0x040
#define LPC32XX_CLKPWR_LCDCTRL_LCDTYPE_TFT15	0x080
#define LPC32XX_CLKPWR_LCDCTRL_LCDTYPE_TFT24	0x0C0
#define LPC32XX_CLKPWR_LCDCTRL_LCDTYPE_STN4M	0x100
#define LPC32XX_CLKPWR_LCDCTRL_LCDTYPE_STN8C	0x140
#define LPC32XX_CLKPWR_LCDCTRL_LCDTYPE_DSTN4M	0x180
#define LPC32XX_CLKPWR_LCDCTRL_LCDTYPE_DSTN8C	0x1C0
#define LPC32XX_CLKPWR_LCDCTRL_LCDTYPE_MSK	0x01C0
#define LPC32XX_CLKPWR_LCDCTRL_CLK_EN		0x020
#define LPC32XX_CLKPWR_LCDCTRL_SET_PSCALE(n)	((n - 1) & 0x1F)
#define LPC32XX_CLKPWR_LCDCTRL_PSCALE_MSK	0x001F

/*
 * clkpwr_hclkpll_ctrl register definitions
 */
#define LPC32XX_CLKPWR_HCLKPLL_POWER_UP		_BIT(16)
#define LPC32XX_CLKPWR_HCLKPLL_CCO_BYPASS	_BIT(15)
#define LPC32XX_CLKPWR_HCLKPLL_POSTDIV_BYPASS	_BIT(14)
#define LPC32XX_CLKPWR_HCLKPLL_FDBK_SEL_FCLK	_BIT(13)
#define LPC32XX_CLKPWR_HCLKPLL_POSTDIV_2POW(n)	(((n) & 0x3) << 11)
#define LPC32XX_CLKPWR_HCLKPLL_PREDIV_PLUS1(n)	(((n) & 0x3) << 9)
#define LPC32XX_CLKPWR_HCLKPLL_PLLM(n)		(((n) & 0xFF) << 1)
#define LPC32XX_CLKPWR_HCLKPLL_PLL_STS		_BIT(0)

/*
 * clkpwr_adc_clk_ctrl_1 register definitions
 */
#define LPC32XX_CLKPWR_ADCCTRL1_RTDIV(n)	(((n) & 0xFF) << 0)
#define LPC32XX_CLKPWR_ADCCTRL1_PCLK_SEL	_BIT(8)

/*
 * clkpwr_usb_ctrl register definitions
 */
#define LPC32XX_CLKPWR_USBCTRL_HCLK_EN		_BIT(24)
#define LPC32XX_CLKPWR_USBCTRL_USBI2C_EN	_BIT(23)
#define LPC32XX_CLKPWR_USBCTRL_USBDVND_EN	_BIT(22)
#define LPC32XX_CLKPWR_USBCTRL_USBHSTND_EN	_BIT(21)
#define LPC32XX_CLKPWR_USBCTRL_PU_ADD		(0x0 << 19)
#define LPC32XX_CLKPWR_USBCTRL_BUS_KEEPER	(0x1 << 19)
#define LPC32XX_CLKPWR_USBCTRL_PD_ADD		(0x3 << 19)
#define LPC32XX_CLKPWR_USBCTRL_CLK_EN2		_BIT(18)
#define LPC32XX_CLKPWR_USBCTRL_CLK_EN1		_BIT(17)
#define LPC32XX_CLKPWR_USBCTRL_PLL_PWRUP	_BIT(16)
#define LPC32XX_CLKPWR_USBCTRL_CCO_BYPASS	_BIT(15)
#define LPC32XX_CLKPWR_USBCTRL_POSTDIV_BYPASS	_BIT(14)
#define LPC32XX_CLKPWR_USBCTRL_FDBK_SEL_FCLK	_BIT(13)
#define LPC32XX_CLKPWR_USBCTRL_POSTDIV_2POW(n)	(((n) & 0x3) << 11)
#define LPC32XX_CLKPWR_USBCTRL_PREDIV_PLUS1(n)	(((n) & 0x3) << 9)
#define LPC32XX_CLKPWR_USBCTRL_FDBK_PLUS1(n)	(((n) & 0xFF) << 1)
#define LPC32XX_CLKPWR_USBCTRL_PLL_STS		_BIT(0)

/*
 * clkpwr_sdramclk_ctrl register definitions
 */
#define LPC32XX_CLKPWR_SDRCLK_FASTSLEW_CLK	_BIT(22)
#define LPC32XX_CLKPWR_SDRCLK_FASTSLEW		_BIT(21)
#define LPC32XX_CLKPWR_SDRCLK_FASTSLEW_DAT	_BIT(20)
#define LPC32XX_CLKPWR_SDRCLK_SW_DDR_RESET	_BIT(19)
#define LPC32XX_CLKPWR_SDRCLK_HCLK_DLY(n)	(((n) & 0x1F) << 14)
#define LPC32XX_CLKPWR_SDRCLK_DLY_ADDR_STS	_BIT(13)
#define LPC32XX_CLKPWR_SDRCLK_SENS_FACT(n)	(((n) & 0x7) << 10)
#define LPC32XX_CLKPWR_SDRCLK_USE_CAL		_BIT(9)
#define LPC32XX_CLKPWR_SDRCLK_DO_CAL		_BIT(8)
#define LPC32XX_CLKPWR_SDRCLK_CAL_ON_RTC	_BIT(7)
#define LPC32XX_CLKPWR_SDRCLK_DQS_DLY(n)	(((n) & 0x1F) << 2)
#define LPC32XX_CLKPWR_SDRCLK_USE_DDR		_BIT(1)
#define LPC32XX_CLKPWR_SDRCLK_CLK_DIS		_BIT(0)

/*
 * clkpwr_ssp_blk_ctrl register definitions
 */
#define LPC32XX_CLKPWR_SSPCTRL_DMA_SSP1RX	_BIT(5)
#define LPC32XX_CLKPWR_SSPCTRL_DMA_SSP1TX	_BIT(4)
#define LPC32XX_CLKPWR_SSPCTRL_DMA_SSP0RX	_BIT(3)
#define LPC32XX_CLKPWR_SSPCTRL_DMA_SSP0TX	_BIT(2)
#define LPC32XX_CLKPWR_SSPCTRL_SSPCLK1_EN	_BIT(1)
#define LPC32XX_CLKPWR_SSPCTRL_SSPCLK0_EN	_BIT(0)

/*
 * clkpwr_i2s_clk_ctrl register definitions
 */
#define LPC32XX_CLKPWR_I2SCTRL_I2S1_RX_FOR_TX	_BIT(6)
#define LPC32XX_CLKPWR_I2SCTRL_I2S1_TX_FOR_RX	_BIT(5)
#define LPC32XX_CLKPWR_I2SCTRL_I2S1_USE_DMA	_BIT(4)
#define LPC32XX_CLKPWR_I2SCTRL_I2S0_RX_FOR_TX	_BIT(3)
#define LPC32XX_CLKPWR_I2SCTRL_I2S0_TX_FOR_RX	_BIT(2)
#define LPC32XX_CLKPWR_I2SCTRL_I2SCLK1_EN	_BIT(1)
#define LPC32XX_CLKPWR_I2SCTRL_I2SCLK0_EN	_BIT(0)

/*
 * clkpwr_ms_ctrl register definitions
 */
#define LPC32XX_CLKPWR_MSCARD_MSDIO_PIN_DIS	_BIT(10)
#define LPC32XX_CLKPWR_MSCARD_MSDIO_PU_EN	_BIT(9)
#define LPC32XX_CLKPWR_MSCARD_MSDIO23_DIS	_BIT(8)
#define LPC32XX_CLKPWR_MSCARD_MSDIO1_DIS	_BIT(7)
#define LPC32XX_CLKPWR_MSCARD_MSDIO0_DIS	_BIT(6)
#define LPC32XX_CLKPWR_MSCARD_SDCARD_EN		_BIT(5)
#define LPC32XX_CLKPWR_MSCARD_SDCARD_DIV(n)	((n) & 0xF)

/*
 * clkpwr_macclk_ctrl register definitions
 */
#define LPC32XX_CLKPWR_MACCTRL_NO_ENET_PIS	0x00
#define LPC32XX_CLKPWR_MACCTRL_USE_MII_PINS	0x08
#define LPC32XX_CLKPWR_MACCTRL_USE_RMII_PINS	0x18
#define LPC32XX_CLKPWR_MACCTRL_PINS_MSK		0x18
#define LPC32XX_CLKPWR_MACCTRL_DMACLK_EN	_BIT(2)
#define LPC32XX_CLKPWR_MACCTRL_MMIOCLK_EN	_BIT(1)
#define LPC32XX_CLKPWR_MACCTRL_HRCCLK_EN	_BIT(0)

/*
 * clkpwr_test_clk_sel register definitions
 */
#define LPC32XX_CLKPWR_TESTCLK1_SEL_PERCLK	(0x0 << 5)
#define LPC32XX_CLKPWR_TESTCLK1_SEL_RTC		(0x1 << 5)
#define LPC32XX_CLKPWR_TESTCLK1_SEL_MOSC	(0x2 << 5)
#define LPC32XX_CLKPWR_TESTCLK1_SEL_MASK	(0x3 << 5)
#define LPC32XX_CLKPWR_TESTCLK_TESTCLK1_EN	_BIT(4)
#define LPC32XX_CLKPWR_TESTCLK2_SEL_HCLK	(0x0 << 1)
#define LPC32XX_CLKPWR_TESTCLK2_SEL_PERCLK	(0x1 << 1)
#define LPC32XX_CLKPWR_TESTCLK2_SEL_USBCLK	(0x2 << 1)
#define LPC32XX_CLKPWR_TESTCLK2_SEL_MOSC	(0x5 << 1)
#define LPC32XX_CLKPWR_TESTCLK2_SEL_PLL397	(0x7 << 1)
#define LPC32XX_CLKPWR_TESTCLK2_SEL_MASK	(0x7 << 1)
#define LPC32XX_CLKPWR_TESTCLK_TESTCLK2_EN	_BIT(0)

/*
 * clkpwr_sw_int register definitions
 */
#define LPC32XX_CLKPWR_SW_INT(n)		(_BIT(0) | (((n) & 0x7F) << 1))
#define LPC32XX_CLKPWR_SW_GET_ARG(n)		(((n) & 0xFE) >> 1)

/*
 * clkpwr_i2c_clk_ctrl register definitions
 */
#define LPC32XX_CLKPWR_I2CCLK_USBI2CHI_DRIVE	_BIT(4)
#define LPC32XX_CLKPWR_I2CCLK_I2C2HI_DRIVE	_BIT(3)
#define LPC32XX_CLKPWR_I2CCLK_I2C1HI_DRIVE	_BIT(2)
#define LPC32XX_CLKPWR_I2CCLK_I2C2CLK_EN	_BIT(1)
#define LPC32XX_CLKPWR_I2CCLK_I2C1CLK_EN	_BIT(0)

/*
 * clkpwr_key_clk_ctrl register definitions
 */
#define LPC32XX_CLKPWR_KEYCLKCTRL_CLK_EN	0x1

/*
 * clkpwr_adc_clk_ctrl register definitions
 */
#define LPC32XX_CLKPWR_ADC32CLKCTRL_CLK_EN	0x1

/*
 * clkpwr_pwm_clk_ctrl register definitions
 */
#define LPC32XX_CLKPWR_PWMCLK_PWM2_DIV(n)	(((n) & 0xF) << 8)
#define LPC32XX_CLKPWR_PWMCLK_PWM1_DIV(n)	(((n) & 0xF) << 4)
#define LPC32XX_CLKPWR_PWMCLK_PWM2SEL_PCLK	0x8
#define LPC32XX_CLKPWR_PWMCLK_PWM2CLK_EN	0x4
#define LPC32XX_CLKPWR_PWMCLK_PWM1SEL_PCLK	0x2
#define LPC32XX_CLKPWR_PWMCLK_PWM1CLK_EN	0x1

/*
 * clkpwr_timer_clk_ctrl register definitions
 */
#define LPC32XX_CLKPWR_PWMCLK_HSTIMER_EN	0x2
#define LPC32XX_CLKPWR_PWMCLK_WDOG_EN		0x1

/*
 * clkpwr_timers_pwms_clk_ctrl_1 register definitions
 */
#define LPC32XX_CLKPWR_TMRPWMCLK_MPWM_EN	0x40
#define LPC32XX_CLKPWR_TMRPWMCLK_TIMER3_EN	0x20
#define LPC32XX_CLKPWR_TMRPWMCLK_TIMER2_EN	0x10
#define LPC32XX_CLKPWR_TMRPWMCLK_TIMER1_EN	0x08
#define LPC32XX_CLKPWR_TMRPWMCLK_TIMER0_EN	0x04
#define LPC32XX_CLKPWR_TMRPWMCLK_PWM4_EN	0x02
#define LPC32XX_CLKPWR_TMRPWMCLK_PWM3_EN	0x01

/*
 * clkpwr_spi_clk_ctrl register definitions
 */
#define LPC32XX_CLKPWR_SPICLK_SET_SPI2DATIO	0x80
#define LPC32XX_CLKPWR_SPICLK_SET_SPI2CLK	0x40
#define LPC32XX_CLKPWR_SPICLK_USE_SPI2		0x20
#define LPC32XX_CLKPWR_SPICLK_SPI2CLK_EN	0x10
#define LPC32XX_CLKPWR_SPICLK_SET_SPI1DATIO	0x08
#define LPC32XX_CLKPWR_SPICLK_SET_SPI1CLK	0x04
#define LPC32XX_CLKPWR_SPICLK_USE_SPI1		0x02
#define LPC32XX_CLKPWR_SPICLK_SPI1CLK_EN	0x01

/*
 * clkpwr_nand_clk_ctrl register definitions
 */
#define LPC32XX_CLKPWR_NANDCLK_INTSEL_MLC	0x20
#define LPC32XX_CLKPWR_NANDCLK_DMA_RNB		0x10
#define LPC32XX_CLKPWR_NANDCLK_DMA_INT		0x08
#define LPC32XX_CLKPWR_NANDCLK_SEL_SLC		0x04
#define LPC32XX_CLKPWR_NANDCLK_MLCCLK_EN	0x02
#define LPC32XX_CLKPWR_NANDCLK_SLCCLK_EN	0x01

/*
 * clkpwr_uart3_clk_ctrl, clkpwr_uart4_clk_ctrl, clkpwr_uart5_clk_ctrl
 * and clkpwr_uart6_clk_ctrl register definitions
 */
#define LPC32XX_CLKPWR_UART_Y_DIV(y)		((y) & 0xFF)
#define LPC32XX_CLKPWR_UART_X_DIV(x)		(((x) & 0xFF) << 8)
#define LPC32XX_CLKPWR_UART_USE_HCLK		_BIT(16)

/*
 * clkpwr_irda_clk_ctrl register definitions
 */
#define LPC32XX_CLKPWR_IRDA_Y_DIV(y)		((y) & 0xFF)
#define LPC32XX_CLKPWR_IRDA_X_DIV(x)		(((x) & 0xFF) << 8)

/*
 * clkpwr_uart_clk_ctrl register definitions
 */
#define LPC32XX_CLKPWR_UARTCLKCTRL_UART6_EN	_BIT(3)
#define LPC32XX_CLKPWR_UARTCLKCTRL_UART5_EN	_BIT(2)
#define LPC32XX_CLKPWR_UARTCLKCTRL_UART4_EN	_BIT(1)
#define LPC32XX_CLKPWR_UARTCLKCTRL_UART3_EN	_BIT(0)

/*
 * clkpwr_dmaclk_ctrl register definitions
 */
#define LPC32XX_CLKPWR_DMACLKCTRL_CLK_EN	0x1

/*
 * clkpwr_autoclock register definitions
 */
#define LPC32XX_CLKPWR_AUTOCLK_USB_EN		0x40
#define LPC32XX_CLKPWR_AUTOCLK_IRAM_EN		0x02
#define LPC32XX_CLKPWR_AUTOCLK_IROM_EN		0x01

/*
 * Interrupt controller register offsets
 */
#define LPC32XX_INTC_MASK(x)			io_p2v((x) + 0x00)
#define LPC32XX_INTC_RAW_STAT(x)		io_p2v((x) + 0x04)
#define LPC32XX_INTC_STAT(x)			io_p2v((x) + 0x08)
#define LPC32XX_INTC_POLAR(x)			io_p2v((x) + 0x0C)
#define LPC32XX_INTC_ACT_TYPE(x)		io_p2v((x) + 0x10)
#define LPC32XX_INTC_TYPE(x)			io_p2v((x) + 0x14)

/*
 * Timer/counter register offsets
 */
#define LPC32XX_TIMER_IR(x)			io_p2v((x) + 0x00)
#define LPC32XX_TIMER_TCR(x)			io_p2v((x) + 0x04)
#define LPC32XX_TIMER_TC(x)			io_p2v((x) + 0x08)
#define LPC32XX_TIMER_PR(x)			io_p2v((x) + 0x0C)
#define LPC32XX_TIMER_PC(x)			io_p2v((x) + 0x10)
#define LPC32XX_TIMER_MCR(x)			io_p2v((x) + 0x14)
#define LPC32XX_TIMER_MR0(x)			io_p2v((x) + 0x18)
#define LPC32XX_TIMER_MR1(x)			io_p2v((x) + 0x1C)
#define LPC32XX_TIMER_MR2(x)			io_p2v((x) + 0x20)
#define LPC32XX_TIMER_MR3(x)			io_p2v((x) + 0x24)
#define LPC32XX_TIMER_CCR(x)			io_p2v((x) + 0x28)
#define LPC32XX_TIMER_CR0(x)			io_p2v((x) + 0x2C)
#define LPC32XX_TIMER_CR1(x)			io_p2v((x) + 0x30)
#define LPC32XX_TIMER_CR2(x)			io_p2v((x) + 0x34)
#define LPC32XX_TIMER_CR3(x)			io_p2v((x) + 0x38)
#define LPC32XX_TIMER_EMR(x)			io_p2v((x) + 0x3C)
#define LPC32XX_TIMER_CTCR(x)			io_p2v((x) + 0x70)

/*
 * ir register definitions
 */
#define LPC32XX_TIMER_CNTR_MTCH_BIT(n)		(1 << ((n) & 0x3))
#define LPC32XX_TIMER_CNTR_CAPT_BIT(n)		(1 << (4 + ((n) & 0x3)))

/*
 * tcr register definitions
 */
#define LPC32XX_TIMER_CNTR_TCR_EN		0x1
#define LPC32XX_TIMER_CNTR_TCR_RESET		0x2

/*
 * mcr register definitions
 */
#define LPC32XX_TIMER_CNTR_MCR_MTCH(n)		(0x1 << ((n) * 3))
#define LPC32XX_TIMER_CNTR_MCR_RESET(n)		(0x1 << (((n) * 3) + 1))
#define LPC32XX_TIMER_CNTR_MCR_STOP(n)		(0x1 << (((n) * 3) + 2))

/*
 * Standard UART register offsets
 */
#define LPC32XX_UART_DLL_FIFO(x)		io_p2v((x) + 0x00)
#define LPC32XX_UART_DLM_IER(x)			io_p2v((x) + 0x04)
#define LPC32XX_UART_IIR_FCR(x)			io_p2v((x) + 0x08)
#define LPC32XX_UART_LCR(x)			io_p2v((x) + 0x0C)
#define LPC32XX_UART_MODEM_CTRL(x)		io_p2v((x) + 0x10)
#define LPC32XX_UART_LSR(x)			io_p2v((x) + 0x14)
#define LPC32XX_UART_MODEM_STATUS(x)		io_p2v((x) + 0x18)
#define LPC32XX_UART_RXLEV(x)			io_p2v((x) + 0x1C)

/*
 * UART control structure offsets
 */
#define _UCREG(x)				io_p2v(\
						LPC32XX_UART_CTRL_BASE + (x))
#define LPC32XX_UARTCTL_CTRL			_UCREG(0x00)
#define LPC32XX_UARTCTL_CLKMODE			_UCREG(0x04)
#define LPC32XX_UARTCTL_CLOOP			_UCREG(0x08)

/*
 * ctrl register definitions
 */
#define LPC32XX_UART_U3_MD_CTRL_EN		_BIT(11)
#define LPC32XX_UART_IRRX6_INV_EN		_BIT(10)
#define LPC32XX_UART_HDPX_EN			_BIT(9)
#define LPC32XX_UART_UART6_IRDAMOD_BYPASS	_BIT(5)
#define LPC32XX_RT_IRTX6_INV_EN			_BIT(4)
#define LPC32XX_RT_IRTX6_INV_MIR_EN		_BIT(3)
#define LPC32XX_RT_RX_IRPULSE_3_16_115K		_BIT(2)
#define LPC32XX_RT_TX_IRPULSE_3_16_115K		_BIT(1)
#define LPC32XX_UART_U5_ROUTE_TO_USB		_BIT(0)

/*
 * clkmode register definitions
 */
#define LPC32XX_UART_ENABLED_CLOCKS(n)		(((n) >> 16) & 0x7F)
#define LPC32XX_UART_ENABLED_CLOCK(n, u)	(((n) >> (16 + (u))) & 0x1)
#define LPC32XX_UART_ENABLED_CLKS_ANY		_BIT(14)
#define LPC32XX_UART_CLKMODE_OFF		0x0
#define LPC32XX_UART_CLKMODE_ON			0x1
#define LPC32XX_UART_CLKMODE_AUTO		0x2
#define LPC32XX_UART_CLKMODE_MASK(u)		(0x3 << ((((u) - 3) * 2) + 4))
#define LPC32XX_UART_CLKMODE_LOAD(m, u)		((m) << ((((u) - 3) * 2) + 4))

/*
 * GPIO Module Register offsets
 */
#define _GPREG(x)				io_p2v(LPC32XX_GPIO_BASE + (x))
#define LPC32XX_GPIO_P_MUX_SET			_GPREG(0x100)
#define LPC32XX_GPIO_P_MUX_CLR			_GPREG(0x104)
#define LPC32XX_GPIO_P_MUX_STATE		_GPREG(0x108)
#define LPC32XX_GPIO_P3_MUX_SET			_GPREG(0x110)
#define LPC32XX_GPIO_P3_MUX_CLR			_GPREG(0x114)
#define LPC32XX_GPIO_P3_MUX_STATE		_GPREG(0x118)
#define LPC32XX_GPIO_P0_MUX_SET			_GPREG(0x120)
#define LPC32XX_GPIO_P0_MUX_CLR			_GPREG(0x124)
#define LPC32XX_GPIO_P0_MUX_STATE		_GPREG(0x128)
#define LPC32XX_GPIO_P1_MUX_SET			_GPREG(0x130)
#define LPC32XX_GPIO_P1_MUX_CLR			_GPREG(0x134)
#define LPC32XX_GPIO_P1_MUX_STATE		_GPREG(0x138)
#define LPC32XX_GPIO_P2_MUX_SET			_GPREG(0x028)
#define LPC32XX_GPIO_P2_MUX_CLR			_GPREG(0x02C)
#define LPC32XX_GPIO_P2_MUX_STATE		_GPREG(0x030)

/*
 * USB Otg Registers
 */
#define _OTGREG(x)			io_p2v(LPC32XX_USB_OTG_BASE + (x))
#define LPC32XX_USB_OTG_CLK_CTRL	_OTGREG(0xFF4)
#define LPC32XX_USB_OTG_CLK_STAT	_OTGREG(0xFF8)

/* USB OTG CLK CTRL bit defines */
#define LPC32XX_USB_OTG_AHB_M_CLOCK_ON	_BIT(4)
#define LPC32XX_USB_OTG_OTG_CLOCK_ON	_BIT(3)
#define LPC32XX_USB_OTG_I2C_CLOCK_ON	_BIT(2)
#define LPC32XX_USB_OTG_DEV_CLOCK_ON	_BIT(1)
#define LPC32XX_USB_OTG_HOST_CLOCK_ON	_BIT(0)

/*
 * Start of virtual addresses for IO devices
 */
#define IO_BASE		0xF0000000

/*
 * This macro relies on fact that for all HW i/o addresses bits 20-23 are 0
 */
#define IO_ADDRESS(x)	IOMEM(((((x) & 0xff000000) >> 4) | ((x) & 0xfffff)) |\
			 IO_BASE)

#define io_p2v(x)	((void __iomem *) (unsigned long) IO_ADDRESS(x))
#define io_v2p(x)	((((x) & 0x0ff00000) << 4) | ((x) & 0x000fffff))

#endif


code:
// SPDX-License-Identifier: GPL-2.0+
/*
 * Platform support for LPC32xx SoC
 *
 * Author: Kevin Wells <kevin.wells@nxp.com>
 *
 * Copyright (C) 2012 Roland Stigge <stigge@antcom.de>
 * Copyright (C) 2010 NXP Semiconductors
 */

#include <linux/amba/pl08x.h>
#include <linux/mtd/lpc32xx_mlc.h>
#include <linux/mtd/lpc32xx_slc.h>
#include <linux/of_platform.h>

#include <asm/mach/arch.h>
#include "common.h"

static struct pl08x_channel_data pl08x_slave_channels[] = {
	{
		.bus_id = "nand-slc",
		.min_signal = 1, /* SLC NAND Flash */
		.max_signal = 1,
		.periph_buses = PL08X_AHB1,
	},
	{
		.bus_id = "nand-mlc",
		.min_signal = 12, /* MLC NAND Flash */
		.max_signal = 12,
		.periph_buses = PL08X_AHB1,
	},
};

static int pl08x_get_signal(const struct pl08x_channel_data *cd)
{
	return cd->min_signal;
}

static void pl08x_put_signal(const struct pl08x_channel_data *cd, int ch)
{
}

static struct pl08x_platform_data pl08x_pd = {
	/* Some reasonable memcpy defaults */
	.memcpy_burst_size = PL08X_BURST_SZ_256,
	.memcpy_bus_width = PL08X_BUS_WIDTH_32_BITS,
	.slave_channels = &pl08x_slave_channels[0],
	.num_slave_channels = ARRAY_SIZE(pl08x_slave_channels),
	.get_xfer_signal = pl08x_get_signal,
	.put_xfer_signal = pl08x_put_signal,
	.lli_buses = PL08X_AHB1,
	.mem_buses = PL08X_AHB1,
};

static struct lpc32xx_slc_platform_data lpc32xx_slc_data = {
	.dma_filter = pl08x_filter_id,
};

static struct lpc32xx_mlc_platform_data lpc32xx_mlc_data = {
	.dma_filter = pl08x_filter_id,
};

static const struct of_dev_auxdata lpc32xx_auxdata_lookup[] __initconst = {
	OF_DEV_AUXDATA("arm,pl080", 0x31000000, "pl08xdmac", &pl08x_pd),
	OF_DEV_AUXDATA("nxp,lpc3220-slc", 0x20020000, "20020000.flash",
		       &lpc32xx_slc_data),
	OF_DEV_AUXDATA("nxp,lpc3220-mlc", 0x200a8000, "200a8000.flash",
		       &lpc32xx_mlc_data),
	{ }
};

static void __init lpc3250_machine_init(void)
{
	lpc32xx_serial_init();

	of_platform_default_populate(NULL, lpc32xx_auxdata_lookup, NULL);
}

static const char *const lpc32xx_dt_compat[] __initconst = {
	"nxp,lpc3220",
	"nxp,lpc3230",
	"nxp,lpc3240",
	"nxp,lpc3250",
	NULL
};

DT_MACHINE_START(LPC32XX_DT, "LPC32XX SoC (Flattened Device Tree)")
	.atag_offset	= 0x100,
	.map_io		= lpc32xx_map_io,
	.init_machine	= lpc3250_machine_init,
	.dt_compat	= lpc32xx_dt_compat,
MACHINE_END


code:
// SPDX-License-Identifier: GPL-2.0-only
/*
 * arch/arm/mach-lpc32xx/pm.c
 *
 * Original authors: Vitaly Wool, Dmitry Chigirev <source@mvista.com>
 * Modified by Kevin Wells <kevin.wells@nxp.com>
 *
 * 2005 (c) MontaVista Software, Inc.
 */

/*
 * LPC32XX CPU and system power management
 *
 * The LPC32XX has three CPU modes for controlling system power: run,
 * direct-run, and halt modes. When switching between halt and run modes,
 * the CPU transistions through direct-run mode. For Linux, direct-run
 * mode is not used in normal operation. Halt mode is used when the
 * system is fully suspended.
 *
 * Run mode:
 * The ARM CPU clock (HCLK_PLL), HCLK bus clock, and PCLK bus clocks are
 * derived from the HCLK PLL. The HCLK and PCLK bus rates are divided from
 * the HCLK_PLL rate. Linux runs in this mode.
 *
 * Direct-run mode:
 * The ARM CPU clock, HCLK bus clock, and PCLK bus clocks are driven from
 * SYSCLK. SYSCLK is usually around 13MHz, but may vary based on SYSCLK
 * source or the frequency of the main oscillator. In this mode, the
 * HCLK_PLL can be safely enabled, changed, or disabled.
 *
 * Halt mode:
 * SYSCLK is gated off and the CPU and system clocks are halted.
 * Peripherals based on the 32KHz oscillator clock (ie, RTC, touch,
 * key scanner, etc.) still operate if enabled. In this state, an enabled
 * system event (ie, GPIO state change, RTC match, key press, etc.) will
 * wake the system up back into direct-run mode.
 *
 * DRAM refresh
 * DRAM clocking and refresh are slightly different for systems with DDR
 * DRAM or regular SDRAM devices. If SDRAM is used in the system, the
 * SDRAM will still be accessible in direct-run mode. In DDR based systems,
 * a transition to direct-run mode will stop all DDR accesses (no clocks).
 * Because of this, the code to switch power modes and the code to enter
 * and exit DRAM self-refresh modes must not be executed in DRAM. A small
 * section of IRAM is used instead for this.
 *
 * Suspend is handled with the following logic:
 *  Backup a small area of IRAM used for the suspend code
 *  Copy suspend code to IRAM
 *  Transfer control to code in IRAM
 *  Places DRAMs in self-refresh mode
 *  Enter direct-run mode
 *  Save state of HCLK_PLL PLL
 *  Disable HCLK_PLL PLL
 *  Enter halt mode - CPU and buses will stop
 *  System enters direct-run mode when an enabled event occurs
 *  HCLK PLL state is restored
 *  Run mode is entered
 *  DRAMS are placed back into normal mode
 *  Code execution returns from IRAM
 *  IRAM code are used for suspend is restored
 *  Suspend mode is exited
 */

#include <linux/suspend.h>
#include <linux/io.h>
#include <linux/slab.h>

#include <asm/cacheflush.h>

#include "lpc32xx.h"
#include "common.h"

#define TEMP_IRAM_AREA  IO_ADDRESS(LPC32XX_IRAM_BASE)

/*
 * Both STANDBY and MEM suspend states are handled the same with no
 * loss of CPU or memory state
 */
static int lpc32xx_pm_enter(suspend_state_t state)
{
	int (*lpc32xx_suspend_ptr) (void);
	void *iram_swap_area;

	/* Allocate some space for temporary IRAM storage */
	iram_swap_area = kmemdup((void *)TEMP_IRAM_AREA,
				 lpc32xx_sys_suspend_sz, GFP_KERNEL);
	if (!iram_swap_area)
		return -ENOMEM;

	/*
	 * Copy code to suspend system into IRAM. The suspend code
	 * needs to run from IRAM as DRAM may no longer be available
	 * when the PLL is stopped.
	 */
	memcpy((void *) TEMP_IRAM_AREA, &lpc32xx_sys_suspend,
		lpc32xx_sys_suspend_sz);
	flush_icache_range((unsigned long)TEMP_IRAM_AREA,
		(unsigned long)(TEMP_IRAM_AREA) + lpc32xx_sys_suspend_sz);

	/* Transfer to suspend code in IRAM */
	lpc32xx_suspend_ptr = (void *) TEMP_IRAM_AREA;
	flush_cache_all();
	(void) lpc32xx_suspend_ptr();

	/* Restore original IRAM contents */
	memcpy((void *) TEMP_IRAM_AREA, iram_swap_area,
		lpc32xx_sys_suspend_sz);

	kfree(iram_swap_area);

	return 0;
}

static const struct platform_suspend_ops lpc32xx_pm_ops = {
	.valid	= suspend_valid_only_mem,
	.enter	= lpc32xx_pm_enter,
};

#define EMC_DYN_MEM_CTRL_OFS 0x20
#define EMC_SRMMC           (1 << 3)
#define EMC_CTRL_REG io_p2v(LPC32XX_EMC_BASE + EMC_DYN_MEM_CTRL_OFS)
static int __init lpc32xx_pm_init(void)
{
	/*
	 * Setup SDRAM self-refresh clock to automatically disable o
	 * start of self-refresh. This only needs to be done once.
	 */
	__raw_writel(__raw_readl(EMC_CTRL_REG) | EMC_SRMMC, EMC_CTRL_REG);

	suspend_set_ops(&lpc32xx_pm_ops);

	return 0;
}
arch_initcall(lpc32xx_pm_init);


code:
// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * arch/arm/mach-lpc32xx/serial.c
 *
 * Author: Kevin Wells <kevin.wells@nxp.com>
 *
 * Copyright (C) 2010 NXP Semiconductors
 */

#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/serial.h>
#include <linux/serial_core.h>
#include <linux/serial_reg.h>
#include <linux/serial_8250.h>
#include <linux/clk.h>
#include <linux/io.h>

#include "lpc32xx.h"
#include "common.h"

#define LPC32XX_SUART_FIFO_SIZE	64

struct uartinit {
	char *uart_ck_name;
	u32 ck_mode_mask;
	void __iomem *pdiv_clk_reg;
	resource_size_t mapbase;
};

static struct uartinit uartinit_data[] __initdata = {
	{
		.uart_ck_name = "uart5_ck",
		.ck_mode_mask =
			LPC32XX_UART_CLKMODE_LOAD(LPC32XX_UART_CLKMODE_ON, 5),
		.pdiv_clk_reg = LPC32XX_CLKPWR_UART5_CLK_CTRL,
		.mapbase = LPC32XX_UART5_BASE,
	},
	{
		.uart_ck_name = "uart3_ck",
		.ck_mode_mask =
			LPC32XX_UART_CLKMODE_LOAD(LPC32XX_UART_CLKMODE_ON, 3),
		.pdiv_clk_reg = LPC32XX_CLKPWR_UART3_CLK_CTRL,
		.mapbase = LPC32XX_UART3_BASE,
	},
	{
		.uart_ck_name = "uart4_ck",
		.ck_mode_mask =
			LPC32XX_UART_CLKMODE_LOAD(LPC32XX_UART_CLKMODE_ON, 4),
		.pdiv_clk_reg = LPC32XX_CLKPWR_UART4_CLK_CTRL,
		.mapbase = LPC32XX_UART4_BASE,
	},
	{
		.uart_ck_name = "uart6_ck",
		.ck_mode_mask =
			LPC32XX_UART_CLKMODE_LOAD(LPC32XX_UART_CLKMODE_ON, 6),
		.pdiv_clk_reg = LPC32XX_CLKPWR_UART6_CLK_CTRL,
		.mapbase = LPC32XX_UART6_BASE,
	},
};

/* LPC3250 Errata HSUART.1: Hang workaround via loopback mode on inactivity */
void lpc32xx_loopback_set(resource_size_t mapbase, int state)
{
	int bit;
	u32 tmp;

	switch (mapbase) {
	case LPC32XX_HS_UART1_BASE:
		bit = 0;
		break;
	case LPC32XX_HS_UART2_BASE:
		bit = 1;
		break;
	case LPC32XX_HS_UART7_BASE:
		bit = 6;
		break;
	default:
		WARN(1, "lpc32xx_hs: Warning: Unknown port at %08x\n", mapbase);
		return;
	}

	tmp = readl(LPC32XX_UARTCTL_CLOOP);
	if (state)
		tmp |= (1 << bit);
	else
		tmp &= ~(1 << bit);
	writel(tmp, LPC32XX_UARTCTL_CLOOP);
}
EXPORT_SYMBOL_GPL(lpc32xx_loopback_set);

void __init lpc32xx_serial_init(void)
{
	u32 tmp, clkmodes = 0;
	struct clk *clk;
	unsigned int puart;
	int i, j;

	for (i = 0; i < ARRAY_SIZE(uartinit_data); i++) {
		clk = clk_get(NULL, uartinit_data[i].uart_ck_name);
		if (!IS_ERR(clk)) {
			clk_enable(clk);
		}

		/* Setup UART clock modes for all UARTs, disable autoclock */
		clkmodes |= uartinit_data[i].ck_mode_mask;

		/* pre-UART clock divider set to 1 */
		__raw_writel(0x0101, uartinit_data[i].pdiv_clk_reg);

		/*
		 * Force a flush of the RX FIFOs to work around a
		 * HW bug
		 */
		puart = uartinit_data[i].mapbase;
		__raw_writel(0xC1, LPC32XX_UART_IIR_FCR(puart));
		__raw_writel(0x00, LPC32XX_UART_DLL_FIFO(puart));
		j = LPC32XX_SUART_FIFO_SIZE;
		while (j--)
			tmp = __raw_readl(
				LPC32XX_UART_DLL_FIFO(puart));
		__raw_writel(0, LPC32XX_UART_IIR_FCR(puart));
	}

	/* This needs to be done after all UART clocks are setup */
	__raw_writel(clkmodes, LPC32XX_UARTCTL_CLKMODE);
	for (i = 0; i < ARRAY_SIZE(uartinit_data); i++) {
		/* Force a flush of the RX FIFOs to work around a HW bug */
		puart = uartinit_data[i].mapbase;
		__raw_writel(0xC1, LPC32XX_UART_IIR_FCR(puart));
		__raw_writel(0x00, LPC32XX_UART_DLL_FIFO(puart));
		j = LPC32XX_SUART_FIFO_SIZE;
		while (j--)
			tmp = __raw_readl(LPC32XX_UART_DLL_FIFO(puart));
		__raw_writel(0, LPC32XX_UART_IIR_FCR(puart));
	}

	/* Disable IrDA pulsing support on UART6 */
	tmp = __raw_readl(LPC32XX_UARTCTL_CTRL);
	tmp |= LPC32XX_UART_UART6_IRDAMOD_BYPASS;
	__raw_writel(tmp, LPC32XX_UARTCTL_CTRL);

	/* Disable UART5->USB transparent mode or USB won't work */
	tmp = __raw_readl(LPC32XX_UARTCTL_CTRL);
	tmp &= ~LPC32XX_UART_U5_ROUTE_TO_USB;
	__raw_writel(tmp, LPC32XX_UARTCTL_CTRL);
}


code:
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * arch/arm/mach-lpc32xx/suspend.S
 *
 * Original authors: Dmitry Chigirev, Vitaly Wool <source@mvista.com>
 * Modified by Kevin Wells <kevin.wells@nxp.com>
 *
 * 2005 (c) MontaVista Software, Inc.
 */
#include <linux/linkage.h>
#include <asm/assembler.h>
#include "lpc32xx.h"

/* Using named register defines makes the code easier to follow */
#define WORK1_REG			r0
#define WORK2_REG			r1
#define SAVED_HCLK_DIV_REG		r2
#define SAVED_HCLK_PLL_REG		r3
#define SAVED_DRAM_CLKCTRL_REG		r4
#define SAVED_PWR_CTRL_REG		r5
#define CLKPWRBASE_REG			r6
#define EMCBASE_REG			r7

#define LPC32XX_EMC_STATUS_OFFS		0x04
#define LPC32XX_EMC_STATUS_BUSY		0x1
#define LPC32XX_EMC_STATUS_SELF_RFSH	0x4

#define LPC32XX_CLKPWR_PWR_CTRL_OFFS	0x44
#define LPC32XX_CLKPWR_HCLK_DIV_OFFS	0x40
#define LPC32XX_CLKPWR_HCLKPLL_CTRL_OFFS 0x58

#define CLKPWR_PCLK_DIV_MASK		0xFFFFFE7F

	.text

ENTRY(lpc32xx_sys_suspend)
	@ Save a copy of the used registers in IRAM, r0 is corrupted
	adr	r0, tmp_stack_end
	stmfd	r0!, {r3 - r7, sp, lr}

	@ Load a few common register addresses
	adr	WORK1_REG, reg_bases
	ldr	CLKPWRBASE_REG, [WORK1_REG, #0]
	ldr	EMCBASE_REG, [WORK1_REG, #4]

	ldr	SAVED_PWR_CTRL_REG, [CLKPWRBASE_REG,\
		#LPC32XX_CLKPWR_PWR_CTRL_OFFS]
	orr	WORK1_REG, SAVED_PWR_CTRL_REG, #LPC32XX_CLKPWR_SDRAM_SELF_RFSH

	@ Wait for SDRAM busy status to go busy and then idle
	@ This guarantees a small windows where DRAM isn't busy
1:
	ldr	WORK2_REG, [EMCBASE_REG, #LPC32XX_EMC_STATUS_OFFS]
	and	WORK2_REG, WORK2_REG, #LPC32XX_EMC_STATUS_BUSY
	cmp	WORK2_REG, #LPC32XX_EMC_STATUS_BUSY
	bne	1b @ Branch while idle
2:
	ldr	WORK2_REG, [EMCBASE_REG, #LPC32XX_EMC_STATUS_OFFS]
	and	WORK2_REG, WORK2_REG, #LPC32XX_EMC_STATUS_BUSY
	cmp	WORK2_REG, #LPC32XX_EMC_STATUS_BUSY
	beq	2b @ Branch until idle

	@ Setup self-refresh with support for manual exit of
	@ self-refresh mode
	str	WORK1_REG, [CLKPWRBASE_REG, #LPC32XX_CLKPWR_PWR_CTRL_OFFS]
	orr	WORK2_REG, WORK1_REG, #LPC32XX_CLKPWR_UPD_SDRAM_SELF_RFSH
	str	WORK2_REG, [CLKPWRBASE_REG, #LPC32XX_CLKPWR_PWR_CTRL_OFFS]
	str	WORK1_REG, [CLKPWRBASE_REG, #LPC32XX_CLKPWR_PWR_CTRL_OFFS]

	@ Wait for self-refresh acknowledge, clocks to the DRAM device
	@ will automatically stop on start of self-refresh
3:
	ldr	WORK2_REG, [EMCBASE_REG, #LPC32XX_EMC_STATUS_OFFS]
	and	WORK2_REG, WORK2_REG, #LPC32XX_EMC_STATUS_SELF_RFSH
	cmp	WORK2_REG, #LPC32XX_EMC_STATUS_SELF_RFSH
	bne	3b @ Branch until self-refresh mode starts

	@ Enter direct-run mode from run mode
	bic	WORK1_REG, WORK1_REG, #LPC32XX_CLKPWR_SELECT_RUN_MODE
	str	WORK1_REG, [CLKPWRBASE_REG, #LPC32XX_CLKPWR_PWR_CTRL_OFFS]

	@ Safe disable of DRAM clock in EMC block, prevents DDR sync
	@ issues on restart
	ldr	SAVED_HCLK_DIV_REG, [CLKPWRBASE_REG,\
		#LPC32XX_CLKPWR_HCLK_DIV_OFFS]
	and	WORK2_REG, SAVED_HCLK_DIV_REG, #CLKPWR_PCLK_DIV_MASK
	str	WORK2_REG, [CLKPWRBASE_REG, #LPC32XX_CLKPWR_HCLK_DIV_OFFS]

	@ Save HCLK PLL state and disable HCLK PLL
	ldr	SAVED_HCLK_PLL_REG, [CLKPWRBASE_REG,\
		#LPC32XX_CLKPWR_HCLKPLL_CTRL_OFFS]
	bic	WORK2_REG, SAVED_HCLK_PLL_REG, #LPC32XX_CLKPWR_HCLKPLL_POWER_UP
	str	WORK2_REG, [CLKPWRBASE_REG, #LPC32XX_CLKPWR_HCLKPLL_CTRL_OFFS]

	@ Enter stop mode until an enabled event occurs
	orr	WORK1_REG, WORK1_REG, #LPC32XX_CLKPWR_STOP_MODE_CTRL
	str	WORK1_REG, [CLKPWRBASE_REG, #LPC32XX_CLKPWR_PWR_CTRL_OFFS]
	.rept 9
	nop
	.endr

	@ Clear stop status
	bic	WORK1_REG, WORK1_REG, #LPC32XX_CLKPWR_STOP_MODE_CTRL

	@ Restore original HCLK PLL value and wait for PLL lock
	str	SAVED_HCLK_PLL_REG, [CLKPWRBASE_REG,\
		#LPC32XX_CLKPWR_HCLKPLL_CTRL_OFFS]
4:
	ldr	WORK2_REG, [CLKPWRBASE_REG, #LPC32XX_CLKPWR_HCLKPLL_CTRL_OFFS]
	and	WORK2_REG, WORK2_REG, #LPC32XX_CLKPWR_HCLKPLL_PLL_STS
	bne	4b

	@ Re-enter run mode with self-refresh flag cleared, but no DRAM
	@ update yet. DRAM is still in self-refresh
	str	SAVED_PWR_CTRL_REG, [CLKPWRBASE_REG,\
		#LPC32XX_CLKPWR_PWR_CTRL_OFFS]

	@ Restore original DRAM clock mode to restore DRAM clocks
	str	SAVED_HCLK_DIV_REG, [CLKPWRBASE_REG,\
		#LPC32XX_CLKPWR_HCLK_DIV_OFFS]

	@ Clear self-refresh mode
	orr	WORK1_REG, SAVED_PWR_CTRL_REG,\
		#LPC32XX_CLKPWR_UPD_SDRAM_SELF_RFSH
	str	WORK1_REG, [CLKPWRBASE_REG, #LPC32XX_CLKPWR_PWR_CTRL_OFFS]
	str	SAVED_PWR_CTRL_REG, [CLKPWRBASE_REG,\
		#LPC32XX_CLKPWR_PWR_CTRL_OFFS]

	@ Wait for EMC to clear self-refresh mode
5:
	ldr	WORK2_REG, [EMCBASE_REG, #LPC32XX_EMC_STATUS_OFFS]
	and	WORK2_REG, WORK2_REG, #LPC32XX_EMC_STATUS_SELF_RFSH
	bne	5b @ Branch until self-refresh has exited

	@ restore regs and return
	adr	r0, tmp_stack
	ldmfd	r0!, {r3 - r7, sp, pc}

reg_bases:
	.long	IO_ADDRESS(LPC32XX_CLK_PM_BASE)
	.long	IO_ADDRESS(LPC32XX_EMC_BASE)

tmp_stack:
	.long	0, 0, 0, 0, 0, 0, 0
tmp_stack_end:

ENTRY(lpc32xx_sys_suspend_sz)
	.word	. - lpc32xx_sys_suspend


code:
# SPDX-License-Identifier: GPL-2.0-only
menuconfig ARCH_MEDIATEK
	bool "MediaTek SoC Support"
	depends on ARCH_MULTI_V7
	select ARM_GIC
	select PINCTRL
	select MTK_TIMER
	select MFD_SYSCON
	help
	  Support for Mediatek MT65xx & MT81xx SoCs

if ARCH_MEDIATEK

config MACH_MT2701
	bool "MediaTek MT2701 SoCs support"
	default ARCH_MEDIATEK

config MACH_MT6589
	bool "MediaTek MT6589 SoCs support"
	default ARCH_MEDIATEK

config MACH_MT6592
	bool "MediaTek MT6592 SoCs support"
	default ARCH_MEDIATEK

config MACH_MT7623
	bool "MediaTek MT7623 SoCs support"
	default ARCH_MEDIATEK

config MACH_MT7629
	bool "MediaTek MT7629 SoCs support"
	default ARCH_MEDIATEK
	select HAVE_ARM_ARCH_TIMER

config MACH_MT8127
	bool "MediaTek MT8127 SoCs support"
	default ARCH_MEDIATEK

config MACH_MT8135
	bool "MediaTek MT8135 SoCs support"
	default ARCH_MEDIATEK

endif

path: arch/arm/mach-mediatek/Kconfig


code:
# SPDX-License-Identifier: GPL-2.0-only
obj-$(CONFIG_SMP)	+= platsmp.o
obj-y			+= mediatek.o

path: arch/arm/mach-mediatek/Makefile


code:
// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Device Tree support for Mediatek SoCs
 *
 * Copyright (c) 2014 MundoReader S.L.
 * Author: Matthias Brugger <matthias.bgg@gmail.com>
 */
#include <linux/init.h>
#include <linux/io.h>
#include <asm/mach/arch.h>
#include <linux/of.h>
#include <linux/of_clk.h>
#include <linux/clocksource.h>

#define GPT6_CON_MT65xx 0x10008060
#define GPT_ENABLE      0x31

static void __init mediatek_timer_init(void)
{
	void __iomem *gpt_base;

	if (of_machine_is_compatible("mediatek,mt6589") ||
	    of_machine_is_compatible("mediatek,mt7623") ||
	    of_machine_is_compatible("mediatek,mt8135") ||
	    of_machine_is_compatible("mediatek,mt8127")) {
		/* turn on GPT6 which ungates arch timer clocks */
		gpt_base = ioremap(GPT6_CON_MT65xx, 0x04);

		/* enable clock and set to free-run */
		writel(GPT_ENABLE, gpt_base);
		iounmap(gpt_base);
	}

	of_clk_init(NULL);
	timer_probe();
};

static const char * const mediatek_board_dt_compat[] = {
	"mediatek,mt2701",
	"mediatek,mt6589",
	"mediatek,mt6592",
	"mediatek,mt7623",
	"mediatek,mt7629",
	"mediatek,mt8127",
	"mediatek,mt8135",
	NULL,
};

DT_MACHINE_START(MEDIATEK_DT, "Mediatek Cortex-A7 (Device Tree)")
	.dt_compat	= mediatek_board_dt_compat,
	.init_time	= mediatek_timer_init,
MACHINE_END


code:
// SPDX-License-Identifier: GPL-2.0-only
/*
 * arch/arm/mach-mediatek/platsmp.c
 *
 * Copyright (c) 2014 Mediatek Inc.
 * Author: Shunli Wang <shunli.wang@mediatek.com>
 *         Yingjoe Chen <yingjoe.chen@mediatek.com>
 */
#include <linux/io.h>
#include <linux/memblock.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/string.h>
#include <linux/threads.h>

#define MTK_MAX_CPU		8
#define MTK_SMP_REG_SIZE	0x1000

struct mtk_smp_boot_info {
	unsigned long smp_base;
	unsigned int jump_reg;
	unsigned int core_keys[MTK_MAX_CPU - 1];
	unsigned int core_regs[MTK_MAX_CPU - 1];
};

static const struct mtk_smp_boot_info mtk_mt8135_tz_boot = {
	0x80002000, 0x3fc,
	{ 0x534c4131, 0x4c415332, 0x41534c33 },
	{ 0x3f8, 0x3f8, 0x3f8 },
};

static const struct mtk_smp_boot_info mtk_mt6589_boot = {
	0x10002000, 0x34,
	{ 0x534c4131, 0x4c415332, 0x41534c33 },
	{ 0x38, 0x3c, 0x40 },
};

static const struct mtk_smp_boot_info mtk_mt7623_boot = {
	0x10202000, 0x34,
	{ 0x534c4131, 0x4c415332, 0x41534c33 },
	{ 0x38, 0x3c, 0x40 },
};

static const struct of_device_id mtk_tz_smp_boot_infos[] __initconst = {
	{ .compatible   = "mediatek,mt8135", .data = &mtk_mt8135_tz_boot },
	{ .compatible   = "mediatek,mt8127", .data = &mtk_mt8135_tz_boot },
	{ .compatible   = "mediatek,mt2701", .data = &mtk_mt8135_tz_boot },
	{},
};

static const struct of_device_id mtk_smp_boot_infos[] __initconst = {
	{ .compatible   = "mediatek,mt6589", .data = &mtk_mt6589_boot },
	{ .compatible   = "mediatek,mt7623", .data = &mtk_mt7623_boot },
	{ .compatible   = "mediatek,mt7629", .data = &mtk_mt7623_boot },
	{},
};

static void __iomem *mtk_smp_base;
static const struct mtk_smp_boot_info *mtk_smp_info;

static int mtk_boot_secondary(unsigned int cpu, struct task_struct *idle)
{
	if (!mtk_smp_base)
		return -EINVAL;

	if (!mtk_smp_info->core_keys[cpu-1])
		return -EINVAL;

	writel_relaxed(mtk_smp_info->core_keys[cpu-1],
		mtk_smp_base + mtk_smp_info->core_regs[cpu-1]);

	arch_send_wakeup_ipi_mask(cpumask_of(cpu));

	return 0;
}

static void __init __mtk_smp_prepare_cpus(unsigned int max_cpus, int trustzone)
{
	int i, num;
	const struct of_device_id *infos;

	if (trustzone) {
		num = ARRAY_SIZE(mtk_tz_smp_boot_infos);
		infos = mtk_tz_smp_boot_infos;
	} else {
		num = ARRAY_SIZE(mtk_smp_boot_infos);
		infos = mtk_smp_boot_infos;
	}

	/* Find smp boot info for this SoC */
	for (i = 0; i < num; i++) {
		if (of_machine_is_compatible(infos[i].compatible)) {
			mtk_smp_info = infos[i].data;
			break;
		}
	}

	if (!mtk_smp_info) {
		pr_err("%s: Device is not supported\n", __func__);
		return;
	}

	if (trustzone) {
		/* smp_base(trustzone-bootinfo) is reserved by device tree */
		mtk_smp_base = phys_to_virt(mtk_smp_info->smp_base);
	} else {
		mtk_smp_base = ioremap(mtk_smp_info->smp_base, MTK_SMP_REG_SIZE);
		if (!mtk_smp_base) {
			pr_err("%s: Can't remap %lx\n", __func__,
				mtk_smp_info->smp_base);
			return;
		}
	}

	/*
	 * write the address of slave startup address into the system-wide
	 * jump register
	 */
	writel_relaxed(__pa_symbol(secondary_startup_arm),
			mtk_smp_base + mtk_smp_info->jump_reg);
}

static void __init mtk_tz_smp_prepare_cpus(unsigned int max_cpus)
{
	__mtk_smp_prepare_cpus(max_cpus, 1);
}

static void __init mtk_smp_prepare_cpus(unsigned int max_cpus)
{
	__mtk_smp_prepare_cpus(max_cpus, 0);
}

static const struct smp_operations mt81xx_tz_smp_ops __initconst = {
	.smp_prepare_cpus = mtk_tz_smp_prepare_cpus,
	.smp_boot_secondary = mtk_boot_secondary,
};
CPU_METHOD_OF_DECLARE(mt81xx_tz_smp, "mediatek,mt81xx-tz-smp", &mt81xx_tz_smp_ops);

static const struct smp_operations mt6589_smp_ops __initconst = {
	.smp_prepare_cpus = mtk_smp_prepare_cpus,
	.smp_boot_secondary = mtk_boot_secondary,
};
CPU_METHOD_OF_DECLARE(mt6589_smp, "mediatek,mt6589-smp", &mt6589_smp_ops);


code:
# SPDX-License-Identifier: GPL-2.0-only
menuconfig ARCH_MESON
	bool "Amlogic Meson SoCs"
	depends on ARCH_MULTI_V7
	select GPIOLIB
	select GENERIC_IRQ_CHIP
	select ARM_GIC
	select ARM_GLOBAL_TIMER
	select CACHE_L2X0
	select PINCTRL
	select PINCTRL_MESON
	select HAVE_ARM_SCU if SMP
	select HAVE_ARM_TWD if SMP

if ARCH_MESON

config MACH_MESON6
	bool "Amlogic Meson6 (8726MX) SoCs support"
	default ARCH_MESON
	select MESON6_TIMER

config MACH_MESON8
	bool "Amlogic Meson8, Meson8b and Meson8m2 SoCs support"
	default ARCH_MESON
	select MESON6_TIMER
	select COMMON_CLK_MESON8B
	select MESON_IRQ_GPIO

endif

path: arch/arm/mach-meson/Kconfig


code:
# SPDX-License-Identifier: GPL-2.0-only
obj-$(CONFIG_ARCH_MESON) += meson.o
obj-$(CONFIG_SMP) += platsmp.o

path: arch/arm/mach-meson/Makefile


code:
// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Copyright (C) 2014 Carlo Caione <carlo@caione.org>
 */

#include <linux/of_platform.h>
#include <asm/mach/arch.h>

static const char * const meson_common_board_compat[] = {
	"amlogic,meson6",
	"amlogic,meson8",
	"amlogic,meson8b",
	"amlogic,meson8m2",
	NULL,
};

DT_MACHINE_START(MESON, "Amlogic Meson platform")
	.dt_compat	= meson_common_board_compat,
	.l2c_aux_val	= 0,
	.l2c_aux_mask	= ~0,
MACHINE_END


code:
// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Copyright (C) 2015 Carlo Caione <carlo@endlessm.com>
 * Copyright (C) 2017 Martin Blumenstingl <martin.blumenstingl@googlemail.com>
 */

#include <linux/delay.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/regmap.h>
#include <linux/reset.h>
#include <linux/smp.h>
#include <linux/mfd/syscon.h>

#include <asm/cacheflush.h>
#include <asm/cp15.h>
#include <asm/smp_scu.h>
#include <asm/smp_plat.h>

#define MESON_SMP_SRAM_CPU_CTRL_REG		(0x00)
#define MESON_SMP_SRAM_CPU_CTRL_ADDR_REG(c)	(0x04 + ((c - 1) << 2))

#define MESON_CPU_AO_RTI_PWR_A9_CNTL0		(0x00)
#define MESON_CPU_AO_RTI_PWR_A9_CNTL1		(0x04)
#define MESON_CPU_AO_RTI_PWR_A9_MEM_PD0		(0x14)

#define MESON_CPU_PWR_A9_CNTL0_M(c)		(0x03 << ((c * 2) + 16))
#define MESON_CPU_PWR_A9_CNTL1_M(c)		(0x03 << ((c + 1) << 1))
#define MESON_CPU_PWR_A9_MEM_PD0_M(c)		(0x0f << (32 - (c * 4)))
#define MESON_CPU_PWR_A9_CNTL1_ST(c)		(0x01 << (c + 16))

static void __iomem *sram_base;
static void __iomem *scu_base;
static struct regmap *pmu;

static struct reset_control *meson_smp_get_core_reset(int cpu)
{
	struct device_node *np = of_get_cpu_node(cpu, 0);

	return of_reset_control_get_exclusive(np, NULL);
}

static void meson_smp_set_cpu_ctrl(int cpu, bool on_off)
{
	u32 val = readl(sram_base + MESON_SMP_SRAM_CPU_CTRL_REG);

	if (on_off)
		val |= BIT(cpu);
	else
		val &= ~BIT(cpu);

	/* keep bit 0 always enabled */
	val |= BIT(0);

	writel(val, sram_base + MESON_SMP_SRAM_CPU_CTRL_REG);
}

static void __init meson_smp_prepare_cpus(const char *scu_compatible,
					  const char *pmu_compatible,
					  const char *sram_compatible)
{
	static struct device_node *node;

	/* SMP SRAM */
	node = of_find_compatible_node(NULL, NULL, sram_compatible);
	if (!node) {
		pr_err("Missing SRAM node\n");
		return;
	}

	sram_base = of_iomap(node, 0);
	of_node_put(node);
	if (!sram_base) {
		pr_err("Couldn't map SRAM registers\n");
		return;
	}

	/* PMU */
	pmu = syscon_regmap_lookup_by_compatible(pmu_compatible);
	if (IS_ERR(pmu)) {
		pr_err("Couldn't map PMU registers\n");
		return;
	}

	/* SCU */
	node = of_find_compatible_node(NULL, NULL, scu_compatible);
	if (!node) {
		pr_err("Missing SCU node\n");
		return;
	}

	scu_base = of_iomap(node, 0);
	of_node_put(node);
	if (!scu_base) {
		pr_err("Couldn't map SCU registers\n");
		return;
	}

	scu_enable(scu_base);
}

static void __init meson8b_smp_prepare_cpus(unsigned int max_cpus)
{
	meson_smp_prepare_cpus("arm,cortex-a5-scu", "amlogic,meson8b-pmu",
			       "amlogic,meson8b-smp-sram");
}

static void __init meson8_smp_prepare_cpus(unsigned int max_cpus)
{
	meson_smp_prepare_cpus("arm,cortex-a9-scu", "amlogic,meson8-pmu",
			       "amlogic,meson8-smp-sram");
}

static void meson_smp_begin_secondary_boot(unsigned int cpu)
{
	/*
	 * Set the entry point before powering on the CPU through the SCU. This
	 * is needed if the CPU is in "warm" state (= after rebooting the
	 * system without power-cycling, or when taking the CPU offline and
	 * then taking it online again.
	 */
	writel(__pa_symbol(secondary_startup),
	       sram_base + MESON_SMP_SRAM_CPU_CTRL_ADDR_REG(cpu));

	/*
	 * SCU Power on CPU (needs to be done before starting the CPU,
	 * otherwise the secondary CPU will not start).
	 */
	scu_cpu_power_enable(scu_base, cpu);
}

static int meson_smp_finalize_secondary_boot(unsigned int cpu)
{
	unsigned long timeout;

	timeout = jiffies + (10 * HZ);
	while (readl(sram_base + MESON_SMP_SRAM_CPU_CTRL_ADDR_REG(cpu))) {
		if (!time_before(jiffies, timeout)) {
			pr_err("Timeout while waiting for CPU%d status\n",
			       cpu);
			return -ETIMEDOUT;
		}
	}

	writel(__pa_symbol(secondary_startup),
	       sram_base + MESON_SMP_SRAM_CPU_CTRL_ADDR_REG(cpu));

	meson_smp_set_cpu_ctrl(cpu, true);

	return 0;
}

static int meson8_smp_boot_secondary(unsigned int cpu,
				     struct task_struct *idle)
{
	struct reset_control *rstc;
	int ret;

	rstc = meson_smp_get_core_reset(cpu);
	if (IS_ERR(rstc)) {
		pr_err("Couldn't get the reset controller for CPU%d\n", cpu);
		return PTR_ERR(rstc);
	}

	meson_smp_begin_secondary_boot(cpu);

	/* Reset enable */
	ret = reset_control_assert(rstc);
	if (ret) {
		pr_err("Failed to assert CPU%d reset\n", cpu);
		goto out;
	}

	/* CPU power ON */
	ret = regmap_update_bits(pmu, MESON_CPU_AO_RTI_PWR_A9_CNTL1,
				 MESON_CPU_PWR_A9_CNTL1_M(cpu), 0);
	if (ret < 0) {
		pr_err("Couldn't wake up CPU%d\n", cpu);
		goto out;
	}

	udelay(10);

	/* Isolation disable */
	ret = regmap_update_bits(pmu, MESON_CPU_AO_RTI_PWR_A9_CNTL0, BIT(cpu),
				 0);
	if (ret < 0) {
		pr_err("Error when disabling isolation of CPU%d\n", cpu);
		goto out;
	}

	/* Reset disable */
	ret = reset_control_deassert(rstc);
	if (ret) {
		pr_err("Failed to de-assert CPU%d reset\n", cpu);
		goto out;
	}

	ret = meson_smp_finalize_secondary_boot(cpu);
	if (ret)
		goto out;

out:
	reset_control_put(rstc);

	return 0;
}

static int meson8b_smp_boot_secondary(unsigned int cpu,
				     struct task_struct *idle)
{
	struct reset_control *rstc;
	int ret;
	u32 val;

	rstc = meson_smp_get_core_reset(cpu);
	if (IS_ERR(rstc)) {
		pr_err("Couldn't get the reset controller for CPU%d\n", cpu);
		return PTR_ERR(rstc);
	}

	meson_smp_begin_secondary_boot(cpu);

	/* CPU power UP */
	ret = regmap_update_bits(pmu, MESON_CPU_AO_RTI_PWR_A9_CNTL0,
				 MESON_CPU_PWR_A9_CNTL0_M(cpu), 0);
	if (ret < 0) {
		pr_err("Couldn't power up CPU%d\n", cpu);
		goto out;
	}

	udelay(5);

	/* Reset enable */
	ret = reset_control_assert(rstc);
	if (ret) {
		pr_err("Failed to assert CPU%d reset\n", cpu);
		goto out;
	}

	/* Memory power UP */
	ret = regmap_update_bits(pmu, MESON_CPU_AO_RTI_PWR_A9_MEM_PD0,
				 MESON_CPU_PWR_A9_MEM_PD0_M(cpu), 0);
	if (ret < 0) {
		pr_err("Couldn't power up the memory for CPU%d\n", cpu);
		goto out;
	}

	/* Wake up CPU */
	ret = regmap_update_bits(pmu, MESON_CPU_AO_RTI_PWR_A9_CNTL1,
				 MESON_CPU_PWR_A9_CNTL1_M(cpu), 0);
	if (ret < 0) {
		pr_err("Couldn't wake up CPU%d\n", cpu);
		goto out;
	}

	udelay(10);

	ret = regmap_read_poll_timeout(pmu, MESON_CPU_AO_RTI_PWR_A9_CNTL1, val,
				       val & MESON_CPU_PWR_A9_CNTL1_ST(cpu),
				       10, 10000);
	if (ret) {
		pr_err("Timeout while polling PMU for CPU%d status\n", cpu);
		goto out;
	}

	/* Isolation disable */
	ret = regmap_update_bits(pmu, MESON_CPU_AO_RTI_PWR_A9_CNTL0, BIT(cpu),
				 0);
	if (ret < 0) {
		pr_err("Error when disabling isolation of CPU%d\n", cpu);
		goto out;
	}

	/* Reset disable */
	ret = reset_control_deassert(rstc);
	if (ret) {
		pr_err("Failed to de-assert CPU%d reset\n", cpu);
		goto out;
	}

	ret = meson_smp_finalize_secondary_boot(cpu);
	if (ret)
		goto out;

out:
	reset_control_put(rstc);

	return 0;
}

#ifdef CONFIG_HOTPLUG_CPU
static void meson8_smp_cpu_die(unsigned int cpu)
{
	meson_smp_set_cpu_ctrl(cpu, false);

	v7_exit_coherency_flush(louis);

	scu_power_mode(scu_base, SCU_PM_POWEROFF);

	dsb();
	wfi();

	/* we should never get here */
	WARN_ON(1);
}

static int meson8_smp_cpu_kill(unsigned int cpu)
{
	int ret, power_mode;
	unsigned long timeout;

	timeout = jiffies + (50 * HZ);
	do {
		power_mode = scu_get_cpu_power_mode(scu_base, cpu);

		if (power_mode == SCU_PM_POWEROFF)
			break;

		usleep_range(10000, 15000);
	} while (time_before(jiffies, timeout));

	if (power_mode != SCU_PM_POWEROFF) {
		pr_err("Error while waiting for SCU power-off on CPU%d\n",
		       cpu);
		return -ETIMEDOUT;
	}

	msleep(30);

	/* Isolation enable */
	ret = regmap_update_bits(pmu, MESON_CPU_AO_RTI_PWR_A9_CNTL0, BIT(cpu),
				 0x3);
	if (ret < 0) {
		pr_err("Error when enabling isolation for CPU%d\n", cpu);
		return ret;
	}

	udelay(10);

	/* CPU power OFF */
	ret = regmap_update_bits(pmu, MESON_CPU_AO_RTI_PWR_A9_CNTL1,
				 MESON_CPU_PWR_A9_CNTL1_M(cpu), 0x3);
	if (ret < 0) {
		pr_err("Couldn't change sleep status of CPU%d\n", cpu);
		return ret;
	}

	return 1;
}

static int meson8b_smp_cpu_kill(unsigned int cpu)
{
	int ret, power_mode, count = 5000;

	do {
		power_mode = scu_get_cpu_power_mode(scu_base, cpu);

		if (power_mode == SCU_PM_POWEROFF)
			break;

		udelay(10);
	} while (++count);

	if (power_mode != SCU_PM_POWEROFF) {
		pr_err("Error while waiting for SCU power-off on CPU%d\n",
		       cpu);
		return -ETIMEDOUT;
	}

	udelay(10);

	/* CPU power DOWN */
	ret = regmap_update_bits(pmu, MESON_CPU_AO_RTI_PWR_A9_CNTL0,
				 MESON_CPU_PWR_A9_CNTL0_M(cpu), 0x3);
	if (ret < 0) {
		pr_err("Couldn't power down CPU%d\n", cpu);
		return ret;
	}

	/* Isolation enable */
	ret = regmap_update_bits(pmu, MESON_CPU_AO_RTI_PWR_A9_CNTL0, BIT(cpu),
				 0x3);
	if (ret < 0) {
		pr_err("Error when enabling isolation for CPU%d\n", cpu);
		return ret;
	}

	udelay(10);

	/* Sleep status */
	ret = regmap_update_bits(pmu, MESON_CPU_AO_RTI_PWR_A9_CNTL1,
				 MESON_CPU_PWR_A9_CNTL1_M(cpu), 0x3);
	if (ret < 0) {
		pr_err("Couldn't change sleep status of CPU%d\n", cpu);
		return ret;
	}

	/* Memory power DOWN */
	ret = regmap_update_bits(pmu, MESON_CPU_AO_RTI_PWR_A9_MEM_PD0,
				 MESON_CPU_PWR_A9_MEM_PD0_M(cpu), 0xf);
	if (ret < 0) {
		pr_err("Couldn't power down the memory of CPU%d\n", cpu);
		return ret;
	}

	return 1;
}
#endif

static struct smp_operations meson8_smp_ops __initdata = {
	.smp_prepare_cpus	= meson8_smp_prepare_cpus,
	.smp_boot_secondary	= meson8_smp_boot_secondary,
#ifdef CONFIG_HOTPLUG_CPU
	.cpu_die		= meson8_smp_cpu_die,
	.cpu_kill		= meson8_smp_cpu_kill,
#endif
};

static struct smp_operations meson8b_smp_ops __initdata = {
	.smp_prepare_cpus	= meson8b_smp_prepare_cpus,
	.smp_boot_secondary	= meson8b_smp_boot_secondary,
#ifdef CONFIG_HOTPLUG_CPU
	.cpu_die		= meson8_smp_cpu_die,
	.cpu_kill		= meson8b_smp_cpu_kill,
#endif
};

CPU_METHOD_OF_DECLARE(meson8_smp, "amlogic,meson8-smp", &meson8_smp_ops);
CPU_METHOD_OF_DECLARE(meson8b_smp, "amlogic,meson8b-smp", &meson8b_smp_ops);


code:
# SPDX-License-Identifier: GPL-2.0
menuconfig ARCH_MILBEAUT
	bool "Socionext Milbeaut SoCs"
	depends on ARCH_MULTI_V7
	select ARM_GIC
	help
	  This enables support for Socionext Milbeaut SoCs

if ARCH_MILBEAUT

config ARCH_MILBEAUT_M10V
	bool "Milbeaut SC2000/M10V platform"
	select ARM_ARCH_TIMER
	select MILBEAUT_TIMER
	select PINCTRL
	select PINCTRL_MILBEAUT
	help
	  Support for Socionext's MILBEAUT M10V based systems

endif

path: arch/arm/mach-milbeaut/Kconfig


code:
# SPDX-License-Identifier: GPL-2.0-only
obj-$(CONFIG_SMP) += platsmp.o

path: arch/arm/mach-milbeaut/Makefile


code:
// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright:	(C) 2018 Socionext Inc.
 * Copyright:	(C) 2015 Linaro Ltd.
 */

#include <linux/cpu_pm.h>
#include <linux/irqchip/arm-gic.h>
#include <linux/of_address.h>
#include <linux/suspend.h>

#include <asm/cacheflush.h>
#include <asm/cp15.h>
#include <asm/idmap.h>
#include <asm/smp_plat.h>
#include <asm/suspend.h>

#define M10V_MAX_CPU	4
#define KERNEL_UNBOOT_FLAG	0x12345678

static void __iomem *m10v_smp_base;

static int m10v_boot_secondary(unsigned int l_cpu, struct task_struct *idle)
{
	unsigned int mpidr, cpu, cluster;

	if (!m10v_smp_base)
		return -ENXIO;

	mpidr = cpu_logical_map(l_cpu);
	cpu = MPIDR_AFFINITY_LEVEL(mpidr, 0);
	cluster = MPIDR_AFFINITY_LEVEL(mpidr, 1);

	if (cpu >= M10V_MAX_CPU)
		return -EINVAL;

	pr_info("%s: cpu %u l_cpu %u cluster %u\n",
			__func__, cpu, l_cpu, cluster);

	writel(__pa_symbol(secondary_startup), m10v_smp_base + cpu * 4);
	arch_send_wakeup_ipi_mask(cpumask_of(l_cpu));

	return 0;
}

static void m10v_smp_init(unsigned int max_cpus)
{
	unsigned int mpidr, cpu, cluster;
	struct device_node *np;

	np = of_find_compatible_node(NULL, NULL, "socionext,milbeaut-smp-sram");
	if (!np)
		return;

	m10v_smp_base = of_iomap(np, 0);
	if (!m10v_smp_base)
		return;

	mpidr = read_cpuid_mpidr();
	cpu = MPIDR_AFFINITY_LEVEL(mpidr, 0);
	cluster = MPIDR_AFFINITY_LEVEL(mpidr, 1);
	pr_info("MCPM boot on cpu_%u cluster_%u\n", cpu, cluster);

	for (cpu = 0; cpu < M10V_MAX_CPU; cpu++)
		writel(KERNEL_UNBOOT_FLAG, m10v_smp_base + cpu * 4);
}

#ifdef CONFIG_HOTPLUG_CPU
static void m10v_cpu_die(unsigned int l_cpu)
{
	gic_cpu_if_down(0);
	v7_exit_coherency_flush(louis);
	wfi();
}

static int m10v_cpu_kill(unsigned int l_cpu)
{
	unsigned int mpidr, cpu;

	mpidr = cpu_logical_map(l_cpu);
	cpu = MPIDR_AFFINITY_LEVEL(mpidr, 0);

	writel(KERNEL_UNBOOT_FLAG, m10v_smp_base + cpu * 4);

	return 1;
}
#endif

static struct smp_operations m10v_smp_ops __initdata = {
	.smp_prepare_cpus	= m10v_smp_init,
	.smp_boot_secondary	= m10v_boot_secondary,
#ifdef CONFIG_HOTPLUG_CPU
	.cpu_die		= m10v_cpu_die,
	.cpu_kill		= m10v_cpu_kill,
#endif
};
CPU_METHOD_OF_DECLARE(m10v_smp, "socionext,milbeaut-m10v-smp", &m10v_smp_ops);

static int m10v_pm_valid(suspend_state_t state)
{
	return (state == PM_SUSPEND_STANDBY) || (state == PM_SUSPEND_MEM);
}

typedef void (*phys_reset_t)(unsigned long);
static phys_reset_t phys_reset;

static int m10v_die(unsigned long arg)
{
	setup_mm_for_reboot();
	asm("wfi");
	/* Boot just like a secondary */
	phys_reset = (phys_reset_t)(unsigned long)virt_to_phys(cpu_reset);
	phys_reset(virt_to_phys(cpu_resume));

	return 0;
}

static int m10v_pm_enter(suspend_state_t state)
{
	switch (state) {
	case PM_SUSPEND_STANDBY:
		asm("wfi");
		break;
	case PM_SUSPEND_MEM:
		cpu_pm_enter();
		cpu_suspend(0, m10v_die);
		cpu_pm_exit();
		break;
	}
	return 0;
}

static const struct platform_suspend_ops m10v_pm_ops = {
	.valid		= m10v_pm_valid,
	.enter		= m10v_pm_enter,
};

struct clk *m10v_clclk_register(struct device *cpu_dev);

static int __init m10v_pm_init(void)
{
	if (of_machine_is_compatible("socionext,milbeaut-evb"))
		suspend_set_ops(&m10v_pm_ops);

	return 0;
}
late_initcall(m10v_pm_init);


code:
# SPDX-License-Identifier: GPL-2.0-only
menuconfig ARCH_MMP
	bool "Marvell PXA168/910/MMP2/MMP3"
	depends on (CPU_LITTLE_ENDIAN && ARCH_MULTI_V5) || ARCH_MULTI_V7
	select GPIO_PXA
	select GPIOLIB
	select PINCTRL
	select PLAT_PXA
	help
	  Support for Marvell's PXA168/PXA910(MMP), MMP2, and MMP3 processor lines.

if ARCH_MMP

menu "Marvell PXA168/910/MMP2 Implementations"

if ATAGS

config MACH_ASPENITE
	bool "Marvell's PXA168 Aspenite Development Board"
	depends on ARCH_MULTI_V5
	depends on UNUSED_BOARD_FILES
	select CPU_PXA168
	help
	  Say 'Y' here if you want to support the Marvell PXA168-based
	  Aspenite Development Board.

config MACH_ZYLONITE2
	bool "Marvell's PXA168 Zylonite2 Development Board"
	depends on ARCH_MULTI_V5
	depends on UNUSED_BOARD_FILES
	select CPU_PXA168
	help
	  Say 'Y' here if you want to support the Marvell PXA168-based
	  Zylonite2 Development Board.

config MACH_AVENGERS_LITE
	bool "Marvell's PXA168 Avengers Lite Development Board"
	depends on ARCH_MULTI_V5
	depends on UNUSED_BOARD_FILES
	select CPU_PXA168
	help
	  Say 'Y' here if you want to support the Marvell PXA168-based
	  Avengers Lite Development Board.

config MACH_TTC_DKB
	bool "Marvell's PXA910 TavorEVB/TTC_DKB Development Board"
	depends on ARCH_MULTI_V5
	depends on UNUSED_BOARD_FILES
	select CPU_PXA910
	help
	  Say 'Y' here if you want to support the Marvell PXA910-based
	  TTC_DKB Development Board.

config MACH_BROWNSTONE
	bool "Marvell's Brownstone Development Platform"
	depends on ARCH_MULTI_V7
	depends on UNUSED_BOARD_FILES
	select CPU_MMP2
	help
	  Say 'Y' here if you want to support the Marvell MMP2-based
	  Brown Development Platform.
	  MMP2-based board can't be co-existed with PXA168-based &
	  PXA910-based development board. Since MMP2 is compatible to
	  ARMv7 architecture.

config MACH_FLINT
	bool "Marvell's Flint Development Platform"
	depends on ARCH_MULTI_V7
	depends on UNUSED_BOARD_FILES
	select CPU_MMP2
	help
	  Say 'Y' here if you want to support the Marvell MMP2-based
	  Flint Development Platform.
	  MMP2-based board can't be co-existed with PXA168-based &
	  PXA910-based development board. Since MMP2 is compatible to
	  ARMv7 architecture.

config MACH_MARVELL_JASPER
	bool "Marvell's Jasper Development Platform"
	depends on ARCH_MULTI_V7
	depends on UNUSED_BOARD_FILES
	select CPU_MMP2
	help
	  Say 'Y' here if you want to support the Marvell MMP2-base
	  Jasper Development Platform.
	  MMP2-based board can't be co-existed with PXA168-based &
	  PXA910-based development board. Since MMP2 is compatible to
	  ARMv7 architecture.

config MACH_TETON_BGA
	bool "Marvell's PXA168 Teton BGA Development Board"
	depends on ARCH_MULTI_V5
	depends on UNUSED_BOARD_FILES
	select CPU_PXA168
	help
	  Say 'Y' here if you want to support the Marvell PXA168-based
	  Teton BGA Development Board.

config MACH_GPLUGD
	bool "Marvell's PXA168 GuruPlug Display (gplugD) Board"
	depends on ARCH_MULTI_V5
	depends on UNUSED_BOARD_FILES
	select CPU_PXA168
	help
	  Say 'Y' here if you want to support the Marvell PXA168-based
	  GuruPlug Display (gplugD) Board
endif

config MACH_MMP_DT
	bool "Support MMP (ARMv5) platforms from device tree"
	depends on ARCH_MULTI_V5
	select PINCTRL
	select PINCTRL_SINGLE
	select ARCH_HAS_RESET_CONTROLLER
	select CPU_MOHAWK
	help
	  Include support for Marvell MMP2 based platforms using
	  the device tree. Needn't select any other machine while
	  MACH_MMP_DT is enabled.

config MACH_MMP2_DT
	bool "Support MMP2 (ARMv7) platforms from device tree"
	depends on ARCH_MULTI_V7
	select PINCTRL
	select PINCTRL_SINGLE
	select ARCH_HAS_RESET_CONTROLLER
	select CPU_PJ4
	select PM_GENERIC_DOMAINS if PM
	select PM_GENERIC_DOMAINS_OF if PM && OF
	help
	  Include support for Marvell MMP2 based platforms using
	  the device tree.

config MACH_MMP3_DT
	bool "Support MMP3 (ARMv7) platforms"
	depends on ARCH_MULTI_V7
	select ARM_GIC
	select HAVE_ARM_SCU if SMP
	select HAVE_ARM_TWD if SMP
	select CACHE_L2X0
	select PINCTRL
	select PINCTRL_SINGLE
	select ARCH_HAS_RESET_CONTROLLER
	select CPU_PJ4B
	select PM_GENERIC_DOMAINS if PM
	select PM_GENERIC_DOMAINS_OF if PM && OF
	help
	  Say 'Y' here if you want to include support for platforms
	  with Marvell MMP3 processor, also known as PXA2128 or
	  Armada 620.

endmenu

config CPU_PXA168
	bool
	select CPU_MOHAWK
	help
	  Select code specific to PXA168

config CPU_PXA910
	bool
	select CPU_MOHAWK
	help
	  Select code specific to PXA910

config CPU_MMP2
	bool
	select CPU_PJ4
	help
	  Select code specific to MMP2. MMP2 is ARMv7 compatible.

config USB_EHCI_MV_U2O
        bool "EHCI support for PXA USB OTG controller"
	depends on USB_EHCI_MV
	help
	  Enables support for OTG controller which can be switched to host mode.

config MMP_SRAM
	bool

endif

path: arch/arm/mach-mmp/Kconfig


code:
# SPDX-License-Identifier: GPL-2.0
#
# Makefile for Marvell's PXA168 processors line
#
obj-y				+= common.o devices.o time.o

# SoC support
obj-$(CONFIG_CPU_PXA168)	+= pxa168.o
obj-$(CONFIG_CPU_PXA910)	+= pxa910.o
obj-$(CONFIG_CPU_MMP2)		+= mmp2.o
obj-$(CONFIG_MMP_SRAM)		+= sram.o

ifeq ($(CONFIG_PM),y)
obj-$(CONFIG_CPU_PXA910)	+= pm-pxa910.o
obj-$(CONFIG_CPU_MMP2)		+= pm-mmp2.o
endif
ifeq ($(CONFIG_SMP),y)
obj-$(CONFIG_MACH_MMP3_DT)	+= platsmp.o
endif

# board support
obj-$(CONFIG_MACH_ASPENITE)	+= aspenite.o
obj-$(CONFIG_MACH_ZYLONITE2)	+= aspenite.o
obj-$(CONFIG_MACH_AVENGERS_LITE)+= avengers_lite.o
obj-$(CONFIG_MACH_TTC_DKB)	+= ttc_dkb.o
obj-$(CONFIG_MACH_BROWNSTONE)	+= brownstone.o
obj-$(CONFIG_MACH_FLINT)	+= flint.o
obj-$(CONFIG_MACH_MARVELL_JASPER) += jasper.o
obj-$(CONFIG_MACH_MMP_DT)	+= mmp-dt.o
obj-$(CONFIG_MACH_MMP2_DT)	+= mmp2-dt.o
obj-$(CONFIG_MACH_MMP3_DT)	+= mmp3.o
obj-$(CONFIG_MACH_TETON_BGA)	+= teton_bga.o
obj-$(CONFIG_MACH_GPLUGD)	+= gplugd.o

path: arch/arm/mach-mmp/Makefile


code:
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 *   Common address map definitions
 */

#ifndef __ASM_MACH_ADDR_MAP_H
#define __ASM_MACH_ADDR_MAP_H

/* APB - Application Subsystem Peripheral Bus
 *
 * NOTE: the DMA controller registers are actually on the AXI fabric #1
 * slave port to AHB/APB bridge, due to its close relationship to those
 * peripherals on APB, let's count it into the ABP mapping area.
 */
#define APB_PHYS_BASE		0xd4000000
#define APB_VIRT_BASE		IOMEM(0xfe000000)
#define APB_PHYS_SIZE		0x00200000

#define AXI_PHYS_BASE		0xd4200000
#define AXI_VIRT_BASE		IOMEM(0xfe200000)
#define AXI_PHYS_SIZE		0x00200000

#define PGU_PHYS_BASE		0xe0000000
#define PGU_VIRT_BASE		IOMEM(0xfe400000)
#define PGU_PHYS_SIZE		0x00100000

/* Static Memory Controller - Chip Select 0 and 1 */
#define SMC_CS0_PHYS_BASE	0x80000000
#define SMC_CS0_PHYS_SIZE	0x10000000
#define SMC_CS1_PHYS_BASE	0x90000000
#define SMC_CS1_PHYS_SIZE	0x10000000

#define APMU_VIRT_BASE		(AXI_VIRT_BASE + 0x82800)
#define APMU_REG(x)		(APMU_VIRT_BASE + (x))

#define APBC_VIRT_BASE		(APB_VIRT_BASE + 0x015000)
#define APBC_REG(x)		(APBC_VIRT_BASE + (x))

#define MPMU_VIRT_BASE		(APB_VIRT_BASE + 0x50000)
#define MPMU_REG(x)		(MPMU_VIRT_BASE + (x))

#define CIU_VIRT_BASE		(AXI_VIRT_BASE + 0x82c00)
#define CIU_REG(x)		(CIU_VIRT_BASE + (x))

#define SCU_VIRT_BASE		(PGU_VIRT_BASE)
#define SCU_REG(x)		(SCU_VIRT_BASE + (x))

#endif /* __ASM_MACH_ADDR_MAP_H */


code:
// SPDX-License-Identifier: GPL-2.0-only
/*
 *  linux/arch/arm/mach-mmp/aspenite.c
 *
 *  Support for the Marvell PXA168-based Aspenite and Zylonite2
 *  Development Platform.
 */
#include <linux/gpio.h>
#include <linux/gpio-pxa.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <linux/smc91x.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/rawnand.h>
#include <linux/interrupt.h>
#include <linux/platform_data/mv_usb.h>

#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <video/pxa168fb.h>
#include <linux/input.h>
#include <linux/platform_data/keypad-pxa27x.h>

#include "addr-map.h"
#include "mfp-pxa168.h"
#include "pxa168.h"
#include "pxa910.h"
#include "irqs.h"
#include "common.h"

static unsigned long common_pin_config[] __initdata = {
	/* Data Flash Interface */
	GPIO0_DFI_D15,
	GPIO1_DFI_D14,
	GPIO2_DFI_D13,
	GPIO3_DFI_D12,
	GPIO4_DFI_D11,
	GPIO5_DFI_D10,
	GPIO6_DFI_D9,
	GPIO7_DFI_D8,
	GPIO8_DFI_D7,
	GPIO9_DFI_D6,
	GPIO10_DFI_D5,
	GPIO11_DFI_D4,
	GPIO12_DFI_D3,
	GPIO13_DFI_D2,
	GPIO14_DFI_D1,
	GPIO15_DFI_D0,

	/* Static Memory Controller */
	GPIO18_SMC_nCS0,
	GPIO34_SMC_nCS1,
	GPIO23_SMC_nLUA,
	GPIO25_SMC_nLLA,
	GPIO28_SMC_RDY,
	GPIO29_SMC_SCLK,
	GPIO35_SMC_BE1,
	GPIO36_SMC_BE2,
	GPIO27_GPIO,	/* Ethernet IRQ */

	/* UART1 */
	GPIO107_UART1_RXD,
	GPIO108_UART1_TXD,

	/* SSP1 */
	GPIO113_I2S_MCLK,
	GPIO114_I2S_FRM,
	GPIO115_I2S_BCLK,
	GPIO116_I2S_RXD,
	GPIO117_I2S_TXD,

	/* LCD */
	GPIO56_LCD_FCLK_RD,
	GPIO57_LCD_LCLK_A0,
	GPIO58_LCD_PCLK_WR,
	GPIO59_LCD_DENA_BIAS,
	GPIO60_LCD_DD0,
	GPIO61_LCD_DD1,
	GPIO62_LCD_DD2,
	GPIO63_LCD_DD3,
	GPIO64_LCD_DD4,
	GPIO65_LCD_DD5,
	GPIO66_LCD_DD6,
	GPIO67_LCD_DD7,
	GPIO68_LCD_DD8,
	GPIO69_LCD_DD9,
	GPIO70_LCD_DD10,
	GPIO71_LCD_DD11,
	GPIO72_LCD_DD12,
	GPIO73_LCD_DD13,
	GPIO74_LCD_DD14,
	GPIO75_LCD_DD15,
	GPIO76_LCD_DD16,
	GPIO77_LCD_DD17,
	GPIO78_LCD_DD18,
	GPIO79_LCD_DD19,
	GPIO80_LCD_DD20,
	GPIO81_LCD_DD21,
	GPIO82_LCD_DD22,
	GPIO83_LCD_DD23,

	/* Keypad */
	GPIO109_KP_MKIN1,
	GPIO110_KP_MKIN0,
	GPIO111_KP_MKOUT7,
	GPIO112_KP_MKOUT6,
	GPIO121_KP_MKIN4,
};

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

static struct smc91x_platdata smc91x_info = {
	.flags	= SMC91X_USE_16BIT | SMC91X_NOWAIT,
};

static struct resource smc91x_resources[] = {
	[0] = {
		.start	= SMC_CS1_PHYS_BASE + 0x300,
		.end	= SMC_CS1_PHYS_BASE + 0xfffff,
		.flags	= IORESOURCE_MEM,
	},
	[1] = {
		.start	= MMP_GPIO_TO_IRQ(27),
		.end	= MMP_GPIO_TO_IRQ(27),
		.flags	= IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
	}
};

static struct platform_device smc91x_device = {
	.name		= "smc91x",
	.id		= 0,
	.dev		= {
		.platform_data = &smc91x_info,
	},
	.num_resources	= ARRAY_SIZE(smc91x_resources),
	.resource	= smc91x_resources,
};

static struct mtd_partition aspenite_nand_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 pxa3xx_nand_platform_data aspenite_nand_info = {
	.parts		= aspenite_nand_partitions,
	.nr_parts	= ARRAY_SIZE(aspenite_nand_partitions),
};

static struct i2c_board_info aspenite_i2c_info[] __initdata = {
	{ I2C_BOARD_INFO("wm8753", 0x1b), },
};

static struct fb_videomode video_modes[] = {
	[0] = {
		.pixclock	= 30120,
		.refresh	= 60,
		.xres		= 800,
		.yres		= 480,
		.hsync_len	= 1,
		.left_margin	= 215,
		.right_margin	= 40,
		.vsync_len	= 1,
		.upper_margin	= 34,
		.lower_margin	= 10,
		.sync		= FB_SYNC_VERT_HIGH_ACT | FB_SYNC_HOR_HIGH_ACT,
	},
};

struct pxa168fb_mach_info aspenite_lcd_info = {
	.id			= "Graphic Frame",
	.modes			= video_modes,
	.num_modes		= ARRAY_SIZE(video_modes),
	.pix_fmt		= PIX_FMT_RGB565,
	.io_pin_allocation_mode = PIN_MODE_DUMB_24,
	.dumb_mode		= DUMB_MODE_RGB888,
	.active			= 1,
	.panel_rbswap		= 0,
	.invert_pixclock	= 0,
};

static const unsigned int aspenite_matrix_key_map[] = {
	KEY(0, 6, KEY_UP),	/* SW 4 */
	KEY(0, 7, KEY_DOWN),	/* SW 5 */
	KEY(1, 6, KEY_LEFT),	/* SW 6 */
	KEY(1, 7, KEY_RIGHT),	/* SW 7 */
	KEY(4, 6, KEY_ENTER),	/* SW 8 */
	KEY(4, 7, KEY_ESC),	/* SW 9 */
};

static struct matrix_keymap_data aspenite_matrix_keymap_data = {
	.keymap			= aspenite_matrix_key_map,
	.keymap_size		= ARRAY_SIZE(aspenite_matrix_key_map),
};

static struct pxa27x_keypad_platform_data aspenite_keypad_info __initdata = {
	.matrix_key_rows	= 5,
	.matrix_key_cols	= 8,
	.matrix_keymap_data	= &aspenite_matrix_keymap_data,
	.debounce_interval	= 30,
};

#if IS_ENABLED(CONFIG_USB_EHCI_MV)
static struct mv_usb_platform_data pxa168_sph_pdata = {
	.mode           = MV_USB_MODE_HOST,
	.phy_init	= pxa_usb_phy_init,
	.phy_deinit	= pxa_usb_phy_deinit,
	.set_vbus	= NULL,
};
#endif

static void __init common_init(void)
{
	mfp_config(ARRAY_AND_SIZE(common_pin_config));

	/* on-chip devices */
	pxa168_add_uart(1);
	pxa168_add_twsi(1, NULL, ARRAY_AND_SIZE(aspenite_i2c_info));
	pxa168_add_ssp(1);
	pxa168_add_nand(&aspenite_nand_info);
	pxa168_add_fb(&aspenite_lcd_info);
	pxa168_add_keypad(&aspenite_keypad_info);
	platform_device_add_data(&pxa168_device_gpio, &pxa168_gpio_pdata,
				 sizeof(struct pxa_gpio_platform_data));
	platform_device_register(&pxa168_device_gpio);

	/* off-chip devices */
	platform_device_register(&smc91x_device);

#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_EHCI_MV)
	pxa168_add_usb_host(&pxa168_sph_pdata);
#endif
#endif
}

MACHINE_START(ASPENITE, "PXA168-based Aspenite Development Platform")
	.map_io		= mmp_map_io,
	.nr_irqs	= MMP_NR_IRQS,
	.init_irq       = pxa168_init_irq,
	.init_time	= pxa168_timer_init,
	.init_machine   = common_init,
	.restart	= pxa168_restart,
MACHINE_END

MACHINE_START(ZYLONITE2, "PXA168-based Zylonite2 Development Platform")
	.map_io		= mmp_map_io,
	.nr_irqs	= MMP_NR_IRQS,
	.init_irq       = pxa168_init_irq,
	.init_time	= pxa168_timer_init,
	.init_machine   = common_init,
	.restart	= pxa168_restart,
MACHINE_END


code:
// SPDX-License-Identifier: GPL-2.0-only
/*
 *  linux/arch/arm/mach-mmp/avengers_lite.c
 *
 *  Support for the Marvell PXA168-based Avengers lite Development Platform.
 *
 *  Copyright (C) 2009-2010 Marvell International Ltd.
 */

#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/gpio-pxa.h>
#include <linux/platform_device.h>

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

#include "common.h"
#include <linux/delay.h>

/* Avengers lite MFP configurations */
static unsigned long avengers_lite_pin_config_V16F[] __initdata = {
	/* DEBUG_UART */
	GPIO88_UART2_TXD,
	GPIO89_UART2_RXD,
};

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

static void __init avengers_lite_init(void)
{
	mfp_config(ARRAY_AND_SIZE(avengers_lite_pin_config_V16F));

	/* on-chip devices */
	pxa168_add_uart(2);
	platform_device_add_data(&pxa168_device_gpio, &pxa168_gpio_pdata,
				 sizeof(struct pxa_gpio_platform_data));
	platform_device_register(&pxa168_device_gpio);
}

MACHINE_START(AVENGERS_LITE, "PXA168 Avengers lite Development Platform")
	.map_io		= mmp_map_io,
	.nr_irqs	= MMP_NR_IRQS,
	.init_irq       = pxa168_init_irq,
	.init_time	= pxa168_timer_init,
	.init_machine   = avengers_lite_init,
	.restart	= pxa168_restart,
MACHINE_END


code:
// SPDX-License-Identifier: GPL-2.0-only
/*
 *  linux/arch/arm/mach-mmp/brownstone.c
 *
 *  Support for the Marvell Brownstone Development Platform.
 *
 *  Copyright (C) 2009-2010 Marvell International Ltd.
 */

#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/gpio-pxa.h>
#include <linux/gpio/machine.h>
#include <linux/regulator/machine.h>
#include <linux/regulator/max8649.h>
#include <linux/regulator/fixed.h>
#include <linux/mfd/max8925.h>

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

#include "common.h"

#define BROWNSTONE_NR_IRQS	(MMP_NR_IRQS + 40)

#define GPIO_5V_ENABLE		(89)

static unsigned long brownstone_pin_config[] __initdata = {
	/* UART1 */
	GPIO29_UART1_RXD,
	GPIO30_UART1_TXD,

	/* UART3 */
	GPIO51_UART3_RXD,
	GPIO52_UART3_TXD,

	/* DFI */
	GPIO168_DFI_D0,
	GPIO167_DFI_D1,
	GPIO166_DFI_D2,
	GPIO165_DFI_D3,
	GPIO107_DFI_D4,
	GPIO106_DFI_D5,
	GPIO105_DFI_D6,
	GPIO104_DFI_D7,
	GPIO111_DFI_D8,
	GPIO164_DFI_D9,
	GPIO163_DFI_D10,
	GPIO162_DFI_D11,
	GPIO161_DFI_D12,
	GPIO110_DFI_D13,
	GPIO109_DFI_D14,
	GPIO108_DFI_D15,
	GPIO143_ND_nCS0,
	GPIO144_ND_nCS1,
	GPIO147_ND_nWE,
	GPIO148_ND_nRE,
	GPIO150_ND_ALE,
	GPIO149_ND_CLE,
	GPIO112_ND_RDY0,
	GPIO160_ND_RDY1,

	/* PMIC */
	PMIC_PMIC_INT | MFP_LPM_EDGE_FALL,

	/* MMC0 */
	GPIO131_MMC1_DAT3 | MFP_PULL_HIGH,
	GPIO132_MMC1_DAT2 | MFP_PULL_HIGH,
	GPIO133_MMC1_DAT1 | MFP_PULL_HIGH,
	GPIO134_MMC1_DAT0 | MFP_PULL_HIGH,
	GPIO136_MMC1_CMD | MFP_PULL_HIGH,
	GPIO139_MMC1_CLK,
	GPIO140_MMC1_CD | MFP_PULL_LOW,
	GPIO141_MMC1_WP | MFP_PULL_LOW,

	/* MMC1 */
	GPIO37_MMC2_DAT3 | MFP_PULL_HIGH,
	GPIO38_MMC2_DAT2 | MFP_PULL_HIGH,
	GPIO39_MMC2_DAT1 | MFP_PULL_HIGH,
	GPIO40_MMC2_DAT0 | MFP_PULL_HIGH,
	GPIO41_MMC2_CMD | MFP_PULL_HIGH,
	GPIO42_MMC2_CLK,

	/* MMC2 */
	GPIO165_MMC3_DAT7 | MFP_PULL_HIGH,
	GPIO162_MMC3_DAT6 | MFP_PULL_HIGH,
	GPIO166_MMC3_DAT5 | MFP_PULL_HIGH,
	GPIO163_MMC3_DAT4 | MFP_PULL_HIGH,
	GPIO167_MMC3_DAT3 | MFP_PULL_HIGH,
	GPIO164_MMC3_DAT2 | MFP_PULL_HIGH,
	GPIO168_MMC3_DAT1 | MFP_PULL_HIGH,
	GPIO111_MMC3_DAT0 | MFP_PULL_HIGH,
	GPIO112_MMC3_CMD | MFP_PULL_HIGH,
	GPIO151_MMC3_CLK,

	/* 5V regulator */
	GPIO89_GPIO,
};

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

static struct regulator_consumer_supply max8649_supply[] = {
	REGULATOR_SUPPLY("vcc_core", NULL),
};

static struct regulator_init_data max8649_init_data = {
	.constraints	= {
		.name		= "vcc_core range",
		.min_uV		= 1150000,
		.max_uV		= 1280000,
		.always_on	= 1,
		.boot_on	= 1,
		.valid_ops_mask	= REGULATOR_CHANGE_VOLTAGE,
	},
	.num_consumer_supplies	= 1,
	.consumer_supplies	= &max8649_supply[0],
};

static struct max8649_platform_data brownstone_max8649_info = {
	.mode		= 2,	/* VID1 = 1, VID0 = 0 */
	.extclk		= 0,
	.ramp_timing	= MAX8649_RAMP_32MV,
	.regulator	= &max8649_init_data,
};

static struct regulator_consumer_supply brownstone_v_5vp_supplies[] = {
	REGULATOR_SUPPLY("v_5vp", NULL),
};

static struct regulator_init_data brownstone_v_5vp_data = {
	.constraints	= {
		.valid_ops_mask		= REGULATOR_CHANGE_STATUS,
	},
	.num_consumer_supplies	= ARRAY_SIZE(brownstone_v_5vp_supplies),
	.consumer_supplies	= brownstone_v_5vp_supplies,
};

static struct fixed_voltage_config brownstone_v_5vp = {
	.supply_name		= "v_5vp",
	.microvolts		= 5000000,
	.enabled_at_boot	= 1,
	.init_data		= &brownstone_v_5vp_data,
};

static struct platform_device brownstone_v_5vp_device = {
	.name		= "reg-fixed-voltage",
	.id		= 1,
	.dev = {
		.platform_data = &brownstone_v_5vp,
	},
};

static struct gpiod_lookup_table brownstone_v_5vp_gpiod_table = {
	.dev_id = "reg-fixed-voltage.1", /* .id set to 1 above */
	.table = {
		GPIO_LOOKUP("gpio-pxa", GPIO_5V_ENABLE,
			    NULL, GPIO_ACTIVE_HIGH),
		{ },
	},
};

static struct max8925_platform_data brownstone_max8925_info = {
	.irq_base		= MMP_NR_IRQS,
};

static struct i2c_board_info brownstone_twsi1_info[] = {
	[0] = {
		.type		= "max8649",
		.addr		= 0x60,
		.platform_data	= &brownstone_max8649_info,
	},
	[1] = {
		.type		= "max8925",
		.addr		= 0x3c,
		.irq		= IRQ_MMP2_PMIC,
		.platform_data	= &brownstone_max8925_info,
	},
};

static struct sdhci_pxa_platdata mmp2_sdh_platdata_mmc0 = {
	.clk_delay_cycles = 0x1f,
};

static struct sdhci_pxa_platdata mmp2_sdh_platdata_mmc2 = {
	.clk_delay_cycles = 0x1f,
	.flags = PXA_FLAG_CARD_PERMANENT
		| PXA_FLAG_SD_8_BIT_CAPABLE_SLOT,
};

static struct sram_platdata mmp2_asram_platdata = {
	.pool_name	= "asram",
	.granularity	= SRAM_GRANULARITY,
};

static struct sram_platdata mmp2_isram_platdata = {
	.pool_name	= "isram",
	.granularity	= SRAM_GRANULARITY,
};

static void __init brownstone_init(void)
{
	mfp_config(ARRAY_AND_SIZE(brownstone_pin_config));

	/* on-chip devices */
	mmp2_add_uart(1);
	mmp2_add_uart(3);
	platform_device_add_data(&mmp2_device_gpio, &mmp2_gpio_pdata,
				 sizeof(struct pxa_gpio_platform_data));
	platform_device_register(&mmp2_device_gpio);
	mmp2_add_twsi(1, NULL, ARRAY_AND_SIZE(brownstone_twsi1_info));
	mmp2_add_sdhost(0, &mmp2_sdh_platdata_mmc0); /* SD/MMC */
	mmp2_add_sdhost(2, &mmp2_sdh_platdata_mmc2); /* eMMC */
	mmp2_add_asram(&mmp2_asram_platdata);
	mmp2_add_isram(&mmp2_isram_platdata);

	/* enable 5v regulator */
	gpiod_add_lookup_table(&brownstone_v_5vp_gpiod_table);
	platform_device_register(&brownstone_v_5vp_device);
}

MACHINE_START(BROWNSTONE, "Brownstone Development Platform")
	/* Maintainer: Haojian Zhuang <haojian.zhuang@marvell.com> */
	.map_io		= mmp_map_io,
	.nr_irqs	= BROWNSTONE_NR_IRQS,
	.init_irq	= mmp2_init_irq,
	.init_time	= mmp2_timer_init,
	.init_machine	= brownstone_init,
	.restart	= mmp_restart,
MACHINE_END


code:
// SPDX-License-Identifier: GPL-2.0-only
/*
 *  linux/arch/arm/mach-mmp/common.c
 *
 *  Code common to PXA168 processor lines
 */

#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>

#include <asm/page.h>
#include <asm/mach/map.h>
#include <asm/system_misc.h>
#include "addr-map.h"
#include <linux/soc/mmp/cputype.h>

#include "common.h"

#define MMP_CHIPID	CIU_REG(0x00)

unsigned int mmp_chip_id;
EXPORT_SYMBOL(mmp_chip_id);

static struct map_desc standard_io_desc[] __initdata = {
	{
		.pfn		= __phys_to_pfn(APB_PHYS_BASE),
		.virtual	= (unsigned long)APB_VIRT_BASE,
		.length		= APB_PHYS_SIZE,
		.type		= MT_DEVICE,
	}, {
		.pfn		= __phys_to_pfn(AXI_PHYS_BASE),
		.virtual	= (unsigned long)AXI_VIRT_BASE,
		.length		= AXI_PHYS_SIZE,
		.type		= MT_DEVICE,
	},
};

static struct map_desc mmp2_io_desc[] __initdata = {
	{
		.pfn		= __phys_to_pfn(PGU_PHYS_BASE),
		.virtual	= (unsigned long)PGU_VIRT_BASE,
		.length		= PGU_PHYS_SIZE,
		.type		= MT_DEVICE,
	},
};

void __init mmp_map_io(void)
{
	iotable_init(standard_io_desc, ARRAY_SIZE(standard_io_desc));

	/* this is early, initialize mmp_chip_id here */
	mmp_chip_id = __raw_readl(MMP_CHIPID);
}

void __init mmp2_map_io(void)
{
	mmp_map_io();
	iotable_init(mmp2_io_desc, ARRAY_SIZE(mmp2_io_desc));
}

void mmp_restart(enum reboot_mode mode, const char *cmd)
{
	soft_restart(0);
}


code:
/* SPDX-License-Identifier: GPL-2.0 */
#include <linux/reboot.h>
#define ARRAY_AND_SIZE(x)	(x), ARRAY_SIZE(x)

extern void mmp_timer_init(int irq, unsigned long rate);

extern void __init mmp_map_io(void);
extern void __init mmp2_map_io(void);
extern void mmp_restart(enum reboot_mode, const char *);


code:
// SPDX-License-Identifier: GPL-2.0-only
/*
 * linux/arch/arm/mach-mmp/devices.c
 */

#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
#include <linux/delay.h>

#include <asm/irq.h>
#include "irqs.h"
#include "devices.h"
#include <linux/soc/mmp/cputype.h>
#include "regs-usb.h"

int __init mmp_register_device(struct mmp_device_desc *desc,
				void *data, size_t size)
{
	struct platform_device *pdev;
	struct resource res[2 + MAX_RESOURCE_DMA];
	int i, ret = 0, nres = 0;

	pdev = platform_device_alloc(desc->drv_name, desc->id);
	if (pdev == NULL)
		return -ENOMEM;

	pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);

	memset(res, 0, sizeof(res));

	if (desc->start != -1ul && desc->size > 0) {
		res[nres].start	= desc->start;
		res[nres].end	= desc->start + desc->size - 1;
		res[nres].flags	= IORESOURCE_MEM;
		nres++;
	}

	if (desc->irq != NO_IRQ) {
		res[nres].start	= desc->irq;
		res[nres].end	= desc->irq;
		res[nres].flags	= IORESOURCE_IRQ;
		nres++;
	}

	for (i = 0; i < MAX_RESOURCE_DMA; i++, nres++) {
		if (desc->dma[i] == 0)
			break;

		res[nres].start	= desc->dma[i];
		res[nres].end	= desc->dma[i];
		res[nres].flags	= IORESOURCE_DMA;
	}

	ret = platform_device_add_resources(pdev, res, nres);
	if (ret) {
		platform_device_put(pdev);
		return ret;
	}

	if (data && size) {
		ret = platform_device_add_data(pdev, data, size);
		if (ret) {
			platform_device_put(pdev);
			return ret;
		}
	}

	return platform_device_add(pdev);
}

#if IS_ENABLED(CONFIG_USB) || IS_ENABLED(CONFIG_USB_GADGET)
#if IS_ENABLED(CONFIG_USB_MV_UDC) || IS_ENABLED(CONFIG_USB_EHCI_MV)
#if IS_ENABLED(CONFIG_CPU_PXA910) || IS_ENABLED(CONFIG_CPU_PXA168)

/*****************************************************************************
 * The registers read/write routines
 *****************************************************************************/

static unsigned int u2o_get(void __iomem *base, unsigned int offset)
{
	return readl_relaxed(base + offset);
}

static void u2o_set(void __iomem *base, unsigned int offset,
		unsigned int value)
{
	u32 reg;

	reg = readl_relaxed(base + offset);
	reg |= value;
	writel_relaxed(reg, base + offset);
	readl_relaxed(base + offset);
}

static void u2o_clear(void __iomem *base, unsigned int offset,
		unsigned int value)
{
	u32 reg;

	reg = readl_relaxed(base + offset);
	reg &= ~value;
	writel_relaxed(reg, base + offset);
	readl_relaxed(base + offset);
}

static void u2o_write(void __iomem *base, unsigned int offset,
		unsigned int value)
{
	writel_relaxed(value, base + offset);
	readl_relaxed(base + offset);
}

static DEFINE_MUTEX(phy_lock);
static int phy_init_cnt;

static int usb_phy_init_internal(void __iomem *base)
{
	int loops;

	pr_info("Init usb phy!!!\n");

	/* Initialize the USB PHY power */
	if (cpu_is_pxa910()) {
		u2o_set(base, UTMI_CTRL, (1<<UTMI_CTRL_INPKT_DELAY_SOF_SHIFT)
			| (1<<UTMI_CTRL_PU_REF_SHIFT));
	}

	u2o_set(base, UTMI_CTRL, 1<<UTMI_CTRL_PLL_PWR_UP_SHIFT);
	u2o_set(base, UTMI_CTRL, 1<<UTMI_CTRL_PWR_UP_SHIFT);

	/* UTMI_PLL settings */
	u2o_clear(base, UTMI_PLL, UTMI_PLL_PLLVDD18_MASK
		| UTMI_PLL_PLLVDD12_MASK | UTMI_PLL_PLLCALI12_MASK
		| UTMI_PLL_FBDIV_MASK | UTMI_PLL_REFDIV_MASK
		| UTMI_PLL_ICP_MASK | UTMI_PLL_KVCO_MASK);

	u2o_set(base, UTMI_PLL, 0xee<<UTMI_PLL_FBDIV_SHIFT
		| 0xb<<UTMI_PLL_REFDIV_SHIFT | 3<<UTMI_PLL_PLLVDD18_SHIFT
		| 3<<UTMI_PLL_PLLVDD12_SHIFT | 3<<UTMI_PLL_PLLCALI12_SHIFT
		| 1<<UTMI_PLL_ICP_SHIFT | 3<<UTMI_PLL_KVCO_SHIFT);

	/* UTMI_TX */
	u2o_clear(base, UTMI_TX, UTMI_TX_REG_EXT_FS_RCAL_EN_MASK
		| UTMI_TX_TXVDD12_MASK | UTMI_TX_CK60_PHSEL_MASK
		| UTMI_TX_IMPCAL_VTH_MASK | UTMI_TX_REG_EXT_FS_RCAL_MASK
		| UTMI_TX_AMP_MASK);
	u2o_set(base, UTMI_TX, 3<<UTMI_TX_TXVDD12_SHIFT
		| 4<<UTMI_TX_CK60_PHSEL_SHIFT | 4<<UTMI_TX_IMPCAL_VTH_SHIFT
		| 8<<UTMI_TX_REG_EXT_FS_RCAL_SHIFT | 3<<UTMI_TX_AMP_SHIFT);

	/* UTMI_RX */
	u2o_clear(base, UTMI_RX, UTMI_RX_SQ_THRESH_MASK
		| UTMI_REG_SQ_LENGTH_MASK);
	u2o_set(base, UTMI_RX, 7<<UTMI_RX_SQ_THRESH_SHIFT
		| 2<<UTMI_REG_SQ_LENGTH_SHIFT);

	/* UTMI_IVREF */
	if (cpu_is_pxa168())
		/* fixing Microsoft Altair board interface with NEC hub issue -
		 * Set UTMI_IVREF from 0x4a3 to 0x4bf */
		u2o_write(base, UTMI_IVREF, 0x4bf);

	/* toggle VCOCAL_START bit of UTMI_PLL */
	udelay(200);
	u2o_set(base, UTMI_PLL, VCOCAL_START);
	udelay(40);
	u2o_clear(base, UTMI_PLL, VCOCAL_START);

	/* toggle REG_RCAL_START bit of UTMI_TX */
	udelay(400);
	u2o_set(base, UTMI_TX, REG_RCAL_START);
	udelay(40);
	u2o_clear(base, UTMI_TX, REG_RCAL_START);
	udelay(400);

	/* Make sure PHY PLL is ready */
	loops = 0;
	while ((u2o_get(base, UTMI_PLL) & PLL_READY) == 0) {
		mdelay(1);
		loops++;
		if (loops > 100) {
			printk(KERN_WARNING "calibrate timeout, UTMI_PLL %x\n",
				u2o_get(base, UTMI_PLL));
			break;
		}
	}

	if (cpu_is_pxa168()) {
		u2o_set(base, UTMI_RESERVE, 1 << 5);
		/* Turn on UTMI PHY OTG extension */
		u2o_write(base, UTMI_OTG_ADDON, 1);
	}

	return 0;
}

static int usb_phy_deinit_internal(void __iomem *base)
{
	pr_info("Deinit usb phy!!!\n");

	if (cpu_is_pxa168())
		u2o_clear(base, UTMI_OTG_ADDON, UTMI_OTG_ADDON_OTG_ON);

	u2o_clear(base, UTMI_CTRL, UTMI_CTRL_RXBUF_PDWN);
	u2o_clear(base, UTMI_CTRL, UTMI_CTRL_TXBUF_PDWN);
	u2o_clear(base, UTMI_CTRL, UTMI_CTRL_USB_CLK_EN);
	u2o_clear(base, UTMI_CTRL, 1<<UTMI_CTRL_PWR_UP_SHIFT);
	u2o_clear(base, UTMI_CTRL, 1<<UTMI_CTRL_PLL_PWR_UP_SHIFT);

	return 0;
}

int pxa_usb_phy_init(void __iomem *phy_reg)
{
	mutex_lock(&phy_lock);
	if (phy_init_cnt++ == 0)
		usb_phy_init_internal(phy_reg);
	mutex_unlock(&phy_lock);
	return 0;
}

void pxa_usb_phy_deinit(void __iomem *phy_reg)
{
	WARN_ON(phy_init_cnt == 0);

	mutex_lock(&phy_lock);
	if (--phy_init_cnt == 0)
		usb_phy_deinit_internal(phy_reg);
	mutex_unlock(&phy_lock);
}
#endif
#endif
#endif

#if IS_ENABLED(CONFIG_USB_SUPPORT)
static u64 __maybe_unused usb_dma_mask = ~(u32)0;

#if IS_ENABLED(CONFIG_PHY_PXA_USB)
static struct resource pxa168_usb_phy_resources[] = {
	[0] = {
		.start	= PXA168_U2O_PHYBASE,
		.end	= PXA168_U2O_PHYBASE + USB_PHY_RANGE,
		.flags	= IORESOURCE_MEM,
	},
};

struct platform_device pxa168_device_usb_phy = {
	.name		= "pxa-usb-phy",
	.id		= -1,
	.resource	= pxa168_usb_phy_resources,
	.num_resources	= ARRAY_SIZE(pxa168_usb_phy_resources),
	.dev		=  {
		.dma_mask	= &usb_dma_mask,
		.coherent_dma_mask = 0xffffffff,
	}
};
#endif /* CONFIG_PHY_PXA_USB */

#if IS_ENABLED(CONFIG_USB_MV_UDC)
static struct resource pxa168_u2o_resources[] = {
	/* regbase */
	[0] = {
		.start	= PXA168_U2O_REGBASE + U2x_CAPREGS_OFFSET,
		.end	= PXA168_U2O_REGBASE + USB_REG_RANGE,
		.flags	= IORESOURCE_MEM,
		.name	= "capregs",
	},
	/* phybase */
	[1] = {
		.start	= PXA168_U2O_PHYBASE,
		.end	= PXA168_U2O_PHYBASE + USB_PHY_RANGE,
		.flags	= IORESOURCE_MEM,
		.name	= "phyregs",
	},
	[2] = {
		.start	= IRQ_PXA168_USB1,
		.end	= IRQ_PXA168_USB1,
		.flags	= IORESOURCE_IRQ,
	},
};

struct platform_device pxa168_device_u2o = {
	.name		= "mv-udc",
	.id		= -1,
	.resource	= pxa168_u2o_resources,
	.num_resources	= ARRAY_SIZE(pxa168_u2o_resources),
	.dev		=  {
		.dma_mask	= &usb_dma_mask,
		.coherent_dma_mask = 0xffffffff,
	}
};
#endif /* CONFIG_USB_MV_UDC */

#if IS_ENABLED(CONFIG_USB_EHCI_MV_U2O)
static struct resource pxa168_u2oehci_resources[] = {
	[0] = {
		.start	= PXA168_U2O_REGBASE,
		.end	= PXA168_U2O_REGBASE + USB_REG_RANGE,
		.flags	= IORESOURCE_MEM,
	},
	[1] = {
		.start	= IRQ_PXA168_USB1,
		.end	= IRQ_PXA168_USB1,
		.flags	= IORESOURCE_IRQ,
	},
};

struct platform_device pxa168_device_u2oehci = {
	.name		= "pxa-u2oehci",
	.id		= -1,
	.dev		= {
		.dma_mask		= &usb_dma_mask,
		.coherent_dma_mask	= 0xffffffff,
	},

	.num_resources	= ARRAY_SIZE(pxa168_u2oehci_resources),
	.resource	= pxa168_u2oehci_resources,
};
#endif

#if IS_ENABLED(CONFIG_USB_MV_OTG)
static struct resource pxa168_u2ootg_resources[] = {
	/* regbase */
	[0] = {
		.start	= PXA168_U2O_REGBASE + U2x_CAPREGS_OFFSET,
		.end	= PXA168_U2O_REGBASE + USB_REG_RANGE,
		.flags	= IORESOURCE_MEM,
		.name	= "capregs",
	},
	/* phybase */
	[1] = {
		.start	= PXA168_U2O_PHYBASE,
		.end	= PXA168_U2O_PHYBASE + USB_PHY_RANGE,
		.flags	= IORESOURCE_MEM,
		.name	= "phyregs",
	},
	[2] = {
		.start	= IRQ_PXA168_USB1,
		.end	= IRQ_PXA168_USB1,
		.flags	= IORESOURCE_IRQ,
	},
};

struct platform_device pxa168_device_u2ootg = {
	.name		= "mv-otg",
	.id		= -1,
	.dev  = {
		.dma_mask          = &usb_dma_mask,
		.coherent_dma_mask = 0xffffffff,
	},

	.num_resources	= ARRAY_SIZE(pxa168_u2ootg_resources),
	.resource      = pxa168_u2ootg_resources,
};
#endif /* CONFIG_USB_MV_OTG */

#endif


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

#include <linux/types.h>

#define MAX_RESOURCE_DMA	2

/* structure for describing the on-chip devices */
struct mmp_device_desc {
	const char	*dev_name;
	const char	*drv_name;
	int		id;
	int		irq;
	unsigned long	start;
	unsigned long	size;
	int		dma[MAX_RESOURCE_DMA];
};

#define PXA168_DEVICE(_name, _drv, _id, _irq, _start, _size, _dma...)	\
struct mmp_device_desc pxa168_device_##_name __initdata = {		\
	.dev_name	= "pxa168-" #_name,				\
	.drv_name	= _drv,						\
	.id		= _id,						\
	.irq		= IRQ_PXA168_##_irq,				\
	.start		= _start,					\
	.size		= _size,					\
	.dma		= { _dma },					\
};

#define PXA910_DEVICE(_name, _drv, _id, _irq, _start, _size, _dma...)	\
struct mmp_device_desc pxa910_device_##_name __initdata = {		\
	.dev_name	= "pxa910-" #_name,				\
	.drv_name	= _drv,						\
	.id		= _id,						\
	.irq		= IRQ_PXA910_##_irq,				\
	.start		= _start,					\
	.size		= _size,					\
	.dma		= { _dma },					\
};

#define MMP2_DEVICE(_name, _drv, _id, _irq, _start, _size, _dma...)	\
struct mmp_device_desc mmp2_device_##_name __initdata = {		\
	.dev_name	= "mmp2-" #_name,				\
	.drv_name	= _drv,						\
	.id		= _id,						\
	.irq		= IRQ_MMP2_##_irq,				\
	.start		= _start,					\
	.size		= _size,					\
	.dma		= { _dma },					\
}

extern int mmp_register_device(struct mmp_device_desc *, void *, size_t);
extern int pxa_usb_phy_init(void __iomem *phy_reg);
extern void pxa_usb_phy_deinit(void __iomem *phy_reg);

#endif /* __MACH_DEVICE_H */