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

mt7621.c (4732B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 *
      4 * Copyright (C) 2015 Nikolay Martynov <mar.kolya@gmail.com>
      5 * Copyright (C) 2015 John Crispin <john@phrozen.org>
      6 */
      7
      8#include <linux/kernel.h>
      9#include <linux/init.h>
     10#include <linux/slab.h>
     11#include <linux/sys_soc.h>
     12#include <linux/memblock.h>
     13#include <linux/pci.h>
     14#include <linux/bug.h>
     15
     16#include <asm/bootinfo.h>
     17#include <asm/mipsregs.h>
     18#include <asm/smp-ops.h>
     19#include <asm/mips-cps.h>
     20#include <asm/mach-ralink/ralink_regs.h>
     21#include <asm/mach-ralink/mt7621.h>
     22
     23#include "common.h"
     24
     25#define MT7621_MEM_TEST_PATTERN         0xaa5555aa
     26
     27static u32 detect_magic __initdata;
     28
     29int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge)
     30{
     31	struct resource_entry *entry;
     32	resource_size_t mask;
     33
     34	entry = resource_list_first_type(&bridge->windows, IORESOURCE_MEM);
     35	if (!entry) {
     36		pr_err("Cannot get memory resource\n");
     37		return -EINVAL;
     38	}
     39
     40	if (mips_cps_numiocu(0)) {
     41		/*
     42		 * Hardware doesn't accept mask values with 1s after
     43		 * 0s (e.g. 0xffef), so warn if that's happen
     44		 */
     45		mask = ~(entry->res->end - entry->res->start) & CM_GCR_REGn_MASK_ADDRMASK;
     46		WARN_ON(mask && BIT(ffz(~mask)) - 1 != ~mask);
     47
     48		write_gcr_reg1_base(entry->res->start);
     49		write_gcr_reg1_mask(mask | CM_GCR_REGn_MASK_CMTGT_IOCU0);
     50		pr_info("PCI coherence region base: 0x%08llx, mask/settings: 0x%08llx\n",
     51			(unsigned long long)read_gcr_reg1_base(),
     52			(unsigned long long)read_gcr_reg1_mask());
     53	}
     54
     55	return 0;
     56}
     57
     58phys_addr_t mips_cpc_default_phys_base(void)
     59{
     60	panic("Cannot detect cpc address");
     61}
     62
     63static bool __init mt7621_addr_wraparound_test(phys_addr_t size)
     64{
     65	void *dm = (void *)KSEG1ADDR(&detect_magic);
     66
     67	if (CPHYSADDR(dm + size) >= MT7621_LOWMEM_MAX_SIZE)
     68		return true;
     69	__raw_writel(MT7621_MEM_TEST_PATTERN, dm);
     70	if (__raw_readl(dm) != __raw_readl(dm + size))
     71		return false;
     72	__raw_writel(~MT7621_MEM_TEST_PATTERN, dm);
     73	return __raw_readl(dm) == __raw_readl(dm + size);
     74}
     75
     76static void __init mt7621_memory_detect(void)
     77{
     78	phys_addr_t size;
     79
     80	for (size = 32 * SZ_1M; size <= 256 * SZ_1M; size <<= 1) {
     81		if (mt7621_addr_wraparound_test(size)) {
     82			memblock_add(MT7621_LOWMEM_BASE, size);
     83			return;
     84		}
     85	}
     86
     87	memblock_add(MT7621_LOWMEM_BASE, MT7621_LOWMEM_MAX_SIZE);
     88	memblock_add(MT7621_HIGHMEM_BASE, MT7621_HIGHMEM_SIZE);
     89}
     90
     91void __init ralink_of_remap(void)
     92{
     93	rt_sysc_membase = plat_of_remap_node("mediatek,mt7621-sysc");
     94	rt_memc_membase = plat_of_remap_node("mediatek,mt7621-memc");
     95
     96	if (!rt_sysc_membase || !rt_memc_membase)
     97		panic("Failed to remap core resources");
     98}
     99
    100static void soc_dev_init(struct ralink_soc_info *soc_info, u32 rev)
    101{
    102	struct soc_device *soc_dev;
    103	struct soc_device_attribute *soc_dev_attr;
    104
    105	soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
    106	if (!soc_dev_attr)
    107		return;
    108
    109	soc_dev_attr->soc_id = "mt7621";
    110	soc_dev_attr->family = "Ralink";
    111
    112	if (((rev >> CHIP_REV_VER_SHIFT) & CHIP_REV_VER_MASK) == 1 &&
    113	    (rev & CHIP_REV_ECO_MASK) == 1)
    114		soc_dev_attr->revision = "E2";
    115	else
    116		soc_dev_attr->revision = "E1";
    117
    118	soc_dev_attr->data = soc_info;
    119
    120	soc_dev = soc_device_register(soc_dev_attr);
    121	if (IS_ERR(soc_dev)) {
    122		kfree(soc_dev_attr);
    123		return;
    124	}
    125}
    126
    127void __init prom_soc_init(struct ralink_soc_info *soc_info)
    128{
    129	void __iomem *sysc = (void __iomem *) KSEG1ADDR(MT7621_SYSC_BASE);
    130	unsigned char *name = NULL;
    131	u32 n0;
    132	u32 n1;
    133	u32 rev;
    134
    135	/* Early detection of CMP support */
    136	mips_cm_probe();
    137	mips_cpc_probe();
    138
    139	if (mips_cps_numiocu(0)) {
    140		/*
    141		 * mips_cm_probe() wipes out bootloader
    142		 * config for CM regions and we have to configure them
    143		 * again. This SoC cannot talk to pamlbus devices
    144		 * witout proper iocu region set up.
    145		 *
    146		 * FIXME: it would be better to do this with values
    147		 * from DT, but we need this very early because
    148		 * without this we cannot talk to pretty much anything
    149		 * including serial.
    150		 */
    151		write_gcr_reg0_base(MT7621_PALMBUS_BASE);
    152		write_gcr_reg0_mask(~MT7621_PALMBUS_SIZE |
    153				    CM_GCR_REGn_MASK_CMTGT_IOCU0);
    154		__sync();
    155	}
    156
    157	n0 = __raw_readl(sysc + SYSC_REG_CHIP_NAME0);
    158	n1 = __raw_readl(sysc + SYSC_REG_CHIP_NAME1);
    159
    160	if (n0 == MT7621_CHIP_NAME0 && n1 == MT7621_CHIP_NAME1) {
    161		name = "MT7621";
    162		soc_info->compatible = "mediatek,mt7621-soc";
    163	} else {
    164		panic("mt7621: unknown SoC, n0:%08x n1:%08x\n", n0, n1);
    165	}
    166	ralink_soc = MT762X_SOC_MT7621AT;
    167	rev = __raw_readl(sysc + SYSC_REG_CHIP_REV);
    168
    169	snprintf(soc_info->sys_type, RAMIPS_SYS_TYPE_LEN,
    170		"MediaTek %s ver:%u eco:%u",
    171		name,
    172		(rev >> CHIP_REV_VER_SHIFT) & CHIP_REV_VER_MASK,
    173		(rev & CHIP_REV_ECO_MASK));
    174
    175	soc_info->mem_detect = mt7621_memory_detect;
    176
    177	soc_dev_init(soc_info, rev);
    178
    179	if (!register_cps_smp_ops())
    180		return;
    181	if (!register_cmp_smp_ops())
    182		return;
    183	if (!register_vsmp_smp_ops())
    184		return;
    185}