cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

setup.c (6182B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * Renesas Technology Europe SDK7786 Support.
      4 *
      5 * Copyright (C) 2010  Matt Fleming
      6 * Copyright (C) 2010  Paul Mundt
      7 */
      8#include <linux/init.h>
      9#include <linux/platform_device.h>
     10#include <linux/io.h>
     11#include <linux/regulator/fixed.h>
     12#include <linux/regulator/machine.h>
     13#include <linux/smsc911x.h>
     14#include <linux/i2c.h>
     15#include <linux/irq.h>
     16#include <linux/clk.h>
     17#include <linux/clkdev.h>
     18#include <mach/fpga.h>
     19#include <mach/irq.h>
     20#include <asm/machvec.h>
     21#include <asm/heartbeat.h>
     22#include <linux/sizes.h>
     23#include <asm/clock.h>
     24#include <asm/reboot.h>
     25#include <asm/smp-ops.h>
     26
     27static struct resource heartbeat_resource = {
     28	.start		= 0x07fff8b0,
     29	.end		= 0x07fff8b0 + sizeof(u16) - 1,
     30	.flags		= IORESOURCE_MEM | IORESOURCE_MEM_16BIT,
     31};
     32
     33static struct platform_device heartbeat_device = {
     34	.name		= "heartbeat",
     35	.id		= -1,
     36	.num_resources	= 1,
     37	.resource	= &heartbeat_resource,
     38};
     39
     40/* Dummy supplies, where voltage doesn't matter */
     41static struct regulator_consumer_supply dummy_supplies[] = {
     42	REGULATOR_SUPPLY("vddvario", "smsc911x"),
     43	REGULATOR_SUPPLY("vdd33a", "smsc911x"),
     44};
     45
     46static struct resource smsc911x_resources[] = {
     47	[0] = {
     48		.name		= "smsc911x-memory",
     49		.start		= 0x07ffff00,
     50		.end		= 0x07ffff00 + SZ_256 - 1,
     51		.flags		= IORESOURCE_MEM,
     52	},
     53	[1] = {
     54		.name		= "smsc911x-irq",
     55		.start		= evt2irq(0x2c0),
     56		.end		= evt2irq(0x2c0),
     57		.flags		= IORESOURCE_IRQ,
     58	},
     59};
     60
     61static struct smsc911x_platform_config smsc911x_config = {
     62	.irq_polarity	= SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
     63	.irq_type	= SMSC911X_IRQ_TYPE_OPEN_DRAIN,
     64	.flags		= SMSC911X_USE_32BIT,
     65	.phy_interface	= PHY_INTERFACE_MODE_MII,
     66};
     67
     68static struct platform_device smsc911x_device = {
     69	.name		= "smsc911x",
     70	.id		= -1,
     71	.num_resources	= ARRAY_SIZE(smsc911x_resources),
     72	.resource	= smsc911x_resources,
     73	.dev = {
     74		.platform_data = &smsc911x_config,
     75	},
     76};
     77
     78static struct resource smbus_fpga_resource = {
     79	.start		= 0x07fff9e0,
     80	.end		= 0x07fff9e0 + SZ_32 - 1,
     81	.flags		= IORESOURCE_MEM,
     82};
     83
     84static struct platform_device smbus_fpga_device = {
     85	.name		= "i2c-sdk7786",
     86	.id		= 0,
     87	.num_resources	= 1,
     88	.resource	= &smbus_fpga_resource,
     89};
     90
     91static struct resource smbus_pcie_resource = {
     92	.start		= 0x07fffc30,
     93	.end		= 0x07fffc30 + SZ_32 - 1,
     94	.flags		= IORESOURCE_MEM,
     95};
     96
     97static struct platform_device smbus_pcie_device = {
     98	.name		= "i2c-sdk7786",
     99	.id		= 1,
    100	.num_resources	= 1,
    101	.resource	= &smbus_pcie_resource,
    102};
    103
    104static struct i2c_board_info __initdata sdk7786_i2c_devices[] = {
    105	{
    106		I2C_BOARD_INFO("max6900", 0x68),
    107	},
    108};
    109
    110static struct platform_device *sh7786_devices[] __initdata = {
    111	&heartbeat_device,
    112	&smsc911x_device,
    113	&smbus_fpga_device,
    114	&smbus_pcie_device,
    115};
    116
    117static int sdk7786_i2c_setup(void)
    118{
    119	unsigned int tmp;
    120
    121	/*
    122	 * Hand over I2C control to the FPGA.
    123	 */
    124	tmp = fpga_read_reg(SBCR);
    125	tmp &= ~SCBR_I2CCEN;
    126	tmp |= SCBR_I2CMEN;
    127	fpga_write_reg(tmp, SBCR);
    128
    129	return i2c_register_board_info(0, sdk7786_i2c_devices,
    130				       ARRAY_SIZE(sdk7786_i2c_devices));
    131}
    132
    133static int __init sdk7786_devices_setup(void)
    134{
    135	int ret;
    136
    137	ret = platform_add_devices(sh7786_devices, ARRAY_SIZE(sh7786_devices));
    138	if (unlikely(ret != 0))
    139		return ret;
    140
    141	return sdk7786_i2c_setup();
    142}
    143device_initcall(sdk7786_devices_setup);
    144
    145static int sdk7786_mode_pins(void)
    146{
    147	return fpga_read_reg(MODSWR);
    148}
    149
    150/*
    151 * FPGA-driven PCIe clocks
    152 *
    153 * Historically these include the oscillator, clock B (slots 2/3/4) and
    154 * clock A (slot 1 and the CPU clock). Newer revs of the PCB shove
    155 * everything under a single PCIe clocks enable bit that happens to map
    156 * to the same bit position as the oscillator bit for earlier FPGA
    157 * versions.
    158 *
    159 * Given that the legacy clocks have the side-effect of shutting the CPU
    160 * off through the FPGA along with the PCI slots, we simply leave them in
    161 * their initial state and don't bother registering them with the clock
    162 * framework.
    163 */
    164static int sdk7786_pcie_clk_enable(struct clk *clk)
    165{
    166	fpga_write_reg(fpga_read_reg(PCIECR) | PCIECR_CLKEN, PCIECR);
    167	return 0;
    168}
    169
    170static void sdk7786_pcie_clk_disable(struct clk *clk)
    171{
    172	fpga_write_reg(fpga_read_reg(PCIECR) & ~PCIECR_CLKEN, PCIECR);
    173}
    174
    175static struct sh_clk_ops sdk7786_pcie_clk_ops = {
    176	.enable		= sdk7786_pcie_clk_enable,
    177	.disable	= sdk7786_pcie_clk_disable,
    178};
    179
    180static struct clk sdk7786_pcie_clk = {
    181	.ops		= &sdk7786_pcie_clk_ops,
    182};
    183
    184static struct clk_lookup sdk7786_pcie_cl = {
    185	.con_id		= "pcie_plat_clk",
    186	.clk		= &sdk7786_pcie_clk,
    187};
    188
    189static int sdk7786_clk_init(void)
    190{
    191	struct clk *clk;
    192	int ret;
    193
    194	/*
    195	 * Only handle the EXTAL case, anyone interfacing a crystal
    196	 * resonator will need to provide their own input clock.
    197	 */
    198	if (test_mode_pin(MODE_PIN9))
    199		return -EINVAL;
    200
    201	clk = clk_get(NULL, "extal");
    202	if (IS_ERR(clk))
    203		return PTR_ERR(clk);
    204	ret = clk_set_rate(clk, 33333333);
    205	clk_put(clk);
    206
    207	/*
    208	 * Setup the FPGA clocks.
    209	 */
    210	ret = clk_register(&sdk7786_pcie_clk);
    211	if (unlikely(ret)) {
    212		pr_err("FPGA clock registration failed\n");
    213		return ret;
    214	}
    215
    216	clkdev_add(&sdk7786_pcie_cl);
    217
    218	return 0;
    219}
    220
    221static void sdk7786_restart(char *cmd)
    222{
    223	fpga_write_reg(0xa5a5, SRSTR);
    224}
    225
    226static void sdk7786_power_off(void)
    227{
    228	fpga_write_reg(fpga_read_reg(PWRCR) | PWRCR_PDWNREQ, PWRCR);
    229
    230	/*
    231	 * It can take up to 20us for the R8C to do its job, back off and
    232	 * wait a bit until we've been shut off. Even though newer FPGA
    233	 * versions don't set the ACK bit, the latency issue remains.
    234	 */
    235	while ((fpga_read_reg(PWRCR) & PWRCR_PDWNACK) == 0)
    236		cpu_sleep();
    237}
    238
    239/* Initialize the board */
    240static void __init sdk7786_setup(char **cmdline_p)
    241{
    242	pr_info("Renesas Technology Europe SDK7786 support:\n");
    243
    244	regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies));
    245
    246	sdk7786_fpga_init();
    247	sdk7786_nmi_init();
    248
    249	pr_info("\tPCB revision:\t%d\n", fpga_read_reg(PCBRR) & 0xf);
    250
    251	machine_ops.restart = sdk7786_restart;
    252	pm_power_off = sdk7786_power_off;
    253
    254	register_smp_ops(&shx3_smp_ops);
    255}
    256
    257/*
    258 * The Machine Vector
    259 */
    260static struct sh_machine_vector mv_sdk7786 __initmv = {
    261	.mv_name		= "SDK7786",
    262	.mv_setup		= sdk7786_setup,
    263	.mv_mode_pins		= sdk7786_mode_pins,
    264	.mv_clk_init		= sdk7786_clk_init,
    265	.mv_init_irq		= sdk7786_init_irq,
    266};