Commit 35499c01 authored by Paul Mackerras's avatar Paul Mackerras

powerpc: Merge in 64-bit powermac support.

This brings in a lot of changes from arch/ppc64/kernel/pmac_*.c to
arch/powerpc/platforms/powermac/*.c and makes various minor tweaks
elsewhere.  On the powermac we now initialize ppc_md by copying
the whole pmac_md structure into it, which required some changes in
the ordering of initializations of individual fields of it.
Signed-off-by: default avatarPaul Mackerras <paulus@samba.org>
parent b6ba9281
...@@ -290,6 +290,7 @@ config PPC_PMAC ...@@ -290,6 +290,7 @@ config PPC_PMAC
config PPC_PMAC64 config PPC_PMAC64
bool bool
depends on PPC_PMAC && POWER4 depends on PPC_PMAC && POWER4
select U3_DART
default y default y
config PPC_PREP config PPC_PREP
......
...@@ -1501,20 +1501,17 @@ copy_to_here: ...@@ -1501,20 +1501,17 @@ copy_to_here:
.section ".text"; .section ".text";
.align 2 ; .align 2 ;
.globl pmac_secondary_start_1 .globl __secondary_start_pmac_0
pmac_secondary_start_1: __secondary_start_pmac_0:
li r24, 1 /* NB the entries for cpus 0, 1, 2 must each occupy 8 bytes. */
b .pmac_secondary_start li r24,0
b 1f
.globl pmac_secondary_start_2 li r24,1
pmac_secondary_start_2: b 1f
li r24, 2 li r24,2
b .pmac_secondary_start b 1f
li r24,3
.globl pmac_secondary_start_3 1:
pmac_secondary_start_3:
li r24, 3
b .pmac_secondary_start
_GLOBAL(pmac_secondary_start) _GLOBAL(pmac_secondary_start)
/* turn on 64-bit mode */ /* turn on 64-bit mode */
......
...@@ -772,7 +772,7 @@ static unsigned long __init prom_next_cell(int s, cell_t **cellp) ...@@ -772,7 +772,7 @@ static unsigned long __init prom_next_cell(int s, cell_t **cellp)
} }
r = *p++; r = *p++;
#ifdef CONFIG_PPC64 #ifdef CONFIG_PPC64
if (s) { if (s > 1) {
r <<= 32; r <<= 32;
r |= *(p++); r |= *(p++);
} }
...@@ -2059,7 +2059,7 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4, ...@@ -2059,7 +2059,7 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4,
reloc_got2(-offset); reloc_got2(-offset);
#endif #endif
__start(hdr, 0, 0); __start(hdr, KERNELBASE + offset, 0);
return 0; return 0;
} }
...@@ -464,14 +464,11 @@ void __init machine_init(unsigned long dt_ptr, unsigned long phys) ...@@ -464,14 +464,11 @@ void __init machine_init(unsigned long dt_ptr, unsigned long phys)
strlcpy(cmd_line, CONFIG_CMDLINE, sizeof(cmd_line)); strlcpy(cmd_line, CONFIG_CMDLINE, sizeof(cmd_line));
#endif /* CONFIG_CMDLINE */ #endif /* CONFIG_CMDLINE */
platform_init();
#ifdef CONFIG_6xx #ifdef CONFIG_6xx
ppc_md.power_save = ppc6xx_idle; ppc_md.power_save = ppc6xx_idle;
#endif #endif
#ifdef CONFIG_POWER4
ppc_md.power_save = power4_idle;
#endif
platform_init();
if (ppc_md.progress) if (ppc_md.progress)
ppc_md.progress("id mach(): done", 0x200); ppc_md.progress("id mach(): done", 0x200);
......
ifeq ($(CONFIG_PPC32),y) ifeq ($(CONFIG_PPC_MERGE),y)
obj-$(CONFIG_PPC_PMAC) += powermac/ obj-$(CONFIG_PPC_PMAC) += powermac/
endif endif
obj-$(CONFIG_4xx) += 4xx/ obj-$(CONFIG_4xx) += 4xx/
......
obj-$(CONFIG_PPC_PMAC) += pic.o setup.o time.o feature.o pci.o \ obj-y += pic.o setup.o time.o feature.o pci.o \
sleep.o low_i2c.o cache.o sleep.o low_i2c.o cache.o
obj-$(CONFIG_PMAC_BACKLIGHT) += backlight.o obj-$(CONFIG_PMAC_BACKLIGHT) += backlight.o
obj-$(CONFIG_CPU_FREQ_PMAC) += cpufreq.o obj-$(CONFIG_CPU_FREQ_PMAC) += cpufreq.o
ifeq ($(CONFIG_PPC_PMAC),y)
obj-$(CONFIG_NVRAM) += nvram.o obj-$(CONFIG_NVRAM) += nvram.o
# ppc64 pmac doesn't define CONFIG_NVRAM but needs nvram stuff
obj-$(CONFIG_PPC64) += nvram.o
obj-$(CONFIG_SMP) += smp.o obj-$(CONFIG_SMP) += smp.o
endif
...@@ -2960,7 +2960,6 @@ static void dump_HT_speeds(char *name, u32 cfg, u32 frq) ...@@ -2960,7 +2960,6 @@ static void dump_HT_speeds(char *name, u32 cfg, u32 frq)
void __init pmac_check_ht_link(void) void __init pmac_check_ht_link(void)
{ {
#if 0 /* Disabled for now */
u32 ufreq, freq, ucfg, cfg; u32 ufreq, freq, ucfg, cfg;
struct device_node *pcix_node; struct device_node *pcix_node;
u8 px_bus, px_devfn; u8 px_bus, px_devfn;
...@@ -2991,10 +2990,8 @@ void __init pmac_check_ht_link(void) ...@@ -2991,10 +2990,8 @@ void __init pmac_check_ht_link(void)
early_read_config_dword(px_hose, px_bus, px_devfn, 0xc8, &cfg); early_read_config_dword(px_hose, px_bus, px_devfn, 0xc8, &cfg);
early_read_config_dword(px_hose, px_bus, px_devfn, 0xd0, &freq); early_read_config_dword(px_hose, px_bus, px_devfn, 0xd0, &freq);
dump_HT_speeds("PCI-X HT Downlink", cfg, freq); dump_HT_speeds("PCI-X HT Downlink", cfg, freq);
#endif
} }
#endif /* 0 */
#endif /* CONFIG_POWER4 */
/* /*
* Early video resume hook * Early video resume hook
......
...@@ -47,7 +47,8 @@ ...@@ -47,7 +47,8 @@
/* On Core99, nvram is either a sharp, a micron or an AMD flash */ /* On Core99, nvram is either a sharp, a micron or an AMD flash */
#define SM_FLASH_STATUS_DONE 0x80 #define SM_FLASH_STATUS_DONE 0x80
#define SM_FLASH_STATUS_ERR 0x38 #define SM_FLASH_STATUS_ERR 0x38
#define SM_FLASH_CMD_ERASE_CONFIRM 0xd0 #define SM_FLASH_CMD_ERASE_CONFIRM 0xd0
#define SM_FLASH_CMD_ERASE_SETUP 0x20 #define SM_FLASH_CMD_ERASE_SETUP 0x20
#define SM_FLASH_CMD_RESET 0xff #define SM_FLASH_CMD_RESET 0xff
...@@ -75,11 +76,11 @@ struct core99_header { ...@@ -75,11 +76,11 @@ struct core99_header {
* Read and write the non-volatile RAM on PowerMacs and CHRP machines. * Read and write the non-volatile RAM on PowerMacs and CHRP machines.
*/ */
static int nvram_naddrs; static int nvram_naddrs;
static volatile unsigned char *nvram_addr;
static volatile unsigned char *nvram_data; static volatile unsigned char *nvram_data;
static int nvram_mult, is_core_99; static int is_core_99;
static int core99_bank = 0; static int core99_bank = 0;
static int nvram_partitions[3]; static int nvram_partitions[3];
// XXX Turn that into a sem
static DEFINE_SPINLOCK(nv_lock); static DEFINE_SPINLOCK(nv_lock);
extern int pmac_newworld; extern int pmac_newworld;
...@@ -105,6 +106,52 @@ static void core99_nvram_write_byte(int addr, unsigned char val) ...@@ -105,6 +106,52 @@ static void core99_nvram_write_byte(int addr, unsigned char val)
nvram_image[addr] = val; nvram_image[addr] = val;
} }
static ssize_t core99_nvram_read(char *buf, size_t count, loff_t *index)
{
int i;
if (nvram_image == NULL)
return -ENODEV;
if (*index > NVRAM_SIZE)
return 0;
i = *index;
if (i + count > NVRAM_SIZE)
count = NVRAM_SIZE - i;
memcpy(buf, &nvram_image[i], count);
*index = i + count;
return count;
}
static ssize_t core99_nvram_write(char *buf, size_t count, loff_t *index)
{
int i;
if (nvram_image == NULL)
return -ENODEV;
if (*index > NVRAM_SIZE)
return 0;
i = *index;
if (i + count > NVRAM_SIZE)
count = NVRAM_SIZE - i;
memcpy(&nvram_image[i], buf, count);
*index = i + count;
return count;
}
static ssize_t core99_nvram_size(void)
{
if (nvram_image == NULL)
return -ENODEV;
return NVRAM_SIZE;
}
#ifdef CONFIG_PPC32
static volatile unsigned char *nvram_addr;
static int nvram_mult;
static unsigned char direct_nvram_read_byte(int addr) static unsigned char direct_nvram_read_byte(int addr)
{ {
...@@ -181,7 +228,7 @@ static void pmu_nvram_write_byte(int addr, unsigned char val) ...@@ -181,7 +228,7 @@ static void pmu_nvram_write_byte(int addr, unsigned char val)
} }
#endif /* CONFIG_ADB_PMU */ #endif /* CONFIG_ADB_PMU */
#endif /* CONFIG_PPC32 */
static u8 chrp_checksum(struct chrp_header* hdr) static u8 chrp_checksum(struct chrp_header* hdr)
{ {
...@@ -249,7 +296,7 @@ static int sm_erase_bank(int bank) ...@@ -249,7 +296,7 @@ static int sm_erase_bank(int bank)
timeout = 0; timeout = 0;
do { do {
if (++timeout > 1000000) { if (++timeout > 1000000) {
printk(KERN_ERR "nvram: Sharp/Miron flash erase timeout !\n"); printk(KERN_ERR "nvram: Sharp/Micron flash erase timeout !\n");
break; break;
} }
out_8(base, SM_FLASH_CMD_READ_STATUS); out_8(base, SM_FLASH_CMD_READ_STATUS);
...@@ -411,7 +458,7 @@ static void __init lookup_partitions(void) ...@@ -411,7 +458,7 @@ static void __init lookup_partitions(void)
buffer[16] = 0; buffer[16] = 0;
do { do {
for (i=0;i<16;i++) for (i=0;i<16;i++)
buffer[i] = nvram_read_byte(offset+i); buffer[i] = ppc_md.nvram_read_val(offset+i);
if (!strcmp(hdr->name, "common")) if (!strcmp(hdr->name, "common"))
nvram_partitions[pmac_nvram_OF] = offset + 0x10; nvram_partitions[pmac_nvram_OF] = offset + 0x10;
if (!strcmp(hdr->name, "APL,MacOS75")) { if (!strcmp(hdr->name, "APL,MacOS75")) {
...@@ -467,65 +514,76 @@ static void core99_nvram_sync(void) ...@@ -467,65 +514,76 @@ static void core99_nvram_sync(void)
#endif #endif
} }
void __init pmac_nvram_init(void) static int __init core99_nvram_setup(struct device_node *dp)
{
int i;
u32 gen_bank0, gen_bank1;
if (nvram_naddrs < 1) {
printk(KERN_ERR "nvram: no address\n");
return -EINVAL;
}
nvram_image = alloc_bootmem(NVRAM_SIZE);
if (nvram_image == NULL) {
printk(KERN_ERR "nvram: can't allocate ram image\n");
return -ENOMEM;
}
nvram_data = ioremap(dp->addrs[0].address, NVRAM_SIZE*2);
nvram_naddrs = 1; /* Make sure we get the correct case */
DBG("nvram: Checking bank 0...\n");
gen_bank0 = core99_check((u8 *)nvram_data);
gen_bank1 = core99_check((u8 *)nvram_data + NVRAM_SIZE);
core99_bank = (gen_bank0 < gen_bank1) ? 1 : 0;
DBG("nvram: gen0=%d, gen1=%d\n", gen_bank0, gen_bank1);
DBG("nvram: Active bank is: %d\n", core99_bank);
for (i=0; i<NVRAM_SIZE; i++)
nvram_image[i] = nvram_data[i + core99_bank*NVRAM_SIZE];
ppc_md.nvram_read_val = core99_nvram_read_byte;
ppc_md.nvram_write_val = core99_nvram_write_byte;
ppc_md.nvram_read = core99_nvram_read;
ppc_md.nvram_write = core99_nvram_write;
ppc_md.nvram_size = core99_nvram_size;
ppc_md.nvram_sync = core99_nvram_sync;
/*
* Maybe we could be smarter here though making an exclusive list
* of known flash chips is a bit nasty as older OF didn't provide us
* with a useful "compatible" entry. A solution would be to really
* identify the chip using flash id commands and base ourselves on
* a list of known chips IDs
*/
if (device_is_compatible(dp, "amd-0137")) {
core99_erase_bank = amd_erase_bank;
core99_write_bank = amd_write_bank;
} else {
core99_erase_bank = sm_erase_bank;
core99_write_bank = sm_write_bank;
}
return 0;
}
int __init pmac_nvram_init(void)
{ {
struct device_node *dp; struct device_node *dp;
int err = 0;
nvram_naddrs = 0; nvram_naddrs = 0;
dp = find_devices("nvram"); dp = find_devices("nvram");
if (dp == NULL) { if (dp == NULL) {
printk(KERN_ERR "Can't find NVRAM device\n"); printk(KERN_ERR "Can't find NVRAM device\n");
return; return -ENODEV;
} }
nvram_naddrs = dp->n_addrs; nvram_naddrs = dp->n_addrs;
is_core_99 = device_is_compatible(dp, "nvram,flash"); is_core_99 = device_is_compatible(dp, "nvram,flash");
if (is_core_99) { if (is_core_99)
int i; err = core99_nvram_setup(dp);
u32 gen_bank0, gen_bank1; #ifdef CONFIG_PPC32
else if (_machine == _MACH_chrp && nvram_naddrs == 1) {
if (nvram_naddrs < 1) {
printk(KERN_ERR "nvram: no address\n");
return;
}
nvram_image = alloc_bootmem(NVRAM_SIZE);
if (nvram_image == NULL) {
printk(KERN_ERR "nvram: can't allocate ram image\n");
return;
}
nvram_data = ioremap(dp->addrs[0].address, NVRAM_SIZE*2);
nvram_naddrs = 1; /* Make sure we get the correct case */
DBG("nvram: Checking bank 0...\n");
gen_bank0 = core99_check((u8 *)nvram_data);
gen_bank1 = core99_check((u8 *)nvram_data + NVRAM_SIZE);
core99_bank = (gen_bank0 < gen_bank1) ? 1 : 0;
DBG("nvram: gen0=%d, gen1=%d\n", gen_bank0, gen_bank1);
DBG("nvram: Active bank is: %d\n", core99_bank);
for (i=0; i<NVRAM_SIZE; i++)
nvram_image[i] = nvram_data[i + core99_bank*NVRAM_SIZE];
ppc_md.nvram_read_val = core99_nvram_read_byte;
ppc_md.nvram_write_val = core99_nvram_write_byte;
ppc_md.nvram_sync = core99_nvram_sync;
/*
* Maybe we could be smarter here though making an exclusive list
* of known flash chips is a bit nasty as older OF didn't provide us
* with a useful "compatible" entry. A solution would be to really
* identify the chip using flash id commands and base ourselves on
* a list of known chips IDs
*/
if (device_is_compatible(dp, "amd-0137")) {
core99_erase_bank = amd_erase_bank;
core99_write_bank = amd_write_bank;
} else {
core99_erase_bank = sm_erase_bank;
core99_write_bank = sm_write_bank;
}
} else if (_machine == _MACH_chrp && nvram_naddrs == 1) {
nvram_data = ioremap(dp->addrs[0].address + isa_mem_base, nvram_data = ioremap(dp->addrs[0].address + isa_mem_base,
dp->addrs[0].size); dp->addrs[0].size);
nvram_mult = 1; nvram_mult = 1;
...@@ -547,11 +605,14 @@ void __init pmac_nvram_init(void) ...@@ -547,11 +605,14 @@ void __init pmac_nvram_init(void)
ppc_md.nvram_read_val = pmu_nvram_read_byte; ppc_md.nvram_read_val = pmu_nvram_read_byte;
ppc_md.nvram_write_val = pmu_nvram_write_byte; ppc_md.nvram_write_val = pmu_nvram_write_byte;
#endif /* CONFIG_ADB_PMU */ #endif /* CONFIG_ADB_PMU */
} else { }
printk(KERN_ERR "Don't know how to access NVRAM with %d addresses\n", #endif
nvram_naddrs); else {
printk(KERN_ERR "Incompatible type of NVRAM\n");
return -ENXIO;
} }
lookup_partitions(); lookup_partitions();
return err;
} }
int pmac_get_partition(int partition) int pmac_get_partition(int partition)
...@@ -561,9 +622,9 @@ int pmac_get_partition(int partition) ...@@ -561,9 +622,9 @@ int pmac_get_partition(int partition)
u8 pmac_xpram_read(int xpaddr) u8 pmac_xpram_read(int xpaddr)
{ {
int offset = nvram_partitions[pmac_nvram_XPRAM]; int offset = pmac_get_partition(pmac_nvram_XPRAM);
if (offset < 0) if (offset < 0 || xpaddr < 0 || xpaddr > 0x100)
return 0xff; return 0xff;
return ppc_md.nvram_read_val(xpaddr + offset); return ppc_md.nvram_read_val(xpaddr + offset);
...@@ -571,9 +632,9 @@ u8 pmac_xpram_read(int xpaddr) ...@@ -571,9 +632,9 @@ u8 pmac_xpram_read(int xpaddr)
void pmac_xpram_write(int xpaddr, u8 data) void pmac_xpram_write(int xpaddr, u8 data)
{ {
int offset = nvram_partitions[pmac_nvram_XPRAM]; int offset = pmac_get_partition(pmac_nvram_XPRAM);
if (offset < 0) if (offset < 0 || xpaddr < 0 || xpaddr > 0x100)
return; return;
ppc_md.nvram_write_val(xpaddr + offset, data); ppc_md.nvram_write_val(xpaddr + offset, data);
......
This diff is collapsed.
...@@ -430,7 +430,6 @@ void __init pmac_pic_init(void) ...@@ -430,7 +430,6 @@ void __init pmac_pic_init(void)
printk(KERN_INFO "PowerMac using OpenPIC irq controller at 0x%08x\n", printk(KERN_INFO "PowerMac using OpenPIC irq controller at 0x%08x\n",
(unsigned int)irqctrler->addrs[0].address); (unsigned int)irqctrler->addrs[0].address);
ppc_md.get_irq = mpic_get_irq;
pmac_call_feature(PMAC_FTR_ENABLE_MPIC, irqctrler, 0, 0); pmac_call_feature(PMAC_FTR_ENABLE_MPIC, irqctrler, 0, 0);
prom_get_irq_senses(senses, 0, 128); prom_get_irq_senses(senses, 0, 128);
...@@ -483,6 +482,7 @@ void __init pmac_pic_init(void) ...@@ -483,6 +482,7 @@ void __init pmac_pic_init(void)
* a Grand Central nor an OHare, then it's an Heathrow * a Grand Central nor an OHare, then it's an Heathrow
* (or Paddington). * (or Paddington).
*/ */
ppc_md.get_irq = pmac_get_irq;
if (find_devices("gc")) if (find_devices("gc"))
level_mask[0] = GC_LEVEL_MASK; level_mask[0] = GC_LEVEL_MASK;
else if (find_devices("ohare")) { else if (find_devices("ohare")) {
......
...@@ -19,7 +19,7 @@ extern int pmac_set_rtc_time(struct rtc_time *); ...@@ -19,7 +19,7 @@ extern int pmac_set_rtc_time(struct rtc_time *);
extern void pmac_read_rtc_time(void); extern void pmac_read_rtc_time(void);
extern void pmac_calibrate_decr(void); extern void pmac_calibrate_decr(void);
extern void pmac_pcibios_fixup(void); extern void pmac_pcibios_fixup(void);
extern void pmac_find_bridges(void); extern void pmac_pci_init(void);
extern unsigned long pmac_ide_get_base(int index); extern unsigned long pmac_ide_get_base(int index);
extern void pmac_ide_init_hwif_ports(hw_regs_t *hw, extern void pmac_ide_init_hwif_ports(hw_regs_t *hw,
unsigned long data_port, unsigned long ctrl_port, int *irq); unsigned long data_port, unsigned long ctrl_port, int *irq);
...@@ -41,7 +41,7 @@ extern unsigned long pmac_ide_get_base(int index); ...@@ -41,7 +41,7 @@ extern unsigned long pmac_ide_get_base(int index);
extern void pmac_ide_init_hwif_ports(hw_regs_t *hw, extern void pmac_ide_init_hwif_ports(hw_regs_t *hw,
unsigned long data_port, unsigned long ctrl_port, int *irq); unsigned long data_port, unsigned long ctrl_port, int *irq);
extern void pmac_nvram_init(void); extern int pmac_nvram_init(void);
extern struct hw_interrupt_type pmac_pic; extern struct hw_interrupt_type pmac_pic;
......
This diff is collapsed.
This diff is collapsed.
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#include <asm/machdep.h> #include <asm/machdep.h>
#include <asm/time.h> #include <asm/time.h>
#include <asm/nvram.h> #include <asm/nvram.h>
#include <asm/smu.h>
#undef DEBUG #undef DEBUG
...@@ -68,8 +69,8 @@ ...@@ -68,8 +69,8 @@
long __init pmac_time_init(void) long __init pmac_time_init(void)
{ {
#ifdef CONFIG_NVRAM
s32 delta = 0; s32 delta = 0;
#ifdef CONFIG_NVRAM
int dst; int dst;
delta = ((s32)pmac_xpram_read(PMAC_XPRAM_MACHINE_LOC + 0x9)) << 16; delta = ((s32)pmac_xpram_read(PMAC_XPRAM_MACHINE_LOC + 0x9)) << 16;
...@@ -80,110 +81,181 @@ long __init pmac_time_init(void) ...@@ -80,110 +81,181 @@ long __init pmac_time_init(void)
dst = ((pmac_xpram_read(PMAC_XPRAM_MACHINE_LOC + 0x8) & 0x80) != 0); dst = ((pmac_xpram_read(PMAC_XPRAM_MACHINE_LOC + 0x8) & 0x80) != 0);
printk("GMT Delta read from XPRAM: %d minutes, DST: %s\n", delta/60, printk("GMT Delta read from XPRAM: %d minutes, DST: %s\n", delta/60,
dst ? "on" : "off"); dst ? "on" : "off");
return delta;
#else
return 0;
#endif #endif
return delta;
} }
unsigned long pmac_get_boot_time(void) static void to_rtc_time(unsigned long now, struct rtc_time *tm)
{
to_tm(now, tm);
tm->tm_year -= 1900;
tm->tm_mon -= 1;
}
static unsigned long from_rtc_time(struct rtc_time *tm)
{
return mktime(tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday,
tm->tm_hour, tm->tm_min, tm->tm_sec);
}
#ifdef CONFIG_ADB_CUDA
static unsigned long cuda_get_time(void)
{ {
#if defined(CONFIG_ADB_CUDA) || defined(CONFIG_ADB_PMU)
struct adb_request req; struct adb_request req;
unsigned long now; unsigned long now;
#endif
/* Get the time from the RTC */ if (cuda_request(&req, NULL, 2, CUDA_PACKET, CUDA_GET_TIME) < 0)
switch (sys_ctrler) { return 0;
#ifdef CONFIG_ADB_CUDA while (!req.complete)
case SYS_CTRLER_CUDA: cuda_poll();
if (cuda_request(&req, NULL, 2, CUDA_PACKET, CUDA_GET_TIME) < 0) if (req.reply_len != 7)
return 0; printk(KERN_ERR "cuda_get_time: got %d byte reply\n",
while (!req.complete) req.reply_len);
cuda_poll(); now = (req.reply[3] << 24) + (req.reply[4] << 16)
if (req.reply_len != 7) + (req.reply[5] << 8) + req.reply[6];
printk(KERN_ERR "pmac_get_rtc_time: got %d byte reply\n", if (now < RTC_OFFSET)
req.reply_len); return 0;
now = (req.reply[3] << 24) + (req.reply[4] << 16) return now - RTC_OFFSET;
+ (req.reply[5] << 8) + req.reply[6]; }
return now - RTC_OFFSET;
#endif /* CONFIG_ADB_CUDA */ #define cuda_get_rtc_time(tm) to_rtc_time(cuda_get_time(), (tm))
#ifdef CONFIG_ADB_PMU
case SYS_CTRLER_PMU: static int cuda_set_rtc_time(struct rtc_time *tm)
if (pmu_request(&req, NULL, 1, PMU_READ_RTC) < 0) {
return 0; unsigned int nowtime;
while (!req.complete) struct adb_request req;
pmu_poll();
if (req.reply_len != 4) nowtime = from_rtc_time(tm) + RTC_OFFSET;
printk(KERN_ERR "pmac_get_rtc_time: got %d byte reply\n", if (cuda_request(&req, NULL, 6, CUDA_PACKET, CUDA_SET_TIME,
req.reply_len); nowtime >> 24, nowtime >> 16, nowtime >> 8,
now = (req.reply[0] << 24) + (req.reply[1] << 16) nowtime) < 0)
+ (req.reply[2] << 8) + req.reply[3]; return -ENXIO;
return now - RTC_OFFSET; while (!req.complete)
#endif /* CONFIG_ADB_PMU */ cuda_poll();
default: ; if ((req.reply_len != 3) && (req.reply_len != 7))
} printk(KERN_ERR "cuda_set_rtc_time: got %d byte reply\n",
req.reply_len);
return 0; return 0;
} }
void pmac_get_rtc_time(struct rtc_time *tm) #else
#define cuda_get_time() 0
#define cuda_get_rtc_time(tm)
#define cuda_set_rtc_time(tm) 0
#endif
#ifdef CONFIG_ADB_PMU
static unsigned long pmu_get_time(void)
{ {
struct adb_request req;
unsigned long now; unsigned long now;
now = pmac_get_boot_time(); if (pmu_request(&req, NULL, 1, PMU_READ_RTC) < 0)
to_tm(now, tm); return 0;
tm->tm_year -= 1900; pmu_wait_complete(&req);
tm->tm_mon -= 1; /* month is 0-based */ if (req.reply_len != 4)
printk(KERN_ERR "pmu_get_time: got %d byte reply from PMU\n",
req.reply_len);
now = (req.reply[0] << 24) + (req.reply[1] << 16)
+ (req.reply[2] << 8) + req.reply[3];
if (now < RTC_OFFSET)
return 0;
return now - RTC_OFFSET;
} }
int pmac_set_rtc_time(struct rtc_time *tm) #define pmu_get_rtc_time(tm) to_rtc_time(pmu_get_time(), (tm))
static int pmu_set_rtc_time(struct rtc_time *tm)
{ {
unsigned long nowtime; unsigned int nowtime;
#if defined(CONFIG_ADB_CUDA) || defined(CONFIG_ADB_PMU)
struct adb_request req; struct adb_request req;
nowtime = from_rtc_time(tm) + RTC_OFFSET;
if (pmu_request(&req, NULL, 5, PMU_SET_RTC, nowtime >> 24,
nowtime >> 16, nowtime >> 8, nowtime) < 0)
return -ENXIO;
pmu_wait_complete(&req);
if (req.reply_len != 0)
printk(KERN_ERR "pmu_set_rtc_time: %d byte reply from PMU\n",
req.reply_len);
return 0;
}
#else
#define pmu_get_time() 0
#define pmu_get_rtc_time(tm)
#define pmu_set_rtc_time(tm) 0
#endif #endif
nowtime = mktime(tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday, #ifdef CONFIG_PMAC_SMU
tm->tm_hour, tm->tm_min, tm->tm_sec); static unsigned long smu_get_time(void)
nowtime += RTC_OFFSET; {
struct rtc_time tm;
if (smu_get_rtc_time(&tm, 1))
return 0;
return from_rtc_time(&tm);
}
#else
#define smu_get_time() 0
#define smu_get_rtc_time(tm, spin)
#define smu_set_rtc_time(tm, spin) 0
#endif
unsigned long pmac_get_boot_time(void)
{
/* Get the time from the RTC, used only at boot time */
switch (sys_ctrler) { switch (sys_ctrler) {
#ifdef CONFIG_ADB_CUDA
case SYS_CTRLER_CUDA: case SYS_CTRLER_CUDA:
if (cuda_request(&req, NULL, 6, CUDA_PACKET, CUDA_SET_TIME, return cuda_get_time();
nowtime >> 24, nowtime >> 16, nowtime >> 8,
nowtime) < 0)
return 0;
while (!req.complete)
cuda_poll();
if ((req.reply_len != 3) && (req.reply_len != 7))
printk(KERN_ERR "pmac_set_rtc_time: got %d byte reply\n",
req.reply_len);
return 1;
#endif /* CONFIG_ADB_CUDA */
#ifdef CONFIG_ADB_PMU
case SYS_CTRLER_PMU: case SYS_CTRLER_PMU:
if (pmu_request(&req, NULL, 5, PMU_SET_RTC, return pmu_get_time();
nowtime >> 24, nowtime >> 16, nowtime >> 8, nowtime) < 0) case SYS_CTRLER_SMU:
return 0; return smu_get_time();
while (!req.complete)
pmu_poll();
if (req.reply_len != 0)
printk(KERN_ERR "pmac_set_rtc_time: got %d byte reply\n",
req.reply_len);
return 1;
#endif /* CONFIG_ADB_PMU */
default: default:
return 0; return 0;
} }
} }
void pmac_get_rtc_time(struct rtc_time *tm)
{
/* Get the time from the RTC, used only at boot time */
switch (sys_ctrler) {
case SYS_CTRLER_CUDA:
cuda_get_rtc_time(tm);
break;
case SYS_CTRLER_PMU:
pmu_get_rtc_time(tm);
break;
case SYS_CTRLER_SMU:
smu_get_rtc_time(tm, 1);
break;
default:
;
}
}
int pmac_set_rtc_time(struct rtc_time *tm)
{
switch (sys_ctrler) {
case SYS_CTRLER_CUDA:
return cuda_set_rtc_time(tm);
case SYS_CTRLER_PMU:
return pmu_set_rtc_time(tm);
case SYS_CTRLER_SMU:
return smu_set_rtc_time(tm, 1);
default:
return -ENODEV;
}
}
#ifdef CONFIG_PPC32
/* /*
* Calibrate the decrementer register using VIA timer 1. * Calibrate the decrementer register using VIA timer 1.
* This is used both on powermacs and CHRP machines. * This is used both on powermacs and CHRP machines.
*/ */
int __init int __init via_calibrate_decr(void)
via_calibrate_decr(void)
{ {
struct device_node *vias; struct device_node *vias;
volatile unsigned char __iomem *via; volatile unsigned char __iomem *via;
...@@ -217,15 +289,12 @@ via_calibrate_decr(void) ...@@ -217,15 +289,12 @@ via_calibrate_decr(void)
dend = get_dec(); dend = get_dec();
ppc_tb_freq = (dstart - dend) * 100 / 6; ppc_tb_freq = (dstart - dend) * 100 / 6;
tb_ticks_per_jiffy = (dstart - dend) / ((6 * HZ)/100);
printk(KERN_INFO "via_calibrate_decr: ticks per jiffy = %lu (%u ticks)\n",
tb_ticks_per_jiffy, dstart - dend);
iounmap(via); iounmap(via);
return 1; return 1;
} }
#endif
#ifdef CONFIG_PM #ifdef CONFIG_PM
/* /*
...@@ -262,19 +331,17 @@ static struct pmu_sleep_notifier time_sleep_notifier = { ...@@ -262,19 +331,17 @@ static struct pmu_sleep_notifier time_sleep_notifier = {
/* /*
* Query the OF and get the decr frequency. * Query the OF and get the decr frequency.
* This was taken from the pmac time_init() when merging the prep/pmac
* time functions.
*/ */
void __init void __init pmac_calibrate_decr(void)
pmac_calibrate_decr(void)
{ {
struct device_node *cpu;
unsigned int freq, *fp;
#ifdef CONFIG_PM #ifdef CONFIG_PM
/* XXX why here? */
pmu_register_sleep_notifier(&time_sleep_notifier); pmu_register_sleep_notifier(&time_sleep_notifier);
#endif /* CONFIG_PM */ #endif /* CONFIG_PM */
generic_calibrate_decr();
#ifdef CONFIG_PPC32
/* We assume MacRISC2 machines have correct device-tree /* We assume MacRISC2 machines have correct device-tree
* calibration. That's better since the VIA itself seems * calibration. That's better since the VIA itself seems
* to be slightly off. --BenH * to be slightly off. --BenH
...@@ -293,18 +360,5 @@ pmac_calibrate_decr(void) ...@@ -293,18 +360,5 @@ pmac_calibrate_decr(void)
if (machine_is_compatible("PowerMac3,5")) if (machine_is_compatible("PowerMac3,5"))
if (via_calibrate_decr()) if (via_calibrate_decr())
return; return;
/* #endif
* The cpu node should have a timebase-frequency property
* to tell us the rate at which the decrementer counts.
*/
cpu = find_type_devices("cpu");
if (cpu == 0)
panic("can't find cpu node in time_init");
fp = (unsigned int *) get_property(cpu, "timebase-frequency", NULL);
if (fp == 0)
panic("can't get cpu timebase frequency");
freq = *fp;
printk("time_init: decrementer frequency = %u.%.6u MHz\n",
freq/1000000, freq%1000000);
ppc_tb_freq = freq;
} }
...@@ -119,6 +119,8 @@ struct machdep_calls { ...@@ -119,6 +119,8 @@ struct machdep_calls {
/* Interface for platform error logging */ /* Interface for platform error logging */
void (*log_error)(char *buf, unsigned int err_type, int fatal); void (*log_error)(char *buf, unsigned int err_type, int fatal);
unsigned char (*nvram_read_val)(int addr);
void (*nvram_write_val)(int addr, unsigned char val);
ssize_t (*nvram_write)(char *buf, size_t count, loff_t *index); ssize_t (*nvram_write)(char *buf, size_t count, loff_t *index);
ssize_t (*nvram_read)(char *buf, size_t count, loff_t *index); ssize_t (*nvram_read)(char *buf, size_t count, loff_t *index);
ssize_t (*nvram_size)(void); ssize_t (*nvram_size)(void);
...@@ -165,15 +167,11 @@ struct machdep_calls { ...@@ -165,15 +167,11 @@ struct machdep_calls {
unsigned long heartbeat_reset; unsigned long heartbeat_reset;
unsigned long heartbeat_count; unsigned long heartbeat_count;
unsigned long (*find_end_of_memory)(void);
void (*setup_io_mappings)(void); void (*setup_io_mappings)(void);
void (*early_serial_map)(void); void (*early_serial_map)(void);
void (*kgdb_map_scc)(void); void (*kgdb_map_scc)(void);
unsigned char (*nvram_read_val)(int addr);
void (*nvram_write_val)(int addr, unsigned char val);
/* /*
* optional PCI "hooks" * optional PCI "hooks"
*/ */
......
...@@ -148,6 +148,8 @@ struct thread_struct; ...@@ -148,6 +148,8 @@ struct thread_struct;
extern struct task_struct * _switch(struct thread_struct *prev, extern struct task_struct * _switch(struct thread_struct *prev,
struct thread_struct *next); struct thread_struct *next);
extern int powersave_nap; /* set if nap mode can be used in idle loop */
/* /*
* Atomic exchange * Atomic exchange
* *
......
...@@ -28,4 +28,7 @@ extern unsigned long udbg_ifdebug(unsigned long flags); ...@@ -28,4 +28,7 @@ extern unsigned long udbg_ifdebug(unsigned long flags);
extern void __init ppcdbg_initialize(void); extern void __init ppcdbg_initialize(void);
extern void udbg_init_uart(void __iomem *comport, unsigned int speed); extern void udbg_init_uart(void __iomem *comport, unsigned int speed);
struct device_node;
extern void udbg_init_scc(struct device_node *np);
#endif #endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment