linux/arch/m68k/apollo/config.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2#include <linux/init.h>
   3#include <linux/types.h>
   4#include <linux/kernel.h>
   5#include <linux/mm.h>
   6#include <linux/tty.h>
   7#include <linux/console.h>
   8#include <linux/rtc.h>
   9#include <linux/vt_kern.h>
  10#include <linux/interrupt.h>
  11
  12#include <asm/setup.h>
  13#include <asm/bootinfo.h>
  14#include <asm/bootinfo-apollo.h>
  15#include <asm/byteorder.h>
  16#include <asm/apollohw.h>
  17#include <asm/irq.h>
  18#include <asm/machdep.h>
  19
  20u_long sio01_physaddr;
  21u_long sio23_physaddr;
  22u_long rtc_physaddr;
  23u_long pica_physaddr;
  24u_long picb_physaddr;
  25u_long cpuctrl_physaddr;
  26u_long timer_physaddr;
  27u_long apollo_model;
  28
  29extern void dn_sched_init(void);
  30extern void dn_init_IRQ(void);
  31extern int dn_dummy_hwclk(int, struct rtc_time *);
  32extern void dn_dummy_reset(void);
  33#ifdef CONFIG_HEARTBEAT
  34static void dn_heartbeat(int on);
  35#endif
  36static irqreturn_t dn_timer_int(int irq,void *);
  37static void dn_get_model(char *model);
  38static const char *apollo_models[] = {
  39        [APOLLO_DN3000-APOLLO_DN3000] = "DN3000 (Otter)",
  40        [APOLLO_DN3010-APOLLO_DN3000] = "DN3010 (Otter)",
  41        [APOLLO_DN3500-APOLLO_DN3000] = "DN3500 (Cougar II)",
  42        [APOLLO_DN4000-APOLLO_DN3000] = "DN4000 (Mink)",
  43        [APOLLO_DN4500-APOLLO_DN3000] = "DN4500 (Roadrunner)"
  44};
  45
  46int __init apollo_parse_bootinfo(const struct bi_record *record)
  47{
  48        int unknown = 0;
  49        const void *data = record->data;
  50
  51        switch (be16_to_cpu(record->tag)) {
  52        case BI_APOLLO_MODEL:
  53                apollo_model = be32_to_cpup(data);
  54                break;
  55
  56        default:
  57                 unknown=1;
  58        }
  59
  60        return unknown;
  61}
  62
  63static void __init dn_setup_model(void)
  64{
  65        pr_info("Apollo hardware found: [%s]\n",
  66                apollo_models[apollo_model - APOLLO_DN3000]);
  67
  68        switch(apollo_model) {
  69                case APOLLO_UNKNOWN:
  70                        panic("Unknown apollo model");
  71                        break;
  72                case APOLLO_DN3000:
  73                case APOLLO_DN3010:
  74                        sio01_physaddr=SAU8_SIO01_PHYSADDR;
  75                        rtc_physaddr=SAU8_RTC_PHYSADDR;
  76                        pica_physaddr=SAU8_PICA;
  77                        picb_physaddr=SAU8_PICB;
  78                        cpuctrl_physaddr=SAU8_CPUCTRL;
  79                        timer_physaddr=SAU8_TIMER;
  80                        break;
  81                case APOLLO_DN4000:
  82                        sio01_physaddr=SAU7_SIO01_PHYSADDR;
  83                        sio23_physaddr=SAU7_SIO23_PHYSADDR;
  84                        rtc_physaddr=SAU7_RTC_PHYSADDR;
  85                        pica_physaddr=SAU7_PICA;
  86                        picb_physaddr=SAU7_PICB;
  87                        cpuctrl_physaddr=SAU7_CPUCTRL;
  88                        timer_physaddr=SAU7_TIMER;
  89                        break;
  90                case APOLLO_DN4500:
  91                        panic("Apollo model not yet supported");
  92                        break;
  93                case APOLLO_DN3500:
  94                        sio01_physaddr=SAU7_SIO01_PHYSADDR;
  95                        sio23_physaddr=SAU7_SIO23_PHYSADDR;
  96                        rtc_physaddr=SAU7_RTC_PHYSADDR;
  97                        pica_physaddr=SAU7_PICA;
  98                        picb_physaddr=SAU7_PICB;
  99                        cpuctrl_physaddr=SAU7_CPUCTRL;
 100                        timer_physaddr=SAU7_TIMER;
 101                        break;
 102                default:
 103                        panic("Undefined apollo model");
 104                        break;
 105        }
 106
 107
 108}
 109
 110int dn_serial_console_wait_key(struct console *co) {
 111
 112        while(!(sio01.srb_csrb & 1))
 113                barrier();
 114        return sio01.rhrb_thrb;
 115}
 116
 117void dn_serial_console_write (struct console *co, const char *str,unsigned int count)
 118{
 119   while(count--) {
 120        if (*str == '\n') {
 121        sio01.rhrb_thrb = (unsigned char)'\r';
 122        while (!(sio01.srb_csrb & 0x4))
 123                ;
 124        }
 125    sio01.rhrb_thrb = (unsigned char)*str++;
 126    while (!(sio01.srb_csrb & 0x4))
 127            ;
 128  }
 129}
 130
 131void dn_serial_print (const char *str)
 132{
 133    while (*str) {
 134        if (*str == '\n') {
 135            sio01.rhrb_thrb = (unsigned char)'\r';
 136            while (!(sio01.srb_csrb & 0x4))
 137                ;
 138        }
 139        sio01.rhrb_thrb = (unsigned char)*str++;
 140        while (!(sio01.srb_csrb & 0x4))
 141            ;
 142    }
 143}
 144
 145void __init config_apollo(void)
 146{
 147        int i;
 148
 149        dn_setup_model();
 150
 151        mach_sched_init=dn_sched_init; /* */
 152        mach_init_IRQ=dn_init_IRQ;
 153        mach_hwclk           = dn_dummy_hwclk; /* */
 154        mach_reset           = dn_dummy_reset;  /* */
 155#ifdef CONFIG_HEARTBEAT
 156        mach_heartbeat = dn_heartbeat;
 157#endif
 158        mach_get_model       = dn_get_model;
 159
 160        cpuctrl=0xaa00;
 161
 162        /* clear DMA translation table */
 163        for(i=0;i<0x400;i++)
 164                addr_xlat_map[i]=0;
 165
 166}
 167
 168irqreturn_t dn_timer_int(int irq, void *dev_id)
 169{
 170        volatile unsigned char x;
 171
 172        legacy_timer_tick(1);
 173        timer_heartbeat();
 174
 175        x = *(volatile unsigned char *)(apollo_timer + 3);
 176        x = *(volatile unsigned char *)(apollo_timer + 5);
 177
 178        return IRQ_HANDLED;
 179}
 180
 181void dn_sched_init(void)
 182{
 183        /* program timer 1 */
 184        *(volatile unsigned char *)(apollo_timer + 3) = 0x01;
 185        *(volatile unsigned char *)(apollo_timer + 1) = 0x40;
 186        *(volatile unsigned char *)(apollo_timer + 5) = 0x09;
 187        *(volatile unsigned char *)(apollo_timer + 7) = 0xc4;
 188
 189        /* enable IRQ of PIC B */
 190        *(volatile unsigned char *)(pica+1)&=(~8);
 191
 192#if 0
 193        pr_info("*(0x10803) %02x\n",
 194                *(volatile unsigned char *)(apollo_timer + 0x3));
 195        pr_info("*(0x10803) %02x\n",
 196                *(volatile unsigned char *)(apollo_timer + 0x3));
 197#endif
 198
 199        if (request_irq(IRQ_APOLLO, dn_timer_int, 0, "time", NULL))
 200                pr_err("Couldn't register timer interrupt\n");
 201}
 202
 203int dn_dummy_hwclk(int op, struct rtc_time *t) {
 204
 205
 206  if(!op) { /* read */
 207    t->tm_sec=rtc->second;
 208    t->tm_min=rtc->minute;
 209    t->tm_hour=rtc->hours;
 210    t->tm_mday=rtc->day_of_month;
 211    t->tm_wday=rtc->day_of_week;
 212    t->tm_mon = rtc->month - 1;
 213    t->tm_year=rtc->year;
 214    if (t->tm_year < 70)
 215        t->tm_year += 100;
 216  } else {
 217    rtc->second=t->tm_sec;
 218    rtc->minute=t->tm_min;
 219    rtc->hours=t->tm_hour;
 220    rtc->day_of_month=t->tm_mday;
 221    if(t->tm_wday!=-1)
 222      rtc->day_of_week=t->tm_wday;
 223    rtc->month = t->tm_mon + 1;
 224    rtc->year = t->tm_year % 100;
 225  }
 226
 227  return 0;
 228
 229}
 230
 231void dn_dummy_reset(void) {
 232
 233  dn_serial_print("The end !\n");
 234
 235  for(;;);
 236
 237}
 238
 239void dn_dummy_waitbut(void) {
 240
 241  dn_serial_print("waitbut\n");
 242
 243}
 244
 245static void dn_get_model(char *model)
 246{
 247    strcpy(model, "Apollo ");
 248    if (apollo_model >= APOLLO_DN3000 && apollo_model <= APOLLO_DN4500)
 249        strcat(model, apollo_models[apollo_model - APOLLO_DN3000]);
 250}
 251
 252#ifdef CONFIG_HEARTBEAT
 253static int dn_cpuctrl=0xff00;
 254
 255static void dn_heartbeat(int on) {
 256
 257        if(on) {
 258                dn_cpuctrl&=~0x100;
 259                cpuctrl=dn_cpuctrl;
 260        }
 261        else {
 262                dn_cpuctrl&=~0x100;
 263                dn_cpuctrl|=0x100;
 264                cpuctrl=dn_cpuctrl;
 265        }
 266}
 267#endif
 268
 269