source: trunk/target/linux/brcm47xx/patches-2.6.38/150-cpu_fixes.patch @ 26524

Last change on this file since 26524 was 26524, checked in by hauke, 6 years ago

brcm47xx: add initial support for kernel 2.6.38

File size: 12.4 KB
  • arch/mips/include/asm/r4kcache.h

    a b  
    1717#include <asm/cpu-features.h> 
    1818#include <asm/mipsmtregs.h> 
    1919 
     20#ifdef CONFIG_BCM47XX 
     21#include <asm/paccess.h> 
     22#include <linux/ssb/ssb.h> 
     23#define BCM4710_DUMMY_RREG() ((void) *((u8 *) KSEG1ADDR(SSB_ENUM_BASE))) 
     24 
     25#define BCM4710_FILL_TLB(addr) (*(volatile unsigned long *)(addr)) 
     26#define BCM4710_PROTECTED_FILL_TLB(addr) ({ unsigned long x; get_dbe(x, (volatile unsigned long *)(addr)); }) 
     27#else 
     28#define BCM4710_DUMMY_RREG() 
     29 
     30#define BCM4710_FILL_TLB(addr) 
     31#define BCM4710_PROTECTED_FILL_TLB(addr) 
     32#endif 
     33 
    2034/* 
    2135 * This macro return a properly sign-extended address suitable as base address 
    2236 * for indexed cache operations.  Two issues here: 
    static inline void flush_icache_line_ind 
    150164static inline void flush_dcache_line_indexed(unsigned long addr) 
    151165{ 
    152166        __dflush_prologue 
     167        BCM4710_DUMMY_RREG(); 
    153168        cache_op(Index_Writeback_Inv_D, addr); 
    154169        __dflush_epilogue 
    155170} 
    static inline void flush_icache_line(uns 
    169184static inline void flush_dcache_line(unsigned long addr) 
    170185{ 
    171186        __dflush_prologue 
     187        BCM4710_DUMMY_RREG(); 
    172188        cache_op(Hit_Writeback_Inv_D, addr); 
    173189        __dflush_epilogue 
    174190} 
    static inline void flush_dcache_line(uns 
    176192static inline void invalidate_dcache_line(unsigned long addr) 
    177193{ 
    178194        __dflush_prologue 
     195        BCM4710_DUMMY_RREG(); 
    179196        cache_op(Hit_Invalidate_D, addr); 
    180197        __dflush_epilogue 
    181198} 
    static inline void flush_scache_line(uns 
    208225 */ 
    209226static inline void protected_flush_icache_line(unsigned long addr) 
    210227{ 
     228        BCM4710_DUMMY_RREG(); 
    211229        protected_cache_op(Hit_Invalidate_I, addr); 
    212230} 
    213231 
    static inline void protected_flush_icach 
    219237 */ 
    220238static inline void protected_writeback_dcache_line(unsigned long addr) 
    221239{ 
     240        BCM4710_DUMMY_RREG(); 
    222241        protected_cache_op(Hit_Writeback_Inv_D, addr); 
    223242} 
    224243 
    static inline void invalidate_tcache_pag 
    339358                : "r" (base),                                           \ 
    340359                  "i" (op)); 
    341360 
     361static inline void blast_dcache(void) 
     362{ 
     363        unsigned long start = KSEG0; 
     364        unsigned long dcache_size = current_cpu_data.dcache.waysize * current_cpu_data.dcache.ways; 
     365        unsigned long end = (start + dcache_size); 
     366 
     367        do { 
     368                BCM4710_DUMMY_RREG(); 
     369                cache_op(Index_Writeback_Inv_D, start); 
     370                start += current_cpu_data.dcache.linesz; 
     371        } while(start < end); 
     372} 
     373 
     374static inline void blast_dcache_page(unsigned long page) 
     375{ 
     376        unsigned long start = page; 
     377        unsigned long end = start + PAGE_SIZE; 
     378 
     379        BCM4710_FILL_TLB(start); 
     380        do { 
     381                BCM4710_DUMMY_RREG(); 
     382                cache_op(Hit_Writeback_Inv_D, start); 
     383                start += current_cpu_data.dcache.linesz; 
     384        } while(start < end); 
     385} 
     386 
     387static inline void blast_dcache_page_indexed(unsigned long page) 
     388{ 
     389        unsigned long start = page; 
     390        unsigned long end = start + PAGE_SIZE; 
     391        unsigned long ws_inc = 1UL << current_cpu_data.dcache.waybit; 
     392        unsigned long ws_end = current_cpu_data.dcache.ways << 
     393                               current_cpu_data.dcache.waybit; 
     394        unsigned long ws, addr; 
     395        for (ws = 0; ws < ws_end; ws += ws_inc) { 
     396                start = page + ws; 
     397                for (addr = start; addr < end; addr += current_cpu_data.dcache.linesz) { 
     398                        BCM4710_DUMMY_RREG(); 
     399                        cache_op(Index_Writeback_Inv_D, addr); 
     400                } 
     401        } 
     402} 
     403 
     404 
    342405/* build blast_xxx, blast_xxx_page, blast_xxx_page_indexed */ 
    343 #define __BUILD_BLAST_CACHE(pfx, desc, indexop, hitop, lsize) \ 
     406#define __BUILD_BLAST_CACHE(pfx, desc, indexop, hitop, lsize, war) \ 
    344407static inline void blast_##pfx##cache##lsize(void)                      \ 
    345408{                                                                       \ 
    346409        unsigned long start = INDEX_BASE;                               \ 
    static inline void blast_##pfx##cache##l 
    352415                                                                        \ 
    353416        __##pfx##flush_prologue                                         \ 
    354417                                                                        \ 
     418        war                                                             \ 
    355419        for (ws = 0; ws < ws_end; ws += ws_inc)                         \ 
    356420                for (addr = start; addr < end; addr += lsize * 32)      \ 
    357421                        cache##lsize##_unroll32(addr|ws, indexop);      \ 
    static inline void blast_##pfx##cache##l 
    366430                                                                        \ 
    367431        __##pfx##flush_prologue                                         \ 
    368432                                                                        \ 
     433        war                                                             \ 
    369434        do {                                                            \ 
    370435                cache##lsize##_unroll32(start, hitop);                  \ 
    371436                start += lsize * 32;                                    \ 
    static inline void blast_##pfx##cache##l 
    384449                               current_cpu_data.desc.waybit;            \ 
    385450        unsigned long ws, addr;                                         \ 
    386451                                                                        \ 
     452        war                                                             \ 
     453                                                                        \ 
    387454        __##pfx##flush_prologue                                         \ 
    388455                                                                        \ 
    389456        for (ws = 0; ws < ws_end; ws += ws_inc)                         \ 
    static inline void blast_##pfx##cache##l 
    393460        __##pfx##flush_epilogue                                         \ 
    394461} 
    395462 
    396 __BUILD_BLAST_CACHE(d, dcache, Index_Writeback_Inv_D, Hit_Writeback_Inv_D, 16) 
    397 __BUILD_BLAST_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I, 16) 
    398 __BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 16) 
    399 __BUILD_BLAST_CACHE(d, dcache, Index_Writeback_Inv_D, Hit_Writeback_Inv_D, 32) 
    400 __BUILD_BLAST_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I, 32) 
    401 __BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 32) 
    402 __BUILD_BLAST_CACHE(d, dcache, Index_Writeback_Inv_D, Hit_Writeback_Inv_D, 64) 
    403 __BUILD_BLAST_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I, 64) 
    404 __BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 64) 
    405 __BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 128) 
    406  
    407 __BUILD_BLAST_CACHE(inv_d, dcache, Index_Writeback_Inv_D, Hit_Invalidate_D, 16) 
    408 __BUILD_BLAST_CACHE(inv_d, dcache, Index_Writeback_Inv_D, Hit_Invalidate_D, 32) 
    409 __BUILD_BLAST_CACHE(inv_s, scache, Index_Writeback_Inv_SD, Hit_Invalidate_SD, 16) 
    410 __BUILD_BLAST_CACHE(inv_s, scache, Index_Writeback_Inv_SD, Hit_Invalidate_SD, 32) 
    411 __BUILD_BLAST_CACHE(inv_s, scache, Index_Writeback_Inv_SD, Hit_Invalidate_SD, 64) 
    412 __BUILD_BLAST_CACHE(inv_s, scache, Index_Writeback_Inv_SD, Hit_Invalidate_SD, 128) 
     463__BUILD_BLAST_CACHE(d, dcache, Index_Writeback_Inv_D, Hit_Writeback_Inv_D, 16, ) 
     464__BUILD_BLAST_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I, 16, BCM4710_FILL_TLB(start);) 
     465__BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 16, ) 
     466__BUILD_BLAST_CACHE(d, dcache, Index_Writeback_Inv_D, Hit_Writeback_Inv_D, 32, ) 
     467__BUILD_BLAST_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I, 32, BCM4710_FILL_TLB(start);) 
     468__BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 32, ) 
     469__BUILD_BLAST_CACHE(d, dcache, Index_Writeback_Inv_D, Hit_Writeback_Inv_D, 64, ) 
     470__BUILD_BLAST_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I, 64, BCM4710_FILL_TLB(start);) 
     471__BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 64, ) 
     472__BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 128, ) 
     473 
     474__BUILD_BLAST_CACHE(inv_d, dcache, Index_Writeback_Inv_D, Hit_Invalidate_D, 16, ) 
     475__BUILD_BLAST_CACHE(inv_d, dcache, Index_Writeback_Inv_D, Hit_Invalidate_D, 32, ) 
     476__BUILD_BLAST_CACHE(inv_s, scache, Index_Writeback_Inv_SD, Hit_Invalidate_SD, 16, ) 
     477__BUILD_BLAST_CACHE(inv_s, scache, Index_Writeback_Inv_SD, Hit_Invalidate_SD, 32, ) 
     478__BUILD_BLAST_CACHE(inv_s, scache, Index_Writeback_Inv_SD, Hit_Invalidate_SD, 64, ) 
     479__BUILD_BLAST_CACHE(inv_s, scache, Index_Writeback_Inv_SD, Hit_Invalidate_SD, 128, ) 
    413480 
    414481/* build blast_xxx_range, protected_blast_xxx_range */ 
    415 #define __BUILD_BLAST_CACHE_RANGE(pfx, desc, hitop, prot) \ 
     482#define __BUILD_BLAST_CACHE_RANGE(pfx, desc, hitop, prot, war, war2) \ 
    416483static inline void prot##blast_##pfx##cache##_range(unsigned long start, \ 
    417484                                                    unsigned long end)  \ 
    418485{                                                                       \ 
    419486        unsigned long lsize = cpu_##desc##_line_size();                 \ 
    420487        unsigned long addr = start & ~(lsize - 1);                      \ 
    421488        unsigned long aend = (end - 1) & ~(lsize - 1);                  \ 
     489        war                                                             \ 
    422490                                                                        \ 
    423491        __##pfx##flush_prologue                                         \ 
    424492                                                                        \ 
    425493        while (1) {                                                     \ 
     494                war2                                            \ 
    426495                prot##cache_op(hitop, addr);                            \ 
    427496                if (addr == aend)                                       \ 
    428497                        break;                                          \ 
    static inline void prot##blast_##pfx##ca 
    432501        __##pfx##flush_epilogue                                         \ 
    433502} 
    434503 
    435 __BUILD_BLAST_CACHE_RANGE(d, dcache, Hit_Writeback_Inv_D, protected_) 
    436 __BUILD_BLAST_CACHE_RANGE(s, scache, Hit_Writeback_Inv_SD, protected_) 
    437 __BUILD_BLAST_CACHE_RANGE(i, icache, Hit_Invalidate_I, protected_) 
    438 __BUILD_BLAST_CACHE_RANGE(d, dcache, Hit_Writeback_Inv_D, ) 
    439 __BUILD_BLAST_CACHE_RANGE(s, scache, Hit_Writeback_Inv_SD, ) 
     504__BUILD_BLAST_CACHE_RANGE(d, dcache, Hit_Writeback_Inv_D, protected_, BCM4710_PROTECTED_FILL_TLB(addr); BCM4710_PROTECTED_FILL_TLB(aend);, BCM4710_DUMMY_RREG();) 
     505__BUILD_BLAST_CACHE_RANGE(s, scache, Hit_Writeback_Inv_SD, protected_,, ) 
     506__BUILD_BLAST_CACHE_RANGE(i, icache, Hit_Invalidate_I, protected_,, ) 
     507__BUILD_BLAST_CACHE_RANGE(d, dcache, Hit_Writeback_Inv_D,, BCM4710_FILL_TLB(addr); BCM4710_FILL_TLB(aend);, BCM4710_DUMMY_RREG();) 
     508__BUILD_BLAST_CACHE_RANGE(s, scache, Hit_Writeback_Inv_SD,,, ) 
    440509/* blast_inv_dcache_range */ 
    441 __BUILD_BLAST_CACHE_RANGE(inv_d, dcache, Hit_Invalidate_D, ) 
    442 __BUILD_BLAST_CACHE_RANGE(inv_s, scache, Hit_Invalidate_SD, ) 
     510__BUILD_BLAST_CACHE_RANGE(inv_d, dcache, Hit_Invalidate_D,,,BCM4710_DUMMY_RREG();) 
     511__BUILD_BLAST_CACHE_RANGE(inv_s, scache, Hit_Invalidate_SD,,, ) 
    443512 
    444513#endif /* _ASM_R4KCACHE_H */ 
  • arch/mips/include/asm/stackframe.h

    a b  
    449449                .macro  RESTORE_SP_AND_RET 
    450450                LONG_L  sp, PT_R29(sp) 
    451451                .set    mips3 
     452#ifdef CONFIG_BCM47XX 
     453                nop 
     454                nop 
     455#endif 
    452456                eret 
    453457                .set    mips0 
    454458                .endm 
  • arch/mips/kernel/genex.S

    a b NESTED(except_vec1_generic, 0, sp) 
    5252NESTED(except_vec3_generic, 0, sp) 
    5353        .set    push 
    5454        .set    noat 
     55#ifdef CONFIG_BCM47XX 
     56        nop 
     57        nop 
     58#endif 
    5559#if R5432_CP0_INTERRUPT_WAR 
    5660        mfc0    k0, CP0_INDEX 
    5761#endif 
  • arch/mips/mm/c-r4k.c

    a b  
    3535#include <asm/cacheflush.h> /* for run_uncached() */ 
    3636 
    3737 
     38/* For enabling BCM4710 cache workarounds */ 
     39int bcm4710 = 0; 
     40 
    3841/* 
    3942 * Special Variant of smp_call_function for use by cache functions: 
    4043 * 
    static void __cpuinit r4k_blast_dcache_p 
    111114{ 
    112115        unsigned long  dc_lsize = cpu_dcache_line_size(); 
    113116 
     117        if (bcm4710) 
     118                r4k_blast_dcache_page = blast_dcache_page; 
     119        else 
    114120        if (dc_lsize == 0) 
    115121                r4k_blast_dcache_page = (void *)cache_noop; 
    116122        else if (dc_lsize == 16) 
    static void __cpuinit r4k_blast_dcache_p 
    127133{ 
    128134        unsigned long dc_lsize = cpu_dcache_line_size(); 
    129135 
     136        if (bcm4710) 
     137                r4k_blast_dcache_page_indexed = blast_dcache_page_indexed; 
     138        else 
    130139        if (dc_lsize == 0) 
    131140                r4k_blast_dcache_page_indexed = (void *)cache_noop; 
    132141        else if (dc_lsize == 16) 
    static void __cpuinit r4k_blast_dcache_s 
    143152{ 
    144153        unsigned long dc_lsize = cpu_dcache_line_size(); 
    145154 
     155        if (bcm4710) 
     156                r4k_blast_dcache = blast_dcache; 
     157        else 
    146158        if (dc_lsize == 0) 
    147159                r4k_blast_dcache = (void *)cache_noop; 
    148160        else if (dc_lsize == 16) 
    static void local_r4k_flush_cache_sigtra 
    679691        unsigned long addr = (unsigned long) arg; 
    680692 
    681693        R4600_HIT_CACHEOP_WAR_IMPL; 
     694        BCM4710_PROTECTED_FILL_TLB(addr); 
     695        BCM4710_PROTECTED_FILL_TLB(addr + 4); 
    682696        if (dc_lsize) 
    683697                protected_writeback_dcache_line(addr & ~(dc_lsize - 1)); 
    684698        if (!cpu_icache_snoops_remote_store && scache_size) 
    static void __cpuinit coherency_setup(vo 
    13101324         * silly idea of putting something else there ... 
    13111325         */ 
    13121326        switch (current_cpu_type()) { 
     1327        case CPU_BMIPS3300: 
     1328                { 
     1329                        u32 cm; 
     1330                        cm = read_c0_diag(); 
     1331                        /* Enable icache */ 
     1332                        cm |= (1 << 31); 
     1333                        /* Enable dcache */ 
     1334                        cm |= (1 << 30); 
     1335                        write_c0_diag(cm); 
     1336                } 
     1337                break; 
    13131338        case CPU_R4000PC: 
    13141339        case CPU_R4000SC: 
    13151340        case CPU_R4000MC: 
    void __cpuinit r4k_cache_init(void) 
    13661391                break; 
    13671392        } 
    13681393 
     1394        /* Check if special workarounds are required */ 
     1395#ifdef CONFIG_BCM47XX 
     1396        if (current_cpu_data.cputype == CPU_BMIPS32 && (current_cpu_data.processor_id & 0xff) == 0) { 
     1397                printk("Enabling BCM4710A0 cache workarounds.\n"); 
     1398                bcm4710 = 1; 
     1399        } else 
     1400#endif 
     1401                bcm4710 = 0; 
     1402 
    13691403        probe_pcache(); 
    13701404        setup_scache(); 
    13711405 
    void __cpuinit r4k_cache_init(void) 
    14241458#if !defined(CONFIG_MIPS_CMP) 
    14251459        local_r4k___flush_cache_all(NULL); 
    14261460#endif 
     1461#ifdef CONFIG_BCM47XX 
     1462        { 
     1463                static void (*_coherency_setup)(void); 
     1464                _coherency_setup = (void (*)(void)) KSEG1ADDR(coherency_setup); 
     1465                _coherency_setup(); 
     1466        } 
     1467#else 
    14271468        coherency_setup(); 
     1469#endif 
    14281470} 
  • arch/mips/mm/tlbex.c

    a b static void __cpuinit build_r4000_tlb_re 
    11871187                        /* No need for uasm_i_nop */ 
    11881188                } 
    11891189 
     1190#ifdef CONFIG_BCM47XX 
     1191                uasm_i_nop(&p); 
     1192#endif 
    11901193#ifdef CONFIG_64BIT 
    11911194                build_get_pmde64(&p, &l, &r, K0, K1); /* get pmd in K1 */ 
    11921195#else 
    build_r4000_tlbchange_handler_head(u32 * 
    17061709                                   struct uasm_reloc **r, unsigned int pte, 
    17071710                                   unsigned int ptr) 
    17081711{ 
     1712#ifdef CONFIG_BCM47XX 
     1713        uasm_i_nop(p); 
     1714#endif 
    17091715#ifdef CONFIG_64BIT 
    17101716        build_get_pmde64(p, l, r, pte, ptr); /* get pmd in ptr */ 
    17111717#else 
Note: See TracBrowser for help on using the repository browser.