Lines Matching +full:multi +full:- +full:cluster
20 #include <linux/clk-provider.h>
36 #define SPCLOG "vexpress-spc: "
47 /* SPC wake-up IRQs status and mask */
54 /* SPC per-CPU mailboxes */
58 /* SPC CPU/cluster reset statue */
76 /* wake-up interrupt masks */
79 /* TC2 static dual-cluster configuration */
83 * Even though the SPC takes max 3-5 ms to complete any OPP/COMMS
105 * A15s cluster identifier
119 static inline bool cluster_is_a15(u32 cluster) in cluster_is_a15() argument
121 return cluster == info->a15_clusid; in cluster_is_a15()
131 * @set: if true, global wake-up IRQs are set, if false they are cleared
137 reg = readl_relaxed(info->baseaddr + WAKE_INT_MASK); in ve_spc_global_wakeup_irq()
144 writel_relaxed(reg, info->baseaddr + WAKE_INT_MASK); in ve_spc_global_wakeup_irq()
150 * Function to set/clear per-CPU wake-up IRQs. Not protected by locking since
154 * @cluster: mpidr[15:8] bitfield describing cluster affinity level
156 * @set: if true, wake-up IRQs are set, if false they are cleared
158 void ve_spc_cpu_wakeup_irq(u32 cluster, u32 cpu, bool set) in ve_spc_cpu_wakeup_irq() argument
162 if (cluster >= MAX_CLUSTERS) in ve_spc_cpu_wakeup_irq()
167 if (!cluster_is_a15(cluster)) in ve_spc_cpu_wakeup_irq()
170 reg = readl_relaxed(info->baseaddr + WAKE_INT_MASK); in ve_spc_cpu_wakeup_irq()
177 writel_relaxed(reg, info->baseaddr + WAKE_INT_MASK); in ve_spc_cpu_wakeup_irq()
181 * ve_spc_set_resume_addr() - set the jump address used for warm boot
183 * @cluster: mpidr[15:8] bitfield describing cluster affinity level
187 void ve_spc_set_resume_addr(u32 cluster, u32 cpu, u32 addr) in ve_spc_set_resume_addr() argument
191 if (cluster >= MAX_CLUSTERS) in ve_spc_set_resume_addr()
194 if (cluster_is_a15(cluster)) in ve_spc_set_resume_addr()
195 baseaddr = info->baseaddr + A15_BX_ADDR0 + (cpu << 2); in ve_spc_set_resume_addr()
197 baseaddr = info->baseaddr + A7_BX_ADDR0 + (cpu << 2); in ve_spc_set_resume_addr()
205 * Function to enable/disable cluster powerdown. Not protected by locking
209 * @cluster: mpidr[15:8] bitfield describing cluster affinity level
212 void ve_spc_powerdown(u32 cluster, bool enable) in ve_spc_powerdown() argument
216 if (cluster >= MAX_CLUSTERS) in ve_spc_powerdown()
219 pwdrn_reg = cluster_is_a15(cluster) ? A15_PWRDN_EN : A7_PWRDN_EN; in ve_spc_powerdown()
220 writel_relaxed(enable, info->baseaddr + pwdrn_reg); in ve_spc_powerdown()
223 static u32 standbywfi_cpu_mask(u32 cpu, u32 cluster) in standbywfi_cpu_mask() argument
225 return cluster_is_a15(cluster) ? in standbywfi_cpu_mask()
231 * ve_spc_cpu_in_wfi(u32 cpu, u32 cluster)
233 * @cpu: mpidr[7:0] bitfield describing CPU affinity level within cluster
234 * @cluster: mpidr[15:8] bitfield describing cluster affinity level
236 * @return: non-zero if and only if the specified CPU is in WFI
242 int ve_spc_cpu_in_wfi(u32 cpu, u32 cluster) in ve_spc_cpu_in_wfi() argument
245 u32 mask = standbywfi_cpu_mask(cpu, cluster); in ve_spc_cpu_in_wfi()
247 if (cluster >= MAX_CLUSTERS) in ve_spc_cpu_in_wfi()
250 ret = readl_relaxed(info->baseaddr + STANDBYWFI_STAT); in ve_spc_cpu_in_wfi()
258 static int ve_spc_get_performance(int cluster, u32 *freq) in ve_spc_get_performance() argument
260 struct ve_spc_opp *opps = info->opps[cluster]; in ve_spc_get_performance()
264 perf_cfg_reg = cluster_is_a15(cluster) ? PERF_LVL_A15 : PERF_LVL_A7; in ve_spc_get_performance()
266 perf = readl_relaxed(info->baseaddr + perf_cfg_reg); in ve_spc_get_performance()
267 if (perf >= info->num_opps[cluster]) in ve_spc_get_performance()
268 return -EINVAL; in ve_spc_get_performance()
271 *freq = opps->freq; in ve_spc_get_performance()
277 static int ve_spc_round_performance(int cluster, u32 freq) in ve_spc_round_performance() argument
279 int idx, max_opp = info->num_opps[cluster]; in ve_spc_round_performance()
280 struct ve_spc_opp *opps = info->opps[cluster]; in ve_spc_round_performance()
285 ftmp = opps->freq; in ve_spc_round_performance()
300 static int ve_spc_find_performance_index(int cluster, u32 freq) in ve_spc_find_performance_index() argument
302 int idx, max_opp = info->num_opps[cluster]; in ve_spc_find_performance_index()
303 struct ve_spc_opp *opps = info->opps[cluster]; in ve_spc_find_performance_index()
306 if (opps->freq == freq) in ve_spc_find_performance_index()
308 return (idx == max_opp) ? -EINVAL : idx; in ve_spc_find_performance_index()
314 &info->done, usecs_to_jiffies(TIMEOUT_US)); in ve_spc_waitforcompletion()
316 ret = -ETIMEDOUT; in ve_spc_waitforcompletion()
318 ret = info->cur_rsp_stat & STAT_COMPLETE(req_type) ? 0 : -EIO; in ve_spc_waitforcompletion()
322 static int ve_spc_set_performance(int cluster, u32 freq) in ve_spc_set_performance() argument
327 if (cluster_is_a15(cluster)) { in ve_spc_set_performance()
335 perf = ve_spc_find_performance_index(cluster, freq); in ve_spc_set_performance()
340 if (down_timeout(&info->sem, usecs_to_jiffies(TIMEOUT_US))) in ve_spc_set_performance()
341 return -ETIME; in ve_spc_set_performance()
343 init_completion(&info->done); in ve_spc_set_performance()
344 info->cur_rsp_mask = RESPONSE_MASK(req_type); in ve_spc_set_performance()
346 writel(perf, info->baseaddr + perf_cfg_reg); in ve_spc_set_performance()
349 info->cur_rsp_mask = 0; in ve_spc_set_performance()
350 up(&info->sem); in ve_spc_set_performance()
359 if (down_timeout(&info->sem, usecs_to_jiffies(TIMEOUT_US))) in ve_spc_read_sys_cfg()
360 return -ETIME; in ve_spc_read_sys_cfg()
362 init_completion(&info->done); in ve_spc_read_sys_cfg()
363 info->cur_rsp_mask = RESPONSE_MASK(SPC_SYS_CFG); in ve_spc_read_sys_cfg()
366 writel(SYSCFG_START | func | offset >> 2, info->baseaddr + COMMS); in ve_spc_read_sys_cfg()
370 *data = readl(info->baseaddr + SYSCFG_RDATA); in ve_spc_read_sys_cfg()
372 info->cur_rsp_mask = 0; in ve_spc_read_sys_cfg()
373 up(&info->sem); in ve_spc_read_sys_cfg()
381 uint32_t status = readl_relaxed(drv_data->baseaddr + PWC_STATUS); in ve_spc_irq_handler()
383 if (info->cur_rsp_mask & status) { in ve_spc_irq_handler()
384 info->cur_rsp_stat = status; in ve_spc_irq_handler()
385 complete(&drv_data->done); in ve_spc_irq_handler()
392 * +--------------------------+
394 * +--------------------------+
396 * +--------------------------+
401 static int ve_spc_populate_opps(uint32_t cluster) in ve_spc_populate_opps() argument
408 return -ENOMEM; in ve_spc_populate_opps()
410 info->opps[cluster] = opps; in ve_spc_populate_opps()
412 off = cluster_is_a15(cluster) ? A15_PERFVAL_BASE : A7_PERFVAL_BASE; in ve_spc_populate_opps()
416 opps->freq = (data & FREQ_MASK) * MULT_FACTOR; in ve_spc_populate_opps()
417 opps->u_volt = (data >> VOLT_SHIFT) * 1000; in ve_spc_populate_opps()
422 info->num_opps[cluster] = idx; in ve_spc_populate_opps()
429 int cluster; in ve_init_opp_table() local
433 cluster = topology_physical_package_id(cpu_dev->id); in ve_init_opp_table()
434 cluster = cluster < 0 ? 0 : cluster; in ve_init_opp_table()
436 max_opp = info->num_opps[cluster]; in ve_init_opp_table()
437 opps = info->opps[cluster]; in ve_init_opp_table()
440 ret = dev_pm_opp_add(cpu_dev, opps->freq * 1000, opps->u_volt); in ve_init_opp_table()
443 opps->freq, opps->u_volt); in ve_init_opp_table()
455 return -ENOMEM; in ve_spc_init()
457 info->baseaddr = baseaddr; in ve_spc_init()
458 info->a15_clusid = a15_clusid; in ve_spc_init()
463 return -EINVAL; in ve_spc_init()
466 init_completion(&info->done); in ve_spc_init()
468 readl_relaxed(info->baseaddr + PWC_STATUS); in ve_spc_init()
471 | IRQF_ONESHOT, "vexpress-spc", info); in ve_spc_init()
475 return -ENODEV; in ve_spc_init()
478 sema_init(&info->sem, 1); in ve_spc_init()
480 * Multi-cluster systems may need this data when non-coherent, during in ve_spc_init()
481 * cluster power-up/power-down. Make sure driver info reaches main in ve_spc_init()
492 int cluster; member
502 if (ve_spc_get_performance(spc->cluster, &freq)) in spc_recalc_rate()
503 return -EIO; in spc_recalc_rate()
513 return ve_spc_round_performance(spc->cluster, drate); in spc_round_rate()
521 return ve_spc_set_performance(spc->cluster, rate / 1000); in spc_set_rate()
537 return ERR_PTR(-ENOMEM); in ve_spc_clk_register()
539 spc->hw.init = &init; in ve_spc_clk_register()
540 spc->cluster = topology_physical_package_id(cpu_dev->id); in ve_spc_clk_register()
542 spc->cluster = spc->cluster < 0 ? 0 : spc->cluster; in ve_spc_clk_register()
549 return devm_clk_register(cpu_dev, &spc->hw); in ve_spc_clk_register()
554 int cpu, cluster; in ve_spc_clk_init() local
563 return -ENODEV; in ve_spc_clk_init()
582 cluster = topology_physical_package_id(cpu_dev->id); in ve_spc_clk_init()
583 if (cluster < 0 || init_opp_table[cluster]) in ve_spc_clk_init()
589 topology_core_cpumask(cpu_dev->id))) in ve_spc_clk_init()
592 init_opp_table[cluster] = true; in ve_spc_clk_init()
595 platform_device_register_simple("vexpress-spc-cpufreq", -1, NULL, 0); in ve_spc_clk_init()