]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - arch/mips/mm/pg-r4k.c
Merge branch 'upstream-linus' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik...
[linux-2.6-omap-h63xx.git] / arch / mips / mm / pg-r4k.c
index f51e180072e3a9f3e737437d7113948310fbe09d..d41fc5885e875f67ec9de7cf3fc2057b6c7c2419 100644 (file)
@@ -124,7 +124,7 @@ static inline void build_nop(void)
 
 static inline void build_src_pref(int advance)
 {
-       if (!(load_offset & (cpu_dcache_line_size() - 1))) {
+       if (!(load_offset & (cpu_dcache_line_size() - 1)) && advance) {
                union mips_instruction mi;
 
                mi.i_format.opcode     = pref_op;
@@ -166,7 +166,7 @@ static inline void build_load_reg(int reg)
 
 static inline void build_dst_pref(int advance)
 {
-       if (!(store_offset & (cpu_dcache_line_size() - 1))) {
+       if (!(store_offset & (cpu_dcache_line_size() - 1)) && advance) {
                union mips_instruction mi;
 
                mi.i_format.opcode     = pref_op;
@@ -270,6 +270,20 @@ static inline void build_addiu_a2_a0(unsigned long offset)
        emit_instruction(mi);
 }
 
+static inline void build_addiu_a2(unsigned long offset)
+{
+       union mips_instruction mi;
+
+       BUG_ON(offset > 0x7fff);
+
+       mi.i_format.opcode     = cpu_has_64bit_gp_regs ? daddiu_op : addiu_op;
+       mi.i_format.rs         = 6;             /* $a2 */
+       mi.i_format.rt         = 6;             /* $a2 */
+       mi.i_format.simmediate = offset;
+
+       emit_instruction(mi);
+}
+
 static inline void build_addiu_a1(unsigned long offset)
 {
        union mips_instruction mi;
@@ -333,6 +347,7 @@ static inline void build_jr_ra(void)
 void __init build_clear_page(void)
 {
        unsigned int loop_start;
+       unsigned long off;
 
        epc = (unsigned int *) &clear_page_array;
        instruction_pending = 0;
@@ -340,6 +355,12 @@ void __init build_clear_page(void)
 
        if (cpu_has_prefetch) {
                switch (current_cpu_data.cputype) {
+               case CPU_TX49XX:
+                       /* TX49 supports only Pref_Load */
+                       pref_offset_clear = 0;
+                       pref_offset_copy = 0;
+                       break;
+
                case CPU_RM9000:
                        /*
                         * As a workaround for erratum G105 which make the
@@ -351,6 +372,7 @@ void __init build_clear_page(void)
 
                case CPU_R10000:
                case CPU_R12000:
+               case CPU_R14000:
                        pref_src_mode = Pref_LoadStreamed;
                        pref_dst_mode = Pref_StoreStreamed;
                        break;
@@ -362,7 +384,12 @@ void __init build_clear_page(void)
                }
        }
 
-       build_addiu_a2_a0(PAGE_SIZE - (cpu_has_prefetch ? pref_offset_clear : 0));
+        off = PAGE_SIZE - (cpu_has_prefetch ? pref_offset_clear : 0);
+       if (off > 0x7fff) {
+               build_addiu_a2_a0(off >> 1);
+               build_addiu_a2(off >> 1);
+       } else
+               build_addiu_a2_a0(off);
 
        if (R4600_V2_HIT_CACHEOP_WAR && cpu_is_r4600_v2_x())
                build_insn_word(0x3c01a000);    /* lui     $at, 0xa000  */
@@ -413,12 +440,18 @@ dest = label();
 void __init build_copy_page(void)
 {
        unsigned int loop_start;
+       unsigned long off;
 
        epc = (unsigned int *) &copy_page_array;
        store_offset = load_offset = 0;
        instruction_pending = 0;
 
-       build_addiu_a2_a0(PAGE_SIZE - (cpu_has_prefetch ? pref_offset_copy : 0));
+       off = PAGE_SIZE - (cpu_has_prefetch ? pref_offset_copy : 0);
+       if (off > 0x7fff) {
+               build_addiu_a2_a0(off >> 1);
+               build_addiu_a2(off >> 1);
+       } else
+               build_addiu_a2_a0(off);
 
        if (R4600_V2_HIT_CACHEOP_WAR && cpu_is_r4600_v2_x())
                build_insn_word(0x3c01a000);    /* lui     $at, 0xa000  */