/*
  *  linux/arch/m32r/boot/setup.S -- A setup code.
  *
- *  Copyright (C) 2001, 2002  Hiroyuki Kondo, Hirokazu Takata,
- *  and Hitoshi Yamamoto
+ *  Copyright (C) 2001-2005   Hiroyuki Kondo, Hirokazu Takata,
+ *                            Hitoshi Yamamoto, Hayato Fujiwara
  *
  */
-/* $Id$ */
 
 #include <linux/linkage.h>
 #include <asm/segment.h>
 ;      ldi     r1, #0x00               ; cache off
        st      r1, @r0
 #elif defined(CONFIG_CHIP_M32104)
+       ldi     r0, #-96                ; DNCR0
+       seth    r1, #0x0060             ;  from 0x00600000
+       or3     r1, r1, #0x0005         ;  size 2MB
+       st      r1, @r0
+       seth    r1, #0x0100             ;  from 0x01000000
+       or3     r1, r1, #0x0003         ;  size 16MB
+       st      r1, @+r0
+       seth    r1, #0x0200             ;  from 0x02000000
+       or3     r1, r1, #0x0002         ;  size 32MB
+       st      r1, @+r0
        ldi     r0, #-4              ;LDIMM     (r0, M32R_MCCR)
        ldi     r1, #0x703              ; cache on (with invalidation)
        st      r1, @r0
 
 /*
  *  linux/arch/m32r/mm/cache.c
  *
- *  Copyright (C) 2002  Hirokazu Takata
+ *  Copyright (C) 2002-2005  Hirokazu Takata, Hayato Fujiwara
  */
 
 #include <linux/config.h>
 
 #undef MCCR
 
-#if defined(CONFIG_CHIP_XNUX2) || defined(CONFIG_CHIP_M32700) || defined(CONFIG_CHIP_VDEC2) || defined(CONFIG_CHIP_OPSP)
+#if defined(CONFIG_CHIP_XNUX2) || defined(CONFIG_CHIP_M32700) \
+       || defined(CONFIG_CHIP_VDEC2) || defined(CONFIG_CHIP_OPSP)
 /* Cache Control Register */
 #define MCCR           ((volatile unsigned long*)0xfffffffc)
 #define MCCR_CC                (1UL << 7)      /* Cache mode modify bit */
 #define MCCR_IIV       (1UL << 0)      /* I-cache invalidate */
 #define MCCR_ICACHE_INV                MCCR_IIV
 #elif defined(CONFIG_CHIP_M32104)
-#define MCCR           ((volatile unsigned long*)0xfffffffc)
+#define MCCR           ((volatile unsigned short*)0xfffffffe)
 #define MCCR_IIV       (1UL << 8)      /* I-cache invalidate */
 #define MCCR_DIV       (1UL << 9)      /* D-cache invalidate */
 #define MCCR_DCB       (1UL << 10)     /* D-cache copy back */
 #define MCCR_ICACHE_INV                MCCR_IIV
 #define MCCR_DCACHE_CB         MCCR_DCB
 #define MCCR_DCACHE_CBINV      (MCCR_DIV|MCCR_DCB)
-#endif /* CONFIG_CHIP_XNUX2 || CONFIG_CHIP_M32700 */
+#endif
 
 #ifndef MCCR
 #error Unknown cache type.
 void _flush_cache_all(void)
 {
 #if defined(CONFIG_CHIP_M32102)
+       unsigned char mccr;
        *MCCR = MCCR_ICACHE_INV;
+#elif defined(CONFIG_CHIP_M32104)
+       unsigned short mccr;
+
+       /* Copyback and invalidate D-cache */
+       /* Invalidate I-cache */
+       *MCCR |= (MCCR_ICACHE_INV | MCCR_DCACHE_CBINV);
 #else
        unsigned long mccr;
 
        /* Copyback and invalidate D-cache */
        /* Invalidate I-cache */
        *MCCR = MCCR_ICACHE_INV | MCCR_DCACHE_CBINV;
-       while ((mccr = *MCCR) & MCCR_IIV); /* loop while invalidating... */
 #endif
+       while ((mccr = *MCCR) & MCCR_IIV); /* loop while invalidating... */
 }
 
 /* Copy back D-cache and invalidate I-cache all */
 void _flush_cache_copyback_all(void)
 {
 #if defined(CONFIG_CHIP_M32102)
+       unsigned char mccr;
        *MCCR = MCCR_ICACHE_INV;
+#elif defined(CONFIG_CHIP_M32104)
+       unsigned short mccr;
+
+       /* Copyback and invalidate D-cache */
+       /* Invalidate I-cache */
+       *MCCR |= (MCCR_ICACHE_INV | MCCR_DCACHE_CB);
 #else
        unsigned long mccr;
 
        /* Copyback D-cache */
        /* Invalidate I-cache */
        *MCCR = MCCR_ICACHE_INV | MCCR_DCACHE_CB;
-       while ((mccr = *MCCR) & MCCR_IIV); /* loop while invalidating... */
-
 #endif
+       while ((mccr = *MCCR) & MCCR_IIV); /* loop while invalidating... */
 }