cregit-Linux how code gets into the kernel

Release 4.11 arch/arm/mach-u300/core.c

/*
 *
 * arch/arm/mach-u300/core.c
 *
 *
 * Copyright (C) 2007-2012 ST-Ericsson SA
 * License terms: GNU General Public License (GPL) version 2
 * Core platform support, IRQ handling and device definitions.
 * Author: Linus Walleij <linus.walleij@stericsson.com>
 */
#include <linux/kernel.h>
#include <linux/pinctrl/machine.h>
#include <linux/pinctrl/pinconf-generic.h>
#include <linux/platform_data/clk-u300.h>
#include <linux/irqchip.h>
#include <linux/of_address.h>
#include <linux/of_platform.h>
#include <linux/clocksource.h>
#include <linux/clk.h>

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

/*
 * These are the large blocks of memory allocated for I/O.
 * the defines are used for setting up the I/O memory mapping.
 */

/* NAND Flash CS0 */

#define U300_NAND_CS0_PHYS_BASE		0x80000000
/* NFIF */

#define U300_NAND_IF_PHYS_BASE		0x9f800000
/* ALE, CLE offset for FSMC NAND */

#define PLAT_NAND_CLE			(1 << 16)

#define PLAT_NAND_ALE			(1 << 17)
/* AHB Peripherals */

#define U300_AHB_PER_PHYS_BASE		0xa0000000

#define U300_AHB_PER_VIRT_BASE		0xff010000
/* FAST Peripherals */

#define U300_FAST_PER_PHYS_BASE		0xc0000000

#define U300_FAST_PER_VIRT_BASE		0xff020000
/* SLOW Peripherals */

#define U300_SLOW_PER_PHYS_BASE		0xc0010000

#define U300_SLOW_PER_VIRT_BASE		0xff000000
/* Boot ROM */

#define U300_BOOTROM_PHYS_BASE		0xffff0000

#define U300_BOOTROM_VIRT_BASE		0xffff0000
/* SEMI config base */

#define U300_SEMI_CONFIG_BASE		0x2FFE0000

/*
 * AHB peripherals
 */

/* AHB Peripherals Bridge Controller */

#define U300_AHB_BRIDGE_BASE		(U300_AHB_PER_PHYS_BASE+0x0000)
/* Vectored Interrupt Controller 0, servicing 32 interrupts */

#define U300_INTCON0_BASE		(U300_AHB_PER_PHYS_BASE+0x1000)

#define U300_INTCON0_VBASE		IOMEM(U300_AHB_PER_VIRT_BASE+0x1000)
/* Vectored Interrupt Controller 1, servicing 32 interrupts */

#define U300_INTCON1_BASE		(U300_AHB_PER_PHYS_BASE+0x2000)

#define U300_INTCON1_VBASE		IOMEM(U300_AHB_PER_VIRT_BASE+0x2000)
/* Memory Stick Pro (MSPRO) controller */

#define U300_MSPRO_BASE			(U300_AHB_PER_PHYS_BASE+0x3000)
/* EMIF Configuration Area */

#define U300_EMIF_CFG_BASE		(U300_AHB_PER_PHYS_BASE+0x4000)

/*
 * FAST peripherals
 */

/* FAST bridge control */

#define U300_FAST_BRIDGE_BASE		(U300_FAST_PER_PHYS_BASE+0x0000)
/* MMC/SD controller */

#define U300_MMCSD_BASE			(U300_FAST_PER_PHYS_BASE+0x1000)
/* PCM I2S0 controller */

#define U300_PCM_I2S0_BASE		(U300_FAST_PER_PHYS_BASE+0x2000)
/* PCM I2S1 controller */

#define U300_PCM_I2S1_BASE		(U300_FAST_PER_PHYS_BASE+0x3000)
/* I2C0 controller */

#define U300_I2C0_BASE			(U300_FAST_PER_PHYS_BASE+0x4000)
/* I2C1 controller */

#define U300_I2C1_BASE			(U300_FAST_PER_PHYS_BASE+0x5000)
/* SPI controller */

#define U300_SPI_BASE			(U300_FAST_PER_PHYS_BASE+0x6000)
/* Fast UART1 on U335 only */

#define U300_UART1_BASE			(U300_FAST_PER_PHYS_BASE+0x7000)

/*
 * SLOW peripherals
 */

/* SLOW bridge control */

#define U300_SLOW_BRIDGE_BASE		(U300_SLOW_PER_PHYS_BASE)
/* SYSCON */

