Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
b87d0087
Commit
b87d0087
authored
Oct 11, 2003
by
Benjamin Herrenschmidt
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix timebase hardware sync on SMP PowerMacs (both oldworld dual 604s and
core99 dual G4s).
parent
96f124ee
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
92 additions
and
10 deletions
+92
-10
arch/ppc/platforms/pmac_smp.c
arch/ppc/platforms/pmac_smp.c
+92
-10
No files found.
arch/ppc/platforms/pmac_smp.c
View file @
b87d0087
...
...
@@ -51,6 +51,7 @@
#include <asm/time.h>
#include <asm/open_pic.h>
#include <asm/cacheflush.h>
#include <asm/keylargo.h>
/*
* Powersurge (old powermac SMP) support.
...
...
@@ -108,9 +109,16 @@ static volatile u32 *psurge_start;
/* what sort of powersurge board we have */
static
int
psurge_type
=
PSURGE_NONE
;
/* L2 and L3 cache settings to pass from CPU0 to CPU1 */
volatile
static
long
int
core99_l2_cache
;
volatile
static
long
int
core99_l3_cache
;
/* Timebase freeze GPIO */
static
unsigned
int
core99_tb_gpio
;
/* Sync flag for HW tb sync */
static
volatile
int
sec_tb_reset
=
0
;
static
void
__init
core99_init_caches
(
int
cpu
)
{
...
...
@@ -380,7 +388,6 @@ static void __init smp_psurge_kick_cpu(int nr)
*/
static
void
__init
psurge_dual_sync_tb
(
int
cpu_nr
)
{
static
volatile
int
sec_tb_reset
=
0
;
int
t
;
set_dec
(
tb_ticks_per_jiffy
);
...
...
@@ -408,8 +415,15 @@ smp_psurge_setup_cpu(int cpu_nr)
{
if
(
cpu_nr
==
0
)
{
if
(
num_online_cpus
()
<
2
)
/* If we failed to start the second CPU, we should still
* send it an IPI to start the timebase & DEC or we might
* have them stuck.
*/
if
(
num_online_cpus
()
<
2
)
{
if
(
psurge_type
==
PSURGE_DUAL
)
psurge_set_ipi
(
1
);
return
;
}
/* reset the entry point so if we get another intr we won't
* try to startup again */
out_be32
(
psurge_start
,
0x100
);
...
...
@@ -421,19 +435,42 @@ smp_psurge_setup_cpu(int cpu_nr)
psurge_dual_sync_tb
(
cpu_nr
);
}
void
__init
smp_psurge_take_timebase
(
void
)
{
/* Dummy implementation */
}
void
__init
smp_psurge_give_timebase
(
void
)
{
/* Dummy implementation */
}
static
int
__init
smp_core99_probe
(
void
)
{
extern
int
powersave_nap
;
struct
device_node
*
cpus
;
int
i
,
ncpus
=
1
;
extern
int
powersave_na
p
;
u32
*
tbpro
p
;
if
(
ppc_md
.
progress
)
ppc_md
.
progress
(
"smp_core99_probe"
,
0x345
);
cpus
=
find_type_devices
(
"cpu"
);
if
(
cpus
)
while
((
cpus
=
cpus
->
next
)
!=
NULL
)
++
ncpus
;
if
(
cpus
==
NULL
)
return
0
;
tbprop
=
(
u32
*
)
get_property
(
cpus
,
"timebase-enable"
,
NULL
);
if
(
tbprop
)
core99_tb_gpio
=
*
tbprop
;
else
core99_tb_gpio
=
KL_GPIO_TB_ENABLE
;
while
((
cpus
=
cpus
->
next
)
!=
NULL
)
++
ncpus
;
printk
(
"smp_core99_probe: found %d cpus
\n
"
,
ncpus
);
if
(
ncpus
>
1
)
{
openpic_request_IPIs
();
for
(
i
=
1
;
i
<
ncpus
;
++
i
)
...
...
@@ -517,14 +554,59 @@ smp_core99_setup_cpu(int cpu_nr)
if
(
ppc_md
.
progress
)
ppc_md
.
progress
(
"core99_setup_cpu 0 done"
,
0x349
);
}
void
__init
smp_core99_take_timebase
(
void
)
{
/* Secondary processor "takes" the timebase by freezing
* it, resetting its local TB and telling CPU 0 to go on
*/
pmac_call_feature
(
PMAC_FTR_WRITE_GPIO
,
NULL
,
core99_tb_gpio
,
4
);
pmac_call_feature
(
PMAC_FTR_READ_GPIO
,
NULL
,
core99_tb_gpio
,
0
);
mb
();
set_dec
(
tb_ticks_per_jiffy
);
set_tb
(
0
,
0
);
last_jiffy_stamp
(
smp_processor_id
())
=
0
;
mb
();
sec_tb_reset
=
1
;
}
void
__init
smp_core99_give_timebase
(
void
)
{
unsigned
int
t
;
/* Primary processor waits for secondary to have frozen
* the timebase, resets local TB, and kick timebase again
*/
/* wait for the secondary to have reset its TB before proceeding */
for
(
t
=
1000
;
t
>
0
&&
!
sec_tb_reset
;
--
t
)
udelay
(
1000
);
if
(
t
==
0
)
printk
(
KERN_WARNING
"Timeout waiting sync on second CPU
\n
"
);
set_dec
(
tb_ticks_per_jiffy
);
set_tb
(
0
,
0
);
last_jiffy_stamp
(
smp_processor_id
())
=
0
;
mb
();
/* Now, restart the timebase by leaving the GPIO to an open collector */
pmac_call_feature
(
PMAC_FTR_WRITE_GPIO
,
NULL
,
core99_tb_gpio
,
0
);
pmac_call_feature
(
PMAC_FTR_READ_GPIO
,
NULL
,
core99_tb_gpio
,
0
);
smp_tb_synchronized
=
1
;
}
/* PowerSurge-style Macs */
struct
smp_ops_t
psurge_smp_ops
__pmacdata
=
{
.
message_pass
=
smp_psurge_message_pass
,
.
probe
=
smp_psurge_probe
,
.
kick_cpu
=
smp_psurge_kick_cpu
,
.
setup_cpu
=
smp_psurge_setup_cpu
,
.
give_timebase
=
smp_
generic
_give_timebase
,
.
take_timebase
=
smp_
generic
_take_timebase
,
.
give_timebase
=
smp_
psurge
_give_timebase
,
.
take_timebase
=
smp_
psurge
_take_timebase
,
};
/* Core99 Macs (dual G4s) */
...
...
@@ -533,6 +615,6 @@ struct smp_ops_t core99_smp_ops __pmacdata = {
.
probe
=
smp_core99_probe
,
.
kick_cpu
=
smp_core99_kick_cpu
,
.
setup_cpu
=
smp_core99_setup_cpu
,
.
give_timebase
=
smp_
generic
_give_timebase
,
.
take_timebase
=
smp_
generic
_take_timebase
,
.
give_timebase
=
smp_
core99
_give_timebase
,
.
take_timebase
=
smp_
core99
_take_timebase
,
};
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment