blob: d6efffd4dd2044be81a770e7522c0238f748ac60 [file] [log] [blame]
Thomas Gleixnerd2912cb2019-06-04 10:11:33 +02001// SPDX-License-Identifier: GPL-2.0-only
John Crispin1df7add2016-01-04 20:23:55 +01002/*
John Crispin1df7add2016-01-04 20:23:55 +01003 *
4 * Copyright (C) 2015 Nikolay Martynov <mar.kolya@gmail.com>
John Crispin97b92102016-05-05 09:57:56 +02005 * Copyright (C) 2015 John Crispin <john@phrozen.org>
John Crispin1df7add2016-01-04 20:23:55 +01006 */
7
8#include <linux/kernel.h>
9#include <linux/init.h>
Sergio Paracuellos71b9b5e012020-03-12 12:29:15 +010010#include <linux/slab.h>
11#include <linux/sys_soc.h>
Chuanhong Guo139c9492021-03-26 22:38:40 -070012#include <linux/memblock.h>
Sergio Paracuellosfe7498e2021-12-07 11:49:21 +010013#include <linux/pci.h>
14#include <linux/bug.h>
John Crispin1df7add2016-01-04 20:23:55 +010015
Chuanhong Guo139c9492021-03-26 22:38:40 -070016#include <asm/bootinfo.h>
John Crispin1df7add2016-01-04 20:23:55 +010017#include <asm/mipsregs.h>
18#include <asm/smp-ops.h>
Paul Burtone83f7e02017-08-12 19:49:41 -070019#include <asm/mips-cps.h>
John Crispin1df7add2016-01-04 20:23:55 +010020#include <asm/mach-ralink/ralink_regs.h>
21#include <asm/mach-ralink/mt7621.h>
22
John Crispin1df7add2016-01-04 20:23:55 +010023#include "common.h"
24
Chuanhong Guo139c9492021-03-26 22:38:40 -070025static void *detect_magic __initdata = detect_memory_region;
26
Sergio Paracuellosfe7498e2021-12-07 11:49:21 +010027int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge)
28{
29 struct resource_entry *entry;
30 resource_size_t mask;
31
32 entry = resource_list_first_type(&bridge->windows, IORESOURCE_MEM);
33 if (!entry) {
34 pr_err("Cannot get memory resource\n");
35 return -EINVAL;
36 }
37
38 if (mips_cps_numiocu(0)) {
39 /*
40 * Hardware doesn't accept mask values with 1s after
41 * 0s (e.g. 0xffef), so warn if that's happen
42 */
43 mask = ~(entry->res->end - entry->res->start) & CM_GCR_REGn_MASK_ADDRMASK;
44 WARN_ON(mask && BIT(ffz(~mask)) - 1 != ~mask);
45
46 write_gcr_reg1_base(entry->res->start);
47 write_gcr_reg1_mask(mask | CM_GCR_REGn_MASK_CMTGT_IOCU0);
48 pr_info("PCI coherence region base: 0x%08llx, mask/settings: 0x%08llx\n",
49 (unsigned long long)read_gcr_reg1_base(),
50 (unsigned long long)read_gcr_reg1_mask());
51 }
52
53 return 0;
54}
55
John Crispin1df7add2016-01-04 20:23:55 +010056phys_addr_t mips_cpc_default_phys_base(void)
57{
58 panic("Cannot detect cpc address");
59}
60
Chuanhong Guo139c9492021-03-26 22:38:40 -070061static void __init mt7621_memory_detect(void)
62{
63 void *dm = &detect_magic;
64 phys_addr_t size;
65
66 for (size = 32 * SZ_1M; size < 256 * SZ_1M; size <<= 1) {
67 if (!__builtin_memcmp(dm, dm + size, sizeof(detect_magic)))
68 break;
69 }
70
71 if ((size == 256 * SZ_1M) &&
72 (CPHYSADDR(dm + size) < MT7621_LOWMEM_MAX_SIZE) &&
73 __builtin_memcmp(dm, dm + size, sizeof(detect_magic))) {
74 memblock_add(MT7621_LOWMEM_BASE, MT7621_LOWMEM_MAX_SIZE);
75 memblock_add(MT7621_HIGHMEM_BASE, MT7621_HIGHMEM_SIZE);
76 } else {
77 memblock_add(MT7621_LOWMEM_BASE, size);
78 }
79}
80
John Crispin1df7add2016-01-04 20:23:55 +010081void __init ralink_of_remap(void)
82{
Sergio Paracuellos49268e22021-04-10 07:50:58 +020083 rt_sysc_membase = plat_of_remap_node("mediatek,mt7621-sysc");
84 rt_memc_membase = plat_of_remap_node("mediatek,mt7621-memc");
John Crispin1df7add2016-01-04 20:23:55 +010085
86 if (!rt_sysc_membase || !rt_memc_membase)
87 panic("Failed to remap core resources");
88}
89
Sergio Paracuellos71b9b5e012020-03-12 12:29:15 +010090static void soc_dev_init(struct ralink_soc_info *soc_info, u32 rev)
91{
92 struct soc_device *soc_dev;
93 struct soc_device_attribute *soc_dev_attr;
94
95 soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
96 if (!soc_dev_attr)
97 return;
98
99 soc_dev_attr->soc_id = "mt7621";
100 soc_dev_attr->family = "Ralink";
101
102 if (((rev >> CHIP_REV_VER_SHIFT) & CHIP_REV_VER_MASK) == 1 &&
103 (rev & CHIP_REV_ECO_MASK) == 1)
104 soc_dev_attr->revision = "E2";
105 else
106 soc_dev_attr->revision = "E1";
107
108 soc_dev_attr->data = soc_info;
109
110 soc_dev = soc_device_register(soc_dev_attr);
111 if (IS_ERR(soc_dev)) {
112 kfree(soc_dev_attr);
113 return;
114 }
115}
116
Ilya Lipnitskiy8eb6eb42021-03-26 22:38:39 -0700117void __init prom_soc_init(struct ralink_soc_info *soc_info)
John Crispin1df7add2016-01-04 20:23:55 +0100118{
119 void __iomem *sysc = (void __iomem *) KSEG1ADDR(MT7621_SYSC_BASE);
120 unsigned char *name = NULL;
121 u32 n0;
122 u32 n1;
123 u32 rev;
124
NeilBrowna63d7062018-03-21 14:02:10 +1100125 /* Early detection of CMP support */
126 mips_cm_probe();
127 mips_cpc_probe();
128
129 if (mips_cps_numiocu(0)) {
130 /*
131 * mips_cm_probe() wipes out bootloader
132 * config for CM regions and we have to configure them
133 * again. This SoC cannot talk to pamlbus devices
134 * witout proper iocu region set up.
135 *
136 * FIXME: it would be better to do this with values
137 * from DT, but we need this very early because
138 * without this we cannot talk to pretty much anything
139 * including serial.
140 */
141 write_gcr_reg0_base(MT7621_PALMBUS_BASE);
142 write_gcr_reg0_mask(~MT7621_PALMBUS_SIZE |
143 CM_GCR_REGn_MASK_CMTGT_IOCU0);
144 __sync();
145 }
146
John Crispin1df7add2016-01-04 20:23:55 +0100147 n0 = __raw_readl(sysc + SYSC_REG_CHIP_NAME0);
148 n1 = __raw_readl(sysc + SYSC_REG_CHIP_NAME1);
149
150 if (n0 == MT7621_CHIP_NAME0 && n1 == MT7621_CHIP_NAME1) {
151 name = "MT7621";
Sergio Paracuellos49268e22021-04-10 07:50:58 +0200152 soc_info->compatible = "mediatek,mt7621-soc";
John Crispin1df7add2016-01-04 20:23:55 +0100153 } else {
154 panic("mt7621: unknown SoC, n0:%08x n1:%08x\n", n0, n1);
155 }
John Crispin4f79dde2016-12-20 19:12:40 +0100156 ralink_soc = MT762X_SOC_MT7621AT;
John Crispin1df7add2016-01-04 20:23:55 +0100157 rev = __raw_readl(sysc + SYSC_REG_CHIP_REV);
158
159 snprintf(soc_info->sys_type, RAMIPS_SYS_TYPE_LEN,
160 "MediaTek %s ver:%u eco:%u",
161 name,
162 (rev >> CHIP_REV_VER_SHIFT) & CHIP_REV_VER_MASK,
163 (rev & CHIP_REV_ECO_MASK));
164
Chuanhong Guo139c9492021-03-26 22:38:40 -0700165 soc_info->mem_detect = mt7621_memory_detect;
John Crispin1df7add2016-01-04 20:23:55 +0100166
Thomas Bogendoerferf75410a2020-03-28 11:27:13 +0100167 soc_dev_init(soc_info, rev);
168
John Crispin1df7add2016-01-04 20:23:55 +0100169 if (!register_cps_smp_ops())
170 return;
171 if (!register_cmp_smp_ops())
172 return;
173 if (!register_vsmp_smp_ops())
174 return;
John Crispin1df7add2016-01-04 20:23:55 +0100175}