^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) #include <linux/smp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) #include <asm/cpu.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <asm/cpu-info.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <asm/elf.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <loongson_regs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <cpucfg-emul.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) static bool is_loongson(struct cpuinfo_mips *c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) switch (c->processor_id & PRID_COMP_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) case PRID_COMP_LEGACY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) return ((c->processor_id & PRID_IMP_MASK) ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) PRID_IMP_LOONGSON_64C);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) case PRID_COMP_LOONGSON:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) static u32 get_loongson_fprev(struct cpuinfo_mips *c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) return c->fpu_id & LOONGSON_FPREV_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) static bool cpu_has_uca(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) u32 diag = read_c0_diag();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) u32 new_diag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) if (diag & LOONGSON_DIAG_UCAC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) /* UCA is already enabled. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) /* See if UCAC bit can be flipped on. This should be safe. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) new_diag = diag | LOONGSON_DIAG_UCAC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) write_c0_diag(new_diag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) new_diag = read_c0_diag();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) write_c0_diag(diag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) return (new_diag & LOONGSON_DIAG_UCAC) != 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) static void probe_uca(struct cpuinfo_mips *c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) if (cpu_has_uca())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) c->loongson3_cpucfg_data[0] |= LOONGSON_CFG1_LSUCA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) static void decode_loongson_config6(struct cpuinfo_mips *c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) u32 config6 = read_c0_config6();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) if (config6 & LOONGSON_CONF6_SFBEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) c->loongson3_cpucfg_data[0] |= LOONGSON_CFG1_SFBP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) if (config6 & LOONGSON_CONF6_LLEXC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) c->loongson3_cpucfg_data[0] |= LOONGSON_CFG1_LLEXC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) if (config6 & LOONGSON_CONF6_SCRAND)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) c->loongson3_cpucfg_data[0] |= LOONGSON_CFG1_SCRAND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) static void patch_cpucfg_sel1(struct cpuinfo_mips *c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) u64 ases = c->ases;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) u64 options = c->options;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) u32 data = c->loongson3_cpucfg_data[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) if (options & MIPS_CPU_FPU) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) data |= LOONGSON_CFG1_FP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) data |= get_loongson_fprev(c) << LOONGSON_CFG1_FPREV_OFFSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) if (ases & MIPS_ASE_LOONGSON_MMI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) data |= LOONGSON_CFG1_MMI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) if (ases & MIPS_ASE_MSA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) data |= LOONGSON_CFG1_MSA1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) c->loongson3_cpucfg_data[0] = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) static void patch_cpucfg_sel2(struct cpuinfo_mips *c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) u64 ases = c->ases;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) u64 options = c->options;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) u32 data = c->loongson3_cpucfg_data[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) if (ases & MIPS_ASE_LOONGSON_EXT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) data |= LOONGSON_CFG2_LEXT1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) if (ases & MIPS_ASE_LOONGSON_EXT2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) data |= LOONGSON_CFG2_LEXT2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) if (options & MIPS_CPU_LDPTE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) data |= LOONGSON_CFG2_LSPW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) if (ases & MIPS_ASE_VZ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) data |= LOONGSON_CFG2_LVZP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) data &= ~LOONGSON_CFG2_LVZREV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) c->loongson3_cpucfg_data[1] = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) static void patch_cpucfg_sel3(struct cpuinfo_mips *c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) u64 ases = c->ases;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) u32 data = c->loongson3_cpucfg_data[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) if (ases & MIPS_ASE_LOONGSON_CAM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) data |= LOONGSON_CFG3_LCAMP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) data &= ~LOONGSON_CFG3_LCAMREV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) data &= ~LOONGSON_CFG3_LCAMNUM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) data &= ~LOONGSON_CFG3_LCAMKW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) data &= ~LOONGSON_CFG3_LCAMVW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) c->loongson3_cpucfg_data[2] = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) void loongson3_cpucfg_synthesize_data(struct cpuinfo_mips *c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) /* Only engage the logic on Loongson processors. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) if (!is_loongson(c))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) /* CPUs with CPUCFG support don't need to synthesize anything. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) if (cpu_has_cfg())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) goto have_cpucfg_now;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) c->loongson3_cpucfg_data[0] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) c->loongson3_cpucfg_data[1] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) c->loongson3_cpucfg_data[2] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) /* Add CPUCFG features non-discoverable otherwise. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) switch (c->processor_id & (PRID_IMP_MASK | PRID_REV_MASK)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) case PRID_IMP_LOONGSON_64R | PRID_REV_LOONGSON2K_R1_0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) case PRID_IMP_LOONGSON_64R | PRID_REV_LOONGSON2K_R1_1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) case PRID_IMP_LOONGSON_64R | PRID_REV_LOONGSON2K_R1_2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) case PRID_IMP_LOONGSON_64R | PRID_REV_LOONGSON2K_R1_3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) decode_loongson_config6(c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) probe_uca(c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) c->loongson3_cpucfg_data[0] |= (LOONGSON_CFG1_LSLDR0 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) LOONGSON_CFG1_LSSYNCI | LOONGSON_CFG1_LLSYNC |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) LOONGSON_CFG1_TGTSYNC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) c->loongson3_cpucfg_data[1] |= (LOONGSON_CFG2_LBT1 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) LOONGSON_CFG2_LBT2 | LOONGSON_CFG2_LPMP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) LOONGSON_CFG2_LPM_REV2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) c->loongson3_cpucfg_data[2] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) case PRID_IMP_LOONGSON_64C | PRID_REV_LOONGSON3A_R1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) c->loongson3_cpucfg_data[0] |= (LOONGSON_CFG1_LSLDR0 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) LOONGSON_CFG1_LSSYNCI | LOONGSON_CFG1_LSUCA |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) LOONGSON_CFG1_LLSYNC | LOONGSON_CFG1_TGTSYNC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) c->loongson3_cpucfg_data[1] |= (LOONGSON_CFG2_LBT1 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) LOONGSON_CFG2_LPMP | LOONGSON_CFG2_LPM_REV1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) c->loongson3_cpucfg_data[2] |= (
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) LOONGSON_CFG3_LCAM_REV1 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) LOONGSON_CFG3_LCAMNUM_REV1 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) LOONGSON_CFG3_LCAMKW_REV1 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) LOONGSON_CFG3_LCAMVW_REV1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) case PRID_IMP_LOONGSON_64C | PRID_REV_LOONGSON3B_R1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) case PRID_IMP_LOONGSON_64C | PRID_REV_LOONGSON3B_R2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) c->loongson3_cpucfg_data[0] |= (LOONGSON_CFG1_LSLDR0 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) LOONGSON_CFG1_LSSYNCI | LOONGSON_CFG1_LSUCA |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) LOONGSON_CFG1_LLSYNC | LOONGSON_CFG1_TGTSYNC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) c->loongson3_cpucfg_data[1] |= (LOONGSON_CFG2_LBT1 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) LOONGSON_CFG2_LPMP | LOONGSON_CFG2_LPM_REV1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) c->loongson3_cpucfg_data[2] |= (
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) LOONGSON_CFG3_LCAM_REV1 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) LOONGSON_CFG3_LCAMNUM_REV1 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) LOONGSON_CFG3_LCAMKW_REV1 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) LOONGSON_CFG3_LCAMVW_REV1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) case PRID_IMP_LOONGSON_64C | PRID_REV_LOONGSON3A_R2_0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) case PRID_IMP_LOONGSON_64C | PRID_REV_LOONGSON3A_R2_1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) case PRID_IMP_LOONGSON_64C | PRID_REV_LOONGSON3A_R3_0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) case PRID_IMP_LOONGSON_64C | PRID_REV_LOONGSON3A_R3_1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) decode_loongson_config6(c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) probe_uca(c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) c->loongson3_cpucfg_data[0] |= (LOONGSON_CFG1_CNT64 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) LOONGSON_CFG1_LSLDR0 | LOONGSON_CFG1_LSPREF |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) LOONGSON_CFG1_LSPREFX | LOONGSON_CFG1_LSSYNCI |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) LOONGSON_CFG1_LLSYNC | LOONGSON_CFG1_TGTSYNC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) c->loongson3_cpucfg_data[1] |= (LOONGSON_CFG2_LBT1 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) LOONGSON_CFG2_LBT2 | LOONGSON_CFG2_LBTMMU |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) LOONGSON_CFG2_LPMP | LOONGSON_CFG2_LPM_REV1 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) LOONGSON_CFG2_LVZ_REV1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) c->loongson3_cpucfg_data[2] |= (LOONGSON_CFG3_LCAM_REV1 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) LOONGSON_CFG3_LCAMNUM_REV1 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) LOONGSON_CFG3_LCAMKW_REV1 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) LOONGSON_CFG3_LCAMVW_REV1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) /* It is possible that some future Loongson cores still do
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) * not have CPUCFG, so do not emulate anything for these
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) * cores.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) /* This feature is set by firmware, but all known Loongson-64 systems
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) * are configured this way.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) c->loongson3_cpucfg_data[0] |= LOONGSON_CFG1_CDMAP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) /* Patch in dynamically probed bits. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) patch_cpucfg_sel1(c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) patch_cpucfg_sel2(c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) patch_cpucfg_sel3(c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) have_cpucfg_now:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) /* We have usable CPUCFG now, emulated or not.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) * Announce CPUCFG availability to userspace via hwcap.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) elf_hwcap |= HWCAP_LOONGSON_CPUCFG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) }