aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Ellerman <michael@ellerman.id.au>2005-09-23 01:03:10 -0400
committerStephen Rothwell <sfr@canb.auug.org.au>2005-09-23 01:03:10 -0400
commit95b293800859886b602e31c8926a840530a82971 (patch)
tree7355f1986b4f41e09c91e354b4a59191de1e799b
parent47db360328582000a7a46390cfa385b8df07b44f (diff)
ppc64 iSeries: Define /cpus in iSeries device tree
Add the /cpus node and nodes for each cpu, as well as cache size properties, reg propery, "linux,boot-cpu", and timebase/clock frequency. With those properties in place we can remove: - setup_iSeries_cache_sizes() - code in iSeries_setup_arch() to calculate timebase etc. - iSeries_calibrate_decr() - smp_iSeries_numProcs() and simplify smp_iSeries_probe() Signed-off-by: Michael Ellerman <michael@ellerman.id.au> Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
-rw-r--r--arch/ppc64/kernel/iSeries_setup.c178
-rw-r--r--arch/ppc64/kernel/iSeries_smp.c30
-rw-r--r--arch/ppc64/kernel/time.c2
3 files changed, 57 insertions, 153 deletions
diff --git a/arch/ppc64/kernel/iSeries_setup.c b/arch/ppc64/kernel/iSeries_setup.c
index 4895f674a4ba..cadfc623a838 100644
--- a/arch/ppc64/kernel/iSeries_setup.c
+++ b/arch/ppc64/kernel/iSeries_setup.c
@@ -74,7 +74,6 @@ extern void hvlog(char *fmt, ...);
74extern void ppcdbg_initialize(void); 74extern void ppcdbg_initialize(void);
75 75
76static void build_iSeries_Memory_Map(void); 76static void build_iSeries_Memory_Map(void);
77static void setup_iSeries_cache_sizes(void);
78static int iseries_shared_idle(void); 77static int iseries_shared_idle(void);
79static int iseries_dedicated_idle(void); 78static int iseries_dedicated_idle(void);
80#ifdef CONFIG_PCI 79#ifdef CONFIG_PCI
@@ -84,14 +83,6 @@ static void iSeries_pci_final_fixup(void) { }
84#endif 83#endif
85 84
86/* Global Variables */ 85/* Global Variables */
87static unsigned long procFreqHz;
88static unsigned long procFreqMhz;
89static unsigned long procFreqMhzHundreths;
90
91static unsigned long tbFreqHz;
92static unsigned long tbFreqMhz;
93static unsigned long tbFreqMhzHundreths;
94
95int piranha_simulator; 86int piranha_simulator;
96 87
97extern int rd_size; /* Defined in drivers/block/rd.c */ 88extern int rd_size; /* Defined in drivers/block/rd.c */
@@ -344,12 +335,6 @@ static void __init iSeries_init_early(void)
344 iSeries_recal_titan = HvCallXm_loadTod(); 335 iSeries_recal_titan = HvCallXm_loadTod();
345 336
346 /* 337 /*
347 * Cache sizes must be initialized before hpte_init_iSeries is called
348 * as the later need them for flush_icache_range()
349 */
350 setup_iSeries_cache_sizes();
351
352 /*
353 * Initialize the hash table management pointers 338 * Initialize the hash table management pointers
354 */ 339 */
355 hpte_init_iSeries(); 340 hpte_init_iSeries();
@@ -581,47 +566,6 @@ static void __init build_iSeries_Memory_Map(void)
581} 566}
582 567
583/* 568/*
584 * Set up the variables that describe the cache line sizes
585 * for this machine.
586 */
587static void __init setup_iSeries_cache_sizes(void)
588{
589 unsigned int i, n;
590 unsigned int procIx = get_paca()->lppaca.dyn_hv_phys_proc_index;
591
592 systemcfg->icache_size =
593 ppc64_caches.isize = xIoHriProcessorVpd[procIx].xInstCacheSize * 1024;
594 systemcfg->icache_line_size =
595 ppc64_caches.iline_size =
596 xIoHriProcessorVpd[procIx].xInstCacheOperandSize;
597 systemcfg->dcache_size =
598 ppc64_caches.dsize =
599 xIoHriProcessorVpd[procIx].xDataL1CacheSizeKB * 1024;
600 systemcfg->dcache_line_size =
601 ppc64_caches.dline_size =
602 xIoHriProcessorVpd[procIx].xDataCacheOperandSize;
603 ppc64_caches.ilines_per_page = PAGE_SIZE / ppc64_caches.iline_size;
604 ppc64_caches.dlines_per_page = PAGE_SIZE / ppc64_caches.dline_size;
605
606 i = ppc64_caches.iline_size;
607 n = 0;
608 while ((i = (i / 2)))
609 ++n;
610 ppc64_caches.log_iline_size = n;
611
612 i = ppc64_caches.dline_size;
613 n = 0;
614 while ((i = (i / 2)))
615 ++n;
616 ppc64_caches.log_dline_size = n;
617
618 printk("D-cache line size = %d\n",
619 (unsigned int)ppc64_caches.dline_size);
620 printk("I-cache line size = %d\n",
621 (unsigned int)ppc64_caches.iline_size);
622}
623
624/*
625 * Document me. 569 * Document me.
626 */ 570 */
627static void __init iSeries_setup_arch(void) 571static void __init iSeries_setup_arch(void)
@@ -636,36 +580,14 @@ static void __init iSeries_setup_arch(void)
636 printk(KERN_INFO "Using dedicated idle loop\n"); 580 printk(KERN_INFO "Using dedicated idle loop\n");
637 } 581 }
638 582
639 /* Add an eye catcher and the systemcfg layout version number */
640 strcpy(systemcfg->eye_catcher, "SYSTEMCFG:PPC64");
641 systemcfg->version.major = SYSTEMCFG_MAJOR;
642 systemcfg->version.minor = SYSTEMCFG_MINOR;
643
644 /* Setup the Lp Event Queue */ 583 /* Setup the Lp Event Queue */
645 setup_hvlpevent_queue(); 584 setup_hvlpevent_queue();
646 585
647 /* Compute processor frequency */
648 procFreqHz = ((1UL << 34) * 1000000) /
649 xIoHriProcessorVpd[procIx].xProcFreq;
650 procFreqMhz = procFreqHz / 1000000;
651 procFreqMhzHundreths = (procFreqHz / 10000) - (procFreqMhz * 100);
652 ppc_proc_freq = procFreqHz;
653
654 /* Compute time base frequency */
655 tbFreqHz = ((1UL << 32) * 1000000) /
656 xIoHriProcessorVpd[procIx].xTimeBaseFreq;
657 tbFreqMhz = tbFreqHz / 1000000;
658 tbFreqMhzHundreths = (tbFreqHz / 10000) - (tbFreqMhz * 100);
659 ppc_tb_freq = tbFreqHz;
660
661 printk("Max logical processors = %d\n", 586 printk("Max logical processors = %d\n",
662 itVpdAreas.xSlicMaxLogicalProcs); 587 itVpdAreas.xSlicMaxLogicalProcs);
663 printk("Max physical processors = %d\n", 588 printk("Max physical processors = %d\n",
664 itVpdAreas.xSlicMaxPhysicalProcs); 589 itVpdAreas.xSlicMaxPhysicalProcs);
665 printk("Processor frequency = %lu.%02lu\n", procFreqMhz, 590
666 procFreqMhzHundreths);
667 printk("Time base frequency = %lu.%02lu\n", tbFreqMhz,
668 tbFreqMhzHundreths);
669 systemcfg->processor = xIoHriProcessorVpd[procIx].xPVR; 591 systemcfg->processor = xIoHriProcessorVpd[procIx].xPVR;
670 printk("Processor version = %x\n", systemcfg->processor); 592 printk("Processor version = %x\n", systemcfg->processor);
671} 593}
@@ -709,49 +631,6 @@ static void iSeries_halt(void)
709 mf_power_off(); 631 mf_power_off();
710} 632}
711 633
712/*
713 * void __init iSeries_calibrate_decr()
714 *
715 * Description:
716 * This routine retrieves the internal processor frequency from the VPD,
717 * and sets up the kernel timer decrementer based on that value.
718 *
719 */
720static void __init iSeries_calibrate_decr(void)
721{
722 unsigned long cyclesPerUsec;
723 struct div_result divres;
724
725 /* Compute decrementer (and TB) frequency in cycles/sec */
726 cyclesPerUsec = ppc_tb_freq / 1000000;
727
728 /*
729 * Set the amount to refresh the decrementer by. This
730 * is the number of decrementer ticks it takes for
731 * 1/HZ seconds.
732 */
733 tb_ticks_per_jiffy = ppc_tb_freq / HZ;
734
735#if 0
736 /* TEST CODE FOR ADJTIME */
737 tb_ticks_per_jiffy += tb_ticks_per_jiffy / 5000;
738 /* END OF TEST CODE */
739#endif
740
741 /*
742 * tb_ticks_per_sec = freq; would give better accuracy
743 * but tb_ticks_per_sec = tb_ticks_per_jiffy*HZ; assures
744 * that jiffies (and xtime) will match the time returned
745 * by do_gettimeofday.
746 */
747 tb_ticks_per_sec = tb_ticks_per_jiffy * HZ;
748 tb_ticks_per_usec = cyclesPerUsec;
749 tb_to_us = mulhwu_scale_factor(ppc_tb_freq, 1000000);
750 div128_by_32(1024 * 1024, 0, tb_ticks_per_sec, &divres);
751 tb_to_xs = divres.result_low;
752 setup_default_decr();
753}
754
755static void __init iSeries_progress(char * st, unsigned short code) 634static void __init iSeries_progress(char * st, unsigned short code)
756{ 635{
757 printk("Progress: [%04x] - %s\n", (unsigned)code, st); 636 printk("Progress: [%04x] - %s\n", (unsigned)code, st);
@@ -901,7 +780,7 @@ struct machdep_calls __initdata iseries_md = {
901 .get_boot_time = iSeries_get_boot_time, 780 .get_boot_time = iSeries_get_boot_time,
902 .set_rtc_time = iSeries_set_rtc_time, 781 .set_rtc_time = iSeries_set_rtc_time,
903 .get_rtc_time = iSeries_get_rtc_time, 782 .get_rtc_time = iSeries_get_rtc_time,
904 .calibrate_decr = iSeries_calibrate_decr, 783 .calibrate_decr = generic_calibrate_decr,
905 .progress = iSeries_progress, 784 .progress = iSeries_progress,
906 .probe = iseries_probe, 785 .probe = iseries_probe,
907 /* XXX Implement enable_pmcs for iSeries */ 786 /* XXX Implement enable_pmcs for iSeries */
@@ -1032,6 +911,57 @@ void dt_prop_empty(struct iseries_flat_dt *dt, char *name)
1032 dt_prop(dt, name, NULL, 0); 911 dt_prop(dt, name, NULL, 0);
1033} 912}
1034 913
914void dt_cpus(struct iseries_flat_dt *dt)
915{
916 unsigned char buf[32];
917 unsigned char *p;
918 unsigned int i, index;
919 struct IoHriProcessorVpd *d;
920
921 /* yuck */
922 snprintf(buf, 32, "PowerPC,%s", cur_cpu_spec->cpu_name);
923 p = strchr(buf, ' ');
924 if (!p) p = buf + strlen(buf);
925
926 dt_start_node(dt, "cpus");
927 dt_prop_u32(dt, "#address-cells", 1);
928 dt_prop_u32(dt, "#size-cells", 0);
929
930 for (i = 0; i < NR_CPUS; i++) {
931 if (paca[i].lppaca.dyn_proc_status >= 2)
932 continue;
933
934 snprintf(p, 32 - (p - buf), "@%d", i);
935 dt_start_node(dt, buf);
936
937 dt_prop_str(dt, "device_type", "cpu");
938
939 index = paca[i].lppaca.dyn_hv_phys_proc_index;
940 d = &xIoHriProcessorVpd[index];
941
942 dt_prop_u32(dt, "i-cache-size", d->xInstCacheSize * 1024);
943 dt_prop_u32(dt, "i-cache-line-size", d->xInstCacheOperandSize);
944
945 dt_prop_u32(dt, "d-cache-size", d->xDataL1CacheSizeKB * 1024);
946 dt_prop_u32(dt, "d-cache-line-size", d->xDataCacheOperandSize);
947
948 /* magic conversions to Hz copied from old code */
949 dt_prop_u32(dt, "clock-frequency",
950 ((1UL << 34) * 1000000) / d->xProcFreq);
951 dt_prop_u32(dt, "timebase-frequency",
952 ((1UL << 32) * 1000000) / d->xTimeBaseFreq);
953
954 dt_prop_u32(dt, "reg", i);
955
956 if (dt->header.boot_cpuid_phys == i)
957 dt_prop_empty(dt, "linux,boot-cpu");
958
959 dt_end_node(dt);
960 }
961
962 dt_end_node(dt);
963}
964
1035void build_flat_dt(struct iseries_flat_dt *dt) 965void build_flat_dt(struct iseries_flat_dt *dt)
1036{ 966{
1037 u64 tmp[2]; 967 u64 tmp[2];
@@ -1057,6 +987,8 @@ void build_flat_dt(struct iseries_flat_dt *dt)
1057 dt_prop_u32(dt, "linux,platform", PLATFORM_ISERIES_LPAR); 987 dt_prop_u32(dt, "linux,platform", PLATFORM_ISERIES_LPAR);
1058 dt_end_node(dt); 988 dt_end_node(dt);
1059 989
990 dt_cpus(dt);
991
1060 dt_end_node(dt); 992 dt_end_node(dt);
1061 993
1062 dt_push_u32(dt, OF_DT_END); 994 dt_push_u32(dt, OF_DT_END);
diff --git a/arch/ppc64/kernel/iSeries_smp.c b/arch/ppc64/kernel/iSeries_smp.c
index f74386e31638..f982e5b805f4 100644
--- a/arch/ppc64/kernel/iSeries_smp.c
+++ b/arch/ppc64/kernel/iSeries_smp.c
@@ -82,35 +82,9 @@ static void smp_iSeries_message_pass(int target, int msg)
82 } 82 }
83} 83}
84 84
85static int smp_iSeries_numProcs(void)
86{
87 unsigned np, i;
88
89 np = 0;
90 for (i=0; i < NR_CPUS; ++i) {
91 if (paca[i].lppaca.dyn_proc_status < 2) {
92 cpu_set(i, cpu_possible_map);
93 cpu_set(i, cpu_present_map);
94 cpu_set(i, cpu_sibling_map[i]);
95 ++np;
96 }
97 }
98 return np;
99}
100
101static int smp_iSeries_probe(void) 85static int smp_iSeries_probe(void)
102{ 86{
103 unsigned i; 87 return cpus_weight(cpu_possible_map);
104 unsigned np = 0;
105
106 for (i=0; i < NR_CPUS; ++i) {
107 if (paca[i].lppaca.dyn_proc_status < 2) {
108 /*paca[i].active = 1;*/
109 ++np;
110 }
111 }
112
113 return np;
114} 88}
115 89
116static void smp_iSeries_kick_cpu(int nr) 90static void smp_iSeries_kick_cpu(int nr)
@@ -144,6 +118,4 @@ static struct smp_ops_t iSeries_smp_ops = {
144void __init smp_init_iSeries(void) 118void __init smp_init_iSeries(void)
145{ 119{
146 smp_ops = &iSeries_smp_ops; 120 smp_ops = &iSeries_smp_ops;
147 systemcfg->processorCount = smp_iSeries_numProcs();
148} 121}
149
diff --git a/arch/ppc64/kernel/time.c b/arch/ppc64/kernel/time.c
index fb4bf0ad8f32..7f63755eddfd 100644
--- a/arch/ppc64/kernel/time.c
+++ b/arch/ppc64/kernel/time.c
@@ -465,7 +465,7 @@ int do_settimeofday(struct timespec *tv)
465 465
466EXPORT_SYMBOL(do_settimeofday); 466EXPORT_SYMBOL(do_settimeofday);
467 467
468#if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_MAPLE) || defined(CONFIG_PPC_BPA) 468#if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_MAPLE) || defined(CONFIG_PPC_BPA) || defined(CONFIG_PPC_ISERIES)
469void __init generic_calibrate_decr(void) 469void __init generic_calibrate_decr(void)
470{ 470{
471 struct device_node *cpu; 471 struct device_node *cpu;