11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * linux/arch/m68knommu/platform/68360/config.c 31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (c) 2000 Michael Leslie <mleslie@lineo.com> 51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (C) 1993 Hamish Macdonald 61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (C) 1999 D. Jeff Dionne <jeff@uclinux.org> 71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This file is subject to the terms and conditions of the GNU General Public 91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * License. See the file COPYING in the main directory of this archive 101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * for more details. 111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <stdarg.h> 141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/types.h> 151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/kernel.h> 161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/mm.h> 17b032fde9097605f9f1099eeca28f3b5b09e55ec0Greg Ungerer#include <linux/interrupt.h> 18aa1f1d10e6f80362123fd7f736011f3ddd3acf25Greg Ungerer#include <linux/irq.h> 191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/setup.h> 211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/pgtable.h> 221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/machdep.h> 231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/m68360.h> 241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef CONFIG_UCQUICC 261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/bootstd.h> 271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsextern void m360_cpm_reset(void); 301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds// Mask to select if the PLL prescaler is enabled. 321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define MCU_PREEN ((unsigned short)(0x0001 << 13)) 331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#if defined(CONFIG_UCQUICC) 351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define OSCILLATOR (unsigned long int)33000000 361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsunsigned long int system_clock; 391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsextern QUICC *pquicc; 411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* TODO DON"T Hard Code this */ 431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* calculate properly using the right PLL and prescaller */ 441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds// unsigned int system_clock = 33000000l; 451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsextern unsigned long int system_clock; //In kernel setup.c 461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 477e6a3d402c97c95ca1f8dc84ad5b69f3118cd2b5Greg Ungerer 487e6a3d402c97c95ca1f8dc84ad5b69f3118cd2b5Greg Ungererstatic irqreturn_t hw_tick(int irq, void *dummy) 497e6a3d402c97c95ca1f8dc84ad5b69f3118cd2b5Greg Ungerer{ 507e6a3d402c97c95ca1f8dc84ad5b69f3118cd2b5Greg Ungerer /* Reset Timer1 */ 517e6a3d402c97c95ca1f8dc84ad5b69f3118cd2b5Greg Ungerer /* TSTAT &= 0; */ 527e6a3d402c97c95ca1f8dc84ad5b69f3118cd2b5Greg Ungerer 537e6a3d402c97c95ca1f8dc84ad5b69f3118cd2b5Greg Ungerer pquicc->timer_ter1 = 0x0002; /* clear timer event */ 547e6a3d402c97c95ca1f8dc84ad5b69f3118cd2b5Greg Ungerer 557e6a3d402c97c95ca1f8dc84ad5b69f3118cd2b5Greg Ungerer return arch_timer_interrupt(irq, dummy); 567e6a3d402c97c95ca1f8dc84ad5b69f3118cd2b5Greg Ungerer} 571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 58aa1f1d10e6f80362123fd7f736011f3ddd3acf25Greg Ungererstatic struct irqaction m68360_timer_irq = { 597e6a3d402c97c95ca1f8dc84ad5b69f3118cd2b5Greg Ungerer .name = "timer", 607e6a3d402c97c95ca1f8dc84ad5b69f3118cd2b5Greg Ungerer .flags = IRQF_DISABLED | IRQF_TIMER, 617e6a3d402c97c95ca1f8dc84ad5b69f3118cd2b5Greg Ungerer .handler = hw_tick, 62aa1f1d10e6f80362123fd7f736011f3ddd3acf25Greg Ungerer}; 63aa1f1d10e6f80362123fd7f736011f3ddd3acf25Greg Ungerer 647e6a3d402c97c95ca1f8dc84ad5b69f3118cd2b5Greg Ungerervoid hw_timer_init(void) 651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned char prescaler; 671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned short tgcr_save; 681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#if 0 701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Restart mode, Enable int, 32KHz, Enable timer */ 711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds TCTL = TCTL_OM | TCTL_IRQEN | TCTL_CLKSOURCE_32KHZ | TCTL_TEN; 721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Set prescaler (Divide 32KHz by 32)*/ 731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds TPRER = 31; 741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Set compare register 32Khz / 32 / 10 = 100 */ 751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds TCMP = 10; 761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 774531dab4294435d6f57ecd942831a79bab303287Greg Ungerer request_irq(IRQ_MACHSPEC | 1, timer_routine, 0, "timer", NULL); 781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* General purpose quicc timers: MC68360UM p7-20 */ 811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Set up timer 1 (in [1..4]) to do 100Hz */ 831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tgcr_save = pquicc->timer_tgcr & 0xfff0; 841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pquicc->timer_tgcr = tgcr_save; /* stop and reset timer 1 */ 851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* pquicc->timer_tgcr |= 0x4444; */ /* halt timers when FREEZE (ie bdm freeze) */ 861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds prescaler = 8; 881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pquicc->timer_tmr1 = 0x001a | /* or=1, frr=1, iclk=01b */ 891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (unsigned short)((prescaler - 1) << 8); 901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pquicc->timer_tcn1 = 0x0000; /* initial count */ 921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* calculate interval for 100Hz based on the _system_clock: */ 931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pquicc->timer_trr1 = (system_clock/ prescaler) / HZ; /* reference count */ 941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pquicc->timer_ter1 = 0x0003; /* clear timer events */ 961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* enable timer 1 interrupt in CIMR */ 98aa1f1d10e6f80362123fd7f736011f3ddd3acf25Greg Ungerer setup_irq(CPMVEC_TIMER1, &m68360_timer_irq); 991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Start timer 1: */ 1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tgcr_save = (pquicc->timer_tgcr & 0xfff0) | 0x0001; 1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pquicc->timer_tgcr = tgcr_save; 1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1057e6a3d402c97c95ca1f8dc84ad5b69f3118cd2b5Greg Ungererint BSP_set_clock_mmss(unsigned long nowtime) 1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#if 0 1081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds short real_seconds = nowtime % 60, real_minutes = (nowtime / 60) % 60; 1091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tod->second1 = real_seconds / 10; 1111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tod->second2 = real_seconds % 10; 1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tod->minute1 = real_minutes / 10; 1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tod->minute2 = real_minutes % 10; 1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid BSP_reset (void) 1191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds local_irq_disable(); 121bda658382614198714b27581528f9bfb60c05a71Greg Ungerer asm volatile ( 122bda658382614198714b27581528f9bfb60c05a71Greg Ungerer "moveal #_start, %a0;\n" 123bda658382614198714b27581528f9bfb60c05a71Greg Ungerer "moveb #0, 0xFFFFF300;\n" 124bda658382614198714b27581528f9bfb60c05a71Greg Ungerer "moveal 0(%a0), %sp;\n" 125bda658382614198714b27581528f9bfb60c05a71Greg Ungerer "moveal 4(%a0), %a0;\n" 126bda658382614198714b27581528f9bfb60c05a71Greg Ungerer "jmp (%a0);\n" 127bda658382614198714b27581528f9bfb60c05a71Greg Ungerer ); 1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsunsigned char *scc1_hwaddr; 1311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int errno; 1321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#if defined (CONFIG_UCQUICC) 1341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds_bsc0(char *, getserialnum) 1351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds_bsc1(unsigned char *, gethwaddr, int, a) 1361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds_bsc1(char *, getbenv, char *, a) 1371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 1381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid config_BSP(char *command, int len) 1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned char *p; 1431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds m360_cpm_reset(); 1451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Calculate the real system clock value. */ 1471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 1481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int local_pllcr = (unsigned int)(pquicc->sim_pllcr); 1491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if( local_pllcr & MCU_PREEN ) // If the prescaler is dividing by 128 1501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 1511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int mf = (int)(pquicc->sim_pllcr & 0x0fff); 1521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds system_clock = (OSCILLATOR / 128) * (mf + 1); 1531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 1551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 1561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int mf = (int)(pquicc->sim_pllcr & 0x0fff); 1571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds system_clock = (OSCILLATOR) * (mf + 1); 1581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_INFO "\n68360 QUICC support (C) 2000 Lineo Inc.\n"); 1621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#if defined(CONFIG_UCQUICC) && 0 1641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_INFO "uCquicc serial string [%s]\n",getserialnum()); 1651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p = scc1_hwaddr = gethwaddr(0); 1661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_INFO "uCquicc hwaddr %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n", 1671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p[0], p[1], p[2], p[3], p[4], p[5]); 1681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p = getbenv("APPEND"); 1701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (p) 1711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds strcpy(p,command); 1721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 1731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds command[0] = 0; 1741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#else 1751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds scc1_hwaddr = "\00\01\02\03\04\05"; 1761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 1771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1789517746131f62294ddd922bcd288415be5104c23Greg Ungerer mach_reset = BSP_reset; 1791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 180