123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327 |
- /*
- * Copyright (c) 2017 Actions Semiconductor Co., Ltd
- *
- * SPDX-License-Identifier: Apache-2.0
- */
- /**
- * @file
- * @brief SPICACHE profile interface for Actions SoC
- */
- #include <errno.h>
- #include <kernel.h>
- #include "soc.h"
- #include "spicache.h"
- #include "board_cfg.h"
- #define SPI1_CACHE_SIZE (1024*32)
- #ifdef CONFIG_SOC_SPICACHE_PROFILE
- static void spicache_update_profile_data(struct spicache_profile *profile)
- {
- if (!profile->spi_id) {
- profile->hit_cnt = sys_read32(SPICACHE_RANGE_ADDR_HIT_COUNT);
- profile->miss_cnt = sys_read32(SPICACHE_RANGE_ADDR_MISS_COUNT);
- profile->total_hit_cnt = sys_read32(SPICACHE_TOTAL_HIT_COUNT);
- profile->total_miss_cnt = sys_read32(SPICACHE_TOTAL_MISS_COUNT);
- } else {
- profile->hit_cnt = sys_read32(SPI1_CACHE_MCPU_HIT_COUNT);
- profile->miss_cnt = sys_read32(SPI1_CACHE_MCPU_MISS_COUNT);
- profile->dma_hit_cnt = sys_read32(SPI1_CACHE_DMA_HIT_COUNT);
- profile->dma_miss_cnt = sys_read32(SPI1_CACHE_DMA_MISS_COUNT);
- }
- }
- int spicache_profile_get_data(struct spicache_profile *profile)
- {
- if (!profile)
- return -EINVAL;
- spicache_update_profile_data(profile);
- return 0;
- }
- int spicache_profile_stop(struct spicache_profile *profile)
- {
- if (!profile)
- return -EINVAL;
- profile->end_time = k_cycle_get_32();
- spicache_update_profile_data(profile);
- if (!profile->spi_id)
- sys_write32(sys_read32(SPICACHE_CTL) & ~(1 << 4), SPICACHE_CTL);
- else
- sys_write32(sys_read32(SPI1_CACHE_CTL) & ~(1 << 4), SPI1_CACHE_CTL);
- return 0;
- }
- int spicache_profile_start(struct spicache_profile *profile)
- {
- if (!profile)
- return -EINVAL;
- if (!profile->spi_id) {
- sys_write32(profile->start_addr, SPICACHE_PROFILE_ADDR_START);
- sys_write32(profile->end_addr, SPICACHE_PROFILE_ADDR_END);
- } else {
- sys_write32(profile->start_addr, SPI1_CACHE_PROFILE_ADDR_START);
- sys_write32(profile->end_addr, SPI1_CACHE_PROFILE_ADDR_END);
- }
- profile->start_time = k_cycle_get_32();
- if (!profile->spi_id)
- sys_write32(sys_read32(SPICACHE_CTL) | (1 << 4), SPICACHE_CTL);
- else
- sys_write32(sys_read32(SPI1_CACHE_CTL) | (1 << 4), SPI1_CACHE_CTL);
- return 0;
- }
- #endif
- int spicache_master_enable(int spi_id, SPI_CACHE_MASTER master_id)
- {
- if (!spi_id) {
- if ((master_id >= SPI0_CACHE_MASTER_DMA) && (master_id <= SPI0_CACHE_MASTER_DE))
- sys_write32(sys_read32(SPICACHE_CTL) | (1<<((master_id - SPI0_CACHE_MASTER_DMA) + 9)), SPICACHE_CTL);
- } else {
- if ((master_id >= SPI1_CACHE_MASTER_GPU) && (master_id <= SPI1_CACHE_MASTER_DE))
- sys_write32(sys_read32(SPI1_CACHE_CTL) | (1<<((master_id - SPI1_CACHE_MASTER_GPU) + 8)), SPI1_CACHE_CTL);
- }
- return 0;
- }
- int spicache_master_disable(int spi_id, SPI_CACHE_MASTER master_id)
- {
- if (!spi_id) {
- if ((master_id >= SPI0_CACHE_MASTER_DMA) && (master_id<=SPI0_CACHE_MASTER_DE))
- sys_write32(sys_read32(SPICACHE_CTL) & ~(1<<((master_id - SPI0_CACHE_MASTER_DMA) + 9)), SPICACHE_CTL);
- } else {
- if ((master_id >= SPI1_CACHE_MASTER_GPU) && (master_id <= SPI1_CACHE_MASTER_DE))
- sys_write32(sys_read32(SPI1_CACHE_CTL) & ~(1<<((master_id - SPI1_CACHE_MASTER_GPU) + 8)), SPI1_CACHE_CTL);
- }
- return 0;
- }
- int spicache_set_priority(int spi_id, SPI_CACHE_PRIORITY priority)
- {
- if (!spi_id) {
- sys_write32((sys_read32(SPICACHE_CTL) & ~(0xf<<20)) | ((priority - SPI0_CACHE_PRIORITY_POLL)<<20), SPICACHE_CTL);
- } else {
- sys_write32((sys_read32(SPI1_CACHE_CTL) & ~(0xf<<20)) | ((priority - SPI1_CACHE_PRIORITY_POLL)<<20), SPI1_CACHE_CTL);
- }
- return 0;
- }
- void spi1_cache_ops_wait_finshed(void)
- {
- while(sys_test_bit(SPI1_CACHE_OPERATE, 0));
- }
- void spi1_cache_ops(SPI_CACHE_OPS ops, void* addr, int size)
- {
- // uint32_t end;
- uint32_t off = (uint32_t)addr;
- uint32_t op;
- if((off < SPI1_CACHE_WT_WNA_ADDR) || (off > SPI1_UNCACHE_END_ADDR))
- return;
- spi1_cache_ops_wait_finshed();
- switch(ops){
- case SPI_CACHE_FLUSH:
- sys_write32((uint32_t)addr, CACHE_OPERATE_ADDR_START);
- sys_write32((uint32_t)addr + size - 1, CACHE_OPERATE_ADDR_END);
- op = 0x13; // write back // configurable address space mode
- sys_write32(op, SPI1_CACHE_OPERATE);
- spi1_cache_ops_wait_finshed();
- return;
- case SPI_CACHE_INVALIDATE:
- sys_write32((uint32_t)addr, CACHE_OPERATE_ADDR_START);
- sys_write32((uint32_t)addr + size - 1, CACHE_OPERATE_ADDR_END);
- op = 0x0b; // invalid // configurable address space mode
- sys_write32(op, SPI1_CACHE_OPERATE);
- spi1_cache_ops_wait_finshed();
- return;
- case SPI_WRITEBUF_FLUSH:
- sys_write32(0x1f, SPI1_CACHE_OPERATE);
- spi1_cache_ops_wait_finshed();
- return;
- case SPI_CACHE_FLUSH_ALL://flush all
- sys_write32(0x11, SPI1_CACHE_OPERATE);
- return ;
- case SPI_CACHE_INVALID_ALL: //invalid all
- sys_write32(0x9, SPI1_CACHE_OPERATE);
- spi1_cache_ops_wait_finshed();
- return ;
- case SPI_CACHE_FLUSH_INVALID:
- sys_write32((uint32_t)addr, CACHE_OPERATE_ADDR_START);
- sys_write32((uint32_t)addr + size - 1, CACHE_OPERATE_ADDR_END);
- op = 0x1b; // writeback & invalid // configurable address space mode
- sys_write32(op, SPI1_CACHE_OPERATE);
- spi1_cache_ops_wait_finshed();
- return;
- case SPI_CACHE_FLUSH_INVALID_ALL:
- sys_write32(0x19, SPI1_CACHE_OPERATE); //flush and invalid all
- return ;
- default:
- return;
- }
- // /*address mode operate*/
- // off = (off - SPI1_BASE_ADDR);
- // end = off + size;
- // off &= (~0x1f);
- // /*not flush all*/
- // while(off < end) {
- // sys_write32(op|off, SPI1_CACHE_OPERATE);
- // off+= 0x20;
- // //while(sys_test_bit(SPI1_CACHE_OPERATE, 0));
- // spi1_cache_ops_wait_finshed();
- // }
- }
- static uint32_t system_phy_addr, sdfs_phy_addr;
- static uint32_t get_system_phy_addr(void)
- {
- if (system_phy_addr == 0) {
- system_phy_addr = soc_boot_get_info()->system_phy_addr;
- }
- return system_phy_addr;
- }
- #include <partition/partition.h>
- static uint32_t get_sdfs_phy_addr(void)
- {
- const struct partition_entry *part;
- if (sdfs_phy_addr == 0) {
- part = partition_get_part(PARTITION_FILE_ID_SDFS);
- if (part) {
- sdfs_phy_addr = part->file_offset;
- }
- }
- return sdfs_phy_addr;
- }
- void * cache_to_uncache(void *vaddr)
- {
- void *pvadr = vaddr;
- if (buf_is_nor(vaddr)) {
- pvadr = (void *) (SPI0_UNCACHE_ADDR + (((uint32_t)vaddr) - SPI0_BASE_ADDR));
- } else if (buf_is_psram_cache(vaddr)) {
- pvadr = (void *) (SPI1_UNCACHE_ADDR + (((uint32_t)vaddr) - SPI1_BASE_ADDR));
- } else if (buf_is_psram_wt_wna(vaddr)) {
- pvadr = (void *) (SPI1_UNCACHE_ADDR + (((uint32_t)vaddr) - SPI1_CACHE_WT_WNA_ADDR));
- }
- return pvadr;
- }
- void * cache_to_unmap_uncache(void *vaddr)
- {
- void *pvadr = vaddr;
- if (buf_is_nor(vaddr)) {
- uint32_t vaddr_val = (uint32_t)vaddr;
- if ((vaddr_val & 0xff000000) == CONFIG_FLASH_BASE_ADDRESS) {
- pvadr = (void *) (SPI0_UNCACHE_ADDR + (vaddr_val - CONFIG_FLASH_BASE_ADDRESS + get_system_phy_addr()));
- } else if ((vaddr_val & 0xff000000) == CONFIG_SPI_XIP_VADDR) {
- pvadr = (void *) ((vaddr_val - CONFIG_SPI_XIP_VADDR + SPI0_UNCACHE_ADDR));
- }
- }
- return pvadr;
- }
- void * cache_to_uncache_by_master(void *vaddr, SPI_CACHE_MASTER master_id)
- {
- if ((master_id >= SPI0_CACHE_MASTER_DMA) && (master_id<=SPI0_CACHE_MASTER_DE))
- return cache_to_unmap_uncache(vaddr);
- return cache_to_uncache(vaddr);
- }
- void * uncache_to_cache(void *paddr)
- {
- void *vaddr = paddr;
- if (buf_is_nor_un(paddr)) {
- vaddr = (void *) (SPI0_BASE_ADDR + (((uint32_t)paddr) - SPI0_UNCACHE_ADDR));
- } else if (buf_is_psram_un(paddr)) {
- vaddr = (void *) (SPI1_BASE_ADDR + (((uint32_t)paddr) - SPI1_UNCACHE_ADDR));
- }
- return vaddr;
- }
- void * unmap_uncache_to_cache(void *paddr)
- {
- void *vaddr = paddr;
- if (buf_is_nor_un(paddr)) {
- uint32_t offs = (uint32_t)paddr - SPI0_UNCACHE_ADDR;
- if ((offs >= get_system_phy_addr()) && (offs < get_sdfs_phy_addr())) {
- vaddr = (void *) (SPI0_BASE_ADDR + (offs- get_system_phy_addr()));
- } else if (offs >= get_sdfs_phy_addr()) {
- vaddr = (void *) (CONFIG_SD_FS_VADDR_START + (offs - get_sdfs_phy_addr()));
- }
- }
- return vaddr;
- }
- void * uncache_to_cache_by_master(void *paddr, SPI_CACHE_MASTER master_id)
- {
- if ((master_id >= SPI0_CACHE_MASTER_DMA) && (master_id<=SPI0_CACHE_MASTER_DE))
- return unmap_uncache_to_cache(paddr);
- return uncache_to_cache(paddr);
- }
- void * uncache_to_wt_wna_cache(void *paddr)
- {
- void *vaddr = paddr;
- if (buf_is_psram_un(paddr)) {
- vaddr = (void *) (SPI1_CACHE_WT_WNA_ADDR + (((uint32_t)paddr) - SPI1_UNCACHE_ADDR));
- }
- return vaddr;
- }
- void * cache_to_wt_wna_cache(void *vaddr)
- {
- void *pvadr = vaddr;
- if (buf_is_psram_cache(vaddr)) {
- pvadr = (void *) (SPI1_CACHE_WT_WNA_ADDR + (((uint32_t)vaddr) - SPI1_BASE_ADDR));
- }
- return pvadr;
- }
- void * wt_wna_cache_to_cache(void *vaddr)
- {
- void *pvadr = vaddr;
- if (buf_is_psram_wt_wna(vaddr)) {
- pvadr = (void *) (SPI1_BASE_ADDR + (((uint32_t)vaddr) - SPI1_CACHE_WT_WNA_ADDR));
- }
- return pvadr;
- }
|