aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/powerpc/include/asm/firmware.h3
-rw-r--r--arch/powerpc/include/asm/hvcall.h12
-rw-r--r--arch/powerpc/include/asm/pSeries_reconfig.h5
-rw-r--r--arch/powerpc/kernel/lparcfg.c53
-rw-r--r--arch/powerpc/kernel/prom_init.c4
-rw-r--r--arch/powerpc/kernel/rtas.c2
-rw-r--r--arch/powerpc/platforms/pseries/lpar.c46
-rw-r--r--arch/powerpc/platforms/pseries/setup.c11
8 files changed, 106 insertions, 30 deletions
diff --git a/arch/powerpc/include/asm/firmware.h b/arch/powerpc/include/asm/firmware.h
index 4ef662e4a31d..3a6c586c4e40 100644
--- a/arch/powerpc/include/asm/firmware.h
+++ b/arch/powerpc/include/asm/firmware.h
@@ -47,6 +47,7 @@
47#define FW_FEATURE_BEAT ASM_CONST(0x0000000001000000) 47#define FW_FEATURE_BEAT ASM_CONST(0x0000000001000000)
48#define FW_FEATURE_CMO ASM_CONST(0x0000000002000000) 48#define FW_FEATURE_CMO ASM_CONST(0x0000000002000000)
49#define FW_FEATURE_VPHN ASM_CONST(0x0000000004000000) 49#define FW_FEATURE_VPHN ASM_CONST(0x0000000004000000)
50#define FW_FEATURE_XCMO ASM_CONST(0x0000000008000000)
50 51
51#ifndef __ASSEMBLY__ 52#ifndef __ASSEMBLY__
52 53
@@ -60,7 +61,7 @@ enum {
60 FW_FEATURE_VIO | FW_FEATURE_RDMA | FW_FEATURE_LLAN | 61 FW_FEATURE_VIO | FW_FEATURE_RDMA | FW_FEATURE_LLAN |
61 FW_FEATURE_BULK_REMOVE | FW_FEATURE_XDABR | 62 FW_FEATURE_BULK_REMOVE | FW_FEATURE_XDABR |
62 FW_FEATURE_MULTITCE | FW_FEATURE_SPLPAR | FW_FEATURE_LPAR | 63 FW_FEATURE_MULTITCE | FW_FEATURE_SPLPAR | FW_FEATURE_LPAR |
63 FW_FEATURE_CMO | FW_FEATURE_VPHN, 64 FW_FEATURE_CMO | FW_FEATURE_VPHN | FW_FEATURE_XCMO,
64 FW_FEATURE_PSERIES_ALWAYS = 0, 65 FW_FEATURE_PSERIES_ALWAYS = 0,
65 FW_FEATURE_ISERIES_POSSIBLE = FW_FEATURE_ISERIES | FW_FEATURE_LPAR, 66 FW_FEATURE_ISERIES_POSSIBLE = FW_FEATURE_ISERIES | FW_FEATURE_LPAR,
66 FW_FEATURE_ISERIES_ALWAYS = FW_FEATURE_ISERIES | FW_FEATURE_LPAR, 67 FW_FEATURE_ISERIES_ALWAYS = FW_FEATURE_ISERIES | FW_FEATURE_LPAR,
diff --git a/arch/powerpc/include/asm/hvcall.h b/arch/powerpc/include/asm/hvcall.h
index 8edec710cc6d..852b8c1c09db 100644
--- a/arch/powerpc/include/asm/hvcall.h
+++ b/arch/powerpc/include/asm/hvcall.h
@@ -102,6 +102,7 @@
102#define H_ANDCOND (1UL<<(63-33)) 102#define H_ANDCOND (1UL<<(63-33))
103#define H_ICACHE_INVALIDATE (1UL<<(63-40)) /* icbi, etc. (ignored for IO pages) */ 103#define H_ICACHE_INVALIDATE (1UL<<(63-40)) /* icbi, etc. (ignored for IO pages) */
104#define H_ICACHE_SYNCHRONIZE (1UL<<(63-41)) /* dcbst, icbi, etc (ignored for IO pages */ 104#define H_ICACHE_SYNCHRONIZE (1UL<<(63-41)) /* dcbst, icbi, etc (ignored for IO pages */
105#define H_COALESCE_CAND (1UL<<(63-42)) /* page is a good candidate for coalescing */
105#define H_ZERO_PAGE (1UL<<(63-48)) /* zero the page before mapping (ignored for IO pages) */ 106#define H_ZERO_PAGE (1UL<<(63-48)) /* zero the page before mapping (ignored for IO pages) */
106#define H_COPY_PAGE (1UL<<(63-49)) 107#define H_COPY_PAGE (1UL<<(63-49))
107#define H_N (1UL<<(63-61)) 108#define H_N (1UL<<(63-61))
@@ -234,6 +235,7 @@
234#define H_GET_MPP 0x2D4 235#define H_GET_MPP 0x2D4
235#define H_HOME_NODE_ASSOCIATIVITY 0x2EC 236#define H_HOME_NODE_ASSOCIATIVITY 0x2EC
236#define H_BEST_ENERGY 0x2F4 237#define H_BEST_ENERGY 0x2F4
238#define H_GET_MPP_X 0x314
237#define MAX_HCALL_OPCODE H_BEST_ENERGY 239#define MAX_HCALL_OPCODE H_BEST_ENERGY
238 240
239#ifndef __ASSEMBLY__ 241#ifndef __ASSEMBLY__
@@ -312,6 +314,16 @@ struct hvcall_mpp_data {
312 314
313int h_get_mpp(struct hvcall_mpp_data *); 315int h_get_mpp(struct hvcall_mpp_data *);
314 316
317struct hvcall_mpp_x_data {
318 unsigned long coalesced_bytes;
319 unsigned long pool_coalesced_bytes;
320 unsigned long pool_purr_cycles;
321 unsigned long pool_spurr_cycles;
322 unsigned long reserved[3];
323};
324
325int h_get_mpp_x(struct hvcall_mpp_x_data *mpp_x_data);
326
315#ifdef CONFIG_PPC_PSERIES 327#ifdef CONFIG_PPC_PSERIES
316extern int CMO_PrPSP; 328extern int CMO_PrPSP;
317extern int CMO_SecPSP; 329extern int CMO_SecPSP;
diff --git a/arch/powerpc/include/asm/pSeries_reconfig.h b/arch/powerpc/include/asm/pSeries_reconfig.h
index d4b4bfa26fb3..89d2f99c1bf4 100644
--- a/arch/powerpc/include/asm/pSeries_reconfig.h
+++ b/arch/powerpc/include/asm/pSeries_reconfig.h
@@ -18,13 +18,18 @@
18extern int pSeries_reconfig_notifier_register(struct notifier_block *); 18extern int pSeries_reconfig_notifier_register(struct notifier_block *);
19extern void pSeries_reconfig_notifier_unregister(struct notifier_block *); 19extern void pSeries_reconfig_notifier_unregister(struct notifier_block *);
20extern struct blocking_notifier_head pSeries_reconfig_chain; 20extern struct blocking_notifier_head pSeries_reconfig_chain;
21/* Not the best place to put this, will be fixed when we move some
22 * of the rtas suspend-me stuff to pseries */
23extern void pSeries_coalesce_init(void);
21#else /* !CONFIG_PPC_PSERIES */ 24#else /* !CONFIG_PPC_PSERIES */
22static inline int pSeries_reconfig_notifier_register(struct notifier_block *nb) 25static inline int pSeries_reconfig_notifier_register(struct notifier_block *nb)
23{ 26{
24 return 0; 27 return 0;
25} 28}
26static inline void pSeries_reconfig_notifier_unregister(struct notifier_block *nb) { } 29static inline void pSeries_reconfig_notifier_unregister(struct notifier_block *nb) { }
30static inline void pSeries_coalesce_init(void) { }
27#endif /* CONFIG_PPC_PSERIES */ 31#endif /* CONFIG_PPC_PSERIES */
28 32
33
29#endif /* __KERNEL__ */ 34#endif /* __KERNEL__ */
30#endif /* _PPC64_PSERIES_RECONFIG_H */ 35#endif /* _PPC64_PSERIES_RECONFIG_H */
diff --git a/arch/powerpc/kernel/lparcfg.c b/arch/powerpc/kernel/lparcfg.c
index 301db65f05a1..84daabe2fcba 100644
--- a/arch/powerpc/kernel/lparcfg.c
+++ b/arch/powerpc/kernel/lparcfg.c
@@ -132,34 +132,6 @@ static int iseries_lparcfg_data(struct seq_file *m, void *v)
132/* 132/*
133 * Methods used to fetch LPAR data when running on a pSeries platform. 133 * Methods used to fetch LPAR data when running on a pSeries platform.
134 */ 134 */
135/**
136 * h_get_mpp
137 * H_GET_MPP hcall returns info in 7 parms
138 */
139int h_get_mpp(struct hvcall_mpp_data *mpp_data)
140{
141 int rc;
142 unsigned long retbuf[PLPAR_HCALL9_BUFSIZE];
143
144 rc = plpar_hcall9(H_GET_MPP, retbuf);
145
146 mpp_data->entitled_mem = retbuf[0];
147 mpp_data->mapped_mem = retbuf[1];
148
149 mpp_data->group_num = (retbuf[2] >> 2 * 8) & 0xffff;
150 mpp_data->pool_num = retbuf[2] & 0xffff;
151
152 mpp_data->mem_weight = (retbuf[3] >> 7 * 8) & 0xff;
153 mpp_data->unallocated_mem_weight = (retbuf[3] >> 6 * 8) & 0xff;
154 mpp_data->unallocated_entitlement = retbuf[3] & 0xffffffffffff;
155
156 mpp_data->pool_size = retbuf[4];
157 mpp_data->loan_request = retbuf[5];
158 mpp_data->backing_mem = retbuf[6];
159
160 return rc;
161}
162EXPORT_SYMBOL(h_get_mpp);
163 135
164struct hvcall_ppp_data { 136struct hvcall_ppp_data {
165 u64 entitlement; 137 u64 entitlement;
@@ -345,6 +317,30 @@ static void parse_mpp_data(struct seq_file *m)
345 seq_printf(m, "backing_memory=%ld bytes\n", mpp_data.backing_mem); 317 seq_printf(m, "backing_memory=%ld bytes\n", mpp_data.backing_mem);
346} 318}
347 319
320/**
321 * parse_mpp_x_data
322 * Parse out data returned from h_get_mpp_x
323 */
324static void parse_mpp_x_data(struct seq_file *m)
325{
326 struct hvcall_mpp_x_data mpp_x_data;
327
328 if (!firmware_has_feature(FW_FEATURE_XCMO))
329 return;
330 if (h_get_mpp_x(&mpp_x_data))
331 return;
332
333 seq_printf(m, "coalesced_bytes=%ld\n", mpp_x_data.coalesced_bytes);
334
335 if (mpp_x_data.pool_coalesced_bytes)
336 seq_printf(m, "pool_coalesced_bytes=%ld\n",
337 mpp_x_data.pool_coalesced_bytes);
338 if (mpp_x_data.pool_purr_cycles)
339 seq_printf(m, "coalesce_pool_purr=%ld\n", mpp_x_data.pool_purr_cycles);
340 if (mpp_x_data.pool_spurr_cycles)
341 seq_printf(m, "coalesce_pool_spurr=%ld\n", mpp_x_data.pool_spurr_cycles);
342}
343
348#define SPLPAR_CHARACTERISTICS_TOKEN 20 344#define SPLPAR_CHARACTERISTICS_TOKEN 20
349#define SPLPAR_MAXLENGTH 1026*(sizeof(char)) 345#define SPLPAR_MAXLENGTH 1026*(sizeof(char))
350 346
@@ -520,6 +516,7 @@ static int pseries_lparcfg_data(struct seq_file *m, void *v)
520 parse_system_parameter_string(m); 516 parse_system_parameter_string(m);
521 parse_ppp_data(m); 517 parse_ppp_data(m);
522 parse_mpp_data(m); 518 parse_mpp_data(m);
519 parse_mpp_x_data(m);
523 pseries_cmo_data(m); 520 pseries_cmo_data(m);
524 splpar_dispatch_data(m); 521 splpar_dispatch_data(m);
525 522
diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c
index 7839bd7bfd15..c016033ba78d 100644
--- a/arch/powerpc/kernel/prom_init.c
+++ b/arch/powerpc/kernel/prom_init.c
@@ -700,8 +700,10 @@ static void __init early_cmdline_parse(void)
700#endif /* CONFIG_PCI_MSI */ 700#endif /* CONFIG_PCI_MSI */
701#ifdef CONFIG_PPC_SMLPAR 701#ifdef CONFIG_PPC_SMLPAR
702#define OV5_CMO 0x80 /* Cooperative Memory Overcommitment */ 702#define OV5_CMO 0x80 /* Cooperative Memory Overcommitment */
703#define OV5_XCMO 0x40 /* Page Coalescing */
703#else 704#else
704#define OV5_CMO 0x00 705#define OV5_CMO 0x00
706#define OV5_XCMO 0x00
705#endif 707#endif
706#define OV5_TYPE1_AFFINITY 0x80 /* Type 1 NUMA affinity */ 708#define OV5_TYPE1_AFFINITY 0x80 /* Type 1 NUMA affinity */
707 709
@@ -756,7 +758,7 @@ static unsigned char ibm_architecture_vec[] = {
756 OV5_LPAR | OV5_SPLPAR | OV5_LARGE_PAGES | OV5_DRCONF_MEMORY | 758 OV5_LPAR | OV5_SPLPAR | OV5_LARGE_PAGES | OV5_DRCONF_MEMORY |
757 OV5_DONATE_DEDICATE_CPU | OV5_MSI, 759 OV5_DONATE_DEDICATE_CPU | OV5_MSI,
758 0, 760 0,
759 OV5_CMO, 761 OV5_CMO | OV5_XCMO,
760 OV5_TYPE1_AFFINITY, 762 OV5_TYPE1_AFFINITY,
761 0, 763 0,
762 0, 764 0,
diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c
index f48446635c89..271ff6318eda 100644
--- a/arch/powerpc/kernel/rtas.c
+++ b/arch/powerpc/kernel/rtas.c
@@ -42,6 +42,7 @@
42#include <asm/time.h> 42#include <asm/time.h>
43#include <asm/mmu.h> 43#include <asm/mmu.h>
44#include <asm/topology.h> 44#include <asm/topology.h>
45#include <asm/pSeries_reconfig.h>
45 46
46struct rtas_t rtas = { 47struct rtas_t rtas = {
47 .lock = __ARCH_SPIN_LOCK_UNLOCKED 48 .lock = __ARCH_SPIN_LOCK_UNLOCKED
@@ -731,6 +732,7 @@ static int __rtas_suspend_last_cpu(struct rtas_suspend_me_data *data, int wake_w
731 732
732 atomic_set(&data->error, rc); 733 atomic_set(&data->error, rc);
733 start_topology_update(); 734 start_topology_update();
735 pSeries_coalesce_init();
734 736
735 if (wake_when_done) { 737 if (wake_when_done) {
736 atomic_set(&data->done, 1); 738 atomic_set(&data->done, 1);
diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c
index 6f0ed3aac77f..39e6e0a7b2fa 100644
--- a/arch/powerpc/platforms/pseries/lpar.c
+++ b/arch/powerpc/platforms/pseries/lpar.c
@@ -329,6 +329,8 @@ static long pSeries_lpar_hpte_insert(unsigned long hpte_group,
329 /* Make pHyp happy */ 329 /* Make pHyp happy */
330 if ((rflags & _PAGE_NO_CACHE) & !(rflags & _PAGE_WRITETHRU)) 330 if ((rflags & _PAGE_NO_CACHE) & !(rflags & _PAGE_WRITETHRU))
331 hpte_r &= ~_PAGE_COHERENT; 331 hpte_r &= ~_PAGE_COHERENT;
332 if (firmware_has_feature(FW_FEATURE_XCMO) && !(hpte_r & HPTE_R_N))
333 flags |= H_COALESCE_CAND;
332 334
333 lpar_rc = plpar_pte_enter(flags, hpte_group, hpte_v, hpte_r, &slot); 335 lpar_rc = plpar_pte_enter(flags, hpte_group, hpte_v, hpte_r, &slot);
334 if (unlikely(lpar_rc == H_PTEG_FULL)) { 336 if (unlikely(lpar_rc == H_PTEG_FULL)) {
@@ -771,3 +773,47 @@ out:
771 local_irq_restore(flags); 773 local_irq_restore(flags);
772} 774}
773#endif 775#endif
776
777/**
778 * h_get_mpp
779 * H_GET_MPP hcall returns info in 7 parms
780 */
781int h_get_mpp(struct hvcall_mpp_data *mpp_data)
782{
783 int rc;
784 unsigned long retbuf[PLPAR_HCALL9_BUFSIZE];
785
786 rc = plpar_hcall9(H_GET_MPP, retbuf);
787
788 mpp_data->entitled_mem = retbuf[0];
789 mpp_data->mapped_mem = retbuf[1];
790
791 mpp_data->group_num = (retbuf[2] >> 2 * 8) & 0xffff;
792 mpp_data->pool_num = retbuf[2] & 0xffff;
793
794 mpp_data->mem_weight = (retbuf[3] >> 7 * 8) & 0xff;
795 mpp_data->unallocated_mem_weight = (retbuf[3] >> 6 * 8) & 0xff;
796 mpp_data->unallocated_entitlement = retbuf[3] & 0xffffffffffff;
797
798 mpp_data->pool_size = retbuf[4];
799 mpp_data->loan_request = retbuf[5];
800 mpp_data->backing_mem = retbuf[6];
801
802 return rc;
803}
804EXPORT_SYMBOL(h_get_mpp);
805
806int h_get_mpp_x(struct hvcall_mpp_x_data *mpp_x_data)
807{
808 int rc;
809 unsigned long retbuf[PLPAR_HCALL9_BUFSIZE] = { 0 };
810
811 rc = plpar_hcall9(H_GET_MPP_X, retbuf);
812
813 mpp_x_data->coalesced_bytes = retbuf[0];
814 mpp_x_data->pool_coalesced_bytes = retbuf[1];
815 mpp_x_data->pool_purr_cycles = retbuf[2];
816 mpp_x_data->pool_spurr_cycles = retbuf[3];
817
818 return rc;
819}
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c
index ab73ad2ff59d..1689adccc6d7 100644
--- a/arch/powerpc/platforms/pseries/setup.c
+++ b/arch/powerpc/platforms/pseries/setup.c
@@ -405,6 +405,16 @@ static int pseries_set_xdabr(unsigned long dabr)
405#define CMO_CHARACTERISTICS_TOKEN 44 405#define CMO_CHARACTERISTICS_TOKEN 44
406#define CMO_MAXLENGTH 1026 406#define CMO_MAXLENGTH 1026
407 407
408void pSeries_coalesce_init(void)
409{
410 struct hvcall_mpp_x_data mpp_x_data;
411
412 if (firmware_has_feature(FW_FEATURE_CMO) && !h_get_mpp_x(&mpp_x_data))
413 powerpc_firmware_features |= FW_FEATURE_XCMO;
414 else
415 powerpc_firmware_features &= ~FW_FEATURE_XCMO;
416}
417
408/** 418/**
409 * fw_cmo_feature_init - FW_FEATURE_CMO is not stored in ibm,hypertas-functions, 419 * fw_cmo_feature_init - FW_FEATURE_CMO is not stored in ibm,hypertas-functions,
410 * handle that here. (Stolen from parse_system_parameter_string) 420 * handle that here. (Stolen from parse_system_parameter_string)
@@ -474,6 +484,7 @@ void pSeries_cmo_feature_init(void)
474 pr_debug("CMO enabled, PrPSP=%d, SecPSP=%d\n", CMO_PrPSP, 484 pr_debug("CMO enabled, PrPSP=%d, SecPSP=%d\n", CMO_PrPSP,
475 CMO_SecPSP); 485 CMO_SecPSP);
476 powerpc_firmware_features |= FW_FEATURE_CMO; 486 powerpc_firmware_features |= FW_FEATURE_CMO;
487 pSeries_coalesce_init();
477 } else 488 } else
478 pr_debug("CMO not enabled, PrPSP=%d, SecPSP=%d\n", CMO_PrPSP, 489 pr_debug("CMO not enabled, PrPSP=%d, SecPSP=%d\n", CMO_PrPSP,
479 CMO_SecPSP); 490 CMO_SecPSP);