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