mirror of
https://github.com/torvalds/linux.git
synced 2024-12-11 13:41:55 +00:00
139c949f7f
mt7621 has the following memory map: 0x0-0x1c000000: lower 448m memory 0x1c000000-0x2000000: peripheral registers 0x20000000-0x2400000: higher 64m memory detect_memory_region in arch/mips/kernel/setup.c only adds the first memory region and isn't suitable for 512m memory detection because it may accidentally read the memory area for peripheral registers. This commit adds memory detection capability for mt7621: 1. Add the highmem area when 512m is detected. 2. Guard memcmp from accessing peripheral registers: This only happens when a user decided to change kernel load address to 256m or higher address. Since this is a quite unusual case, we just skip 512m testing and return 256m as memory size. Signed-off-by: Chuanhong Guo <gch981213@gmail.com> [Minor commit message reword, make mt7621_memory_detect static] Signed-off-by: Ilya Lipnitskiy <ilya.lipnitskiy@gmail.com> Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
233 lines
6.9 KiB
C
233 lines
6.9 KiB
C
// SPDX-License-Identifier: GPL-2.0-only
|
|
/*
|
|
*
|
|
* Copyright (C) 2015 Nikolay Martynov <mar.kolya@gmail.com>
|
|
* Copyright (C) 2015 John Crispin <john@phrozen.org>
|
|
*/
|
|
|
|
#include <linux/kernel.h>
|
|
#include <linux/init.h>
|
|
#include <linux/slab.h>
|
|
#include <linux/sys_soc.h>
|
|
#include <linux/memblock.h>
|
|
|
|
#include <asm/bootinfo.h>
|
|
#include <asm/mipsregs.h>
|
|
#include <asm/smp-ops.h>
|
|
#include <asm/mips-cps.h>
|
|
#include <asm/mach-ralink/ralink_regs.h>
|
|
#include <asm/mach-ralink/mt7621.h>
|
|
|
|
#include <pinmux.h>
|
|
|
|
#include "common.h"
|
|
|
|
#define MT7621_GPIO_MODE_UART1 1
|
|
#define MT7621_GPIO_MODE_I2C 2
|
|
#define MT7621_GPIO_MODE_UART3_MASK 0x3
|
|
#define MT7621_GPIO_MODE_UART3_SHIFT 3
|
|
#define MT7621_GPIO_MODE_UART3_GPIO 1
|
|
#define MT7621_GPIO_MODE_UART2_MASK 0x3
|
|
#define MT7621_GPIO_MODE_UART2_SHIFT 5
|
|
#define MT7621_GPIO_MODE_UART2_GPIO 1
|
|
#define MT7621_GPIO_MODE_JTAG 7
|
|
#define MT7621_GPIO_MODE_WDT_MASK 0x3
|
|
#define MT7621_GPIO_MODE_WDT_SHIFT 8
|
|
#define MT7621_GPIO_MODE_WDT_GPIO 1
|
|
#define MT7621_GPIO_MODE_PCIE_RST 0
|
|
#define MT7621_GPIO_MODE_PCIE_REF 2
|
|
#define MT7621_GPIO_MODE_PCIE_MASK 0x3
|
|
#define MT7621_GPIO_MODE_PCIE_SHIFT 10
|
|
#define MT7621_GPIO_MODE_PCIE_GPIO 1
|
|
#define MT7621_GPIO_MODE_MDIO_MASK 0x3
|
|
#define MT7621_GPIO_MODE_MDIO_SHIFT 12
|
|
#define MT7621_GPIO_MODE_MDIO_GPIO 1
|
|
#define MT7621_GPIO_MODE_RGMII1 14
|
|
#define MT7621_GPIO_MODE_RGMII2 15
|
|
#define MT7621_GPIO_MODE_SPI_MASK 0x3
|
|
#define MT7621_GPIO_MODE_SPI_SHIFT 16
|
|
#define MT7621_GPIO_MODE_SPI_GPIO 1
|
|
#define MT7621_GPIO_MODE_SDHCI_MASK 0x3
|
|
#define MT7621_GPIO_MODE_SDHCI_SHIFT 18
|
|
#define MT7621_GPIO_MODE_SDHCI_GPIO 1
|
|
|
|
static void *detect_magic __initdata = detect_memory_region;
|
|
|
|
static struct rt2880_pmx_func uart1_grp[] = { FUNC("uart1", 0, 1, 2) };
|
|
static struct rt2880_pmx_func i2c_grp[] = { FUNC("i2c", 0, 3, 2) };
|
|
static struct rt2880_pmx_func uart3_grp[] = {
|
|
FUNC("uart3", 0, 5, 4),
|
|
FUNC("i2s", 2, 5, 4),
|
|
FUNC("spdif3", 3, 5, 4),
|
|
};
|
|
static struct rt2880_pmx_func uart2_grp[] = {
|
|
FUNC("uart2", 0, 9, 4),
|
|
FUNC("pcm", 2, 9, 4),
|
|
FUNC("spdif2", 3, 9, 4),
|
|
};
|
|
static struct rt2880_pmx_func jtag_grp[] = { FUNC("jtag", 0, 13, 5) };
|
|
static struct rt2880_pmx_func wdt_grp[] = {
|
|
FUNC("wdt rst", 0, 18, 1),
|
|
FUNC("wdt refclk", 2, 18, 1),
|
|
};
|
|
static struct rt2880_pmx_func pcie_rst_grp[] = {
|
|
FUNC("pcie rst", MT7621_GPIO_MODE_PCIE_RST, 19, 1),
|
|
FUNC("pcie refclk", MT7621_GPIO_MODE_PCIE_REF, 19, 1)
|
|
};
|
|
static struct rt2880_pmx_func mdio_grp[] = { FUNC("mdio", 0, 20, 2) };
|
|
static struct rt2880_pmx_func rgmii2_grp[] = { FUNC("rgmii2", 0, 22, 12) };
|
|
static struct rt2880_pmx_func spi_grp[] = {
|
|
FUNC("spi", 0, 34, 7),
|
|
FUNC("nand1", 2, 34, 7),
|
|
};
|
|
static struct rt2880_pmx_func sdhci_grp[] = {
|
|
FUNC("sdhci", 0, 41, 8),
|
|
FUNC("nand2", 2, 41, 8),
|
|
};
|
|
static struct rt2880_pmx_func rgmii1_grp[] = { FUNC("rgmii1", 0, 49, 12) };
|
|
|
|
static struct rt2880_pmx_group mt7621_pinmux_data[] = {
|
|
GRP("uart1", uart1_grp, 1, MT7621_GPIO_MODE_UART1),
|
|
GRP("i2c", i2c_grp, 1, MT7621_GPIO_MODE_I2C),
|
|
GRP_G("uart3", uart3_grp, MT7621_GPIO_MODE_UART3_MASK,
|
|
MT7621_GPIO_MODE_UART3_GPIO, MT7621_GPIO_MODE_UART3_SHIFT),
|
|
GRP_G("uart2", uart2_grp, MT7621_GPIO_MODE_UART2_MASK,
|
|
MT7621_GPIO_MODE_UART2_GPIO, MT7621_GPIO_MODE_UART2_SHIFT),
|
|
GRP("jtag", jtag_grp, 1, MT7621_GPIO_MODE_JTAG),
|
|
GRP_G("wdt", wdt_grp, MT7621_GPIO_MODE_WDT_MASK,
|
|
MT7621_GPIO_MODE_WDT_GPIO, MT7621_GPIO_MODE_WDT_SHIFT),
|
|
GRP_G("pcie", pcie_rst_grp, MT7621_GPIO_MODE_PCIE_MASK,
|
|
MT7621_GPIO_MODE_PCIE_GPIO, MT7621_GPIO_MODE_PCIE_SHIFT),
|
|
GRP_G("mdio", mdio_grp, MT7621_GPIO_MODE_MDIO_MASK,
|
|
MT7621_GPIO_MODE_MDIO_GPIO, MT7621_GPIO_MODE_MDIO_SHIFT),
|
|
GRP("rgmii2", rgmii2_grp, 1, MT7621_GPIO_MODE_RGMII2),
|
|
GRP_G("spi", spi_grp, MT7621_GPIO_MODE_SPI_MASK,
|
|
MT7621_GPIO_MODE_SPI_GPIO, MT7621_GPIO_MODE_SPI_SHIFT),
|
|
GRP_G("sdhci", sdhci_grp, MT7621_GPIO_MODE_SDHCI_MASK,
|
|
MT7621_GPIO_MODE_SDHCI_GPIO, MT7621_GPIO_MODE_SDHCI_SHIFT),
|
|
GRP("rgmii1", rgmii1_grp, 1, MT7621_GPIO_MODE_RGMII1),
|
|
{ 0 }
|
|
};
|
|
|
|
phys_addr_t mips_cpc_default_phys_base(void)
|
|
{
|
|
panic("Cannot detect cpc address");
|
|
}
|
|
|
|
static void __init mt7621_memory_detect(void)
|
|
{
|
|
void *dm = &detect_magic;
|
|
phys_addr_t size;
|
|
|
|
for (size = 32 * SZ_1M; size < 256 * SZ_1M; size <<= 1) {
|
|
if (!__builtin_memcmp(dm, dm + size, sizeof(detect_magic)))
|
|
break;
|
|
}
|
|
|
|
if ((size == 256 * SZ_1M) &&
|
|
(CPHYSADDR(dm + size) < MT7621_LOWMEM_MAX_SIZE) &&
|
|
__builtin_memcmp(dm, dm + size, sizeof(detect_magic))) {
|
|
memblock_add(MT7621_LOWMEM_BASE, MT7621_LOWMEM_MAX_SIZE);
|
|
memblock_add(MT7621_HIGHMEM_BASE, MT7621_HIGHMEM_SIZE);
|
|
} else {
|
|
memblock_add(MT7621_LOWMEM_BASE, size);
|
|
}
|
|
}
|
|
|
|
void __init ralink_of_remap(void)
|
|
{
|
|
rt_sysc_membase = plat_of_remap_node("mtk,mt7621-sysc");
|
|
rt_memc_membase = plat_of_remap_node("mtk,mt7621-memc");
|
|
|
|
if (!rt_sysc_membase || !rt_memc_membase)
|
|
panic("Failed to remap core resources");
|
|
}
|
|
|
|
static void soc_dev_init(struct ralink_soc_info *soc_info, u32 rev)
|
|
{
|
|
struct soc_device *soc_dev;
|
|
struct soc_device_attribute *soc_dev_attr;
|
|
|
|
soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
|
|
if (!soc_dev_attr)
|
|
return;
|
|
|
|
soc_dev_attr->soc_id = "mt7621";
|
|
soc_dev_attr->family = "Ralink";
|
|
|
|
if (((rev >> CHIP_REV_VER_SHIFT) & CHIP_REV_VER_MASK) == 1 &&
|
|
(rev & CHIP_REV_ECO_MASK) == 1)
|
|
soc_dev_attr->revision = "E2";
|
|
else
|
|
soc_dev_attr->revision = "E1";
|
|
|
|
soc_dev_attr->data = soc_info;
|
|
|
|
soc_dev = soc_device_register(soc_dev_attr);
|
|
if (IS_ERR(soc_dev)) {
|
|
kfree(soc_dev_attr);
|
|
return;
|
|
}
|
|
}
|
|
|
|
void __init prom_soc_init(struct ralink_soc_info *soc_info)
|
|
{
|
|
void __iomem *sysc = (void __iomem *) KSEG1ADDR(MT7621_SYSC_BASE);
|
|
unsigned char *name = NULL;
|
|
u32 n0;
|
|
u32 n1;
|
|
u32 rev;
|
|
|
|
/* Early detection of CMP support */
|
|
mips_cm_probe();
|
|
mips_cpc_probe();
|
|
|
|
if (mips_cps_numiocu(0)) {
|
|
/*
|
|
* mips_cm_probe() wipes out bootloader
|
|
* config for CM regions and we have to configure them
|
|
* again. This SoC cannot talk to pamlbus devices
|
|
* witout proper iocu region set up.
|
|
*
|
|
* FIXME: it would be better to do this with values
|
|
* from DT, but we need this very early because
|
|
* without this we cannot talk to pretty much anything
|
|
* including serial.
|
|
*/
|
|
write_gcr_reg0_base(MT7621_PALMBUS_BASE);
|
|
write_gcr_reg0_mask(~MT7621_PALMBUS_SIZE |
|
|
CM_GCR_REGn_MASK_CMTGT_IOCU0);
|
|
__sync();
|
|
}
|
|
|
|
n0 = __raw_readl(sysc + SYSC_REG_CHIP_NAME0);
|
|
n1 = __raw_readl(sysc + SYSC_REG_CHIP_NAME1);
|
|
|
|
if (n0 == MT7621_CHIP_NAME0 && n1 == MT7621_CHIP_NAME1) {
|
|
name = "MT7621";
|
|
soc_info->compatible = "mtk,mt7621-soc";
|
|
} else {
|
|
panic("mt7621: unknown SoC, n0:%08x n1:%08x\n", n0, n1);
|
|
}
|
|
ralink_soc = MT762X_SOC_MT7621AT;
|
|
rev = __raw_readl(sysc + SYSC_REG_CHIP_REV);
|
|
|
|
snprintf(soc_info->sys_type, RAMIPS_SYS_TYPE_LEN,
|
|
"MediaTek %s ver:%u eco:%u",
|
|
name,
|
|
(rev >> CHIP_REV_VER_SHIFT) & CHIP_REV_VER_MASK,
|
|
(rev & CHIP_REV_ECO_MASK));
|
|
|
|
soc_info->mem_detect = mt7621_memory_detect;
|
|
rt2880_pinmux_data = mt7621_pinmux_data;
|
|
|
|
soc_dev_init(soc_info, rev);
|
|
|
|
if (!register_cps_smp_ops())
|
|
return;
|
|
if (!register_cmp_smp_ops())
|
|
return;
|
|
if (!register_vsmp_smp_ops())
|
|
return;
|
|
}
|