#define U300_SYSCON_BASE		(U300_SLOW_PER_PHYS_BASE+0x1000)

#define U300_SYSCON_VBASE		IOMEM(U300_SLOW_PER_VIRT_BASE+0x1000)
/* Watchdog */

#define U300_WDOG_BASE			(U300_SLOW_PER_PHYS_BASE+0x2000)
/* UART0 */

#define U300_UART0_BASE			(U300_SLOW_PER_PHYS_BASE+0x3000)
/* APP side special timer */

#define U300_TIMER_APP_BASE		(U300_SLOW_PER_PHYS_BASE+0x4000)

#define U300_TIMER_APP_VBASE		IOMEM(U300_SLOW_PER_VIRT_BASE+0x4000)
/* Keypad */

#define U300_KEYPAD_BASE		(U300_SLOW_PER_PHYS_BASE+0x5000)
/* GPIO */

#define U300_GPIO_BASE			(U300_SLOW_PER_PHYS_BASE+0x6000)
/* RTC */

#define U300_RTC_BASE			(U300_SLOW_PER_PHYS_BASE+0x7000)
/* Bus tracer */

#define U300_BUSTR_BASE			(U300_SLOW_PER_PHYS_BASE+0x8000)
/* Event handler (hardware queue) */

#define U300_EVHIST_BASE		(U300_SLOW_PER_PHYS_BASE+0x9000)
/* Genric Timer */

#define U300_TIMER_BASE			(U300_SLOW_PER_PHYS_BASE+0xa000)
/* PPM */

#define U300_PPM_BASE			(U300_SLOW_PER_PHYS_BASE+0xb000)

/*
 * REST peripherals
 */

/* ISP (image signal processor) */

#define U300_ISP_BASE			(0xA0008000)
/* DMA Controller base */

#define U300_DMAC_BASE			(0xC0020000)
/* MSL Base */

#define U300_MSL_BASE			(0xc0022000)
/* APEX Base */

#define U300_APEX_BASE			(0xc0030000)
/* Video Encoder Base */

#define U300_VIDEOENC_BASE		(0xc0080000)
/* XGAM Base */

#define U300_XGAM_BASE			(0xd0000000)

/*
 * SYSCON addresses applicable to the core machine.
 */

/* Chip ID register 16bit (R/-) */

#define U300_SYSCON_CIDR					(0x400)
/* SMCR */

#define U300_SYSCON_SMCR					(0x4d0)

#define U300_SYSCON_SMCR_FIELD_MASK				(0x000e)

#define U300_SYSCON_SMCR_SEMI_SREFACK_IND			(0x0008)

#define U300_SYSCON_SMCR_SEMI_SREFREQ_ENABLE			(0x0004)

#define U300_SYSCON_SMCR_SEMI_EXT_BOOT_MODE_ENABLE		(0x0002)
/* CPU_SW_DBGEN Software Debug Enable 16bit (R/W) */

#define U300_SYSCON_CSDR					(0x4f0)

#define U300_SYSCON_CSDR_SW_DEBUG_ENABLE			(0x0001)
/* PRINT_CONTROL Print Control 16bit (R/-) */

#define U300_SYSCON_PCR						(0x4f8)

#define U300_SYSCON_PCR_SERV_IND				(0x0001)
/* BOOT_CONTROL 16bit (R/-) */

#define U300_SYSCON_BCR						(0x4fc)

#define U300_SYSCON_BCR_ACC_CPU_SUBSYS_VINITHI_IND		(0x0400)

#define U300_SYSCON_BCR_APP_CPU_SUBSYS_VINITHI_IND		(0x0200)

#define U300_SYSCON_BCR_EXTRA_BOOT_OPTION_MASK			(0x01FC)

#define U300_SYSCON_BCR_APP_BOOT_SERV_MASK			(0x0003)


static void __iomem *syscon_base;

/*
 * Static I/O mappings that are needed for booting the U300 platforms. The
 * only things we need are the areas where we find the timer, syscon and
 * intcon, since the remaining device drivers will map their own memory
 * physical to virtual as the need arise.
 */

