Skip to content

Commit

Permalink
MIPS: Loongson: Add basic Loongson-3 CPU support
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Huacai Chen authored and Ralf Baechle committed Mar 31, 2014
1 parent 152ebb4 commit c579d31
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 5 deletions.
4 changes: 4 additions & 0 deletions arch/mips/include/asm/cpu-type.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
12 changes: 9 additions & 3 deletions arch/mips/kernel/cpu-probe.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
59 changes: 59 additions & 0 deletions arch/mips/mm/c-r4k.c
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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.");
Expand Down Expand Up @@ -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 = &current_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);
Expand Down Expand Up @@ -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;
Expand Down
5 changes: 3 additions & 2 deletions arch/mips/mm/tlb-r4k.c
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
1 change: 1 addition & 0 deletions arch/mips/mm/tlbex.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down

0 comments on commit c579d31

Please sign in to comment.