diff options
Diffstat (limited to 'arch/mips/netlogic/xlp')
-rw-r--r-- | arch/mips/netlogic/xlp/nlm_hal.c | 67 | ||||
-rw-r--r-- | arch/mips/netlogic/xlp/setup.c | 50 | ||||
-rw-r--r-- | arch/mips/netlogic/xlp/wakeup.c | 83 |
3 files changed, 98 insertions, 102 deletions
diff --git a/arch/mips/netlogic/xlp/nlm_hal.c b/arch/mips/netlogic/xlp/nlm_hal.c index 6c65ac701912..529e74742d9f 100644 --- a/arch/mips/netlogic/xlp/nlm_hal.c +++ b/arch/mips/netlogic/xlp/nlm_hal.c | |||
@@ -40,23 +40,23 @@ | |||
40 | #include <asm/mipsregs.h> | 40 | #include <asm/mipsregs.h> |
41 | #include <asm/time.h> | 41 | #include <asm/time.h> |
42 | 42 | ||
43 | #include <asm/netlogic/common.h> | ||
43 | #include <asm/netlogic/haldefs.h> | 44 | #include <asm/netlogic/haldefs.h> |
44 | #include <asm/netlogic/xlp-hal/iomap.h> | 45 | #include <asm/netlogic/xlp-hal/iomap.h> |
45 | #include <asm/netlogic/xlp-hal/xlp.h> | 46 | #include <asm/netlogic/xlp-hal/xlp.h> |
46 | #include <asm/netlogic/xlp-hal/pic.h> | 47 | #include <asm/netlogic/xlp-hal/pic.h> |
47 | #include <asm/netlogic/xlp-hal/sys.h> | 48 | #include <asm/netlogic/xlp-hal/sys.h> |
48 | 49 | ||
49 | /* These addresses are computed by the nlm_hal_init() */ | ||
50 | uint64_t nlm_io_base; | ||
51 | uint64_t nlm_sys_base; | ||
52 | uint64_t nlm_pic_base; | ||
53 | |||
54 | /* Main initialization */ | 50 | /* Main initialization */ |
55 | void nlm_hal_init(void) | 51 | void nlm_node_init(int node) |
56 | { | 52 | { |
57 | nlm_io_base = CKSEG1ADDR(XLP_DEFAULT_IO_BASE); | 53 | struct nlm_soc_info *nodep; |
58 | nlm_sys_base = nlm_get_sys_regbase(0); /* node 0 */ | 54 | |
59 | nlm_pic_base = nlm_get_pic_regbase(0); /* node 0 */ | 55 | nodep = nlm_get_node(node); |
56 | nodep->sysbase = nlm_get_sys_regbase(node); | ||
57 | nodep->picbase = nlm_get_pic_regbase(node); | ||
58 | nodep->ebase = read_c0_ebase() & (~((1 << 12) - 1)); | ||
59 | spin_lock_init(&nodep->piclock); | ||
60 | } | 60 | } |
61 | 61 | ||
62 | int nlm_irq_to_irt(int irq) | 62 | int nlm_irq_to_irt(int irq) |
@@ -100,52 +100,15 @@ int nlm_irq_to_irt(int irq) | |||
100 | } | 100 | } |
101 | } | 101 | } |
102 | 102 | ||
103 | int nlm_irt_to_irq(int irt) | 103 | unsigned int nlm_get_core_frequency(int node, int core) |
104 | { | ||
105 | switch (irt) { | ||
106 | case PIC_IRT_UART_0_INDEX: | ||
107 | return PIC_UART_0_IRQ; | ||
108 | case PIC_IRT_UART_1_INDEX: | ||
109 | return PIC_UART_1_IRQ; | ||
110 | case PIC_IRT_PCIE_LINK_0_INDEX: | ||
111 | return PIC_PCIE_LINK_0_IRQ; | ||
112 | case PIC_IRT_PCIE_LINK_1_INDEX: | ||
113 | return PIC_PCIE_LINK_1_IRQ; | ||
114 | case PIC_IRT_PCIE_LINK_2_INDEX: | ||
115 | return PIC_PCIE_LINK_2_IRQ; | ||
116 | case PIC_IRT_PCIE_LINK_3_INDEX: | ||
117 | return PIC_PCIE_LINK_3_IRQ; | ||
118 | case PIC_IRT_EHCI_0_INDEX: | ||
119 | return PIC_EHCI_0_IRQ; | ||
120 | case PIC_IRT_EHCI_1_INDEX: | ||
121 | return PIC_EHCI_1_IRQ; | ||
122 | case PIC_IRT_OHCI_0_INDEX: | ||
123 | return PIC_OHCI_0_IRQ; | ||
124 | case PIC_IRT_OHCI_1_INDEX: | ||
125 | return PIC_OHCI_1_IRQ; | ||
126 | case PIC_IRT_OHCI_2_INDEX: | ||
127 | return PIC_OHCI_2_IRQ; | ||
128 | case PIC_IRT_OHCI_3_INDEX: | ||
129 | return PIC_OHCI_3_IRQ; | ||
130 | case PIC_IRT_MMC_INDEX: | ||
131 | return PIC_MMC_IRQ; | ||
132 | case PIC_IRT_I2C_0_INDEX: | ||
133 | return PIC_I2C_0_IRQ; | ||
134 | case PIC_IRT_I2C_1_INDEX: | ||
135 | return PIC_I2C_1_IRQ; | ||
136 | default: | ||
137 | return -1; | ||
138 | } | ||
139 | } | ||
140 | |||
141 | unsigned int nlm_get_core_frequency(int core) | ||
142 | { | 104 | { |
143 | unsigned int pll_divf, pll_divr, dfs_div, ext_div; | 105 | unsigned int pll_divf, pll_divr, dfs_div, ext_div; |
144 | unsigned int rstval, dfsval, denom; | 106 | unsigned int rstval, dfsval, denom; |
145 | uint64_t num; | 107 | uint64_t num, sysbase; |
146 | 108 | ||
147 | rstval = nlm_read_sys_reg(nlm_sys_base, SYS_POWER_ON_RESET_CFG); | 109 | sysbase = nlm_get_node(node)->sysbase; |
148 | dfsval = nlm_read_sys_reg(nlm_sys_base, SYS_CORE_DFS_DIV_VALUE); | 110 | rstval = nlm_read_sys_reg(sysbase, SYS_POWER_ON_RESET_CFG); |
111 | dfsval = nlm_read_sys_reg(sysbase, SYS_CORE_DFS_DIV_VALUE); | ||
149 | pll_divf = ((rstval >> 10) & 0x7f) + 1; | 112 | pll_divf = ((rstval >> 10) & 0x7f) + 1; |
150 | pll_divr = ((rstval >> 8) & 0x3) + 1; | 113 | pll_divr = ((rstval >> 8) & 0x3) + 1; |
151 | ext_div = ((rstval >> 30) & 0x3) + 1; | 114 | ext_div = ((rstval >> 30) & 0x3) + 1; |
@@ -159,5 +122,5 @@ unsigned int nlm_get_core_frequency(int core) | |||
159 | 122 | ||
160 | unsigned int nlm_get_cpu_frequency(void) | 123 | unsigned int nlm_get_cpu_frequency(void) |
161 | { | 124 | { |
162 | return nlm_get_core_frequency(0); | 125 | return nlm_get_core_frequency(0, 0); |
163 | } | 126 | } |
diff --git a/arch/mips/netlogic/xlp/setup.c b/arch/mips/netlogic/xlp/setup.c index d8997098defd..4894d62043ac 100644 --- a/arch/mips/netlogic/xlp/setup.c +++ b/arch/mips/netlogic/xlp/setup.c | |||
@@ -52,26 +52,40 @@ | |||
52 | #include <asm/netlogic/xlp-hal/xlp.h> | 52 | #include <asm/netlogic/xlp-hal/xlp.h> |
53 | #include <asm/netlogic/xlp-hal/sys.h> | 53 | #include <asm/netlogic/xlp-hal/sys.h> |
54 | 54 | ||
55 | unsigned long nlm_common_ebase = 0x0; | 55 | uint64_t nlm_io_base; |
56 | 56 | struct nlm_soc_info nlm_nodes[NLM_NR_NODES]; | |
57 | /* default to uniprocessor */ | 57 | cpumask_t nlm_cpumask = CPU_MASK_CPU0; |
58 | uint32_t nlm_coremask = 1, nlm_cpumask = 1; | 58 | unsigned int nlm_threads_per_core; |
59 | int nlm_threads_per_core = 1; | ||
60 | extern u32 __dtb_start[]; | 59 | extern u32 __dtb_start[]; |
61 | 60 | ||
62 | static void nlm_linux_exit(void) | 61 | static void nlm_linux_exit(void) |
63 | { | 62 | { |
64 | nlm_write_sys_reg(nlm_sys_base, SYS_CHIP_RESET, 1); | 63 | uint64_t sysbase = nlm_get_node(0)->sysbase; |
64 | |||
65 | nlm_write_sys_reg(sysbase, SYS_CHIP_RESET, 1); | ||
65 | for ( ; ; ) | 66 | for ( ; ; ) |
66 | cpu_wait(); | 67 | cpu_wait(); |
67 | } | 68 | } |
68 | 69 | ||
69 | void __init plat_mem_setup(void) | 70 | void __init plat_mem_setup(void) |
70 | { | 71 | { |
72 | void *fdtp; | ||
73 | |||
71 | panic_timeout = 5; | 74 | panic_timeout = 5; |
72 | _machine_restart = (void (*)(char *))nlm_linux_exit; | 75 | _machine_restart = (void (*)(char *))nlm_linux_exit; |
73 | _machine_halt = nlm_linux_exit; | 76 | _machine_halt = nlm_linux_exit; |
74 | pm_power_off = nlm_linux_exit; | 77 | pm_power_off = nlm_linux_exit; |
78 | |||
79 | /* | ||
80 | * If no FDT pointer is passed in, use the built-in FDT. | ||
81 | * device_tree_init() does not handle CKSEG0 pointers in | ||
82 | * 64-bit, so convert pointer. | ||
83 | */ | ||
84 | fdtp = (void *)(long)fw_arg0; | ||
85 | if (!fdtp) | ||
86 | fdtp = __dtb_start; | ||
87 | fdtp = phys_to_virt(__pa(fdtp)); | ||
88 | early_init_devtree(fdtp); | ||
75 | } | 89 | } |
76 | 90 | ||
77 | const char *get_system_type(void) | 91 | const char *get_system_type(void) |
@@ -94,27 +108,19 @@ void xlp_mmu_init(void) | |||
94 | (13 + (ffz(PM_DEFAULT_MASK >> 13) / 2))); | 108 | (13 + (ffz(PM_DEFAULT_MASK >> 13) / 2))); |
95 | } | 109 | } |
96 | 110 | ||
97 | void __init prom_init(void) | 111 | void nlm_percpu_init(int hwcpuid) |
98 | { | 112 | { |
99 | void *fdtp; | 113 | } |
100 | 114 | ||
115 | void __init prom_init(void) | ||
116 | { | ||
117 | nlm_io_base = CKSEG1ADDR(XLP_DEFAULT_IO_BASE); | ||
101 | xlp_mmu_init(); | 118 | xlp_mmu_init(); |
102 | nlm_hal_init(); | 119 | nlm_node_init(0); |
103 | |||
104 | /* | ||
105 | * If no FDT pointer is passed in, use the built-in FDT. | ||
106 | * device_tree_init() does not handle CKSEG0 pointers in | ||
107 | * 64-bit, so convert pointer. | ||
108 | */ | ||
109 | fdtp = (void *)(long)fw_arg0; | ||
110 | if (!fdtp) | ||
111 | fdtp = __dtb_start; | ||
112 | fdtp = phys_to_virt(__pa(fdtp)); | ||
113 | early_init_devtree(fdtp); | ||
114 | 120 | ||
115 | nlm_common_ebase = read_c0_ebase() & (~((1 << 12) - 1)); | ||
116 | #ifdef CONFIG_SMP | 121 | #ifdef CONFIG_SMP |
117 | nlm_wakeup_secondary_cpus(0xffffffff); | 122 | cpumask_setall(&nlm_cpumask); |
123 | nlm_wakeup_secondary_cpus(); | ||
118 | 124 | ||
119 | /* update TLB size after waking up threads */ | 125 | /* update TLB size after waking up threads */ |
120 | current_cpu_data.tlbsize = ((read_c0_config6() >> 16) & 0xffff) + 1; | 126 | current_cpu_data.tlbsize = ((read_c0_config6() >> 16) & 0xffff) + 1; |
diff --git a/arch/mips/netlogic/xlp/wakeup.c b/arch/mips/netlogic/xlp/wakeup.c index 44d923ff3846..cb9010642ac3 100644 --- a/arch/mips/netlogic/xlp/wakeup.c +++ b/arch/mips/netlogic/xlp/wakeup.c | |||
@@ -51,45 +51,72 @@ | |||
51 | #include <asm/netlogic/xlp-hal/xlp.h> | 51 | #include <asm/netlogic/xlp-hal/xlp.h> |
52 | #include <asm/netlogic/xlp-hal/sys.h> | 52 | #include <asm/netlogic/xlp-hal/sys.h> |
53 | 53 | ||
54 | static void xlp_enable_secondary_cores(void) | 54 | static int xlp_wakeup_core(uint64_t sysbase, int core) |
55 | { | 55 | { |
56 | uint32_t core, value, coremask, syscoremask; | 56 | uint32_t coremask, value; |
57 | int count; | 57 | int count; |
58 | 58 | ||
59 | /* read cores in reset from SYS block */ | 59 | coremask = (1 << core); |
60 | syscoremask = nlm_read_sys_reg(nlm_sys_base, SYS_CPU_RESET); | ||
61 | 60 | ||
62 | /* update user specified */ | 61 | /* Enable CPU clock */ |
63 | nlm_coremask = nlm_coremask & (syscoremask | 1); | 62 | value = nlm_read_sys_reg(sysbase, SYS_CORE_DFS_DIS_CTRL); |
63 | value &= ~coremask; | ||
64 | nlm_write_sys_reg(sysbase, SYS_CORE_DFS_DIS_CTRL, value); | ||
64 | 65 | ||
65 | for (core = 1; core < 8; core++) { | 66 | /* Remove CPU Reset */ |
66 | coremask = 1 << core; | 67 | value = nlm_read_sys_reg(sysbase, SYS_CPU_RESET); |
67 | if ((nlm_coremask & coremask) == 0) | 68 | value &= ~coremask; |
68 | continue; | 69 | nlm_write_sys_reg(sysbase, SYS_CPU_RESET, value); |
69 | 70 | ||
70 | /* Enable CPU clock */ | 71 | /* Poll for CPU to mark itself coherent */ |
71 | value = nlm_read_sys_reg(nlm_sys_base, SYS_CORE_DFS_DIS_CTRL); | 72 | count = 100000; |
72 | value &= ~coremask; | 73 | do { |
73 | nlm_write_sys_reg(nlm_sys_base, SYS_CORE_DFS_DIS_CTRL, value); | 74 | value = nlm_read_sys_reg(sysbase, SYS_CPU_NONCOHERENT_MODE); |
75 | } while ((value & coremask) != 0 && --count > 0); | ||
74 | 76 | ||
75 | /* Remove CPU Reset */ | 77 | return count != 0; |
76 | value = nlm_read_sys_reg(nlm_sys_base, SYS_CPU_RESET); | 78 | } |
77 | value &= ~coremask; | 79 | |
78 | nlm_write_sys_reg(nlm_sys_base, SYS_CPU_RESET, value); | 80 | static void xlp_enable_secondary_cores(const cpumask_t *wakeup_mask) |
81 | { | ||
82 | struct nlm_soc_info *nodep; | ||
83 | uint64_t syspcibase; | ||
84 | uint32_t syscoremask; | ||
85 | int core, n, cpu; | ||
86 | |||
87 | for (n = 0; n < NLM_NR_NODES; n++) { | ||
88 | syspcibase = nlm_get_sys_pcibase(n); | ||
89 | if (nlm_read_reg(syspcibase, 0) == 0xffffffff) | ||
90 | break; | ||
91 | |||
92 | /* read cores in reset from SYS and account for boot cpu */ | ||
93 | nlm_node_init(n); | ||
94 | nodep = nlm_get_node(n); | ||
95 | syscoremask = nlm_read_sys_reg(nodep->sysbase, SYS_CPU_RESET); | ||
96 | if (n == 0) | ||
97 | syscoremask |= 1; | ||
98 | |||
99 | for (core = 0; core < NLM_CORES_PER_NODE; core++) { | ||
100 | /* see if the core exists */ | ||
101 | if ((syscoremask & (1 << core)) == 0) | ||
102 | continue; | ||
79 | 103 | ||
80 | /* Poll for CPU to mark itself coherent */ | 104 | /* see if at least the first thread is enabled */ |
81 | count = 100000; | 105 | cpu = (n * NLM_CORES_PER_NODE + core) |
82 | do { | 106 | * NLM_THREADS_PER_CORE; |
83 | value = nlm_read_sys_reg(nlm_sys_base, | 107 | if (!cpumask_test_cpu(cpu, wakeup_mask)) |
84 | SYS_CPU_NONCOHERENT_MODE); | 108 | continue; |
85 | } while ((value & coremask) != 0 && count-- > 0); | ||
86 | 109 | ||
87 | if (count == 0) | 110 | /* wake up the core */ |
88 | pr_err("Failed to enable core %d\n", core); | 111 | if (xlp_wakeup_core(nodep->sysbase, core)) |
112 | nodep->coremask |= 1u << core; | ||
113 | else | ||
114 | pr_err("Failed to enable core %d\n", core); | ||
115 | } | ||
89 | } | 116 | } |
90 | } | 117 | } |
91 | 118 | ||
92 | void xlp_wakeup_secondary_cpus(void) | 119 | void xlp_wakeup_secondary_cpus() |
93 | { | 120 | { |
94 | /* | 121 | /* |
95 | * In case of u-boot, the secondaries are in reset | 122 | * In case of u-boot, the secondaries are in reset |
@@ -98,5 +125,5 @@ void xlp_wakeup_secondary_cpus(void) | |||
98 | xlp_boot_core0_siblings(); | 125 | xlp_boot_core0_siblings(); |
99 | 126 | ||
100 | /* now get other cores out of reset */ | 127 | /* now get other cores out of reset */ |
101 | xlp_enable_secondary_cores(); | 128 | xlp_enable_secondary_cores(&nlm_cpumask); |
102 | } | 129 | } |