static struct map_desc u300_io_desc[] __initdata = {
	{
		.virtual	= U300_SLOW_PER_VIRT_BASE,
		.pfn		= __phys_to_pfn(U300_SLOW_PER_PHYS_BASE),
		.length		= SZ_64K,
		.type		= MT_DEVICE,
        },
	{
		.virtual	= U300_AHB_PER_VIRT_BASE,
		.pfn		= __phys_to_pfn(U300_AHB_PER_PHYS_BASE),
		.length		= SZ_32K,
		.type		= MT_DEVICE,
        },
	{
		.virtual	= U300_FAST_PER_VIRT_BASE,
		.pfn		= __phys_to_pfn(U300_FAST_PER_PHYS_BASE),
		.length		= SZ_32K,
		.type		= MT_DEVICE,
        },
};


static void __init u300_map_io(void) { iotable_init(u300_io_desc, ARRAY_SIZE(u300_io_desc)); }

Contributors

PersonTokensPropCommitsCommitProp
Linus Walleij19100.00%2100.00%
Total19100.00%2100.00%

static unsigned long pin_pullup_conf[] = { PIN_CONF_PACKED(PIN_CONFIG_BIAS_PULL_UP, 1), }; static unsigned long pin_highz_conf[] = { PIN_CONF_PACKED(PIN_CONFIG_BIAS_HIGH_IMPEDANCE, 0), }; /* Pin control settings */ static struct pinctrl_map __initdata u300_pinmux_map[] = { /* anonymous maps for chip power and EMIFs */ PIN_MAP_MUX_GROUP_HOG_DEFAULT("pinctrl-u300", NULL, "power"), PIN_MAP_MUX_GROUP_HOG_DEFAULT("pinctrl-u300", NULL, "emif0"), PIN_MAP_MUX_GROUP_HOG_DEFAULT("pinctrl-u300", NULL, "emif1"), /* per-device maps for MMC/SD, SPI and UART */ PIN_MAP_MUX_GROUP_DEFAULT("mmci", "pinctrl-u300", NULL, "mmc0"), PIN_MAP_MUX_GROUP_DEFAULT("pl022", "pinctrl-u300", NULL, "spi0"), PIN_MAP_MUX_GROUP_DEFAULT("uart0", "pinctrl-u300", NULL, "uart0"), /* This pin is used for clock return rather than GPIO */ PIN_MAP_CONFIGS_PIN_DEFAULT("mmci", "pinctrl-u300", "PIO APP GPIO 11", pin_pullup_conf), /* This pin is used for card detect */ PIN_MAP_CONFIGS_PIN_DEFAULT("mmci", "pinctrl-u300", "PIO MS INS", pin_highz_conf), }; struct db_chip { u16 chipid; const char *name; }; /* * This is a list of the Digital Baseband chips used in the U300 platform. */ static struct db_chip db_chips[] __initdata = { { .chipid = 0xb800, .name = "DB3000", }, { .chipid = 0xc000, .name = "DB3100", }, { .chipid = 0xc800, .name = "DB3150", }, { .chipid = 0xd800, .name = "DB3200", }, { .chipid = 0xe000, .name = "DB3250", }, { .chipid = 0xe800, .name = "DB3210", }, { .chipid = 0xf000, .name = "DB3350 P1x", }, { .chipid = 0xf100, .name = "DB3350 P2x", }, { .chipid = 0x0000, /* List terminator */ .name = NULL, } };
static void __init u300_init_check_chip(void) { u16 val; struct db_chip *chip; const char *chipname; const char unknown[] = "UNKNOWN"; /* Read out and print chip ID */ val = readw(syscon_base + U300_SYSCON_CIDR); /* This is in funky bigendian order... */ val = (val & 0xFFU) << 8 | (val >> 8); chip = db_chips; chipname = unknown; for ( ; chip->chipid; chip++) { if (chip->chipid == (val & 0xFF00U)) { chipname = chip->name; break; } } printk(KERN_INFO "Initializing U300 system on %s baseband chip " \ "(chip ID 0x%04x)\n", chipname, val); if ((val & 0xFF00U) != 0xf000 && (val & 0xFF00U) != 0xf100) { printk(KERN_ERR "Platform configured for BS335 " \ " with DB3350 but %s detected, expect problems!", chipname); } }

Contributors

PersonTokensPropCommitsCommitProp
Linus Walleij139100.00%4100.00%
Total139100.00%4100.00%

