Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

MIPS: CPS: Boot CPUs in secondary clusters

Probe for & boot CPUs (cores & VPs) in secondary clusters (ie. not the
cluster that began booting Linux) when they are present in systems with
CM 3.5 or higher.

Signed-off-by: Paul Burton <paulburton@kernel.org>
Signed-off-by: Chao-ying Fu <cfu@wavecomp.com>
Signed-off-by: Dragan Mladjenovic <dragan.mladjenovic@syrmia.com>
Signed-off-by: Aleksandar Rikalo <arikalo@gmail.com>
Tested-by: Serge Semin <fancer.lancer@gmail.com>
Tested-by: Gregory CLEMENT <gregory.clement@bootlin.com>
Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>

authored by

Paul Burton and committed by
Thomas Bogendoerfer
0856c143 75fa6a58

+207 -21
+18
arch/mips/include/asm/mips-cm.h
··· 255 255 GCR_ACCESSOR_RO(32, 0x150, sys_config2) 256 256 #define CM_GCR_SYS_CONFIG2_MAXVPW GENMASK(3, 0) 257 257 258 + /* GCR_L2-RAM_CONFIG - Configuration & status of L2 cache RAMs */ 259 + GCR_ACCESSOR_RW(64, 0x240, l2_ram_config) 260 + #define CM_GCR_L2_RAM_CONFIG_PRESENT BIT(31) 261 + #define CM_GCR_L2_RAM_CONFIG_HCI_DONE BIT(30) 262 + #define CM_GCR_L2_RAM_CONFIG_HCI_SUPPORTED BIT(29) 263 + 258 264 /* GCR_L2_PFT_CONTROL - Controls hardware L2 prefetching */ 259 265 GCR_ACCESSOR_RW(32, 0x300, l2_pft_control) 260 266 #define CM_GCR_L2_PFT_CONTROL_PAGEMASK GENMASK(31, 12) ··· 271 265 GCR_ACCESSOR_RW(32, 0x308, l2_pft_control_b) 272 266 #define CM_GCR_L2_PFT_CONTROL_B_CEN BIT(8) 273 267 #define CM_GCR_L2_PFT_CONTROL_B_PORTID GENMASK(7, 0) 268 + 269 + /* GCR_L2_TAG_ADDR - Access addresses in L2 cache tags */ 270 + GCR_ACCESSOR_RW(64, 0x600, l2_tag_addr) 271 + 272 + /* GCR_L2_TAG_STATE - Access L2 cache tag state */ 273 + GCR_ACCESSOR_RW(64, 0x608, l2_tag_state) 274 + 275 + /* GCR_L2_DATA - Access data in L2 cache lines */ 276 + GCR_ACCESSOR_RW(64, 0x610, l2_data) 277 + 278 + /* GCR_L2_ECC - Access ECC information from L2 cache lines */ 279 + GCR_ACCESSOR_RW(64, 0x618, l2_ecc) 274 280 275 281 /* GCR_L2SM_COP - L2 cache op state machine control */ 276 282 GCR_ACCESSOR_RW(32, 0x620, l2sm_cop)
+1
arch/mips/include/asm/smp-cps.h
··· 23 23 }; 24 24 25 25 struct cluster_boot_config { 26 + unsigned long *core_power; 26 27 struct core_boot_config *core_config; 27 28 }; 28 29
+3 -1
arch/mips/kernel/mips-cm.c
··· 308 308 FIELD_PREP(CM3_GCR_Cx_OTHER_VP, vp); 309 309 310 310 if (cm_rev >= CM_REV_CM3_5) { 311 - val |= CM_GCR_Cx_OTHER_CLUSTER_EN; 311 + if (cluster != cpu_cluster(&current_cpu_data)) 312 + val |= CM_GCR_Cx_OTHER_CLUSTER_EN; 313 + val |= CM_GCR_Cx_OTHER_GIC_EN; 312 314 val |= FIELD_PREP(CM_GCR_Cx_OTHER_CLUSTER, cluster); 313 315 val |= FIELD_PREP(CM_GCR_Cx_OTHER_BLOCK, block); 314 316 } else {
+185 -20
arch/mips/kernel/smp-cps.c
··· 36 36 37 37 UASM_L_LA(_not_nmi) 38 38 39 - static DECLARE_BITMAP(core_power, NR_CPUS); 40 39 static u64 core_entry_reg; 41 40 static phys_addr_t cps_vec_pa; 42 41 43 42 struct cluster_boot_config *mips_cps_cluster_bootcfg; 43 + 44 + static void power_up_other_cluster(unsigned int cluster) 45 + { 46 + u32 stat, seq_state; 47 + unsigned int timeout; 48 + 49 + mips_cm_lock_other(cluster, CM_GCR_Cx_OTHER_CORE_CM, 0, 50 + CM_GCR_Cx_OTHER_BLOCK_LOCAL); 51 + stat = read_cpc_co_stat_conf(); 52 + mips_cm_unlock_other(); 53 + 54 + seq_state = stat & CPC_Cx_STAT_CONF_SEQSTATE; 55 + seq_state >>= __ffs(CPC_Cx_STAT_CONF_SEQSTATE); 56 + if (seq_state == CPC_Cx_STAT_CONF_SEQSTATE_U5) 57 + return; 58 + 59 + /* Set endianness & power up the CM */ 60 + mips_cm_lock_other(cluster, 0, 0, CM_GCR_Cx_OTHER_BLOCK_GLOBAL); 61 + write_cpc_redir_sys_config(IS_ENABLED(CONFIG_CPU_BIG_ENDIAN)); 62 + write_cpc_redir_pwrup_ctl(1); 63 + mips_cm_unlock_other(); 64 + 65 + /* Wait for the CM to start up */ 66 + timeout = 1000; 67 + mips_cm_lock_other(cluster, CM_GCR_Cx_OTHER_CORE_CM, 0, 68 + CM_GCR_Cx_OTHER_BLOCK_LOCAL); 69 + while (1) { 70 + stat = read_cpc_co_stat_conf(); 71 + seq_state = stat & CPC_Cx_STAT_CONF_SEQSTATE; 72 + seq_state >>= __ffs(CPC_Cx_STAT_CONF_SEQSTATE); 73 + if (seq_state == CPC_Cx_STAT_CONF_SEQSTATE_U5) 74 + break; 75 + 76 + if (timeout) { 77 + mdelay(1); 78 + timeout--; 79 + } else { 80 + pr_warn("Waiting for cluster %u CM to power up... STAT_CONF=0x%x\n", 81 + cluster, stat); 82 + mdelay(1000); 83 + } 84 + } 85 + 86 + mips_cm_unlock_other(); 87 + } 44 88 45 89 static unsigned __init core_vpe_count(unsigned int cluster, unsigned core) 46 90 { ··· 222 178 pr_cont(","); 223 179 pr_cont("{"); 224 180 181 + if (mips_cm_revision() >= CM_REV_CM3_5) 182 + power_up_other_cluster(cl); 183 + 225 184 ncores = mips_cps_numcores(cl); 226 185 for (c = 0; c < ncores; c++) { 227 186 core_vpes = core_vpe_count(cl, c); ··· 252 205 253 206 /* Indicate present CPUs (CPU being synonymous with VPE) */ 254 207 for (v = 0; v < min_t(unsigned, nvpes, NR_CPUS); v++) { 255 - set_cpu_possible(v, cpu_cluster(&cpu_data[v]) == 0); 256 - set_cpu_present(v, cpu_cluster(&cpu_data[v]) == 0); 208 + set_cpu_possible(v, true); 209 + set_cpu_present(v, true); 257 210 __cpu_number_map[v] = v; 258 211 __cpu_logical_map[v] = v; 259 212 } 260 213 261 214 /* Set a coherent default CCA (CWB) */ 262 215 change_c0_config(CONF_CM_CMASK, 0x5); 263 - 264 - /* Core 0 is powered up (we're running on it) */ 265 - bitmap_set(core_power, 0, 1); 266 216 267 217 /* Initialise core 0 */ 268 218 mips_cps_core_init(); ··· 342 298 goto err_out; 343 299 mips_cps_cluster_bootcfg[cl].core_config = core_bootcfg; 344 300 301 + mips_cps_cluster_bootcfg[cl].core_power = 302 + kcalloc(BITS_TO_LONGS(ncores), sizeof(unsigned long), 303 + GFP_KERNEL); 304 + 345 305 /* Allocate VPE boot configuration structs */ 346 306 for (c = 0; c < ncores; c++) { 347 307 core_vpes = core_vpe_count(cl, c); ··· 357 309 } 358 310 } 359 311 360 - /* Mark this CPU as booted */ 312 + /* Mark this CPU as powered up & booted */ 361 313 cl = cpu_cluster(&current_cpu_data); 362 314 c = cpu_core(&current_cpu_data); 363 315 cluster_bootcfg = &mips_cps_cluster_bootcfg[cl]; 364 316 core_bootcfg = &cluster_bootcfg->core_config[c]; 317 + bitmap_set(cluster_bootcfg->core_power, cpu_core(&current_cpu_data), 1); 365 318 atomic_set(&core_bootcfg->vpe_mask, 1 << cpu_vpe_id(&current_cpu_data)); 366 319 367 320 return; ··· 390 341 } 391 342 } 392 343 393 - static void boot_core(unsigned int core, unsigned int vpe_id) 344 + static void init_cluster_l2(void) 394 345 { 395 - u32 stat, seq_state; 396 - unsigned timeout; 346 + u32 l2_cfg, l2sm_cop, result; 347 + 348 + while (1) { 349 + l2_cfg = read_gcr_redir_l2_ram_config(); 350 + 351 + /* If HCI is not supported, use the state machine below */ 352 + if (!(l2_cfg & CM_GCR_L2_RAM_CONFIG_PRESENT)) 353 + break; 354 + if (!(l2_cfg & CM_GCR_L2_RAM_CONFIG_HCI_SUPPORTED)) 355 + break; 356 + 357 + /* If the HCI_DONE bit is set, we're finished */ 358 + if (l2_cfg & CM_GCR_L2_RAM_CONFIG_HCI_DONE) 359 + return; 360 + } 361 + 362 + l2sm_cop = read_gcr_redir_l2sm_cop(); 363 + if (WARN(!(l2sm_cop & CM_GCR_L2SM_COP_PRESENT), 364 + "L2 init not supported on this system yet")) 365 + return; 366 + 367 + /* Clear L2 tag registers */ 368 + write_gcr_redir_l2_tag_state(0); 369 + write_gcr_redir_l2_ecc(0); 370 + 371 + /* Ensure the L2 tag writes complete before the state machine starts */ 372 + mb(); 373 + 374 + /* Wait for the L2 state machine to be idle */ 375 + do { 376 + l2sm_cop = read_gcr_redir_l2sm_cop(); 377 + } while (l2sm_cop & CM_GCR_L2SM_COP_RUNNING); 378 + 379 + /* Start a store tag operation */ 380 + l2sm_cop = CM_GCR_L2SM_COP_TYPE_IDX_STORETAG; 381 + l2sm_cop <<= __ffs(CM_GCR_L2SM_COP_TYPE); 382 + l2sm_cop |= CM_GCR_L2SM_COP_CMD_START; 383 + write_gcr_redir_l2sm_cop(l2sm_cop); 384 + 385 + /* Ensure the state machine starts before we poll for completion */ 386 + mb(); 387 + 388 + /* Wait for the operation to be complete */ 389 + do { 390 + l2sm_cop = read_gcr_redir_l2sm_cop(); 391 + result = l2sm_cop & CM_GCR_L2SM_COP_RESULT; 392 + result >>= __ffs(CM_GCR_L2SM_COP_RESULT); 393 + } while (!result); 394 + 395 + WARN(result != CM_GCR_L2SM_COP_RESULT_DONE_OK, 396 + "L2 state machine failed cache init with error %u\n", result); 397 + } 398 + 399 + static void boot_core(unsigned int cluster, unsigned int core, 400 + unsigned int vpe_id) 401 + { 402 + struct cluster_boot_config *cluster_cfg; 403 + u32 access, stat, seq_state; 404 + unsigned int timeout, ncores; 405 + 406 + cluster_cfg = &mips_cps_cluster_bootcfg[cluster]; 407 + ncores = mips_cps_numcores(cluster); 408 + 409 + if ((cluster != cpu_cluster(&current_cpu_data)) && 410 + bitmap_empty(cluster_cfg->core_power, ncores)) { 411 + power_up_other_cluster(cluster); 412 + 413 + mips_cm_lock_other(cluster, core, 0, 414 + CM_GCR_Cx_OTHER_BLOCK_GLOBAL); 415 + 416 + /* Ensure cluster GCRs are where we expect */ 417 + write_gcr_redir_base(read_gcr_base()); 418 + write_gcr_redir_cpc_base(read_gcr_cpc_base()); 419 + write_gcr_redir_gic_base(read_gcr_gic_base()); 420 + 421 + init_cluster_l2(); 422 + 423 + /* Mirror L2 configuration */ 424 + write_gcr_redir_l2_only_sync_base(read_gcr_l2_only_sync_base()); 425 + write_gcr_redir_l2_pft_control(read_gcr_l2_pft_control()); 426 + write_gcr_redir_l2_pft_control_b(read_gcr_l2_pft_control_b()); 427 + 428 + /* Mirror ECC/parity setup */ 429 + write_gcr_redir_err_control(read_gcr_err_control()); 430 + 431 + /* Set BEV base */ 432 + write_gcr_redir_bev_base(core_entry_reg); 433 + 434 + mips_cm_unlock_other(); 435 + } 436 + 437 + if (cluster != cpu_cluster(&current_cpu_data)) { 438 + mips_cm_lock_other(cluster, core, 0, 439 + CM_GCR_Cx_OTHER_BLOCK_GLOBAL); 440 + 441 + /* Ensure the core can access the GCRs */ 442 + access = read_gcr_redir_access(); 443 + access |= BIT(core); 444 + write_gcr_redir_access(access); 445 + 446 + mips_cm_unlock_other(); 447 + } else { 448 + /* Ensure the core can access the GCRs */ 449 + access = read_gcr_access(); 450 + access |= BIT(core); 451 + write_gcr_access(access); 452 + } 397 453 398 454 /* Select the appropriate core */ 399 - mips_cm_lock_other(0, core, 0, CM_GCR_Cx_OTHER_BLOCK_LOCAL); 455 + mips_cm_lock_other(cluster, core, 0, CM_GCR_Cx_OTHER_BLOCK_LOCAL); 400 456 401 457 /* Set its reset vector */ 402 458 if (mips_cm_is64) ··· 570 416 mips_cm_unlock_other(); 571 417 572 418 /* The core is now powered up */ 573 - bitmap_set(core_power, core, 1); 419 + bitmap_set(cluster_cfg->core_power, core, 1); 420 + 421 + /* 422 + * Restore CM_PWRUP=0 so that the CM can power down if all the cores in 423 + * the cluster do (eg. if they're all removed via hotplug. 424 + */ 425 + if (mips_cm_revision() >= CM_REV_CM3_5) { 426 + mips_cm_lock_other(cluster, 0, 0, CM_GCR_Cx_OTHER_BLOCK_GLOBAL); 427 + write_cpc_redir_pwrup_ctl(0); 428 + mips_cm_unlock_other(); 429 + } 574 430 } 575 431 576 432 static void remote_vpe_boot(void *dummy) ··· 606 442 unsigned int remote; 607 443 int err; 608 444 609 - /* We don't yet support booting CPUs in other clusters */ 610 - if (cpu_cluster(&cpu_data[cpu]) != cpu_cluster(&raw_current_cpu_data)) 611 - return -ENOSYS; 612 - 613 445 vpe_cfg->pc = (unsigned long)&smp_bootstrap; 614 446 vpe_cfg->sp = __KSTK_TOS(idle); 615 447 vpe_cfg->gp = (unsigned long)task_thread_info(idle); ··· 614 454 615 455 preempt_disable(); 616 456 617 - if (!test_bit(core, core_power)) { 457 + if (!test_bit(core, cluster_cfg->core_power)) { 618 458 /* Boot a VPE on a powered down core */ 619 - boot_core(core, vpe_id); 459 + boot_core(cluster, core, vpe_id); 620 460 goto out; 621 461 } 622 462 623 463 if (cpu_has_vp) { 624 - mips_cm_lock_other(0, core, vpe_id, CM_GCR_Cx_OTHER_BLOCK_LOCAL); 464 + mips_cm_lock_other(cluster, core, vpe_id, 465 + CM_GCR_Cx_OTHER_BLOCK_LOCAL); 625 466 if (mips_cm_is64) 626 467 write_gcr_co_reset64_base(core_entry_reg); 627 468 else ··· 832 671 833 672 static void cps_cleanup_dead_cpu(unsigned cpu) 834 673 { 674 + unsigned int cluster = cpu_cluster(&cpu_data[cpu]); 835 675 unsigned core = cpu_core(&cpu_data[cpu]); 836 676 unsigned int vpe_id = cpu_vpe_id(&cpu_data[cpu]); 837 677 ktime_t fail_time; 838 678 unsigned stat; 839 679 int err; 680 + struct cluster_boot_config *cluster_cfg; 681 + 682 + cluster_cfg = &mips_cps_cluster_bootcfg[cluster]; 840 683 841 684 /* 842 685 * Now wait for the CPU to actually offline. Without doing this that ··· 892 727 } while (1); 893 728 894 729 /* Indicate the core is powered off */ 895 - bitmap_clear(core_power, core, 1); 730 + bitmap_clear(cluster_cfg->core_power, core, 1); 896 731 } else if (cpu_has_mipsmt) { 897 732 /* 898 733 * Have a CPU with access to the offlined CPUs registers wait