1031e3601SZhichang Yuan // SPDX-License-Identifier: GPL-2.0+ 2031e3601SZhichang Yuan /* 3031e3601SZhichang Yuan * Copyright (C) 2017 HiSilicon Limited, All Rights Reserved. 4031e3601SZhichang Yuan * Author: Gabriele Paoloni <gabriele.paoloni@huawei.com> 5031e3601SZhichang Yuan * Author: Zhichang Yuan <yuanzhichang@hisilicon.com> 6031e3601SZhichang Yuan */ 7031e3601SZhichang Yuan 8031e3601SZhichang Yuan #ifndef __LINUX_LOGIC_PIO_H 9031e3601SZhichang Yuan #define __LINUX_LOGIC_PIO_H 10031e3601SZhichang Yuan 11031e3601SZhichang Yuan #include <linux/fwnode.h> 12031e3601SZhichang Yuan 13031e3601SZhichang Yuan enum { 14031e3601SZhichang Yuan LOGIC_PIO_INDIRECT, /* Indirect IO flag */ 15031e3601SZhichang Yuan LOGIC_PIO_CPU_MMIO, /* Memory-mapped IO flag */ 16031e3601SZhichang Yuan }; 17031e3601SZhichang Yuan 18031e3601SZhichang Yuan struct logic_pio_hwaddr { 19031e3601SZhichang Yuan struct list_head list; 20031e3601SZhichang Yuan struct fwnode_handle *fwnode; 21031e3601SZhichang Yuan resource_size_t hw_start; 22031e3601SZhichang Yuan resource_size_t io_start; 23031e3601SZhichang Yuan resource_size_t size; /* range size populated */ 24031e3601SZhichang Yuan unsigned long flags; 25031e3601SZhichang Yuan 26031e3601SZhichang Yuan void *hostdata; 27031e3601SZhichang Yuan const struct logic_pio_host_ops *ops; 28031e3601SZhichang Yuan }; 29031e3601SZhichang Yuan 30031e3601SZhichang Yuan struct logic_pio_host_ops { 31031e3601SZhichang Yuan u32 (*in)(void *hostdata, unsigned long addr, size_t dwidth); 32031e3601SZhichang Yuan void (*out)(void *hostdata, unsigned long addr, u32 val, 33031e3601SZhichang Yuan size_t dwidth); 34031e3601SZhichang Yuan u32 (*ins)(void *hostdata, unsigned long addr, void *buffer, 35031e3601SZhichang Yuan size_t dwidth, unsigned int count); 36031e3601SZhichang Yuan void (*outs)(void *hostdata, unsigned long addr, const void *buffer, 37031e3601SZhichang Yuan size_t dwidth, unsigned int count); 38031e3601SZhichang Yuan }; 39031e3601SZhichang Yuan 40031e3601SZhichang Yuan #ifdef CONFIG_INDIRECT_PIO 41031e3601SZhichang Yuan u8 logic_inb(unsigned long addr); 42031e3601SZhichang Yuan void logic_outb(u8 value, unsigned long addr); 43031e3601SZhichang Yuan void logic_outw(u16 value, unsigned long addr); 44031e3601SZhichang Yuan void logic_outl(u32 value, unsigned long addr); 45031e3601SZhichang Yuan u16 logic_inw(unsigned long addr); 46031e3601SZhichang Yuan u32 logic_inl(unsigned long addr); 47031e3601SZhichang Yuan void logic_outb(u8 value, unsigned long addr); 48031e3601SZhichang Yuan void logic_outw(u16 value, unsigned long addr); 49031e3601SZhichang Yuan void logic_outl(u32 value, unsigned long addr); 50031e3601SZhichang Yuan void logic_insb(unsigned long addr, void *buffer, unsigned int count); 51031e3601SZhichang Yuan void logic_insl(unsigned long addr, void *buffer, unsigned int count); 52031e3601SZhichang Yuan void logic_insw(unsigned long addr, void *buffer, unsigned int count); 53031e3601SZhichang Yuan void logic_outsb(unsigned long addr, const void *buffer, unsigned int count); 54031e3601SZhichang Yuan void logic_outsw(unsigned long addr, const void *buffer, unsigned int count); 55031e3601SZhichang Yuan void logic_outsl(unsigned long addr, const void *buffer, unsigned int count); 56031e3601SZhichang Yuan 57031e3601SZhichang Yuan #ifndef inb 58031e3601SZhichang Yuan #define inb logic_inb 59031e3601SZhichang Yuan #endif 60031e3601SZhichang Yuan 61031e3601SZhichang Yuan #ifndef inw 62031e3601SZhichang Yuan #define inw logic_inw 63031e3601SZhichang Yuan #endif 64031e3601SZhichang Yuan 65031e3601SZhichang Yuan #ifndef inl 66031e3601SZhichang Yuan #define inl logic_inl 67031e3601SZhichang Yuan #endif 68031e3601SZhichang Yuan 69031e3601SZhichang Yuan #ifndef outb 70031e3601SZhichang Yuan #define outb logic_outb 71031e3601SZhichang Yuan #endif 72031e3601SZhichang Yuan 73031e3601SZhichang Yuan #ifndef outw 74031e3601SZhichang Yuan #define outw logic_outw 75031e3601SZhichang Yuan #endif 76031e3601SZhichang Yuan 77031e3601SZhichang Yuan #ifndef outl 78031e3601SZhichang Yuan #define outl logic_outl 79031e3601SZhichang Yuan #endif 80031e3601SZhichang Yuan 81031e3601SZhichang Yuan #ifndef insb 82031e3601SZhichang Yuan #define insb logic_insb 83031e3601SZhichang Yuan #endif 84031e3601SZhichang Yuan 85031e3601SZhichang Yuan #ifndef insw 86031e3601SZhichang Yuan #define insw logic_insw 87031e3601SZhichang Yuan #endif 88031e3601SZhichang Yuan 89031e3601SZhichang Yuan #ifndef insl 90031e3601SZhichang Yuan #define insl logic_insl 91031e3601SZhichang Yuan #endif 92031e3601SZhichang Yuan 93031e3601SZhichang Yuan #ifndef outsb 94031e3601SZhichang Yuan #define outsb logic_outsb 95031e3601SZhichang Yuan #endif 96031e3601SZhichang Yuan 97031e3601SZhichang Yuan #ifndef outsw 98031e3601SZhichang Yuan #define outsw logic_outsw 99031e3601SZhichang Yuan #endif 100031e3601SZhichang Yuan 101031e3601SZhichang Yuan #ifndef outsl 102031e3601SZhichang Yuan #define outsl logic_outsl 103031e3601SZhichang Yuan #endif 104031e3601SZhichang Yuan 105031e3601SZhichang Yuan /* 106031e3601SZhichang Yuan * We reserve 0x4000 bytes for Indirect IO as so far this library is only 107031e3601SZhichang Yuan * used by the HiSilicon LPC Host. If needed, we can reserve a wider IO 108031e3601SZhichang Yuan * area by redefining the macro below. 109031e3601SZhichang Yuan */ 110031e3601SZhichang Yuan #define PIO_INDIRECT_SIZE 0x4000 111031e3601SZhichang Yuan #else 112b8104fdaSJohn Garry #define PIO_INDIRECT_SIZE 0 113031e3601SZhichang Yuan #endif /* CONFIG_INDIRECT_PIO */ 114b8104fdaSJohn Garry #define MMIO_UPPER_LIMIT (IO_SPACE_LIMIT - PIO_INDIRECT_SIZE) 115031e3601SZhichang Yuan 116031e3601SZhichang Yuan struct logic_pio_hwaddr *find_io_range_by_fwnode(struct fwnode_handle *fwnode); 117031e3601SZhichang Yuan unsigned long logic_pio_trans_hwaddr(struct fwnode_handle *fwnode, 118031e3601SZhichang Yuan resource_size_t hw_addr, resource_size_t size); 119031e3601SZhichang Yuan int logic_pio_register_range(struct logic_pio_hwaddr *newrange); 120b884e2deSJohn Garry void logic_pio_unregister_range(struct logic_pio_hwaddr *range); 121031e3601SZhichang Yuan resource_size_t logic_pio_to_hwaddr(unsigned long pio); 122031e3601SZhichang Yuan unsigned long logic_pio_trans_cpuaddr(resource_size_t hw_addr); 123031e3601SZhichang Yuan 124031e3601SZhichang Yuan #endif /* __LINUX_LOGIC_PIO_H */ 125