1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright (C) 2017 HiSilicon Limited, All Rights Reserved. 4 * Author: Gabriele Paoloni <gabriele.paoloni@huawei.com> 5 * Author: Zhichang Yuan <yuanzhichang@hisilicon.com> 6 */ 7 8 #ifndef __LINUX_LOGIC_PIO_H 9 #define __LINUX_LOGIC_PIO_H 10 11 #include <linux/fwnode.h> 12 13 enum { 14 LOGIC_PIO_INDIRECT, /* Indirect IO flag */ 15 LOGIC_PIO_CPU_MMIO, /* Memory-mapped IO flag */ 16 }; 17 18 struct logic_pio_hwaddr { 19 struct list_head list; 20 struct fwnode_handle *fwnode; 21 resource_size_t hw_start; 22 resource_size_t io_start; 23 resource_size_t size; /* range size populated */ 24 unsigned long flags; 25 26 void *hostdata; 27 const struct logic_pio_host_ops *ops; 28 }; 29 30 struct logic_pio_host_ops { 31 u32 (*in)(void *hostdata, unsigned long addr, size_t dwidth); 32 void (*out)(void *hostdata, unsigned long addr, u32 val, 33 size_t dwidth); 34 u32 (*ins)(void *hostdata, unsigned long addr, void *buffer, 35 size_t dwidth, unsigned int count); 36 void (*outs)(void *hostdata, unsigned long addr, const void *buffer, 37 size_t dwidth, unsigned int count); 38 }; 39 40 #ifdef CONFIG_INDIRECT_PIO 41 u8 logic_inb(unsigned long addr); 42 u16 logic_inw(unsigned long addr); 43 u32 logic_inl(unsigned long addr); 44 void logic_outb(u8 value, unsigned long addr); 45 void logic_outw(u16 value, unsigned long addr); 46 void logic_outl(u32 value, unsigned long addr); 47 void logic_insb(unsigned long addr, void *buffer, unsigned int count); 48 void logic_insl(unsigned long addr, void *buffer, unsigned int count); 49 void logic_insw(unsigned long addr, void *buffer, unsigned int count); 50 void logic_outsb(unsigned long addr, const void *buffer, unsigned int count); 51 void logic_outsw(unsigned long addr, const void *buffer, unsigned int count); 52 void logic_outsl(unsigned long addr, const void *buffer, unsigned int count); 53 54 #ifndef inb 55 #define inb logic_inb 56 #endif 57 58 #ifndef inw 59 #define inw logic_inw 60 #endif 61 62 #ifndef inl 63 #define inl logic_inl 64 #endif 65 66 #ifndef outb 67 #define outb logic_outb 68 #endif 69 70 #ifndef outw 71 #define outw logic_outw 72 #endif 73 74 #ifndef outl 75 #define outl logic_outl 76 #endif 77 78 #ifndef insb 79 #define insb logic_insb 80 #endif 81 82 #ifndef insw 83 #define insw logic_insw 84 #endif 85 86 #ifndef insl 87 #define insl logic_insl 88 #endif 89 90 #ifndef outsb 91 #define outsb logic_outsb 92 #endif 93 94 #ifndef outsw 95 #define outsw logic_outsw 96 #endif 97 98 #ifndef outsl 99 #define outsl logic_outsl 100 #endif 101 102 /* 103 * We reserve 0x4000 bytes for Indirect IO as so far this library is only 104 * used by the HiSilicon LPC Host. If needed, we can reserve a wider IO 105 * area by redefining the macro below. 106 */ 107 #define PIO_INDIRECT_SIZE 0x4000 108 #else 109 #define PIO_INDIRECT_SIZE 0 110 #endif /* CONFIG_INDIRECT_PIO */ 111 #define MMIO_UPPER_LIMIT (IO_SPACE_LIMIT - PIO_INDIRECT_SIZE) 112 113 struct logic_pio_hwaddr *find_io_range_by_fwnode(struct fwnode_handle *fwnode); 114 unsigned long logic_pio_trans_hwaddr(struct fwnode_handle *fwnode, 115 resource_size_t hw_addr, resource_size_t size); 116 int logic_pio_register_range(struct logic_pio_hwaddr *newrange); 117 void logic_pio_unregister_range(struct logic_pio_hwaddr *range); 118 resource_size_t logic_pio_to_hwaddr(unsigned long pio); 119 unsigned long logic_pio_trans_cpuaddr(resource_size_t hw_addr); 120 121 #endif /* __LINUX_LOGIC_PIO_H */ 122