/* Forward declare this function from the watchdog */ void coh901327_watchdog_reset(void);
static void u300_restart(enum reboot_mode mode, const char *cmd) { switch (mode) { case REBOOT_SOFT: case REBOOT_HARD: #ifdef CONFIG_COH901327_WATCHDOG coh901327_watchdog_reset(); #endif break; default: /* Do nothing */ break; } /* Wait for system do die/reset. */ while (1); }

Contributors

PersonTokensPropCommitsCommitProp
Russell King4088.89%133.33%
Robin Holt48.89%133.33%
Linus Walleij12.22%133.33%
Total45100.00%3100.00%

/* These are mostly to get the right device names for the clock lookups */ static struct of_dev_auxdata u300_auxdata_lookup[] __initdata = { OF_DEV_AUXDATA("stericsson,pinctrl-u300", U300_SYSCON_BASE, "pinctrl-u300", NULL), OF_DEV_AUXDATA("stericsson,gpio-coh901", U300_GPIO_BASE, "u300-gpio", NULL), OF_DEV_AUXDATA("stericsson,coh901327", U300_WDOG_BASE, "coh901327_wdog", NULL), OF_DEV_AUXDATA("stericsson,coh901331", U300_RTC_BASE, "rtc-coh901331", NULL), OF_DEV_AUXDATA("stericsson,coh901318", U300_DMAC_BASE, "coh901318", NULL), OF_DEV_AUXDATA("stericsson,fsmc-nand", U300_NAND_IF_PHYS_BASE, "fsmc-nand", NULL), OF_DEV_AUXDATA("arm,primecell", U300_UART0_BASE, "uart0", NULL), OF_DEV_AUXDATA("arm,primecell", U300_UART1_BASE, "uart1", NULL), OF_DEV_AUXDATA("arm,primecell", U300_SPI_BASE, "pl022", NULL), OF_DEV_AUXDATA("st,ddci2c", U300_I2C0_BASE, "stu300.0", NULL), OF_DEV_AUXDATA("st,ddci2c", U300_I2C1_BASE, "stu300.1", NULL), OF_DEV_AUXDATA("arm,primecell", U300_MMCSD_BASE, "mmci", NULL), { /* sentinel */ }, };
static void __init u300_init_irq_dt(void) { struct device_node *syscon; struct clk *clk; syscon = of_find_node_by_path("/syscon@c0011000"); if (!syscon) { pr_crit("could not find syscon node\n"); return; } syscon_base = of_iomap(syscon, 0); if (!syscon_base) { pr_crit("could not remap syscon\n"); return; } /* initialize clocking early, we want to clock the INTCON */ u300_clk_init(syscon_base); /* Bootstrap EMIF and SEMI clocks */ clk = clk_get_sys("pl172", NULL); BUG_ON(IS_ERR(clk)); clk_prepare_enable(clk); clk = clk_get_sys("semi", NULL); BUG_ON(IS_ERR(clk)); clk_prepare_enable(clk); /* Clock the interrupt controller */ clk = clk_get_sys("intcon", NULL); BUG_ON(IS_ERR(clk)); clk_prepare_enable(clk); irqchip_init(); }

Contributors

PersonTokensPropCommitsCommitProp
Linus Walleij138100.00%2100.00%
Total138100.00%2100.00%


static void __init u300_init_machine_dt(void) { u16 val; /* Check what platform we run and print some status information */ u300_init_check_chip(); /* Initialize pinmuxing */ pinctrl_register_mappings(u300_pinmux_map, ARRAY_SIZE(u300_pinmux_map)); of_platform_default_populate(NULL, u300_auxdata_lookup, NULL); /* Enable SEMI self refresh */ val = readw(syscon_base + U300_SYSCON_SMCR) | U300_SYSCON_SMCR_SEMI_SREFREQ_ENABLE; writew(val, syscon_base + U300_SYSCON_SMCR); }

Contributors

PersonTokensPropCommitsCommitProp
Linus Walleij5698.25%266.67%
Kefeng Wang11.75%133.33%
Total57100.00%3100.00%

static const char * u300_board_compat[] = { "stericsson,u300", NULL, }; DT_MACHINE_START(U300_DT, "U300 S335/B335 (Device Tree)") .map_io = u300_map_io, .init_irq = u300_init_irq_dt, .init_time = clocksource_probe, .init_machine = u300_init_machine_dt, .restart = u300_restart, .dt_compat = u300_board_compat, MACHINE_END

Overall Contributors

PersonTokensPropCommitsCommitProp
Linus Walleij120994.01%2275.86%
Russell King564.35%26.90%
Stephen Warren151.17%26.90%
Robin Holt40.31%13.45%
Marc Zyngier10.08%13.45%
Kefeng Wang10.08%13.45%
Total1286100.00%29100.00%
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with cregit.