18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci *
48c2ecf20Sopenharmony_ci * arch/arm/mach-u300/core.c
58c2ecf20Sopenharmony_ci *
68c2ecf20Sopenharmony_ci * Copyright (C) 2007-2012 ST-Ericsson SA
78c2ecf20Sopenharmony_ci * Core platform support, IRQ handling and device definitions.
88c2ecf20Sopenharmony_ci * Author: Linus Walleij <linus.walleij@stericsson.com>
98c2ecf20Sopenharmony_ci */
108c2ecf20Sopenharmony_ci#include <linux/kernel.h>
118c2ecf20Sopenharmony_ci#include <linux/pinctrl/machine.h>
128c2ecf20Sopenharmony_ci#include <linux/pinctrl/pinconf-generic.h>
138c2ecf20Sopenharmony_ci#include <linux/platform_data/clk-u300.h>
148c2ecf20Sopenharmony_ci#include <linux/irqchip.h>
158c2ecf20Sopenharmony_ci#include <linux/of_address.h>
168c2ecf20Sopenharmony_ci#include <linux/of_platform.h>
178c2ecf20Sopenharmony_ci#include <linux/clocksource.h>
188c2ecf20Sopenharmony_ci#include <linux/clk.h>
198c2ecf20Sopenharmony_ci
208c2ecf20Sopenharmony_ci#include <asm/mach/map.h>
218c2ecf20Sopenharmony_ci#include <asm/mach/arch.h>
228c2ecf20Sopenharmony_ci
238c2ecf20Sopenharmony_ci/*
248c2ecf20Sopenharmony_ci * These are the large blocks of memory allocated for I/O.
258c2ecf20Sopenharmony_ci * the defines are used for setting up the I/O memory mapping.
268c2ecf20Sopenharmony_ci */
278c2ecf20Sopenharmony_ci
288c2ecf20Sopenharmony_ci/* NAND Flash CS0 */
298c2ecf20Sopenharmony_ci#define U300_NAND_CS0_PHYS_BASE		0x80000000
308c2ecf20Sopenharmony_ci/* NFIF */
318c2ecf20Sopenharmony_ci#define U300_NAND_IF_PHYS_BASE		0x9f800000
328c2ecf20Sopenharmony_ci/* ALE, CLE offset for FSMC NAND */
338c2ecf20Sopenharmony_ci#define PLAT_NAND_CLE			(1 << 16)
348c2ecf20Sopenharmony_ci#define PLAT_NAND_ALE			(1 << 17)
358c2ecf20Sopenharmony_ci/* AHB Peripherals */
368c2ecf20Sopenharmony_ci#define U300_AHB_PER_PHYS_BASE		0xa0000000
378c2ecf20Sopenharmony_ci#define U300_AHB_PER_VIRT_BASE		0xff010000
388c2ecf20Sopenharmony_ci/* FAST Peripherals */
398c2ecf20Sopenharmony_ci#define U300_FAST_PER_PHYS_BASE		0xc0000000
408c2ecf20Sopenharmony_ci#define U300_FAST_PER_VIRT_BASE		0xff020000
418c2ecf20Sopenharmony_ci/* SLOW Peripherals */
428c2ecf20Sopenharmony_ci#define U300_SLOW_PER_PHYS_BASE		0xc0010000
438c2ecf20Sopenharmony_ci#define U300_SLOW_PER_VIRT_BASE		0xff000000
448c2ecf20Sopenharmony_ci/* Boot ROM */
458c2ecf20Sopenharmony_ci#define U300_BOOTROM_PHYS_BASE		0xffff0000
468c2ecf20Sopenharmony_ci#define U300_BOOTROM_VIRT_BASE		0xffff0000
478c2ecf20Sopenharmony_ci/* SEMI config base */
488c2ecf20Sopenharmony_ci#define U300_SEMI_CONFIG_BASE		0x2FFE0000
498c2ecf20Sopenharmony_ci
508c2ecf20Sopenharmony_ci/*
518c2ecf20Sopenharmony_ci * AHB peripherals
528c2ecf20Sopenharmony_ci */
538c2ecf20Sopenharmony_ci
548c2ecf20Sopenharmony_ci/* AHB Peripherals Bridge Controller */
558c2ecf20Sopenharmony_ci#define U300_AHB_BRIDGE_BASE		(U300_AHB_PER_PHYS_BASE+0x0000)
568c2ecf20Sopenharmony_ci/* Vectored Interrupt Controller 0, servicing 32 interrupts */
578c2ecf20Sopenharmony_ci#define U300_INTCON0_BASE		(U300_AHB_PER_PHYS_BASE+0x1000)
588c2ecf20Sopenharmony_ci#define U300_INTCON0_VBASE		IOMEM(U300_AHB_PER_VIRT_BASE+0x1000)
598c2ecf20Sopenharmony_ci/* Vectored Interrupt Controller 1, servicing 32 interrupts */
608c2ecf20Sopenharmony_ci#define U300_INTCON1_BASE		(U300_AHB_PER_PHYS_BASE+0x2000)
618c2ecf20Sopenharmony_ci#define U300_INTCON1_VBASE		IOMEM(U300_AHB_PER_VIRT_BASE+0x2000)
628c2ecf20Sopenharmony_ci/* Memory Stick Pro (MSPRO) controller */
638c2ecf20Sopenharmony_ci#define U300_MSPRO_BASE			(U300_AHB_PER_PHYS_BASE+0x3000)
648c2ecf20Sopenharmony_ci/* EMIF Configuration Area */
658c2ecf20Sopenharmony_ci#define U300_EMIF_CFG_BASE		(U300_AHB_PER_PHYS_BASE+0x4000)
668c2ecf20Sopenharmony_ci
678c2ecf20Sopenharmony_ci/*
688c2ecf20Sopenharmony_ci * FAST peripherals
698c2ecf20Sopenharmony_ci */
708c2ecf20Sopenharmony_ci
718c2ecf20Sopenharmony_ci/* FAST bridge control */
728c2ecf20Sopenharmony_ci#define U300_FAST_BRIDGE_BASE		(U300_FAST_PER_PHYS_BASE+0x0000)
738c2ecf20Sopenharmony_ci/* MMC/SD controller */
748c2ecf20Sopenharmony_ci#define U300_MMCSD_BASE			(U300_FAST_PER_PHYS_BASE+0x1000)
758c2ecf20Sopenharmony_ci/* PCM I2S0 controller */
768c2ecf20Sopenharmony_ci#define U300_PCM_I2S0_BASE		(U300_FAST_PER_PHYS_BASE+0x2000)
778c2ecf20Sopenharmony_ci/* PCM I2S1 controller */
788c2ecf20Sopenharmony_ci#define U300_PCM_I2S1_BASE		(U300_FAST_PER_PHYS_BASE+0x3000)
798c2ecf20Sopenharmony_ci/* I2C0 controller */
808c2ecf20Sopenharmony_ci#define U300_I2C0_BASE			(U300_FAST_PER_PHYS_BASE+0x4000)
818c2ecf20Sopenharmony_ci/* I2C1 controller */
828c2ecf20Sopenharmony_ci#define U300_I2C1_BASE			(U300_FAST_PER_PHYS_BASE+0x5000)
838c2ecf20Sopenharmony_ci/* SPI controller */
848c2ecf20Sopenharmony_ci#define U300_SPI_BASE			(U300_FAST_PER_PHYS_BASE+0x6000)
858c2ecf20Sopenharmony_ci/* Fast UART1 on U335 only */
868c2ecf20Sopenharmony_ci#define U300_UART1_BASE			(U300_FAST_PER_PHYS_BASE+0x7000)
878c2ecf20Sopenharmony_ci
888c2ecf20Sopenharmony_ci/*
898c2ecf20Sopenharmony_ci * SLOW peripherals
908c2ecf20Sopenharmony_ci */
918c2ecf20Sopenharmony_ci
928c2ecf20Sopenharmony_ci/* SLOW bridge control */
938c2ecf20Sopenharmony_ci#define U300_SLOW_BRIDGE_BASE		(U300_SLOW_PER_PHYS_BASE)
948c2ecf20Sopenharmony_ci/* SYSCON */
958c2ecf20Sopenharmony_ci#define U300_SYSCON_BASE		(U300_SLOW_PER_PHYS_BASE+0x1000)
968c2ecf20Sopenharmony_ci#define U300_SYSCON_VBASE		IOMEM(U300_SLOW_PER_VIRT_BASE+0x1000)
978c2ecf20Sopenharmony_ci/* Watchdog */
988c2ecf20Sopenharmony_ci#define U300_WDOG_BASE			(U300_SLOW_PER_PHYS_BASE+0x2000)
998c2ecf20Sopenharmony_ci/* UART0 */
1008c2ecf20Sopenharmony_ci#define U300_UART0_BASE			(U300_SLOW_PER_PHYS_BASE+0x3000)
1018c2ecf20Sopenharmony_ci/* APP side special timer */
1028c2ecf20Sopenharmony_ci#define U300_TIMER_APP_BASE		(U300_SLOW_PER_PHYS_BASE+0x4000)
1038c2ecf20Sopenharmony_ci#define U300_TIMER_APP_VBASE		IOMEM(U300_SLOW_PER_VIRT_BASE+0x4000)
1048c2ecf20Sopenharmony_ci/* Keypad */
1058c2ecf20Sopenharmony_ci#define U300_KEYPAD_BASE		(U300_SLOW_PER_PHYS_BASE+0x5000)
1068c2ecf20Sopenharmony_ci/* GPIO */
1078c2ecf20Sopenharmony_ci#define U300_GPIO_BASE			(U300_SLOW_PER_PHYS_BASE+0x6000)
1088c2ecf20Sopenharmony_ci/* RTC */
1098c2ecf20Sopenharmony_ci#define U300_RTC_BASE			(U300_SLOW_PER_PHYS_BASE+0x7000)
1108c2ecf20Sopenharmony_ci/* Bus tracer */
1118c2ecf20Sopenharmony_ci#define U300_BUSTR_BASE			(U300_SLOW_PER_PHYS_BASE+0x8000)
1128c2ecf20Sopenharmony_ci/* Event handler (hardware queue) */
1138c2ecf20Sopenharmony_ci#define U300_EVHIST_BASE		(U300_SLOW_PER_PHYS_BASE+0x9000)
1148c2ecf20Sopenharmony_ci/* Genric Timer */
1158c2ecf20Sopenharmony_ci#define U300_TIMER_BASE			(U300_SLOW_PER_PHYS_BASE+0xa000)
1168c2ecf20Sopenharmony_ci/* PPM */
1178c2ecf20Sopenharmony_ci#define U300_PPM_BASE			(U300_SLOW_PER_PHYS_BASE+0xb000)
1188c2ecf20Sopenharmony_ci
1198c2ecf20Sopenharmony_ci/*
1208c2ecf20Sopenharmony_ci * REST peripherals
1218c2ecf20Sopenharmony_ci */
1228c2ecf20Sopenharmony_ci
1238c2ecf20Sopenharmony_ci/* ISP (image signal processor) */
1248c2ecf20Sopenharmony_ci#define U300_ISP_BASE			(0xA0008000)
1258c2ecf20Sopenharmony_ci/* DMA Controller base */
1268c2ecf20Sopenharmony_ci#define U300_DMAC_BASE			(0xC0020000)
1278c2ecf20Sopenharmony_ci/* MSL Base */
1288c2ecf20Sopenharmony_ci#define U300_MSL_BASE			(0xc0022000)
1298c2ecf20Sopenharmony_ci/* APEX Base */
1308c2ecf20Sopenharmony_ci#define U300_APEX_BASE			(0xc0030000)
1318c2ecf20Sopenharmony_ci/* Video Encoder Base */
1328c2ecf20Sopenharmony_ci#define U300_VIDEOENC_BASE		(0xc0080000)
1338c2ecf20Sopenharmony_ci/* XGAM Base */
1348c2ecf20Sopenharmony_ci#define U300_XGAM_BASE			(0xd0000000)
1358c2ecf20Sopenharmony_ci
1368c2ecf20Sopenharmony_ci/*
1378c2ecf20Sopenharmony_ci * SYSCON addresses applicable to the core machine.
1388c2ecf20Sopenharmony_ci */
1398c2ecf20Sopenharmony_ci
1408c2ecf20Sopenharmony_ci/* Chip ID register 16bit (R/-) */
1418c2ecf20Sopenharmony_ci#define U300_SYSCON_CIDR					(0x400)
1428c2ecf20Sopenharmony_ci/* SMCR */
1438c2ecf20Sopenharmony_ci#define U300_SYSCON_SMCR					(0x4d0)
1448c2ecf20Sopenharmony_ci#define U300_SYSCON_SMCR_FIELD_MASK				(0x000e)
1458c2ecf20Sopenharmony_ci#define U300_SYSCON_SMCR_SEMI_SREFACK_IND			(0x0008)
1468c2ecf20Sopenharmony_ci#define U300_SYSCON_SMCR_SEMI_SREFREQ_ENABLE			(0x0004)
1478c2ecf20Sopenharmony_ci#define U300_SYSCON_SMCR_SEMI_EXT_BOOT_MODE_ENABLE		(0x0002)
1488c2ecf20Sopenharmony_ci/* CPU_SW_DBGEN Software Debug Enable 16bit (R/W) */
1498c2ecf20Sopenharmony_ci#define U300_SYSCON_CSDR					(0x4f0)
1508c2ecf20Sopenharmony_ci#define U300_SYSCON_CSDR_SW_DEBUG_ENABLE			(0x0001)
1518c2ecf20Sopenharmony_ci/* PRINT_CONTROL Print Control 16bit (R/-) */
1528c2ecf20Sopenharmony_ci#define U300_SYSCON_PCR						(0x4f8)
1538c2ecf20Sopenharmony_ci#define U300_SYSCON_PCR_SERV_IND				(0x0001)
1548c2ecf20Sopenharmony_ci/* BOOT_CONTROL 16bit (R/-) */
1558c2ecf20Sopenharmony_ci#define U300_SYSCON_BCR						(0x4fc)
1568c2ecf20Sopenharmony_ci#define U300_SYSCON_BCR_ACC_CPU_SUBSYS_VINITHI_IND		(0x0400)
1578c2ecf20Sopenharmony_ci#define U300_SYSCON_BCR_APP_CPU_SUBSYS_VINITHI_IND		(0x0200)
1588c2ecf20Sopenharmony_ci#define U300_SYSCON_BCR_EXTRA_BOOT_OPTION_MASK			(0x01FC)
1598c2ecf20Sopenharmony_ci#define U300_SYSCON_BCR_APP_BOOT_SERV_MASK			(0x0003)
1608c2ecf20Sopenharmony_ci
1618c2ecf20Sopenharmony_cistatic void __iomem *syscon_base;
1628c2ecf20Sopenharmony_ci
1638c2ecf20Sopenharmony_ci/*
1648c2ecf20Sopenharmony_ci * Static I/O mappings that are needed for booting the U300 platforms. The
1658c2ecf20Sopenharmony_ci * only things we need are the areas where we find the timer, syscon and
1668c2ecf20Sopenharmony_ci * intcon, since the remaining device drivers will map their own memory
1678c2ecf20Sopenharmony_ci * physical to virtual as the need arise.
1688c2ecf20Sopenharmony_ci */
1698c2ecf20Sopenharmony_cistatic struct map_desc u300_io_desc[] __initdata = {
1708c2ecf20Sopenharmony_ci	{
1718c2ecf20Sopenharmony_ci		.virtual	= U300_SLOW_PER_VIRT_BASE,
1728c2ecf20Sopenharmony_ci		.pfn		= __phys_to_pfn(U300_SLOW_PER_PHYS_BASE),
1738c2ecf20Sopenharmony_ci		.length		= SZ_64K,
1748c2ecf20Sopenharmony_ci		.type		= MT_DEVICE,
1758c2ecf20Sopenharmony_ci	},
1768c2ecf20Sopenharmony_ci	{
1778c2ecf20Sopenharmony_ci		.virtual	= U300_AHB_PER_VIRT_BASE,
1788c2ecf20Sopenharmony_ci		.pfn		= __phys_to_pfn(U300_AHB_PER_PHYS_BASE),
1798c2ecf20Sopenharmony_ci		.length		= SZ_32K,
1808c2ecf20Sopenharmony_ci		.type		= MT_DEVICE,
1818c2ecf20Sopenharmony_ci	},
1828c2ecf20Sopenharmony_ci	{
1838c2ecf20Sopenharmony_ci		.virtual	= U300_FAST_PER_VIRT_BASE,
1848c2ecf20Sopenharmony_ci		.pfn		= __phys_to_pfn(U300_FAST_PER_PHYS_BASE),
1858c2ecf20Sopenharmony_ci		.length		= SZ_32K,
1868c2ecf20Sopenharmony_ci		.type		= MT_DEVICE,
1878c2ecf20Sopenharmony_ci	},
1888c2ecf20Sopenharmony_ci};
1898c2ecf20Sopenharmony_ci
1908c2ecf20Sopenharmony_cistatic void __init u300_map_io(void)
1918c2ecf20Sopenharmony_ci{
1928c2ecf20Sopenharmony_ci	iotable_init(u300_io_desc, ARRAY_SIZE(u300_io_desc));
1938c2ecf20Sopenharmony_ci}
1948c2ecf20Sopenharmony_ci
1958c2ecf20Sopenharmony_cistatic unsigned long pin_pullup_conf[] = {
1968c2ecf20Sopenharmony_ci	PIN_CONF_PACKED(PIN_CONFIG_BIAS_PULL_UP, 1),
1978c2ecf20Sopenharmony_ci};
1988c2ecf20Sopenharmony_ci
1998c2ecf20Sopenharmony_cistatic unsigned long pin_highz_conf[] = {
2008c2ecf20Sopenharmony_ci	PIN_CONF_PACKED(PIN_CONFIG_BIAS_HIGH_IMPEDANCE, 0),
2018c2ecf20Sopenharmony_ci};
2028c2ecf20Sopenharmony_ci
2038c2ecf20Sopenharmony_ci/* Pin control settings */
2048c2ecf20Sopenharmony_cistatic const struct pinctrl_map u300_pinmux_map[] = {
2058c2ecf20Sopenharmony_ci	/* anonymous maps for chip power and EMIFs */
2068c2ecf20Sopenharmony_ci	PIN_MAP_MUX_GROUP_HOG_DEFAULT("pinctrl-u300", NULL, "power"),
2078c2ecf20Sopenharmony_ci	PIN_MAP_MUX_GROUP_HOG_DEFAULT("pinctrl-u300", NULL, "emif0"),
2088c2ecf20Sopenharmony_ci	PIN_MAP_MUX_GROUP_HOG_DEFAULT("pinctrl-u300", NULL, "emif1"),
2098c2ecf20Sopenharmony_ci	/* per-device maps for MMC/SD, SPI and UART */
2108c2ecf20Sopenharmony_ci	PIN_MAP_MUX_GROUP_DEFAULT("mmci",  "pinctrl-u300", NULL, "mmc0"),
2118c2ecf20Sopenharmony_ci	PIN_MAP_MUX_GROUP_DEFAULT("pl022", "pinctrl-u300", NULL, "spi0"),
2128c2ecf20Sopenharmony_ci	PIN_MAP_MUX_GROUP_DEFAULT("uart0", "pinctrl-u300", NULL, "uart0"),
2138c2ecf20Sopenharmony_ci	/* This pin is used for clock return rather than GPIO */
2148c2ecf20Sopenharmony_ci	PIN_MAP_CONFIGS_PIN_DEFAULT("mmci", "pinctrl-u300", "PIO APP GPIO 11",
2158c2ecf20Sopenharmony_ci				    pin_pullup_conf),
2168c2ecf20Sopenharmony_ci	/* This pin is used for card detect */
2178c2ecf20Sopenharmony_ci	PIN_MAP_CONFIGS_PIN_DEFAULT("mmci", "pinctrl-u300", "PIO MS INS",
2188c2ecf20Sopenharmony_ci				    pin_highz_conf),
2198c2ecf20Sopenharmony_ci};
2208c2ecf20Sopenharmony_ci
2218c2ecf20Sopenharmony_cistruct db_chip {
2228c2ecf20Sopenharmony_ci	u16 chipid;
2238c2ecf20Sopenharmony_ci	const char *name;
2248c2ecf20Sopenharmony_ci};
2258c2ecf20Sopenharmony_ci
2268c2ecf20Sopenharmony_ci/*
2278c2ecf20Sopenharmony_ci * This is a list of the Digital Baseband chips used in the U300 platform.
2288c2ecf20Sopenharmony_ci */
2298c2ecf20Sopenharmony_cistatic struct db_chip db_chips[] __initdata = {
2308c2ecf20Sopenharmony_ci	{
2318c2ecf20Sopenharmony_ci		.chipid = 0xb800,
2328c2ecf20Sopenharmony_ci		.name = "DB3000",
2338c2ecf20Sopenharmony_ci	},
2348c2ecf20Sopenharmony_ci	{
2358c2ecf20Sopenharmony_ci		.chipid = 0xc000,
2368c2ecf20Sopenharmony_ci		.name = "DB3100",
2378c2ecf20Sopenharmony_ci	},
2388c2ecf20Sopenharmony_ci	{
2398c2ecf20Sopenharmony_ci		.chipid = 0xc800,
2408c2ecf20Sopenharmony_ci		.name = "DB3150",
2418c2ecf20Sopenharmony_ci	},
2428c2ecf20Sopenharmony_ci	{
2438c2ecf20Sopenharmony_ci		.chipid = 0xd800,
2448c2ecf20Sopenharmony_ci		.name = "DB3200",
2458c2ecf20Sopenharmony_ci	},
2468c2ecf20Sopenharmony_ci	{
2478c2ecf20Sopenharmony_ci		.chipid = 0xe000,
2488c2ecf20Sopenharmony_ci		.name = "DB3250",
2498c2ecf20Sopenharmony_ci	},
2508c2ecf20Sopenharmony_ci	{
2518c2ecf20Sopenharmony_ci		.chipid = 0xe800,
2528c2ecf20Sopenharmony_ci		.name = "DB3210",
2538c2ecf20Sopenharmony_ci	},
2548c2ecf20Sopenharmony_ci	{
2558c2ecf20Sopenharmony_ci		.chipid = 0xf000,
2568c2ecf20Sopenharmony_ci		.name = "DB3350 P1x",
2578c2ecf20Sopenharmony_ci	},
2588c2ecf20Sopenharmony_ci	{
2598c2ecf20Sopenharmony_ci		.chipid = 0xf100,
2608c2ecf20Sopenharmony_ci		.name = "DB3350 P2x",
2618c2ecf20Sopenharmony_ci	},
2628c2ecf20Sopenharmony_ci	{
2638c2ecf20Sopenharmony_ci		.chipid = 0x0000, /* List terminator */
2648c2ecf20Sopenharmony_ci		.name = NULL,
2658c2ecf20Sopenharmony_ci	}
2668c2ecf20Sopenharmony_ci};
2678c2ecf20Sopenharmony_ci
2688c2ecf20Sopenharmony_cistatic void __init u300_init_check_chip(void)
2698c2ecf20Sopenharmony_ci{
2708c2ecf20Sopenharmony_ci
2718c2ecf20Sopenharmony_ci	u16 val;
2728c2ecf20Sopenharmony_ci	struct db_chip *chip;
2738c2ecf20Sopenharmony_ci	const char *chipname;
2748c2ecf20Sopenharmony_ci	const char unknown[] = "UNKNOWN";
2758c2ecf20Sopenharmony_ci
2768c2ecf20Sopenharmony_ci	/* Read out and print chip ID */
2778c2ecf20Sopenharmony_ci	val = readw(syscon_base + U300_SYSCON_CIDR);
2788c2ecf20Sopenharmony_ci	/* This is in funky bigendian order... */
2798c2ecf20Sopenharmony_ci	val = (val & 0xFFU) << 8 | (val >> 8);
2808c2ecf20Sopenharmony_ci	chip = db_chips;
2818c2ecf20Sopenharmony_ci	chipname = unknown;
2828c2ecf20Sopenharmony_ci
2838c2ecf20Sopenharmony_ci	for ( ; chip->chipid; chip++) {
2848c2ecf20Sopenharmony_ci		if (chip->chipid == (val & 0xFF00U)) {
2858c2ecf20Sopenharmony_ci			chipname = chip->name;
2868c2ecf20Sopenharmony_ci			break;
2878c2ecf20Sopenharmony_ci		}
2888c2ecf20Sopenharmony_ci	}
2898c2ecf20Sopenharmony_ci	printk(KERN_INFO "Initializing U300 system on %s baseband chip " \
2908c2ecf20Sopenharmony_ci	       "(chip ID 0x%04x)\n", chipname, val);
2918c2ecf20Sopenharmony_ci
2928c2ecf20Sopenharmony_ci	if ((val & 0xFF00U) != 0xf000 && (val & 0xFF00U) != 0xf100) {
2938c2ecf20Sopenharmony_ci		printk(KERN_ERR "Platform configured for BS335 " \
2948c2ecf20Sopenharmony_ci		       " with DB3350 but %s detected, expect problems!",
2958c2ecf20Sopenharmony_ci		       chipname);
2968c2ecf20Sopenharmony_ci	}
2978c2ecf20Sopenharmony_ci}
2988c2ecf20Sopenharmony_ci
2998c2ecf20Sopenharmony_ci/* Forward declare this function from the watchdog */
3008c2ecf20Sopenharmony_civoid coh901327_watchdog_reset(void);
3018c2ecf20Sopenharmony_ci
3028c2ecf20Sopenharmony_cistatic void u300_restart(enum reboot_mode mode, const char *cmd)
3038c2ecf20Sopenharmony_ci{
3048c2ecf20Sopenharmony_ci	switch (mode) {
3058c2ecf20Sopenharmony_ci	case REBOOT_SOFT:
3068c2ecf20Sopenharmony_ci	case REBOOT_HARD:
3078c2ecf20Sopenharmony_ci#ifdef CONFIG_COH901327_WATCHDOG
3088c2ecf20Sopenharmony_ci		coh901327_watchdog_reset();
3098c2ecf20Sopenharmony_ci#endif
3108c2ecf20Sopenharmony_ci		break;
3118c2ecf20Sopenharmony_ci	default:
3128c2ecf20Sopenharmony_ci		/* Do nothing */
3138c2ecf20Sopenharmony_ci		break;
3148c2ecf20Sopenharmony_ci	}
3158c2ecf20Sopenharmony_ci	/* Wait for system do die/reset. */
3168c2ecf20Sopenharmony_ci	while (1);
3178c2ecf20Sopenharmony_ci}
3188c2ecf20Sopenharmony_ci
3198c2ecf20Sopenharmony_ci/* These are mostly to get the right device names for the clock lookups */
3208c2ecf20Sopenharmony_cistatic struct of_dev_auxdata u300_auxdata_lookup[] __initdata = {
3218c2ecf20Sopenharmony_ci	OF_DEV_AUXDATA("stericsson,pinctrl-u300", U300_SYSCON_BASE,
3228c2ecf20Sopenharmony_ci		"pinctrl-u300", NULL),
3238c2ecf20Sopenharmony_ci	OF_DEV_AUXDATA("stericsson,gpio-coh901", U300_GPIO_BASE,
3248c2ecf20Sopenharmony_ci		"u300-gpio", NULL),
3258c2ecf20Sopenharmony_ci	OF_DEV_AUXDATA("stericsson,coh901327", U300_WDOG_BASE,
3268c2ecf20Sopenharmony_ci		"coh901327_wdog", NULL),
3278c2ecf20Sopenharmony_ci	OF_DEV_AUXDATA("stericsson,coh901331", U300_RTC_BASE,
3288c2ecf20Sopenharmony_ci		"rtc-coh901331", NULL),
3298c2ecf20Sopenharmony_ci	OF_DEV_AUXDATA("stericsson,coh901318", U300_DMAC_BASE,
3308c2ecf20Sopenharmony_ci		"coh901318", NULL),
3318c2ecf20Sopenharmony_ci	OF_DEV_AUXDATA("stericsson,fsmc-nand", U300_NAND_IF_PHYS_BASE,
3328c2ecf20Sopenharmony_ci		"fsmc-nand", NULL),
3338c2ecf20Sopenharmony_ci	OF_DEV_AUXDATA("arm,primecell", U300_UART0_BASE,
3348c2ecf20Sopenharmony_ci		"uart0", NULL),
3358c2ecf20Sopenharmony_ci	OF_DEV_AUXDATA("arm,primecell", U300_UART1_BASE,
3368c2ecf20Sopenharmony_ci		"uart1", NULL),
3378c2ecf20Sopenharmony_ci	OF_DEV_AUXDATA("arm,primecell", U300_SPI_BASE,
3388c2ecf20Sopenharmony_ci		"pl022", NULL),
3398c2ecf20Sopenharmony_ci	OF_DEV_AUXDATA("st,ddci2c", U300_I2C0_BASE,
3408c2ecf20Sopenharmony_ci		"stu300.0", NULL),
3418c2ecf20Sopenharmony_ci	OF_DEV_AUXDATA("st,ddci2c", U300_I2C1_BASE,
3428c2ecf20Sopenharmony_ci		"stu300.1", NULL),
3438c2ecf20Sopenharmony_ci	OF_DEV_AUXDATA("arm,primecell", U300_MMCSD_BASE,
3448c2ecf20Sopenharmony_ci		"mmci", NULL),
3458c2ecf20Sopenharmony_ci	{ /* sentinel */ },
3468c2ecf20Sopenharmony_ci};
3478c2ecf20Sopenharmony_ci
3488c2ecf20Sopenharmony_cistatic void __init u300_init_irq_dt(void)
3498c2ecf20Sopenharmony_ci{
3508c2ecf20Sopenharmony_ci	struct device_node *syscon;
3518c2ecf20Sopenharmony_ci	struct clk *clk;
3528c2ecf20Sopenharmony_ci
3538c2ecf20Sopenharmony_ci	syscon = of_find_node_by_path("/syscon@c0011000");
3548c2ecf20Sopenharmony_ci	if (!syscon) {
3558c2ecf20Sopenharmony_ci		pr_crit("could not find syscon node\n");
3568c2ecf20Sopenharmony_ci		return;
3578c2ecf20Sopenharmony_ci	}
3588c2ecf20Sopenharmony_ci	syscon_base = of_iomap(syscon, 0);
3598c2ecf20Sopenharmony_ci	if (!syscon_base) {
3608c2ecf20Sopenharmony_ci		pr_crit("could not remap syscon\n");
3618c2ecf20Sopenharmony_ci		return;
3628c2ecf20Sopenharmony_ci	}
3638c2ecf20Sopenharmony_ci	/* initialize clocking early, we want to clock the INTCON */
3648c2ecf20Sopenharmony_ci	u300_clk_init(syscon_base);
3658c2ecf20Sopenharmony_ci
3668c2ecf20Sopenharmony_ci	/* Bootstrap EMIF and SEMI clocks */
3678c2ecf20Sopenharmony_ci	clk = clk_get_sys("pl172", NULL);
3688c2ecf20Sopenharmony_ci	BUG_ON(IS_ERR(clk));
3698c2ecf20Sopenharmony_ci	clk_prepare_enable(clk);
3708c2ecf20Sopenharmony_ci	clk = clk_get_sys("semi", NULL);
3718c2ecf20Sopenharmony_ci	BUG_ON(IS_ERR(clk));
3728c2ecf20Sopenharmony_ci	clk_prepare_enable(clk);
3738c2ecf20Sopenharmony_ci
3748c2ecf20Sopenharmony_ci	/* Clock the interrupt controller */
3758c2ecf20Sopenharmony_ci	clk = clk_get_sys("intcon", NULL);
3768c2ecf20Sopenharmony_ci	BUG_ON(IS_ERR(clk));
3778c2ecf20Sopenharmony_ci	clk_prepare_enable(clk);
3788c2ecf20Sopenharmony_ci
3798c2ecf20Sopenharmony_ci	irqchip_init();
3808c2ecf20Sopenharmony_ci}
3818c2ecf20Sopenharmony_ci
3828c2ecf20Sopenharmony_cistatic void __init u300_init_machine_dt(void)
3838c2ecf20Sopenharmony_ci{
3848c2ecf20Sopenharmony_ci	u16 val;
3858c2ecf20Sopenharmony_ci
3868c2ecf20Sopenharmony_ci	/* Check what platform we run and print some status information */
3878c2ecf20Sopenharmony_ci	u300_init_check_chip();
3888c2ecf20Sopenharmony_ci
3898c2ecf20Sopenharmony_ci	/* Initialize pinmuxing */
3908c2ecf20Sopenharmony_ci	pinctrl_register_mappings(u300_pinmux_map,
3918c2ecf20Sopenharmony_ci				  ARRAY_SIZE(u300_pinmux_map));
3928c2ecf20Sopenharmony_ci
3938c2ecf20Sopenharmony_ci	of_platform_default_populate(NULL, u300_auxdata_lookup, NULL);
3948c2ecf20Sopenharmony_ci
3958c2ecf20Sopenharmony_ci	/* Enable SEMI self refresh */
3968c2ecf20Sopenharmony_ci	val = readw(syscon_base + U300_SYSCON_SMCR) |
3978c2ecf20Sopenharmony_ci		U300_SYSCON_SMCR_SEMI_SREFREQ_ENABLE;
3988c2ecf20Sopenharmony_ci	writew(val, syscon_base + U300_SYSCON_SMCR);
3998c2ecf20Sopenharmony_ci}
4008c2ecf20Sopenharmony_ci
4018c2ecf20Sopenharmony_cistatic const char * u300_board_compat[] = {
4028c2ecf20Sopenharmony_ci	"stericsson,u300",
4038c2ecf20Sopenharmony_ci	NULL,
4048c2ecf20Sopenharmony_ci};
4058c2ecf20Sopenharmony_ci
4068c2ecf20Sopenharmony_ciDT_MACHINE_START(U300_DT, "U300 S335/B335 (Device Tree)")
4078c2ecf20Sopenharmony_ci	.map_io		= u300_map_io,
4088c2ecf20Sopenharmony_ci	.init_irq	= u300_init_irq_dt,
4098c2ecf20Sopenharmony_ci	.init_time	= timer_probe,
4108c2ecf20Sopenharmony_ci	.init_machine	= u300_init_machine_dt,
4118c2ecf20Sopenharmony_ci	.restart	= u300_restart,
4128c2ecf20Sopenharmony_ci	.dt_compat      = u300_board_compat,
4138c2ecf20Sopenharmony_ciMACHINE_END
414