Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-or-later */
0002 /*
0003  *  linux/arch/arm/mm/proc-mohawk.S: MMU functions for Marvell PJ1 core
0004  *
0005  *  PJ1 (codename Mohawk) is a hybrid of the xscale3 and Marvell's own core.
0006  *
0007  *  Heavily based on proc-arm926.S and proc-xsc3.S
0008  */
0009 
0010 #include <linux/linkage.h>
0011 #include <linux/init.h>
0012 #include <linux/pgtable.h>
0013 #include <asm/assembler.h>
0014 #include <asm/hwcap.h>
0015 #include <asm/pgtable-hwdef.h>
0016 #include <asm/page.h>
0017 #include <asm/ptrace.h>
0018 #include "proc-macros.S"
0019 
0020 /*
0021  * This is the maximum size of an area which will be flushed.  If the
0022  * area is larger than this, then we flush the whole cache.
0023  */
0024 #define CACHE_DLIMIT    32768
0025 
0026 /*
0027  * The cache line size of the L1 D cache.
0028  */
0029 #define CACHE_DLINESIZE 32
0030 
0031 /*
0032  * cpu_mohawk_proc_init()
0033  */
0034 ENTRY(cpu_mohawk_proc_init)
0035     ret lr
0036 
0037 /*
0038  * cpu_mohawk_proc_fin()
0039  */
0040 ENTRY(cpu_mohawk_proc_fin)
0041     mrc p15, 0, r0, c1, c0, 0       @ ctrl register
0042     bic r0, r0, #0x1800         @ ...iz...........
0043     bic r0, r0, #0x0006         @ .............ca.
0044     mcr p15, 0, r0, c1, c0, 0       @ disable caches
0045     ret lr
0046 
0047 /*
0048  * cpu_mohawk_reset(loc)
0049  *
0050  * Perform a soft reset of the system.  Put the CPU into the
0051  * same state as it would be if it had been reset, and branch
0052  * to what would be the reset vector.
0053  *
0054  * loc: location to jump to for soft reset
0055  *
0056  * (same as arm926)
0057  */
0058     .align  5
0059     .pushsection    .idmap.text, "ax"
0060 ENTRY(cpu_mohawk_reset)
0061     mov ip, #0
0062     mcr p15, 0, ip, c7, c7, 0       @ invalidate I,D caches
0063     mcr p15, 0, ip, c7, c10, 4      @ drain WB
0064     mcr p15, 0, ip, c8, c7, 0       @ invalidate I & D TLBs
0065     mrc p15, 0, ip, c1, c0, 0       @ ctrl register
0066     bic ip, ip, #0x0007         @ .............cam
0067     bic ip, ip, #0x1100         @ ...i...s........
0068     mcr p15, 0, ip, c1, c0, 0       @ ctrl register
0069     ret r0
0070 ENDPROC(cpu_mohawk_reset)
0071     .popsection
0072 
0073 /*
0074  * cpu_mohawk_do_idle()
0075  *
0076  * Called with IRQs disabled
0077  */
0078     .align  5
0079 ENTRY(cpu_mohawk_do_idle)
0080     mov r0, #0
0081     mcr p15, 0, r0, c7, c10, 4      @ drain write buffer
0082     mcr p15, 0, r0, c7, c0, 4       @ wait for interrupt
0083     ret lr
0084 
0085 /*
0086  *  flush_icache_all()
0087  *
0088  *  Unconditionally clean and invalidate the entire icache.
0089  */
0090 ENTRY(mohawk_flush_icache_all)
0091     mov r0, #0
0092     mcr p15, 0, r0, c7, c5, 0       @ invalidate I cache
0093     ret lr
0094 ENDPROC(mohawk_flush_icache_all)
0095 
0096 /*
0097  *  flush_user_cache_all()
0098  *
0099  *  Clean and invalidate all cache entries in a particular
0100  *  address space.
0101  */
0102 ENTRY(mohawk_flush_user_cache_all)
0103     /* FALLTHROUGH */
0104 
0105 /*
0106  *  flush_kern_cache_all()
0107  *
0108  *  Clean and invalidate the entire cache.
0109  */
0110 ENTRY(mohawk_flush_kern_cache_all)
0111     mov r2, #VM_EXEC
0112     mov ip, #0
0113 __flush_whole_cache:
0114     mcr p15, 0, ip, c7, c14, 0      @ clean & invalidate all D cache
0115     tst r2, #VM_EXEC
0116     mcrne   p15, 0, ip, c7, c5, 0       @ invalidate I cache
0117     mcrne   p15, 0, ip, c7, c10, 0      @ drain write buffer
0118     ret lr
0119 
0120 /*
0121  *  flush_user_cache_range(start, end, flags)
0122  *
0123  *  Clean and invalidate a range of cache entries in the
0124  *  specified address range.
0125  *
0126  *  - start - start address (inclusive)
0127  *  - end   - end address (exclusive)
0128  *  - flags - vm_flags describing address space
0129  *
0130  * (same as arm926)
0131  */
0132 ENTRY(mohawk_flush_user_cache_range)
0133     mov ip, #0
0134     sub r3, r1, r0          @ calculate total size
0135     cmp r3, #CACHE_DLIMIT
0136     bgt __flush_whole_cache
0137 1:  tst r2, #VM_EXEC
0138     mcr p15, 0, r0, c7, c14, 1      @ clean and invalidate D entry
0139     mcrne   p15, 0, r0, c7, c5, 1       @ invalidate I entry
0140     add r0, r0, #CACHE_DLINESIZE
0141     mcr p15, 0, r0, c7, c14, 1      @ clean and invalidate D entry
0142     mcrne   p15, 0, r0, c7, c5, 1       @ invalidate I entry
0143     add r0, r0, #CACHE_DLINESIZE
0144     cmp r0, r1
0145     blo 1b
0146     tst r2, #VM_EXEC
0147     mcrne   p15, 0, ip, c7, c10, 4      @ drain WB
0148     ret lr
0149 
0150 /*
0151  *  coherent_kern_range(start, end)
0152  *
0153  *  Ensure coherency between the Icache and the Dcache in the
0154  *  region described by start, end.  If you have non-snooping
0155  *  Harvard caches, you need to implement this function.
0156  *
0157  *  - start - virtual start address
0158  *  - end   - virtual end address
0159  */
0160 ENTRY(mohawk_coherent_kern_range)
0161     /* FALLTHROUGH */
0162 
0163 /*
0164  *  coherent_user_range(start, end)
0165  *
0166  *  Ensure coherency between the Icache and the Dcache in the
0167  *  region described by start, end.  If you have non-snooping
0168  *  Harvard caches, you need to implement this function.
0169  *
0170  *  - start - virtual start address
0171  *  - end   - virtual end address
0172  *
0173  * (same as arm926)
0174  */
0175 ENTRY(mohawk_coherent_user_range)
0176     bic r0, r0, #CACHE_DLINESIZE - 1
0177 1:  mcr p15, 0, r0, c7, c10, 1      @ clean D entry
0178     mcr p15, 0, r0, c7, c5, 1       @ invalidate I entry
0179     add r0, r0, #CACHE_DLINESIZE
0180     cmp r0, r1
0181     blo 1b
0182     mcr p15, 0, r0, c7, c10, 4      @ drain WB
0183     mov r0, #0
0184     ret lr
0185 
0186 /*
0187  *  flush_kern_dcache_area(void *addr, size_t size)
0188  *
0189  *  Ensure no D cache aliasing occurs, either with itself or
0190  *  the I cache
0191  *
0192  *  - addr  - kernel address
0193  *  - size  - region size
0194  */
0195 ENTRY(mohawk_flush_kern_dcache_area)
0196     add r1, r0, r1
0197 1:  mcr p15, 0, r0, c7, c14, 1      @ clean+invalidate D entry
0198     add r0, r0, #CACHE_DLINESIZE
0199     cmp r0, r1
0200     blo 1b
0201     mov r0, #0
0202     mcr p15, 0, r0, c7, c5, 0       @ invalidate I cache
0203     mcr p15, 0, r0, c7, c10, 4      @ drain WB
0204     ret lr
0205 
0206 /*
0207  *  dma_inv_range(start, end)
0208  *
0209  *  Invalidate (discard) the specified virtual address range.
0210  *  May not write back any entries.  If 'start' or 'end'
0211  *  are not cache line aligned, those lines must be written
0212  *  back.
0213  *
0214  *  - start - virtual start address
0215  *  - end   - virtual end address
0216  *
0217  * (same as v4wb)
0218  */
0219 mohawk_dma_inv_range:
0220     tst r0, #CACHE_DLINESIZE - 1
0221     mcrne   p15, 0, r0, c7, c10, 1      @ clean D entry
0222     tst r1, #CACHE_DLINESIZE - 1
0223     mcrne   p15, 0, r1, c7, c10, 1      @ clean D entry
0224     bic r0, r0, #CACHE_DLINESIZE - 1
0225 1:  mcr p15, 0, r0, c7, c6, 1       @ invalidate D entry
0226     add r0, r0, #CACHE_DLINESIZE
0227     cmp r0, r1
0228     blo 1b
0229     mcr p15, 0, r0, c7, c10, 4      @ drain WB
0230     ret lr
0231 
0232 /*
0233  *  dma_clean_range(start, end)
0234  *
0235  *  Clean the specified virtual address range.
0236  *
0237  *  - start - virtual start address
0238  *  - end   - virtual end address
0239  *
0240  * (same as v4wb)
0241  */
0242 mohawk_dma_clean_range:
0243     bic r0, r0, #CACHE_DLINESIZE - 1
0244 1:  mcr p15, 0, r0, c7, c10, 1      @ clean D entry
0245     add r0, r0, #CACHE_DLINESIZE
0246     cmp r0, r1
0247     blo 1b
0248     mcr p15, 0, r0, c7, c10, 4      @ drain WB
0249     ret lr
0250 
0251 /*
0252  *  dma_flush_range(start, end)
0253  *
0254  *  Clean and invalidate the specified virtual address range.
0255  *
0256  *  - start - virtual start address
0257  *  - end   - virtual end address
0258  */
0259 ENTRY(mohawk_dma_flush_range)
0260     bic r0, r0, #CACHE_DLINESIZE - 1
0261 1:
0262     mcr p15, 0, r0, c7, c14, 1      @ clean+invalidate D entry
0263     add r0, r0, #CACHE_DLINESIZE
0264     cmp r0, r1
0265     blo 1b
0266     mcr p15, 0, r0, c7, c10, 4      @ drain WB
0267     ret lr
0268 
0269 /*
0270  *  dma_map_area(start, size, dir)
0271  *  - start - kernel virtual start address
0272  *  - size  - size of region
0273  *  - dir   - DMA direction
0274  */
0275 ENTRY(mohawk_dma_map_area)
0276     add r1, r1, r0
0277     cmp r2, #DMA_TO_DEVICE
0278     beq mohawk_dma_clean_range
0279     bcs mohawk_dma_inv_range
0280     b   mohawk_dma_flush_range
0281 ENDPROC(mohawk_dma_map_area)
0282 
0283 /*
0284  *  dma_unmap_area(start, size, dir)
0285  *  - start - kernel virtual start address
0286  *  - size  - size of region
0287  *  - dir   - DMA direction
0288  */
0289 ENTRY(mohawk_dma_unmap_area)
0290     ret lr
0291 ENDPROC(mohawk_dma_unmap_area)
0292 
0293     .globl  mohawk_flush_kern_cache_louis
0294     .equ    mohawk_flush_kern_cache_louis, mohawk_flush_kern_cache_all
0295 
0296     @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
0297     define_cache_functions mohawk
0298 
0299 ENTRY(cpu_mohawk_dcache_clean_area)
0300 1:  mcr p15, 0, r0, c7, c10, 1      @ clean D entry
0301     add r0, r0, #CACHE_DLINESIZE
0302     subs    r1, r1, #CACHE_DLINESIZE
0303     bhi 1b
0304     mcr p15, 0, r0, c7, c10, 4      @ drain WB
0305     ret lr
0306 
0307 /*
0308  * cpu_mohawk_switch_mm(pgd)
0309  *
0310  * Set the translation base pointer to be as described by pgd.
0311  *
0312  * pgd: new page tables
0313  */
0314     .align  5
0315 ENTRY(cpu_mohawk_switch_mm)
0316     mov ip, #0
0317     mcr p15, 0, ip, c7, c14, 0      @ clean & invalidate all D cache
0318     mcr p15, 0, ip, c7, c5, 0       @ invalidate I cache
0319     mcr p15, 0, ip, c7, c10, 4      @ drain WB
0320     orr r0, r0, #0x18           @ cache the page table in L2
0321     mcr p15, 0, r0, c2, c0, 0       @ load page table pointer
0322     mcr p15, 0, ip, c8, c7, 0       @ invalidate I & D TLBs
0323     ret lr
0324 
0325 /*
0326  * cpu_mohawk_set_pte_ext(ptep, pte, ext)
0327  *
0328  * Set a PTE and flush it out
0329  */
0330     .align  5
0331 ENTRY(cpu_mohawk_set_pte_ext)
0332 #ifdef CONFIG_MMU
0333     armv3_set_pte_ext
0334     mov r0, r0
0335     mcr p15, 0, r0, c7, c10, 1      @ clean D entry
0336     mcr p15, 0, r0, c7, c10, 4      @ drain WB
0337     ret lr
0338 #endif
0339 
0340 .globl  cpu_mohawk_suspend_size
0341 .equ    cpu_mohawk_suspend_size, 4 * 6
0342 #ifdef CONFIG_ARM_CPU_SUSPEND
0343 ENTRY(cpu_mohawk_do_suspend)
0344     stmfd   sp!, {r4 - r9, lr}
0345     mrc p14, 0, r4, c6, c0, 0   @ clock configuration, for turbo mode
0346     mrc p15, 0, r5, c15, c1, 0  @ CP access reg
0347     mrc p15, 0, r6, c13, c0, 0  @ PID
0348     mrc     p15, 0, r7, c3, c0, 0   @ domain ID
0349     mrc p15, 0, r8, c1, c0, 1   @ auxiliary control reg
0350     mrc     p15, 0, r9, c1, c0, 0   @ control reg
0351     bic r4, r4, #2      @ clear frequency change bit
0352     stmia   r0, {r4 - r9}       @ store cp regs
0353     ldmia   sp!, {r4 - r9, pc}
0354 ENDPROC(cpu_mohawk_do_suspend)
0355 
0356 ENTRY(cpu_mohawk_do_resume)
0357     ldmia   r0, {r4 - r9}       @ load cp regs
0358     mov ip, #0
0359     mcr p15, 0, ip, c7, c7, 0   @ invalidate I & D caches, BTB
0360     mcr p15, 0, ip, c7, c10, 4  @ drain write (&fill) buffer
0361     mcr p15, 0, ip, c7, c5, 4   @ flush prefetch buffer
0362     mcr p15, 0, ip, c8, c7, 0   @ invalidate I & D TLBs
0363     mcr p14, 0, r4, c6, c0, 0   @ clock configuration, turbo mode.
0364     mcr p15, 0, r5, c15, c1, 0  @ CP access reg
0365     mcr p15, 0, r6, c13, c0, 0  @ PID
0366     mcr p15, 0, r7, c3, c0, 0   @ domain ID
0367     orr r1, r1, #0x18       @ cache the page table in L2
0368     mcr p15, 0, r1, c2, c0, 0   @ translation table base addr
0369     mcr p15, 0, r8, c1, c0, 1   @ auxiliary control reg
0370     mov r0, r9          @ control register
0371     b   cpu_resume_mmu
0372 ENDPROC(cpu_mohawk_do_resume)
0373 #endif
0374 
0375     .type   __mohawk_setup, #function
0376 __mohawk_setup:
0377     mov r0, #0
0378     mcr p15, 0, r0, c7, c7      @ invalidate I,D caches
0379     mcr p15, 0, r0, c7, c10, 4      @ drain write buffer
0380     mcr p15, 0, r0, c8, c7      @ invalidate I,D TLBs
0381     orr r4, r4, #0x18           @ cache the page table in L2
0382     mcr p15, 0, r4, c2, c0, 0       @ load page table pointer
0383 
0384     mov r0, #0              @ don't allow CP access
0385     mcr p15, 0, r0, c15, c1, 0      @ write CP access register
0386 
0387     adr r5, mohawk_crval
0388     ldmia   r5, {r5, r6}
0389     mrc p15, 0, r0, c1, c0      @ get control register
0390     bic r0, r0, r5
0391     orr r0, r0, r6
0392     ret lr
0393 
0394     .size   __mohawk_setup, . - __mohawk_setup
0395 
0396     /*
0397      *  R
0398      * .RVI ZFRS BLDP WCAM
0399      * .011 1001 ..00 0101
0400      *
0401      */
0402     .type   mohawk_crval, #object
0403 mohawk_crval:
0404     crval   clear=0x00007f3f, mmuset=0x00003905, ucset=0x00001134
0405 
0406     __INITDATA
0407 
0408     @ define struct processor (see <asm/proc-fns.h> and proc-macros.S)
0409     define_processor_functions mohawk, dabort=v5t_early_abort, pabort=legacy_pabort
0410 
0411     .section ".rodata"
0412 
0413     string  cpu_arch_name, "armv5te"
0414     string  cpu_elf_name, "v5"
0415     string  cpu_mohawk_name, "Marvell 88SV331x"
0416 
0417     .align
0418 
0419     .section ".proc.info.init", "a"
0420 
0421     .type   __88sv331x_proc_info,#object
0422 __88sv331x_proc_info:
0423     .long   0x56158000          @ Marvell 88SV331x (MOHAWK)
0424     .long   0xfffff000
0425     .long   PMD_TYPE_SECT | \
0426         PMD_SECT_BUFFERABLE | \
0427         PMD_SECT_CACHEABLE | \
0428         PMD_BIT4 | \
0429         PMD_SECT_AP_WRITE | \
0430         PMD_SECT_AP_READ
0431     .long   PMD_TYPE_SECT | \
0432         PMD_BIT4 | \
0433         PMD_SECT_AP_WRITE | \
0434         PMD_SECT_AP_READ
0435     initfn  __mohawk_setup, __88sv331x_proc_info
0436     .long   cpu_arch_name
0437     .long   cpu_elf_name
0438     .long   HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP
0439     .long   cpu_mohawk_name
0440     .long   mohawk_processor_functions
0441     .long   v4wbi_tlb_fns
0442     .long   v4wb_user_fns
0443     .long   mohawk_cache_fns
0444     .size   __88sv331x_proc_info, . - __88sv331x_proc_info