MIPS: Loongson: Add basic Loongson-3 CPU support
Basic Loongson-3 CPU support include CPU probing and TLB/cache initializing. Signed-off-by: Huacai Chen <chenhc@lemote.com> Signed-off-by: Hongliang Tao <taohl@lemote.com> Signed-off-by: Hua Yan <yanh@lemote.com> Tested-by: Alex Smith <alex.smith@imgtec.com> Reviewed-by: Alex Smith <alex.smith@imgtec.com> Cc: John Crispin <john@phrozen.org> Cc: Steven J. Hill <Steven.Hill@imgtec.com> Cc: Aurelien Jarno <aurelien@aurel32.net> Cc: linux-mips@linux-mips.org Cc: Fuxin Zhang <zhangfx@lemote.com> Cc: Zhangjin Wu <wuzhangjin@gmail.com> Patchwork: https://patchwork.linux-mips.org/patch/6630 Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
This commit is contained in:
parent
152ebb44ef
commit
c579d310b9
5 changed files with 76 additions and 5 deletions
|
@ -20,6 +20,10 @@ static inline int __pure __get_cpu_type(const int cpu_type)
|
|||
case CPU_LOONGSON2:
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SYS_HAS_CPU_LOONGSON3
|
||||
case CPU_LOONGSON3:
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SYS_HAS_CPU_LOONGSON1B
|
||||
case CPU_LOONGSON1:
|
||||
#endif
|
||||
|
|
|
@ -735,16 +735,22 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)
|
|||
c->tlbsize = 64;
|
||||
break;
|
||||
case PRID_IMP_LOONGSON_64: /* Loongson-2/3 */
|
||||
c->cputype = CPU_LOONGSON2;
|
||||
__cpu_name[cpu] = "ICT Loongson-2";
|
||||
|
||||
switch (c->processor_id & PRID_REV_MASK) {
|
||||
case PRID_REV_LOONGSON2E:
|
||||
c->cputype = CPU_LOONGSON2;
|
||||
__cpu_name[cpu] = "ICT Loongson-2";
|
||||
set_elf_platform(cpu, "loongson2e");
|
||||
break;
|
||||
case PRID_REV_LOONGSON2F:
|
||||
c->cputype = CPU_LOONGSON2;
|
||||
__cpu_name[cpu] = "ICT Loongson-2";
|
||||
set_elf_platform(cpu, "loongson2f");
|
||||
break;
|
||||
case PRID_REV_LOONGSON3A:
|
||||
c->cputype = CPU_LOONGSON3;
|
||||
__cpu_name[cpu] = "ICT Loongson-3";
|
||||
set_elf_platform(cpu, "loongson3a");
|
||||
break;
|
||||
}
|
||||
|
||||
set_isa(c, MIPS_CPU_ISA_III);
|
||||
|
|
|
@ -398,6 +398,7 @@ static inline void local_r4k___flush_cache_all(void * args)
|
|||
{
|
||||
switch (current_cpu_type()) {
|
||||
case CPU_LOONGSON2:
|
||||
case CPU_LOONGSON3:
|
||||
case CPU_R4000SC:
|
||||
case CPU_R4000MC:
|
||||
case CPU_R4400SC:
|
||||
|
@ -1066,6 +1067,33 @@ static void probe_pcache(void)
|
|||
c->dcache.waybit = 0;
|
||||
break;
|
||||
|
||||
case CPU_LOONGSON3:
|
||||
config1 = read_c0_config1();
|
||||
lsize = (config1 >> 19) & 7;
|
||||
if (lsize)
|
||||
c->icache.linesz = 2 << lsize;
|
||||
else
|
||||
c->icache.linesz = 0;
|
||||
c->icache.sets = 64 << ((config1 >> 22) & 7);
|
||||
c->icache.ways = 1 + ((config1 >> 16) & 7);
|
||||
icache_size = c->icache.sets *
|
||||
c->icache.ways *
|
||||
c->icache.linesz;
|
||||
c->icache.waybit = 0;
|
||||
|
||||
lsize = (config1 >> 10) & 7;
|
||||
if (lsize)
|
||||
c->dcache.linesz = 2 << lsize;
|
||||
else
|
||||
c->dcache.linesz = 0;
|
||||
c->dcache.sets = 64 << ((config1 >> 13) & 7);
|
||||
c->dcache.ways = 1 + ((config1 >> 7) & 7);
|
||||
dcache_size = c->dcache.sets *
|
||||
c->dcache.ways *
|
||||
c->dcache.linesz;
|
||||
c->dcache.waybit = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (!(config & MIPS_CONF_M))
|
||||
panic("Don't know how to probe P-caches on this cpu.");
|
||||
|
@ -1303,6 +1331,33 @@ static void __init loongson2_sc_init(void)
|
|||
c->options |= MIPS_CPU_INCLUSIVE_CACHES;
|
||||
}
|
||||
|
||||
static void __init loongson3_sc_init(void)
|
||||
{
|
||||
struct cpuinfo_mips *c = ¤t_cpu_data;
|
||||
unsigned int config2, lsize;
|
||||
|
||||
config2 = read_c0_config2();
|
||||
lsize = (config2 >> 4) & 15;
|
||||
if (lsize)
|
||||
c->scache.linesz = 2 << lsize;
|
||||
else
|
||||
c->scache.linesz = 0;
|
||||
c->scache.sets = 64 << ((config2 >> 8) & 15);
|
||||
c->scache.ways = 1 + (config2 & 15);
|
||||
|
||||
scache_size = c->scache.sets *
|
||||
c->scache.ways *
|
||||
c->scache.linesz;
|
||||
/* Loongson-3 has 4 cores, 1MB scache for each. scaches are shared */
|
||||
scache_size *= 4;
|
||||
c->scache.waybit = 0;
|
||||
pr_info("Unified secondary cache %ldkB %s, linesize %d bytes.\n",
|
||||
scache_size >> 10, way_string[c->scache.ways], c->scache.linesz);
|
||||
if (scache_size)
|
||||
c->options |= MIPS_CPU_INCLUSIVE_CACHES;
|
||||
return;
|
||||
}
|
||||
|
||||
extern int r5k_sc_init(void);
|
||||
extern int rm7k_sc_init(void);
|
||||
extern int mips_sc_init(void);
|
||||
|
@ -1355,6 +1410,10 @@ static void setup_scache(void)
|
|||
loongson2_sc_init();
|
||||
return;
|
||||
|
||||
case CPU_LOONGSON3:
|
||||
loongson3_sc_init();
|
||||
return;
|
||||
|
||||
case CPU_XLP:
|
||||
/* don't need to worry about L2, fully coherent */
|
||||
return;
|
||||
|
|
|
@ -48,13 +48,14 @@ extern void build_tlb_refill_handler(void);
|
|||
#endif /* CONFIG_MIPS_MT_SMTC */
|
||||
|
||||
/*
|
||||
* LOONGSON2 has a 4 entry itlb which is a subset of dtlb,
|
||||
* unfortrunately, itlb is not totally transparent to software.
|
||||
* LOONGSON2/3 has a 4 entry itlb which is a subset of dtlb,
|
||||
* unfortunately, itlb is not totally transparent to software.
|
||||
*/
|
||||
static inline void flush_itlb(void)
|
||||
{
|
||||
switch (current_cpu_type()) {
|
||||
case CPU_LOONGSON2:
|
||||
case CPU_LOONGSON3:
|
||||
write_c0_diag(4);
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -582,6 +582,7 @@ static void build_tlb_write_entry(u32 **p, struct uasm_label **l,
|
|||
case CPU_BMIPS4380:
|
||||
case CPU_BMIPS5000:
|
||||
case CPU_LOONGSON2:
|
||||
case CPU_LOONGSON3:
|
||||
case CPU_R5500:
|
||||
if (m4kc_tlbp_war())
|
||||
uasm_i_nop(p);
|
||||
|
|
Loading…
Reference in a new issue