162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright (C) 2020-2022 Loongson Technology Corporation Limited 462306a36Sopenharmony_ci */ 562306a36Sopenharmony_ci#ifndef _ASM_IO_H 662306a36Sopenharmony_ci#define _ASM_IO_H 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci#include <linux/kernel.h> 962306a36Sopenharmony_ci#include <linux/types.h> 1062306a36Sopenharmony_ci 1162306a36Sopenharmony_ci#include <asm/addrspace.h> 1262306a36Sopenharmony_ci#include <asm/cpu.h> 1362306a36Sopenharmony_ci#include <asm/page.h> 1462306a36Sopenharmony_ci#include <asm/pgtable-bits.h> 1562306a36Sopenharmony_ci#include <asm/string.h> 1662306a36Sopenharmony_ci 1762306a36Sopenharmony_ci/* 1862306a36Sopenharmony_ci * Change "struct page" to physical address. 1962306a36Sopenharmony_ci */ 2062306a36Sopenharmony_ci#define page_to_phys(page) ((phys_addr_t)page_to_pfn(page) << PAGE_SHIFT) 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_ciextern void __init __iomem *early_ioremap(u64 phys_addr, unsigned long size); 2362306a36Sopenharmony_ciextern void __init early_iounmap(void __iomem *addr, unsigned long size); 2462306a36Sopenharmony_ci 2562306a36Sopenharmony_ci#define early_memremap early_ioremap 2662306a36Sopenharmony_ci#define early_memunmap early_iounmap 2762306a36Sopenharmony_ci 2862306a36Sopenharmony_ci#ifdef CONFIG_ARCH_IOREMAP 2962306a36Sopenharmony_ci 3062306a36Sopenharmony_cistatic inline void __iomem *ioremap_prot(phys_addr_t offset, unsigned long size, 3162306a36Sopenharmony_ci unsigned long prot_val) 3262306a36Sopenharmony_ci{ 3362306a36Sopenharmony_ci if (prot_val & _CACHE_CC) 3462306a36Sopenharmony_ci return (void __iomem *)(unsigned long)(CACHE_BASE + offset); 3562306a36Sopenharmony_ci else 3662306a36Sopenharmony_ci return (void __iomem *)(unsigned long)(UNCACHE_BASE + offset); 3762306a36Sopenharmony_ci} 3862306a36Sopenharmony_ci 3962306a36Sopenharmony_ci#define ioremap(offset, size) \ 4062306a36Sopenharmony_ci ioremap_prot((offset), (size), pgprot_val(PAGE_KERNEL_SUC)) 4162306a36Sopenharmony_ci 4262306a36Sopenharmony_ci#define iounmap(addr) ((void)(addr)) 4362306a36Sopenharmony_ci 4462306a36Sopenharmony_ci#endif 4562306a36Sopenharmony_ci 4662306a36Sopenharmony_ci/* 4762306a36Sopenharmony_ci * On LoongArch, ioremap() has two variants, ioremap_wc() and ioremap_cache(). 4862306a36Sopenharmony_ci * They map bus memory into CPU space, the mapped memory is marked uncachable 4962306a36Sopenharmony_ci * (_CACHE_SUC), uncachable but accelerated by write-combine (_CACHE_WUC) and 5062306a36Sopenharmony_ci * cachable (_CACHE_CC) respectively for CPU access. 5162306a36Sopenharmony_ci * 5262306a36Sopenharmony_ci * @offset: bus address of the memory 5362306a36Sopenharmony_ci * @size: size of the resource to map 5462306a36Sopenharmony_ci */ 5562306a36Sopenharmony_ci#define ioremap_wc(offset, size) \ 5662306a36Sopenharmony_ci ioremap_prot((offset), (size), \ 5762306a36Sopenharmony_ci pgprot_val(wc_enabled ? PAGE_KERNEL_WUC : PAGE_KERNEL_SUC)) 5862306a36Sopenharmony_ci 5962306a36Sopenharmony_ci#define ioremap_cache(offset, size) \ 6062306a36Sopenharmony_ci ioremap_prot((offset), (size), pgprot_val(PAGE_KERNEL)) 6162306a36Sopenharmony_ci 6262306a36Sopenharmony_ci#define mmiowb() wmb() 6362306a36Sopenharmony_ci 6462306a36Sopenharmony_ci/* 6562306a36Sopenharmony_ci * String version of I/O memory access operations. 6662306a36Sopenharmony_ci */ 6762306a36Sopenharmony_ciextern void __memset_io(volatile void __iomem *dst, int c, size_t count); 6862306a36Sopenharmony_ciextern void __memcpy_toio(volatile void __iomem *to, const void *from, size_t count); 6962306a36Sopenharmony_ciextern void __memcpy_fromio(void *to, const volatile void __iomem *from, size_t count); 7062306a36Sopenharmony_ci#define memset_io(c, v, l) __memset_io((c), (v), (l)) 7162306a36Sopenharmony_ci#define memcpy_fromio(a, c, l) __memcpy_fromio((a), (c), (l)) 7262306a36Sopenharmony_ci#define memcpy_toio(c, a, l) __memcpy_toio((c), (a), (l)) 7362306a36Sopenharmony_ci 7462306a36Sopenharmony_ci#include <asm-generic/io.h> 7562306a36Sopenharmony_ci 7662306a36Sopenharmony_ci#define ARCH_HAS_VALID_PHYS_ADDR_RANGE 7762306a36Sopenharmony_ciextern int valid_phys_addr_range(phys_addr_t addr, size_t size); 7862306a36Sopenharmony_ciextern int valid_mmap_phys_addr_range(unsigned long pfn, size_t size); 7962306a36Sopenharmony_ci 8062306a36Sopenharmony_ci#endif /* _ASM_IO_H */ 81