1*4882a593Smuzhiyun /* 2*4882a593Smuzhiyun * Setup the right wbflush routine for the different DECstations. 3*4882a593Smuzhiyun * 4*4882a593Smuzhiyun * Created with information from: 5*4882a593Smuzhiyun * DECstation 3100 Desktop Workstation Functional Specification 6*4882a593Smuzhiyun * DECstation 5000/200 KN02 System Module Functional Specification 7*4882a593Smuzhiyun * mipsel-linux-objdump --disassemble vmunix | grep "wbflush" :-) 8*4882a593Smuzhiyun * 9*4882a593Smuzhiyun * This file is subject to the terms and conditions of the GNU General Public 10*4882a593Smuzhiyun * License. See the file "COPYING" in the main directory of this archive 11*4882a593Smuzhiyun * for more details. 12*4882a593Smuzhiyun * 13*4882a593Smuzhiyun * Copyright (C) 1998 Harald Koerfgen 14*4882a593Smuzhiyun * Copyright (C) 2002 Maciej W. Rozycki 15*4882a593Smuzhiyun */ 16*4882a593Smuzhiyun 17*4882a593Smuzhiyun #include <linux/export.h> 18*4882a593Smuzhiyun #include <linux/init.h> 19*4882a593Smuzhiyun 20*4882a593Smuzhiyun #include <asm/bootinfo.h> 21*4882a593Smuzhiyun #include <asm/wbflush.h> 22*4882a593Smuzhiyun #include <asm/barrier.h> 23*4882a593Smuzhiyun 24*4882a593Smuzhiyun static void wbflush_kn01(void); 25*4882a593Smuzhiyun static void wbflush_kn210(void); 26*4882a593Smuzhiyun static void wbflush_mips(void); 27*4882a593Smuzhiyun 28*4882a593Smuzhiyun void (*__wbflush) (void); 29*4882a593Smuzhiyun wbflush_setup(void)30*4882a593Smuzhiyunvoid __init wbflush_setup(void) 31*4882a593Smuzhiyun { 32*4882a593Smuzhiyun switch (mips_machtype) { 33*4882a593Smuzhiyun case MACH_DS23100: 34*4882a593Smuzhiyun case MACH_DS5000_200: /* DS5000 3max */ 35*4882a593Smuzhiyun __wbflush = wbflush_kn01; 36*4882a593Smuzhiyun break; 37*4882a593Smuzhiyun case MACH_DS5100: /* DS5100 MIPSMATE */ 38*4882a593Smuzhiyun __wbflush = wbflush_kn210; 39*4882a593Smuzhiyun break; 40*4882a593Smuzhiyun case MACH_DS5000_1XX: /* DS5000/100 3min */ 41*4882a593Smuzhiyun case MACH_DS5000_XX: /* Personal DS5000/2x */ 42*4882a593Smuzhiyun case MACH_DS5000_2X0: /* DS5000/240 3max+ */ 43*4882a593Smuzhiyun case MACH_DS5900: /* DS5900 bigmax */ 44*4882a593Smuzhiyun default: 45*4882a593Smuzhiyun __wbflush = wbflush_mips; 46*4882a593Smuzhiyun break; 47*4882a593Smuzhiyun } 48*4882a593Smuzhiyun } 49*4882a593Smuzhiyun 50*4882a593Smuzhiyun /* 51*4882a593Smuzhiyun * For the DS3100 and DS5000/200 the R2020/R3220 writeback buffer functions 52*4882a593Smuzhiyun * as part of Coprocessor 0. 53*4882a593Smuzhiyun */ wbflush_kn01(void)54*4882a593Smuzhiyunstatic void wbflush_kn01(void) 55*4882a593Smuzhiyun { 56*4882a593Smuzhiyun asm(".set\tpush\n\t" 57*4882a593Smuzhiyun ".set\tnoreorder\n\t" 58*4882a593Smuzhiyun "1:\tbc0f\t1b\n\t" 59*4882a593Smuzhiyun "nop\n\t" 60*4882a593Smuzhiyun ".set\tpop"); 61*4882a593Smuzhiyun } 62*4882a593Smuzhiyun 63*4882a593Smuzhiyun /* 64*4882a593Smuzhiyun * For the DS5100 the writeback buffer seems to be a part of Coprocessor 3. 65*4882a593Smuzhiyun * But CP3 has to enabled first. 66*4882a593Smuzhiyun */ wbflush_kn210(void)67*4882a593Smuzhiyunstatic void wbflush_kn210(void) 68*4882a593Smuzhiyun { 69*4882a593Smuzhiyun asm(".set\tpush\n\t" 70*4882a593Smuzhiyun ".set\tnoreorder\n\t" 71*4882a593Smuzhiyun "mfc0\t$2,$12\n\t" 72*4882a593Smuzhiyun "lui\t$3,0x8000\n\t" 73*4882a593Smuzhiyun "or\t$3,$2,$3\n\t" 74*4882a593Smuzhiyun "mtc0\t$3,$12\n\t" 75*4882a593Smuzhiyun "nop\n" 76*4882a593Smuzhiyun "1:\tbc3f\t1b\n\t" 77*4882a593Smuzhiyun "nop\n\t" 78*4882a593Smuzhiyun "mtc0\t$2,$12\n\t" 79*4882a593Smuzhiyun "nop\n\t" 80*4882a593Smuzhiyun ".set\tpop" 81*4882a593Smuzhiyun : : : "$2", "$3"); 82*4882a593Smuzhiyun } 83*4882a593Smuzhiyun 84*4882a593Smuzhiyun /* 85*4882a593Smuzhiyun * I/O ASIC systems use a standard writeback buffer that gets flushed 86*4882a593Smuzhiyun * upon an uncached read. 87*4882a593Smuzhiyun */ wbflush_mips(void)88*4882a593Smuzhiyunstatic void wbflush_mips(void) 89*4882a593Smuzhiyun { 90*4882a593Smuzhiyun __fast_iob(); 91*4882a593Smuzhiyun } 92*4882a593Smuzhiyun EXPORT_SYMBOL(__wbflush); 93