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 void logic_outb(u8 value, unsigned long addr); 43 void logic_outw(u16 value, unsigned long addr); 44 void logic_outl(u32 value, unsigned long addr); 45 u16 logic_inw(unsigned long addr); 46 u32 logic_inl(unsigned long addr); 47 void logic_outb(u8 value, unsigned long addr); 48 void logic_outw(u16 value, unsigned long addr); 49 void logic_outl(u32 value, unsigned long addr); 50 void logic_insb(unsigned long addr, void *buffer, unsigned int count); 51 void logic_insl(unsigned long addr, void *buffer, unsigned int count); 52 void logic_insw(unsigned long addr, void *buffer, unsigned int count); 53 void logic_outsb(unsigned long addr, const void *buffer, unsigned int count); 54 void logic_outsw(unsigned long addr, const void *buffer, unsigned int count); 55 void logic_outsl(unsigned long addr, const void *buffer, unsigned int count); 56 57 #ifndef inb 58 #define inb logic_inb 59 #endif 60 61 #ifndef inw 62 #define inw logic_inw 63 #endif 64 65 #ifndef inl 66 #define inl logic_inl 67 #endif 68 69 #ifndef outb 70 #define outb logic_outb 71 #endif 72 73 #ifndef outw 74 #define outw logic_outw 75 #endif 76 77 #ifndef outl 78 #define outl logic_outl 79 #endif 80 81 #ifndef insb 82 #define insb logic_insb 83 #endif 84 85 #ifndef insw 86 #define insw logic_insw 87 #endif 88 89 #ifndef insl 90 #define insl logic_insl 91 #endif 92 93 #ifndef outsb 94 #define outsb logic_outsb 95 #endif 96 97 #ifndef outsw 98 #define outsw logic_outsw 99 #endif 100 101 #ifndef outsl 102 #define outsl logic_outsl 103 #endif 104 105 /* 106 * We reserve 0x4000 bytes for Indirect IO as so far this library is only 107 * used by the HiSilicon LPC Host. If needed, we can reserve a wider IO 108 * area by redefining the macro below. 109 */ 110 #define PIO_INDIRECT_SIZE 0x4000 111 #else 112 #define PIO_INDIRECT_SIZE 0 113 #endif /* CONFIG_INDIRECT_PIO */ 114 #define MMIO_UPPER_LIMIT (IO_SPACE_LIMIT - PIO_INDIRECT_SIZE) 115 116 struct logic_pio_hwaddr *find_io_range_by_fwnode(struct fwnode_handle *fwnode); 117 unsigned long logic_pio_trans_hwaddr(struct fwnode_handle *fwnode, 118 resource_size_t hw_addr, resource_size_t size); 119 int logic_pio_register_range(struct logic_pio_hwaddr *newrange); 120 void logic_pio_unregister_range(struct logic_pio_hwaddr *range); 121 resource_size_t logic_pio_to_hwaddr(unsigned long pio); 122 unsigned long logic_pio_trans_cpuaddr(resource_size_t hw_addr); 123 124 #endif /* __LINUX_LOGIC_PIO_H */ 125