void platform_start(__register_t a0, __register_t a1, __register_t a2 __unused, __register_t a3) { const struct octeon_feature_description *ofd; uint64_t platform_counter_freq; int rv; mips_postboot_fixup(); /* * Initialize boot parameters so that we can determine things like * which console we shoud use, etc. */ octeon_boot_params_init(a3); /* Initialize pcpu stuff */ mips_pcpu0_init(); mips_timer_early_init(cvmx_sysinfo_get()->cpu_clock_hz); /* Initialize console. */ cninit(); /* * Display information about the CPU. */ #if !defined(OCTEON_MODEL) printf("Using runtime CPU model checks.\n"); #else printf("Compiled for CPU model: " __XSTRING(OCTEON_MODEL) "\n"); #endif strcpy(cpu_model, octeon_model_get_string(cvmx_get_proc_id())); printf("CPU Model: %s\n", cpu_model); printf("CPU clock: %uMHz Core Mask: %#x\n", cvmx_sysinfo_get()->cpu_clock_hz / 1000000, cvmx_sysinfo_get()->core_mask); rv = octeon_model_version_check(cvmx_get_proc_id()); if (rv == -1) panic("%s: kernel not compatible with this processor.", __func__); /* * Display information about the board. */ #if defined(OCTEON_BOARD_CAPK_0100ND) strcpy(cpu_board, "CAPK-0100ND"); if (cvmx_sysinfo_get()->board_type != CVMX_BOARD_TYPE_CN3010_EVB_HS5) { panic("Compiled for %s, but board type is %s.", cpu_board, cvmx_board_type_to_string(cvmx_sysinfo_get()->board_type)); } #else strcpy(cpu_board, cvmx_board_type_to_string(cvmx_sysinfo_get()->board_type)); #endif printf("Board: %s\n", cpu_board); printf("Board Type: %u Revision: %u/%u\n", cvmx_sysinfo_get()->board_type, cvmx_sysinfo_get()->board_rev_major, cvmx_sysinfo_get()->board_rev_minor); printf("Serial number: %s\n", cvmx_sysinfo_get()->board_serial_number); /* * Additional on-chip hardware/settings. * * XXX Display PCI host/target? What else? */ printf("MAC address base: %6D (%u configured)\n", cvmx_sysinfo_get()->mac_addr_base, ":", cvmx_sysinfo_get()->mac_addr_count); octeon_ciu_reset(); /* * Convert U-Boot 'bootoctlinux' loader command line arguments into * boot flags and kernel environment variables. */ bootverbose = 1; octeon_init_kenv(a3); /* * For some reason on the cn38xx simulator ebase register is set to * 0x80001000 at bootup time. Move it back to the default, but * when we move to having support for multiple executives, we need * to rethink this. */ mips_wr_ebase(0x80000000); octeon_memory_init(); init_param1(); init_param2(physmem); mips_cpu_init(); pmap_bootstrap(); mips_proc0_init(); mutex_init(); kdb_init(); #ifdef KDB if (boothowto & RB_KDB) kdb_enter(KDB_WHY_BOOTFLAGS, "Boot flags requested debugger"); #endif cpu_clock = cvmx_sysinfo_get()->cpu_clock_hz; platform_counter_freq = cpu_clock; octeon_timecounter.tc_frequency = cpu_clock; platform_timecounter = &octeon_timecounter; mips_timer_init_params(platform_counter_freq, 0); set_cputicker(octeon_get_ticks, cpu_clock, 0); #ifdef SMP /* * Clear any pending IPIs. */ cvmx_write_csr(CVMX_CIU_MBOX_CLRX(0), 0xffffffff); #endif printf("Octeon SDK: %s\n", OCTEON_SDK_VERSION_STRING); printf("Available Octeon features:"); for (ofd = octeon_feature_descriptions; ofd->ofd_string != NULL; ofd++) if (octeon_has_feature(ofd->ofd_feature)) printf(" %s", ofd->ofd_string); printf("\n"); }
void write_rld_cfg(rldram_csr_config_t *cfg_ptr) { cvmx_dfa_memcfg0_t memcfg0; cvmx_dfa_memcfg2_t memcfg2; memcfg0.u64 = cfg_ptr->dfa_memcfg0_base; if ((OCTEON_IS_MODEL(OCTEON_CN38XX) || OCTEON_IS_MODEL(OCTEON_CN58XX))) { uint32_t dfa_memcfg0; if (OCTEON_IS_MODEL (OCTEON_CN58XX)) { // Set RLDQK90_RST and RDLCK_RST to reset all three DLLs. memcfg0.s.rldck_rst = 1; memcfg0.s.rldqck90_rst = 1; cvmx_write_csr(CVMX_DFA_MEMCFG0, memcfg0.u64); ll_printf("CVMX_DFA_MEMCFG0: 0x%08x clk/qk90 reset\n", (uint32_t) memcfg0.u64); cvmx_csr_db_decode(cvmx_get_proc_id(), CVMX_DFA_MEMCFG0 & ~(1ull<<63), memcfg0.u64); // Clear RDLCK_RST while asserting RLDQK90_RST to bring RLDCK DLL out of reset. memcfg0.s.rldck_rst = 0; memcfg0.s.rldqck90_rst = 1; cvmx_write_csr(CVMX_DFA_MEMCFG0, memcfg0.u64); cvmx_wait(4000000); /* Wait */ ll_printf("CVMX_DFA_MEMCFG0: 0x%08x qk90 reset\n", (uint32_t) memcfg0.u64); cvmx_csr_db_decode(cvmx_get_proc_id(), CVMX_DFA_MEMCFG0 & ~(1ull<<63), memcfg0.u64); // Clear both RDLCK90_RST and RLDQK90_RST to bring the RLDQK90 DLL out of reset. memcfg0.s.rldck_rst = 0; memcfg0.s.rldqck90_rst = 0; cvmx_write_csr(CVMX_DFA_MEMCFG0, memcfg0.u64); cvmx_wait(4000000); /* Wait */ ll_printf("CVMX_DFA_MEMCFG0: 0x%08x DLL out of reset\n", (uint32_t) memcfg0.u64); cvmx_csr_db_decode(cvmx_get_proc_id(), CVMX_DFA_MEMCFG0 & ~(1ull<<63), memcfg0.u64); } //======================================================================= // Now print out the sequence of events: cvmx_write_csr(CVMX_DFA_MEMCFG0, cfg_ptr->dfa_memcfg0_base); ll_printf("CVMX_DFA_MEMCFG0: 0x%08x port enables\n", cfg_ptr->dfa_memcfg0_base); cvmx_csr_db_decode(cvmx_get_proc_id(), CVMX_DFA_MEMCFG0 & ~(1ull<<63), cfg_ptr->dfa_memcfg0_base); cvmx_wait(4000000); /* Wait */ cvmx_write_csr(CVMX_DFA_MEMCFG1, cfg_ptr->dfa_memcfg1_base); ll_printf("CVMX_DFA_MEMCFG1: 0x%08x\n", cfg_ptr->dfa_memcfg1_base); cvmx_csr_db_decode(cvmx_get_proc_id(), CVMX_DFA_MEMCFG1 & ~(1ull<<63), cfg_ptr->dfa_memcfg1_base); if (cfg_ptr->p0_ena ==1) { cvmx_write_csr(CVMX_DFA_MEMRLD, cfg_ptr->mrs_dat_p0bunk0); ll_printf("CVMX_DFA_MEMRLD : 0x%08x p0_ena memrld\n", cfg_ptr->mrs_dat_p0bunk0); cvmx_csr_db_decode(cvmx_get_proc_id(), CVMX_DFA_MEMRLD & ~(1ull<<63), cfg_ptr->mrs_dat_p0bunk0); dfa_memcfg0 = ( cfg_ptr->dfa_memcfg0_base | (1 << 23) | // P0_INIT (1 << 25) // BUNK_INIT[1:0]=Bunk#0 ); cvmx_write_csr(CVMX_DFA_MEMCFG0, dfa_memcfg0); ll_printf("CVMX_DFA_MEMCFG0: 0x%08x p0_init/bunk_init\n", dfa_memcfg0); cvmx_csr_db_decode(cvmx_get_proc_id(), CVMX_DFA_MEMCFG0 & ~(1ull<<63), dfa_memcfg0); cvmx_wait(RLD_INIT_DELAY); ll_printf("Delay.....\n"); cvmx_write_csr(CVMX_DFA_MEMCFG0, cfg_ptr->dfa_memcfg0_base); ll_printf("CVMX_DFA_MEMCFG0: 0x%08x back to base\n", cfg_ptr->dfa_memcfg0_base); cvmx_csr_db_decode(cvmx_get_proc_id(), CVMX_DFA_MEMCFG0 & ~(1ull<<63), cfg_ptr->dfa_memcfg0_base); } if (cfg_ptr->p1_ena ==1) { cvmx_write_csr(CVMX_DFA_MEMRLD, cfg_ptr->mrs_dat_p1bunk0); ll_printf("CVMX_DFA_MEMRLD : 0x%08x p1_ena memrld\n", cfg_ptr->mrs_dat_p1bunk0); cvmx_csr_db_decode(cvmx_get_proc_id(), CVMX_DFA_MEMRLD & ~(1ull<<63), cfg_ptr->mrs_dat_p1bunk0); dfa_memcfg0 = ( cfg_ptr->dfa_memcfg0_base | (1 << 24) | // P1_INIT (1 << 25) // BUNK_INIT[1:0]=Bunk#0 ); cvmx_write_csr(CVMX_DFA_MEMCFG0, dfa_memcfg0); ll_printf("CVMX_DFA_MEMCFG0: 0x%08x p1_init/bunk_init\n", dfa_memcfg0); cvmx_csr_db_decode(cvmx_get_proc_id(), CVMX_DFA_MEMCFG0 & ~(1ull<<63), dfa_memcfg0); cvmx_wait(RLD_INIT_DELAY); ll_printf("Delay.....\n"); cvmx_write_csr(CVMX_DFA_MEMCFG0, cfg_ptr->dfa_memcfg0_base); ll_printf("CVMX_DFA_MEMCFG0: 0x%08x back to base\n", cfg_ptr->dfa_memcfg0_base); cvmx_csr_db_decode(cvmx_get_proc_id(), CVMX_DFA_MEMCFG0 & ~(1ull<<63), cfg_ptr->dfa_memcfg0_base); } // P0 Bunk#1 if ((cfg_ptr->p0_ena ==1) && (cfg_ptr->bunkport == 2)) { cvmx_write_csr(CVMX_DFA_MEMRLD, cfg_ptr->mrs_dat_p0bunk1); ll_printf("CVMX_DFA_MEMRLD : 0x%08x p0_ena memrld\n", cfg_ptr->mrs_dat_p0bunk1); cvmx_csr_db_decode(cvmx_get_proc_id(), CVMX_DFA_MEMRLD & ~(1ull<<63), cfg_ptr->mrs_dat_p0bunk1); dfa_memcfg0 = ( cfg_ptr->dfa_memcfg0_base | (1 << 23) | // P0_INIT (2 << 25) // BUNK_INIT[1:0]=Bunk#1 ); cvmx_write_csr(CVMX_DFA_MEMCFG0, dfa_memcfg0); ll_printf("CVMX_DFA_MEMCFG0: 0x%08x p0_init/bunk_init\n", dfa_memcfg0); cvmx_csr_db_decode(cvmx_get_proc_id(), CVMX_DFA_MEMCFG0 & ~(1ull<<63), dfa_memcfg0); cvmx_wait(RLD_INIT_DELAY); ll_printf("Delay.....\n"); if (cfg_ptr->p1_ena == 1) { // Re-arm Px_INIT if P1-B1 init is required cvmx_write_csr(CVMX_DFA_MEMCFG0, cfg_ptr->dfa_memcfg0_base); ll_printf("CVMX_DFA_MEMCFG0: 0x%08x px_init rearm\n", cfg_ptr->dfa_memcfg0_base); cvmx_csr_db_decode(cvmx_get_proc_id(), CVMX_DFA_MEMCFG0 & ~(1ull<<63), cfg_ptr->dfa_memcfg0_base); } } if ((cfg_ptr->p1_ena == 1) && (cfg_ptr->bunkport == 2)) { cvmx_write_csr(CVMX_DFA_MEMRLD, cfg_ptr->mrs_dat_p1bunk1); ll_printf("CVMX_DFA_MEMRLD : 0x%08x p1_ena memrld\n", cfg_ptr->mrs_dat_p1bunk1); cvmx_csr_db_decode(cvmx_get_proc_id(), CVMX_DFA_MEMRLD & ~(1ull<<63), cfg_ptr->mrs_dat_p1bunk1); dfa_memcfg0 = ( cfg_ptr->dfa_memcfg0_base | (1 << 24) | // P1_INIT (2 << 25) // BUNK_INIT[1:0]=10 ); cvmx_write_csr(CVMX_DFA_MEMCFG0, dfa_memcfg0); ll_printf("CVMX_DFA_MEMCFG0: 0x%08x p1_init/bunk_init\n", dfa_memcfg0); cvmx_csr_db_decode(cvmx_get_proc_id(), CVMX_DFA_MEMCFG0 & ~(1ull<<63), dfa_memcfg0); } cvmx_wait(4000000); // 1/100S, 0.01S, 10mS ll_printf("Delay.....\n"); /* Enable bunks */ dfa_memcfg0 = cfg_ptr->dfa_memcfg0_base |((cfg_ptr->bunkport >= 1) << 25) | ((cfg_ptr->bunkport == 2) << 26); cvmx_write_csr(CVMX_DFA_MEMCFG0, dfa_memcfg0); ll_printf("CVMX_DFA_MEMCFG0: 0x%08x enable bunks\n", dfa_memcfg0); cvmx_csr_db_decode(cvmx_get_proc_id(), CVMX_DFA_MEMCFG0 & ~(1ull<<63), dfa_memcfg0); cvmx_wait(RLD_INIT_DELAY); ll_printf("Delay.....\n"); /* Issue a Silo reset by toggling SILRST in memcfg2. */ memcfg2.u64 = cvmx_read_csr (CVMX_DFA_MEMCFG2); memcfg2.s.silrst = 1; cvmx_write_csr (CVMX_DFA_MEMCFG2, memcfg2.u64); ll_printf("CVMX_DFA_MEMCFG2: 0x%08x silo reset start\n", (uint32_t) memcfg2.u64); memcfg2.s.silrst = 0; cvmx_write_csr (CVMX_DFA_MEMCFG2, memcfg2.u64); ll_printf("CVMX_DFA_MEMCFG2: 0x%08x silo reset done\n", (uint32_t) memcfg2.u64); } }