diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/powerpc/include/asm/firmware.h | 3 | ||||
-rw-r--r-- | arch/powerpc/include/asm/hvcall.h | 12 | ||||
-rw-r--r-- | arch/powerpc/include/asm/pSeries_reconfig.h | 5 | ||||
-rw-r--r-- | arch/powerpc/kernel/lparcfg.c | 53 | ||||
-rw-r--r-- | arch/powerpc/kernel/prom_init.c | 4 | ||||
-rw-r--r-- | arch/powerpc/kernel/rtas.c | 2 | ||||
-rw-r--r-- | arch/powerpc/platforms/pseries/lpar.c | 46 | ||||
-rw-r--r-- | arch/powerpc/platforms/pseries/setup.c | 11 |
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 | ||
313 | int h_get_mpp(struct hvcall_mpp_data *); | 315 | int h_get_mpp(struct hvcall_mpp_data *); |
314 | 316 | ||
317 | struct 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 | |||
325 | int h_get_mpp_x(struct hvcall_mpp_x_data *mpp_x_data); | ||
326 | |||
315 | #ifdef CONFIG_PPC_PSERIES | 327 | #ifdef CONFIG_PPC_PSERIES |
316 | extern int CMO_PrPSP; | 328 | extern int CMO_PrPSP; |
317 | extern int CMO_SecPSP; | 329 | extern 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 @@ | |||
18 | extern int pSeries_reconfig_notifier_register(struct notifier_block *); | 18 | extern int pSeries_reconfig_notifier_register(struct notifier_block *); |
19 | extern void pSeries_reconfig_notifier_unregister(struct notifier_block *); | 19 | extern void pSeries_reconfig_notifier_unregister(struct notifier_block *); |
20 | extern struct blocking_notifier_head pSeries_reconfig_chain; | 20 | extern 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 */ | ||
23 | extern void pSeries_coalesce_init(void); | ||
21 | #else /* !CONFIG_PPC_PSERIES */ | 24 | #else /* !CONFIG_PPC_PSERIES */ |
22 | static inline int pSeries_reconfig_notifier_register(struct notifier_block *nb) | 25 | static inline int pSeries_reconfig_notifier_register(struct notifier_block *nb) |
23 | { | 26 | { |
24 | return 0; | 27 | return 0; |
25 | } | 28 | } |
26 | static inline void pSeries_reconfig_notifier_unregister(struct notifier_block *nb) { } | 29 | static inline void pSeries_reconfig_notifier_unregister(struct notifier_block *nb) { } |
30 | static 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 | */ | ||
139 | int 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 | } | ||
162 | EXPORT_SYMBOL(h_get_mpp); | ||
163 | 135 | ||
164 | struct hvcall_ppp_data { | 136 | struct 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 | */ | ||
324 | static 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 | ||
46 | struct rtas_t rtas = { | 47 | struct 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 | */ | ||
781 | int 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 | } | ||
804 | EXPORT_SYMBOL(h_get_mpp); | ||
805 | |||
806 | int 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 | ||
408 | void 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); |