Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1516761 > unrolled thread
| Started by | "zhichang.yuan" <yuanzhichang@hisilicon.com> |
|---|---|
| First post | 2016-11-08 04:30 +0100 |
| Last post | 2016-11-11 18:10 +0100 |
| Articles | 17 — 5 participants |
Back to article view | Back to linux.kernel
[PATCH V5 0/3] ARM64 LPC: legacy ISA I/O support "zhichang.yuan" <yuanzhichang@hisilicon.com> - 2016-11-08 04:30 +0100
[PATCH V5 3/3] ARM64 LPC: LPC driver implementation on Hip06 "zhichang.yuan" <yuanzhichang@hisilicon.com> - 2016-11-08 04:50 +0100
Re: [PATCH V5 3/3] ARM64 LPC: LPC driver implementation on Hip06 Arnd Bergmann <arnd@arndb.de> - 2016-11-08 17:30 +0100
RE: [PATCH V5 3/3] ARM64 LPC: LPC driver implementation on Hip06 Gabriele Paoloni <gabriele.paoloni@huawei.com> - 2016-11-09 13:20 +0100
Re: [PATCH V5 3/3] ARM64 LPC: LPC driver implementation on Hip06 Arnd Bergmann <arnd@arndb.de> - 2016-11-09 22:40 +0100
Re: [PATCH V5 3/3] ARM64 LPC: LPC driver implementation on Hip06 "zhichang.yuan" <yuanzhichang@hisilicon.com> - 2016-11-10 07:50 +0100
Re: [PATCH V5 3/3] ARM64 LPC: LPC driver implementation on Hip06 Arnd Bergmann <arnd@arndb.de> - 2016-11-10 10:20 +0100
Re: [PATCH V5 3/3] ARM64 LPC: LPC driver implementation on Hip06 "zhichang.yuan" <yuanzhichang@hisilicon.com> - 2016-11-10 13:40 +0100
RE: [PATCH V5 3/3] ARM64 LPC: LPC driver implementation on Hip06 Gabriele Paoloni <gabriele.paoloni@huawei.com> - 2016-11-10 16:40 +0100
Re: [PATCH V5 3/3] ARM64 LPC: LPC driver implementation on Hip06 Arnd Bergmann <arnd@arndb.de> - 2016-11-10 17:10 +0100
Re: [PATCH V5 3/3] ARM64 LPC: LPC driver implementation on Hip06 "zhichang.yuan" <yuanzhichang@hisilicon.com> - 2016-11-11 11:20 +0100
Re: [PATCH V5 3/3] ARM64 LPC: LPC driver implementation on Hip06 "liviu.dudau@arm.com" <liviu.dudau@arm.com> - 2016-11-11 11:50 +0100
RE: [PATCH V5 3/3] ARM64 LPC: LPC driver implementation on Hip06 Gabriele Paoloni <gabriele.paoloni@huawei.com> - 2016-11-11 14:50 +0100
Re: [PATCH V5 3/3] ARM64 LPC: LPC driver implementation on Hip06 "liviu.dudau@arm.com" <liviu.dudau@arm.com> - 2016-11-11 15:50 +0100
RE: [PATCH V5 3/3] ARM64 LPC: LPC driver implementation on Hip06 Gabriele Paoloni <gabriele.paoloni@huawei.com> - 2016-11-11 17:00 +0100
Re: [PATCH V5 3/3] ARM64 LPC: LPC driver implementation on Hip06 "liviu.dudau@arm.com" <liviu.dudau@arm.com> - 2016-11-11 19:20 +0100
Re: [PATCH V5 3/3] ARM64 LPC: LPC driver implementation on Hip06 "zhichang.yuan" <zhichang.yuan02@gmail.com> - 2016-11-11 18:10 +0100
| From | "zhichang.yuan" <yuanzhichang@hisilicon.com> |
|---|---|
| Date | 2016-11-08 04:30 +0100 |
| Subject | [PATCH V5 0/3] ARM64 LPC: legacy ISA I/O support |
| Message-ID | <sB5gJ-3TL-9@gated-at.bofh.it> |
This patch supports the IPMI-bt device attached to the Low-Pin-Count interface
implemented on Hisilicon Hip06 SoC.
-----------
| LPC host|
| |
-----------
|
_____________V_______________LPC
| |
V V
------------
| BT(ipmi)|
------------
When master accesses those periperals beneath the Hip06 LPC, a specific LPC
driver is needed to make LPC host generate the standard LPC I/O cycles with
the target periperals'I/O port addresses. But on curent arm64 world, there is
no real I/O accesses. All the I/O operations through in/out pair are based on
MMIO which is not satisfied the I/O mechanism on Hip06 LPC.
To solve this issue and keep the relevant existing peripherals' driver
unchanged, this patch set redefines the in/out pair to support both the IO
operations for Hip06 LPC and the original MMIO. The way specific to Hip06 is
named as indirect-IO in this patchset.
Changes from V4:
- Some revises based on the comments from Bjorn, Rob on V4;
- Fixed the compile error on some platforms, such as openrisc;
Changes from V3:
- UART support deferred to a separate patchset; This patchset only support
ipmi device under LPC;
- LPC bus I/O range is fixed to 0 ~ (PCIBIOS_MIN_IO - 1), which is separeted
from PCI/PCIE PIO space;
- Based on Arnd's remarks, removed the ranges property from Hip06 lpc dts and
added a new fixup function, of_isa_indirect_io(), to get the I/O address
directly from LPC dts configurations;
- Support in(w,l)/out(w,l) for Hip06 lpc I/O;
- Decouple the header file dependency on the gerenic io.h by defining in/out
as normal functions in c file;
- removed unused macro definitions in the LPC driver;
Changes from V2:
- Support the PIO retrieval from the linux PIO generated by
pci_address_to_pio. This method replace the 4K PIO reservation in V2;
- Support the flat-tree earlycon;
- Some revises based on Arnd's remarks;
- Make sure the linux PIO range allocated to Hip06 LPC peripherals starts
from non-ZERO;
Changes from V1:
- Support the ACPI LPC device;
- Optimize the dts LPC driver in ISA compatible mode;
- Reserve the IO range below 4K in avoid the possible conflict with PCI host
IO ranges;
- Support the LPC uart and relevant earlycon;
Signed-off-by: Zhichang Yuan <yuanzhichang@hisilicon.com>
zhichang.yuan (3):
ARM64 LPC: Indirect ISA port IO introduced
ARM64 LPC: Add missing range exception for special ISA
ARM64 LPC: LPC driver implementation on Hip06
.../arm/hisilicon/hisilicon-low-pin-count.txt | 31 ++
MAINTAINERS | 8 +
arch/arm64/Kconfig | 6 +
arch/arm64/include/asm/extio.h | 94 ++++
arch/arm64/include/asm/io.h | 35 ++
arch/arm64/kernel/Makefile | 1 +
arch/arm64/kernel/extio.c | 52 +++
drivers/bus/Kconfig | 8 +
drivers/bus/Makefile | 1 +
drivers/bus/hisi_lpc.c | 501 +++++++++++++++++++++
drivers/of/address.c | 56 ++-
drivers/pci/pci.c | 6 +-
include/linux/of_address.h | 17 +
include/linux/pci.h | 8 +
14 files changed, 820 insertions(+), 4 deletions(-)
create mode 100644 Documentation/devicetree/bindings/arm/hisilicon/hisilicon-low-pin-count.txt
create mode 100644 arch/arm64/include/asm/extio.h
create mode 100644 arch/arm64/kernel/extio.c
create mode 100644 drivers/bus/hisi_lpc.c
--
1.9.1
[toc] | [next] | [standalone]
| From | "zhichang.yuan" <yuanzhichang@hisilicon.com> |
|---|---|
| Date | 2016-11-08 04:50 +0100 |
| Subject | [PATCH V5 3/3] ARM64 LPC: LPC driver implementation on Hip06 |
| Message-ID | <sB5A5-408-5@gated-at.bofh.it> |
| In reply to | #1516761 |
On hip06, the accesses to LPC peripherals work in an indirect way. A
corresponding LPC driver configure some registers in LPC master at first, then
the real accesses on LPC slave devices are finished by the LPC master, which
is transparent to LPC driver.
This patch implement the relevant driver for Hip06 LPC. Cooperating with
indirect-IO, ipmi messages is in service without any changes on ipmi driver.
Signed-off-by: zhichang.yuan <yuanzhichang@hisilicon.com>
Signed-off-by: Gabriele Paoloni <gabriele.paoloni@huawei.com>
---
MAINTAINERS | 8 +
drivers/bus/Kconfig | 8 +
drivers/bus/Makefile | 1 +
drivers/bus/hisi_lpc.c | 501 +++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 518 insertions(+)
create mode 100644 drivers/bus/hisi_lpc.c
diff --git a/MAINTAINERS b/MAINTAINERS
index ccae35b..4c7a350 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -5729,6 +5729,14 @@ F: include/uapi/linux/if_hippi.h
F: net/802/hippi.c
F: drivers/net/hippi/
+HISILICON LPC BUS DRIVER
+M: Zhichang Yuan <yuanzhichang@hisilicon.com>
+L: linux-arm-kernel@lists.infradead.org
+W: http://www.hisilicon.com
+S: Maintained
+F: drivers/bus/hisi_lpc.c
+F: Documentation/devicetree/bindings/arm/hisilicon/hisilicon-low-pin-count.txt
+
HISILICON NETWORK SUBSYSTEM DRIVER
M: Yisen Zhuang <yisen.zhuang@huawei.com>
M: Salil Mehta <salil.mehta@huawei.com>
diff --git a/drivers/bus/Kconfig b/drivers/bus/Kconfig
index 7875105..4fa8ab4 100644
--- a/drivers/bus/Kconfig
+++ b/drivers/bus/Kconfig
@@ -64,6 +64,14 @@ config BRCMSTB_GISB_ARB
arbiter. This driver provides timeout and target abort error handling
and internal bus master decoding.
+config HISILICON_LPC
+ bool "Workaround for nonstandard ISA I/O space on Hisilicon Hip0X"
+ depends on (ARCH_HISI || COMPILE_TEST) && ARM64
+ select ARM64_INDIRECT_PIO
+ help
+ Driver needed for some legacy ISA devices attached to Low-Pin-Count
+ on Hisilicon Hip0X SoC.
+
config IMX_WEIM
bool "Freescale EIM DRIVER"
depends on ARCH_MXC
diff --git a/drivers/bus/Makefile b/drivers/bus/Makefile
index c6cfa6b..10b4983 100644
--- a/drivers/bus/Makefile
+++ b/drivers/bus/Makefile
@@ -7,6 +7,7 @@ obj-$(CONFIG_ARM_CCI) += arm-cci.o
obj-$(CONFIG_ARM_CCN) += arm-ccn.o
obj-$(CONFIG_BRCMSTB_GISB_ARB) += brcmstb_gisb.o
+obj-$(CONFIG_HISILICON_LPC) += hisi_lpc.o
obj-$(CONFIG_IMX_WEIM) += imx-weim.o
obj-$(CONFIG_MIPS_CDMM) += mips_cdmm.o
obj-$(CONFIG_MVEBU_MBUS) += mvebu-mbus.o
diff --git a/drivers/bus/hisi_lpc.c b/drivers/bus/hisi_lpc.c
new file mode 100644
index 0000000..47dc081
--- /dev/null
+++ b/drivers/bus/hisi_lpc.c
@@ -0,0 +1,501 @@
+/*
+ * Copyright (C) 2016 Hisilicon Limited, All Rights Reserved.
+ * Author: Zhichang Yuan <yuanzhichang@hisilicon.com>
+ * Author: Zou Rongrong <zourongrong@huawei.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/acpi.h>
+#include <linux/console.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+#include <linux/pci.h>
+#include <linux/serial_8250.h>
+#include <linux/slab.h>
+
+/*
+ * setting this bit means each IO operation will target to different port address;
+ * 0 means repeatly IO operations will be sticked on the same port, such as BT;
+ */
+#define FG_INCRADDR_LPC 0x02
+
+struct lpc_cycle_para {
+ unsigned int opflags;
+ unsigned int csize; /* the data length of each operation */
+};
+
+struct hisilpc_dev {
+ spinlock_t cycle_lock;
+ void __iomem *membase;
+ struct extio_ops io_ops;
+};
+
+
+/* The maximum continous operations*/
+#define LPC_MAX_OPCNT 16
+/* only support IO data unit length is four at maximum */
+#define LPC_MAX_DULEN 4
+#if LPC_MAX_DULEN > LPC_MAX_OPCNT
+#error "LPC.. MAX_DULEN must be not bigger than MAX_OPCNT!"
+#endif
+
+#define LPC_REG_START 0x00 /* start a new LPC cycle */
+#define LPC_REG_OP_STATUS 0x04 /* the current LPC status */
+#define LPC_REG_IRQ_ST 0x08 /* interrupt enable&status */
+#define LPC_REG_OP_LEN 0x10 /* how many LPC cycles each start */
+#define LPC_REG_CMD 0x14 /* command for the required LPC cycle */
+#define LPC_REG_ADDR 0x20 /* LPC target address */
+#define LPC_REG_WDATA 0x24 /* data to be written */
+#define LPC_REG_RDATA 0x28 /* data coming from peer */
+
+
+/* The command register fields*/
+#define LPC_CMD_SAMEADDR 0x08
+#define LPC_CMD_TYPE_IO 0x00
+#define LPC_CMD_WRITE 0x01
+#define LPC_CMD_READ 0x00
+/* the bit attribute is W1C. 1 represents OK. */
+#define LPC_STAT_BYIRQ 0x02
+
+#define LPC_STATUS_IDLE 0x01
+#define LPC_OP_FINISHED 0x02
+
+#define START_WORK 0x01
+
+/*
+ * The minimal waiting interval... Suggest it is not less than 10.
+ * Bigger value probably will lower the performance.
+ */
+#define LPC_NSEC_PERWAIT 100
+/*
+ * The maximum waiting time is about 128us.
+ * The fastest IO cycle time is about 390ns, but the worst case will wait
+ * for extra 256 lpc clocks, so (256 + 13) * 30ns = 8 us. The maximum
+ * burst cycles is 16. So, the maximum waiting time is about 128us under
+ * worst case.
+ * choose 1300 as the maximum.
+ */
+#define LPC_MAX_WAITCNT 1300
+/* About 10us. This is specfic for single IO operation, such as inb. */
+#define LPC_PEROP_WAITCNT 100
+
+
+static inline int wait_lpc_idle(unsigned char *mbase,
+ unsigned int waitcnt) {
+ u32 opstatus;
+
+ while (waitcnt--) {
+ ndelay(LPC_NSEC_PERWAIT);
+ opstatus = readl(mbase + LPC_REG_OP_STATUS);
+ if (opstatus & LPC_STATUS_IDLE)
+ return (opstatus & LPC_OP_FINISHED) ? 0 : (-EIO);
+ }
+ return -ETIME;
+}
+
+/**
+ * hisilpc_target_in - trigger a series of lpc cycles to read required data
+ * from target periperal.
+ * @pdev: pointer to hisi lpc device
+ * @para: some paramerters used to control the lpc I/O operations
+ * @ptaddr: the lpc I/O target port address
+ * @buf: where the read back data is stored
+ * @opcnt: how many I/O operations required in this calling
+ *
+ * only one byte data is read each I/O operation.
+ *
+ * Returns 0 on success, non-zero on fail.
+ *
+ */
+static int hisilpc_target_in(struct hisilpc_dev *lpcdev,
+ struct lpc_cycle_para *para,
+ unsigned long ptaddr, unsigned char *buf,
+ unsigned long opcnt)
+{
+ unsigned long cnt_per_trans;
+ unsigned int cmd_word;
+ unsigned int waitcnt;
+ int ret;
+
+ if (!buf || !opcnt || !para || !para->csize || !lpcdev)
+ return -EINVAL;
+
+ if (opcnt > LPC_MAX_OPCNT)
+ return -EINVAL;
+
+ cmd_word = LPC_CMD_TYPE_IO | LPC_CMD_READ;
+ waitcnt = (LPC_PEROP_WAITCNT);
+ if (!(para->opflags & FG_INCRADDR_LPC)) {
+ cmd_word |= LPC_CMD_SAMEADDR;
+ waitcnt = LPC_MAX_WAITCNT;
+ }
+
+ ret = 0;
+ cnt_per_trans = (para->csize == 1) ? opcnt : para->csize;
+ for (; opcnt && !ret; cnt_per_trans = para->csize) {
+ unsigned long flags;
+
+ /* whole operation must be atomic */
+ spin_lock_irqsave(&lpcdev->cycle_lock, flags);
+
+ writel(cnt_per_trans, lpcdev->membase + LPC_REG_OP_LEN);
+
+ writel(cmd_word, lpcdev->membase + LPC_REG_CMD);
+
+ writel(ptaddr, lpcdev->membase + LPC_REG_ADDR);
+
+ writel(START_WORK, lpcdev->membase + LPC_REG_START);
+
+ /* whether the operation is finished */
+ ret = wait_lpc_idle(lpcdev->membase, waitcnt);
+ if (!ret) {
+ opcnt -= cnt_per_trans;
+ for (; cnt_per_trans--; buf++)
+ *buf = readl(lpcdev->membase + LPC_REG_RDATA);
+ }
+
+ spin_unlock_irqrestore(&lpcdev->cycle_lock, flags);
+ }
+
+ return ret;
+}
+
+/**
+ * hisilpc_target_out - trigger a series of lpc cycles to write required data
+ * to target periperal.
+ * @pdev: pointer to hisi lpc device
+ * @para: some paramerters used to control the lpc I/O operations
+ * @ptaddr: the lpc I/O target port address
+ * @buf: where the data to be written is stored
+ * @opcnt: how many I/O operations required
+ *
+ * only one byte data is read each I/O operation.
+ *
+ * Returns 0 on success, non-zero on fail.
+ *
+ */
+static int hisilpc_target_out(struct hisilpc_dev *lpcdev,
+ struct lpc_cycle_para *para,
+ unsigned long ptaddr,
+ const unsigned char *buf,
+ unsigned long opcnt)
+{
+ unsigned long cnt_per_trans;
+ unsigned int cmd_word;
+ unsigned int waitcnt;
+ int ret;
+
+ if (!buf || !opcnt || !para || !lpcdev)
+ return -EINVAL;
+
+ if (opcnt > LPC_MAX_OPCNT)
+ return -EINVAL;
+ /* default is increasing address */
+ cmd_word = LPC_CMD_TYPE_IO | LPC_CMD_WRITE;
+ waitcnt = (LPC_PEROP_WAITCNT);
+ if (!(para->opflags & FG_INCRADDR_LPC)) {
+ cmd_word |= LPC_CMD_SAMEADDR;
+ waitcnt = LPC_MAX_WAITCNT;
+ }
+
+ ret = 0;
+ cnt_per_trans = (para->csize == 1) ? opcnt : para->csize;
+ for (; opcnt && !ret; cnt_per_trans = para->csize) {
+ unsigned long flags;
+
+ spin_lock_irqsave(&lpcdev->cycle_lock, flags);
+
+ writel(cnt_per_trans, lpcdev->membase + LPC_REG_OP_LEN);
+ opcnt -= cnt_per_trans;
+ for (; cnt_per_trans--; buf++)
+ writel(*buf, lpcdev->membase + LPC_REG_WDATA);
+
+ writel(cmd_word, lpcdev->membase + LPC_REG_CMD);
+
+ writel(ptaddr, lpcdev->membase + LPC_REG_ADDR);
+
+ writel(START_WORK, lpcdev->membase + LPC_REG_START);
+
+ /* whether the operation is finished */
+ ret = wait_lpc_idle(lpcdev->membase, waitcnt);
+
+ spin_unlock_irqrestore(&lpcdev->cycle_lock, flags);
+ }
+
+ return ret;
+}
+
+/**
+ * hisilpc_comm_in - read/input the data from the I/O peripheral through LPC.
+ * @devobj: pointer to the device information relevant to LPC controller.
+ * @ptaddr: the target I/O port address.
+ * @dlen: the data length required to read from the target I/O port.
+ *
+ * when succeed, the data read back is stored in buffer pointed by inbuf.
+ * For inb, return the data read from I/O or -1 when error occur.
+ */
+static u64 hisilpc_comm_in(void *devobj, unsigned long ptaddr, size_t dlen)
+{
+ struct hisilpc_dev *lpcdev;
+ struct lpc_cycle_para iopara;
+ u32 rd_data;
+ unsigned char *newbuf;
+ int ret = 0;
+
+ if (!devobj || !dlen || dlen > LPC_MAX_DULEN || (dlen & (dlen - 1)))
+ return -1;
+
+ /* the local buffer must be enough for one data unit */
+ if (sizeof(rd_data) < dlen)
+ return -1;
+
+ newbuf = (unsigned char *)&rd_data;
+
+ lpcdev = (struct hisilpc_dev *)devobj;
+
+ iopara.opflags = FG_INCRADDR_LPC;
+ iopara.csize = dlen;
+
+ ret = hisilpc_target_in(lpcdev, &iopara, ptaddr, newbuf, dlen);
+ if (ret)
+ return -1;
+
+ return le32_to_cpu(rd_data);
+}
+
+/**
+ * hisilpc_comm_out - write/output the data whose maximal length is four bytes to
+ * the I/O peripheral through LPC.
+ * @devobj: pointer to the device information relevant to LPC controller.
+ * @outval: a value to be outputed from caller, maximum is four bytes.
+ * @ptaddr: the target I/O port address.
+ * @dlen: the data length required writing to the target I/O port .
+ *
+ * This function is corresponding to out(b,w,l) only
+ *
+ */
+static void hisilpc_comm_out(void *devobj, unsigned long ptaddr,
+ u32 outval, size_t dlen)
+{
+ struct hisilpc_dev *lpcdev;
+ struct lpc_cycle_para iopara;
+ const unsigned char *newbuf;
+
+ if (!devobj || !dlen || dlen > LPC_MAX_DULEN)
+ return;
+
+ if (sizeof(outval) < dlen)
+ return;
+
+ outval = cpu_to_le32(outval);
+
+ newbuf = (const unsigned char *)&outval;
+ lpcdev = (struct hisilpc_dev *)devobj;
+
+ iopara.opflags = FG_INCRADDR_LPC;
+ iopara.csize = dlen;
+
+ hisilpc_target_out(lpcdev, &iopara, ptaddr, newbuf, dlen);
+}
+
+/**
+ * hisilpc_comm_ins - read/input the data in buffer to the I/O peripheral
+ * through LPC, it corresponds to ins(b,w,l)
+ * @devobj: pointer to the device information relevant to LPC controller.
+ * @ptaddr: the target I/O port address.
+ * @inbuf: a buffer where read/input data bytes are stored.
+ * @dlen: the data length required writing to the target I/O port.
+ * @count: how many data units whose length is dlen will be read.
+ *
+ */
+static u64 hisilpc_comm_ins(void *devobj, unsigned long ptaddr,
+ void *inbuf, size_t dlen, unsigned int count)
+{
+ struct hisilpc_dev *lpcdev;
+ struct lpc_cycle_para iopara;
+ unsigned char *newbuf;
+ unsigned int loopcnt, cntleft;
+ unsigned int max_perburst;
+ int ret = 0;
+
+ if (!devobj || !inbuf || !count || !dlen ||
+ dlen > LPC_MAX_DULEN || (dlen & (dlen - 1)))
+ return -1;
+
+ iopara.opflags = 0;
+ if (dlen > 1)
+ iopara.opflags |= FG_INCRADDR_LPC;
+ iopara.csize = dlen;
+
+ lpcdev = (struct hisilpc_dev *)devobj;
+ newbuf = (unsigned char *)inbuf;
+ /*
+ * ensure data stream whose length is multiple of dlen to be processed
+ * each IO input
+ */
+ max_perburst = LPC_MAX_OPCNT & (~(dlen - 1));
+ cntleft = count * dlen;
+ do {
+ loopcnt = (cntleft >= max_perburst) ? max_perburst : cntleft;
+ ret = hisilpc_target_in(lpcdev, &iopara, ptaddr, newbuf,
+ loopcnt);
+ if (ret)
+ break;
+ newbuf += loopcnt;
+ cntleft -= loopcnt;
+ } while (cntleft);
+
+ return ret;
+}
+
+/**
+ * hisilpc_comm_outs - write/output the data in buffer to the I/O peripheral
+ * through LPC, it corresponds to outs(b,w,l)
+ * @devobj: pointer to the device information relevant to LPC controller.
+ * @ptaddr: the target I/O port address.
+ * @outbuf: a buffer where write/output data bytes are stored.
+ * @dlen: the data length required writing to the target I/O port .
+ * @count: how many data units whose length is dlen will be written.
+ *
+ */
+static void hisilpc_comm_outs(void *devobj, unsigned long ptaddr,
+ const void *outbuf, size_t dlen, unsigned int count)
+{
+ struct hisilpc_dev *lpcdev;
+ struct lpc_cycle_para iopara;
+ const unsigned char *newbuf;
+ unsigned int loopcnt, cntleft;
+ unsigned int max_perburst;
+ int ret = 0;
+
+ if (!devobj || !outbuf || !count || !dlen ||
+ dlen > LPC_MAX_DULEN || (dlen & (dlen - 1)))
+ return;
+
+ iopara.opflags = 0;
+ if (dlen > 1)
+ iopara.opflags |= FG_INCRADDR_LPC;
+ iopara.csize = dlen;
+
+ lpcdev = (struct hisilpc_dev *)devobj;
+ newbuf = (unsigned char *)outbuf;
+ /*
+ * ensure data stream whose lenght is multiple of dlen to be processed
+ * each IO input
+ */
+ max_perburst = LPC_MAX_OPCNT & (~(dlen - 1));
+ cntleft = count * dlen;
+ do {
+ loopcnt = (cntleft >= max_perburst) ? max_perburst : cntleft;
+ ret = hisilpc_target_out(lpcdev, &iopara, ptaddr, newbuf,
+ loopcnt);
+ if (ret)
+ break;
+ newbuf += loopcnt;
+ cntleft -= loopcnt;
+ } while (cntleft);
+}
+
+/**
+ * hisilpc_probe - the probe callback function for hisi lpc device,
+ * will finish all the intialization.
+ * @pdev: the platform device corresponding to hisi lpc
+ *
+ * Returns 0 on success, non-zero on fail.
+ *
+ */
+static int hisilpc_probe(struct platform_device *pdev)
+{
+ struct resource *iores;
+ struct hisilpc_dev *lpcdev;
+ int ret;
+
+ dev_info(&pdev->dev, "probing hslpc...\n");
+
+ lpcdev = devm_kzalloc(&pdev->dev,
+ sizeof(struct hisilpc_dev), GFP_KERNEL);
+ if (!lpcdev)
+ return -ENOMEM;
+
+ spin_lock_init(&lpcdev->cycle_lock);
+ iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ lpcdev->membase = devm_ioremap_resource(&pdev->dev, iores);
+ if (IS_ERR(lpcdev->membase)) {
+ dev_err(&pdev->dev, "ioremap memory FAIL(%d)!\n",
+ PTR_ERR(lpcdev->membase));
+ return PTR_ERR(lpcdev->membase);
+ }
+ /*
+ * The first PCIBIOS_MIN_IO is reserved specifically for indirectIO.
+ * It will separate indirectIO range from pci host bridge to
+ * avoid the possible PIO conflict.
+ * Set the indirectIO range directly here.
+ */
+ lpcdev->io_ops.start = 0;
+ lpcdev->io_ops.end = PCIBIOS_MIN_IO - 1;
+ lpcdev->io_ops.devpara = lpcdev;
+ lpcdev->io_ops.pfin = hisilpc_comm_in;
+ lpcdev->io_ops.pfout = hisilpc_comm_out;
+ lpcdev->io_ops.pfins = hisilpc_comm_ins;
+ lpcdev->io_ops.pfouts = hisilpc_comm_outs;
+
+ platform_set_drvdata(pdev, lpcdev);
+
+ arm64_set_extops(&lpcdev->io_ops);
+
+ /*
+ * The children scanning is only for dts mode. For ACPI children,
+ * the corresponding devices had be created during acpi scanning.
+ */
+ ret = 0;
+ if (!has_acpi_companion(&pdev->dev))
+ ret = of_platform_populate(pdev->dev.of_node, NULL, NULL,
+ &pdev->dev);
+
+ if (!ret)
+ dev_info(&pdev->dev, "hslpc end probing. range[0x%lx - %lx]\n",
+ arm64_extio_ops->start, arm64_extio_ops->end);
+ else
+ dev_info(&pdev->dev, "hslpc probing is fail(%d)\n", ret);
+
+ return ret;
+}
+
+static const struct of_device_id hisilpc_of_match[] = {
+ {
+ .compatible = "hisilicon,hip06-lpc",
+ },
+ {},
+};
+
+static const struct acpi_device_id hisilpc_acpi_match[] = {
+ {"HISI0191", },
+ {},
+};
+
+static struct platform_driver hisilpc_driver = {
+ .driver = {
+ .name = "hisi_lpc",
+ .of_match_table = hisilpc_of_match,
+ .acpi_match_table = hisilpc_acpi_match,
+ },
+ .probe = hisilpc_probe,
+};
+
+
+builtin_platform_driver(hisilpc_driver);
--
1.9.1
[toc] | [prev] | [next] | [standalone]
| From | Arnd Bergmann <arnd@arndb.de> |
|---|---|
| Date | 2016-11-08 17:30 +0100 |
| Subject | Re: [PATCH V5 3/3] ARM64 LPC: LPC driver implementation on Hip06 |
| Message-ID | <sBhrA-3gP-37@gated-at.bofh.it> |
| In reply to | #1516766 |
On Tuesday, November 8, 2016 11:47:09 AM CET zhichang.yuan wrote: > + /* > + * The first PCIBIOS_MIN_IO is reserved specifically for indirectIO. > + * It will separate indirectIO range from pci host bridge to > + * avoid the possible PIO conflict. > + * Set the indirectIO range directly here. > + */ > + lpcdev->io_ops.start = 0; > + lpcdev->io_ops.end = PCIBIOS_MIN_IO - 1; > + lpcdev->io_ops.devpara = lpcdev; > + lpcdev->io_ops.pfin = hisilpc_comm_in; > + lpcdev->io_ops.pfout = hisilpc_comm_out; > + lpcdev->io_ops.pfins = hisilpc_comm_ins; > + lpcdev->io_ops.pfouts = hisilpc_comm_outs; I have to look at patch 2 in more detail again, after missing a few review rounds. I'm still a bit skeptical about hardcoding a logical I/O port range here, and would hope that we can just go through the same assignment of logical port ranges that we have for PCI buses, decoupling the bus addresses from the linux-internal ones. Arnd
[toc] | [prev] | [next] | [standalone]
| From | Gabriele Paoloni <gabriele.paoloni@huawei.com> |
|---|---|
| Date | 2016-11-09 13:20 +0100 |
| Subject | RE: [PATCH V5 3/3] ARM64 LPC: LPC driver implementation on Hip06 |
| Message-ID | <sBA1b-7dw-1@gated-at.bofh.it> |
| In reply to | #1517358 |
Hi Arnd > -----Original Message----- > From: Arnd Bergmann [mailto:arnd@arndb.de] > Sent: 08 November 2016 16:25 > To: Yuanzhichang > Cc: catalin.marinas@arm.com; will.deacon@arm.com; robh+dt@kernel.org; > bhelgaas@google.com; mark.rutland@arm.com; olof@lixom.net; linux-arm- > kernel@lists.infradead.org; lorenzo.pieralisi@arm.com; linux- > kernel@vger.kernel.org; Linuxarm; devicetree@vger.kernel.org; linux- > pci@vger.kernel.org; linux-serial@vger.kernel.org; minyard@acm.org; > benh@kernel.crashing.org; liviu.dudau@arm.com; zourongrong@gmail.com; > John Garry; Gabriele Paoloni; zhichang.yuan02@gmail.com; > kantyzc@163.com; xuwei (O) > Subject: Re: [PATCH V5 3/3] ARM64 LPC: LPC driver implementation on > Hip06 > > On Tuesday, November 8, 2016 11:47:09 AM CET zhichang.yuan wrote: > > + /* > > + * The first PCIBIOS_MIN_IO is reserved specifically for > indirectIO. > > + * It will separate indirectIO range from pci host bridge to > > + * avoid the possible PIO conflict. > > + * Set the indirectIO range directly here. > > + */ > > + lpcdev->io_ops.start = 0; > > + lpcdev->io_ops.end = PCIBIOS_MIN_IO - 1; > > + lpcdev->io_ops.devpara = lpcdev; > > + lpcdev->io_ops.pfin = hisilpc_comm_in; > > + lpcdev->io_ops.pfout = hisilpc_comm_out; > > + lpcdev->io_ops.pfins = hisilpc_comm_ins; > > + lpcdev->io_ops.pfouts = hisilpc_comm_outs; > > I have to look at patch 2 in more detail again, after missing a few > review > rounds. I'm still a bit skeptical about hardcoding a logical I/O port > range here, and would hope that we can just go through the same > assignment of logical port ranges that we have for PCI buses, > decoupling > the bus addresses from the linux-internal ones. The point here is that we want to avoid any conflict/overlap between the LPC I/O space and the PCI I/O space. With the assignment above we make sure that LPC never interfere with PCI I/O space. Thanks Gab > > Arnd
[toc] | [prev] | [next] | [standalone]
| From | Arnd Bergmann <arnd@arndb.de> |
|---|---|
| Date | 2016-11-09 22:40 +0100 |
| Subject | Re: [PATCH V5 3/3] ARM64 LPC: LPC driver implementation on Hip06 |
| Message-ID | <sBIL7-4mX-3@gated-at.bofh.it> |
| In reply to | #1518109 |
On Wednesday, November 9, 2016 12:10:43 PM CET Gabriele Paoloni wrote: > > On Tuesday, November 8, 2016 11:47:09 AM CET zhichang.yuan wrote: > > > + /* > > > + * The first PCIBIOS_MIN_IO is reserved specifically for > > indirectIO. > > > + * It will separate indirectIO range from pci host bridge to > > > + * avoid the possible PIO conflict. > > > + * Set the indirectIO range directly here. > > > + */ > > > + lpcdev->io_ops.start = 0; > > > + lpcdev->io_ops.end = PCIBIOS_MIN_IO - 1; > > > + lpcdev->io_ops.devpara = lpcdev; > > > + lpcdev->io_ops.pfin = hisilpc_comm_in; > > > + lpcdev->io_ops.pfout = hisilpc_comm_out; > > > + lpcdev->io_ops.pfins = hisilpc_comm_ins; > > > + lpcdev->io_ops.pfouts = hisilpc_comm_outs; > > > > I have to look at patch 2 in more detail again, after missing a few > > review > > rounds. I'm still a bit skeptical about hardcoding a logical I/O port > > range here, and would hope that we can just go through the same > > assignment of logical port ranges that we have for PCI buses, > > decoupling > > the bus addresses from the linux-internal ones. > > The point here is that we want to avoid any conflict/overlap between > the LPC I/O space and the PCI I/O space. With the assignment above > we make sure that LPC never interfere with PCI I/O space. But we already abstract the PCI I/O space using dynamic registration. There is no need to hardcode the logical address for ISA, though I think we can hardcode the bus address to start at zero here. Arnd
[toc] | [prev] | [next] | [standalone]
| From | "zhichang.yuan" <yuanzhichang@hisilicon.com> |
|---|---|
| Date | 2016-11-10 07:50 +0100 |
| Subject | Re: [PATCH V5 3/3] ARM64 LPC: LPC driver implementation on Hip06 |
| Message-ID | <sBRlo-1Xo-3@gated-at.bofh.it> |
| In reply to | #1518505 |
Hi, Arnd, On 2016/11/10 5:34, Arnd Bergmann wrote: > On Wednesday, November 9, 2016 12:10:43 PM CET Gabriele Paoloni wrote: >>> On Tuesday, November 8, 2016 11:47:09 AM CET zhichang.yuan wrote: >>>> + /* >>>> + * The first PCIBIOS_MIN_IO is reserved specifically for >>> indirectIO. >>>> + * It will separate indirectIO range from pci host bridge to >>>> + * avoid the possible PIO conflict. >>>> + * Set the indirectIO range directly here. >>>> + */ >>>> + lpcdev->io_ops.start = 0; >>>> + lpcdev->io_ops.end = PCIBIOS_MIN_IO - 1; >>>> + lpcdev->io_ops.devpara = lpcdev; >>>> + lpcdev->io_ops.pfin = hisilpc_comm_in; >>>> + lpcdev->io_ops.pfout = hisilpc_comm_out; >>>> + lpcdev->io_ops.pfins = hisilpc_comm_ins; >>>> + lpcdev->io_ops.pfouts = hisilpc_comm_outs; >>> >>> I have to look at patch 2 in more detail again, after missing a few >>> review >>> rounds. I'm still a bit skeptical about hardcoding a logical I/O port >>> range here, and would hope that we can just go through the same >>> assignment of logical port ranges that we have for PCI buses, >>> decoupling >>> the bus addresses from the linux-internal ones. >> >> The point here is that we want to avoid any conflict/overlap between >> the LPC I/O space and the PCI I/O space. With the assignment above >> we make sure that LPC never interfere with PCI I/O space. > > But we already abstract the PCI I/O space using dynamic registration. > There is no need to hardcode the logical address for ISA, though > I think we can hardcode the bus address to start at zero here. Do you means that we can pick up the maximal I/O address from all children's device resources?? Thanks, Zhichang > > Arnd > > . >
[toc] | [prev] | [next] | [standalone]
| From | Arnd Bergmann <arnd@arndb.de> |
|---|---|
| Date | 2016-11-10 10:20 +0100 |
| Subject | Re: [PATCH V5 3/3] ARM64 LPC: LPC driver implementation on Hip06 |
| Message-ID | <sBTGx-3Ex-25@gated-at.bofh.it> |
| In reply to | #1518711 |
On Thursday, November 10, 2016 2:40:26 PM CET zhichang.yuan wrote:
> On 2016/11/10 5:34, Arnd Bergmann wrote:
> > On Wednesday, November 9, 2016 12:10:43 PM CET Gabriele Paoloni wrote:
> >>> On Tuesday, November 8, 2016 11:47:09 AM CET zhichang.yuan wrote:
> >>>> + /*
> >>>> + * The first PCIBIOS_MIN_IO is reserved specifically for
> >>> indirectIO.
> >>>> + * It will separate indirectIO range from pci host bridge to
> >>>> + * avoid the possible PIO conflict.
> >>>> + * Set the indirectIO range directly here.
> >>>> + */
> >>>> + lpcdev->io_ops.start = 0;
> >>>> + lpcdev->io_ops.end = PCIBIOS_MIN_IO - 1;
> >>>> + lpcdev->io_ops.devpara = lpcdev;
> >>>> + lpcdev->io_ops.pfin = hisilpc_comm_in;
> >>>> + lpcdev->io_ops.pfout = hisilpc_comm_out;
> >>>> + lpcdev->io_ops.pfins = hisilpc_comm_ins;
> >>>> + lpcdev->io_ops.pfouts = hisilpc_comm_outs;
> >>>
> >>> I have to look at patch 2 in more detail again, after missing a few
> >>> review
> >>> rounds. I'm still a bit skeptical about hardcoding a logical I/O port
> >>> range here, and would hope that we can just go through the same
> >>> assignment of logical port ranges that we have for PCI buses,
> >>> decoupling
> >>> the bus addresses from the linux-internal ones.
> >>
> >> The point here is that we want to avoid any conflict/overlap between
> >> the LPC I/O space and the PCI I/O space. With the assignment above
> >> we make sure that LPC never interfere with PCI I/O space.
> >
> > But we already abstract the PCI I/O space using dynamic registration.
> > There is no need to hardcode the logical address for ISA, though
> > I think we can hardcode the bus address to start at zero here.
>
> Do you means that we can pick up the maximal I/O address from all children's
> device resources??
The driver should not look at the resources of its children, just
register a range of addresses dynamically, as I suggested in an
earlier review.
Your current version has
if (arm64_extio_ops->pfout) \
arm64_extio_ops->pfout(arm64_extio_ops->devpara,\
addr, value, sizeof(type)); \
Instead, just subtract the start of the range from the logical
port number to transform it back into a bus-local port number:
if (arm64_extio_ops->pfout) \
arm64_extio_ops->pfout(arm64_extio_ops->devpara,\
addr - arm64_extio_ops->start, value, sizeof(type)); \
We know that the ISA/LPC bus can only have up to 65536 ports,
so you can register all of those, or possibly limit it further to
1024 or 4096 ports, whichever matches the bus implementation.
Arnd
[toc] | [prev] | [next] | [standalone]
| From | "zhichang.yuan" <yuanzhichang@hisilicon.com> |
|---|---|
| Date | 2016-11-10 13:40 +0100 |
| Subject | Re: [PATCH V5 3/3] ARM64 LPC: LPC driver implementation on Hip06 |
| Message-ID | <sBWO5-6e8-13@gated-at.bofh.it> |
| In reply to | #1518771 |
Hi, Arnd, On 2016/11/10 17:12, Arnd Bergmann wrote: > On Thursday, November 10, 2016 2:40:26 PM CET zhichang.yuan wrote: >> On 2016/11/10 5:34, Arnd Bergmann wrote: >>> On Wednesday, November 9, 2016 12:10:43 PM CET Gabriele Paoloni wrote: >>>>> On Tuesday, November 8, 2016 11:47:09 AM CET zhichang.yuan wrote: >>>>>> + /* >>>>>> + * The first PCIBIOS_MIN_IO is reserved specifically for >>>>> indirectIO. >>>>>> + * It will separate indirectIO range from pci host bridge to >>>>>> + * avoid the possible PIO conflict. >>>>>> + * Set the indirectIO range directly here. >>>>>> + */ >>>>>> + lpcdev->io_ops.start = 0; >>>>>> + lpcdev->io_ops.end = PCIBIOS_MIN_IO - 1; >>>>>> + lpcdev->io_ops.devpara = lpcdev; >>>>>> + lpcdev->io_ops.pfin = hisilpc_comm_in; >>>>>> + lpcdev->io_ops.pfout = hisilpc_comm_out; >>>>>> + lpcdev->io_ops.pfins = hisilpc_comm_ins; >>>>>> + lpcdev->io_ops.pfouts = hisilpc_comm_outs; >>>>> >>>>> I have to look at patch 2 in more detail again, after missing a few >>>>> review >>>>> rounds. I'm still a bit skeptical about hardcoding a logical I/O port >>>>> range here, and would hope that we can just go through the same >>>>> assignment of logical port ranges that we have for PCI buses, >>>>> decoupling >>>>> the bus addresses from the linux-internal ones. >>>> >>>> The point here is that we want to avoid any conflict/overlap between >>>> the LPC I/O space and the PCI I/O space. With the assignment above >>>> we make sure that LPC never interfere with PCI I/O space. >>> >>> But we already abstract the PCI I/O space using dynamic registration. >>> There is no need to hardcode the logical address for ISA, though >>> I think we can hardcode the bus address to start at zero here. >> >> Do you means that we can pick up the maximal I/O address from all children's >> device resources?? > > The driver should not look at the resources of its children, just > register a range of addresses dynamically, as I suggested in an > earlier review. > Sorry! I can't catch your idea yet:( When to register the I/O range? Is it done just after the successfully of_translate_address() during the children scanning? If yes, when a child is scanning, there is no range data in arm64_extio_ops. The addr_is_indirect_io() calling in of_get_isa_indirect_io() don't need. All we can check is just whether the address to be translated is IO and is under a parent device which has no 'ranges' property. > > Your current version has > > if (arm64_extio_ops->pfout) \ > arm64_extio_ops->pfout(arm64_extio_ops->devpara,\ > addr, value, sizeof(type)); \ > > Instead, just subtract the start of the range from the logical > port number to transform it back into a bus-local port number: > > if (arm64_extio_ops->pfout) \ > arm64_extio_ops->pfout(arm64_extio_ops->devpara,\ > addr - arm64_extio_ops->start, value, sizeof(type)); \ > I think there is some information needed sync. In the old patch-set, we don't bypass the pci_address_to_pio() after successfully of_translate_address(). In this way, we don't need to reserve any PIO space for our LPC since the logical port are from the same mapping algorithm. Based on this way, the port number in the device resource is logical one, then we need to subtract the start of the resource to get back the bus-local port. From V3, we don't apply the mapping based on pci_address_to_pio(), the of_translate_address() return the bus-local port directly and store into relevant device resource. So, in the current arm64_extio_ops->pfout(), the reverse translation don't need anymore. The input "addr" is bus-local port now. Thanks, Zhichang > We know that the ISA/LPC bus can only have up to 65536 ports, > so you can register all of those, or possibly limit it further to > 1024 or 4096 ports, whichever matches the bus implementation. > > Arnd > > . >
[toc] | [prev] | [next] | [standalone]
| From | Gabriele Paoloni <gabriele.paoloni@huawei.com> |
|---|---|
| Date | 2016-11-10 16:40 +0100 |
| Subject | RE: [PATCH V5 3/3] ARM64 LPC: LPC driver implementation on Hip06 |
| Message-ID | <sBZCi-83k-39@gated-at.bofh.it> |
| In reply to | #1518771 |
Hi Arnd > -----Original Message----- > From: Arnd Bergmann [mailto:arnd@arndb.de] > Sent: 10 November 2016 09:12 > To: linux-arm-kernel@lists.infradead.org > Cc: Yuanzhichang; mark.rutland@arm.com; devicetree@vger.kernel.org; > lorenzo.pieralisi@arm.com; Gabriele Paoloni; minyard@acm.org; linux- > pci@vger.kernel.org; benh@kernel.crashing.org; John Garry; > will.deacon@arm.com; linux-kernel@vger.kernel.org; xuwei (O); Linuxarm; > zourongrong@gmail.com; robh+dt@kernel.org; kantyzc@163.com; linux- > serial@vger.kernel.org; catalin.marinas@arm.com; olof@lixom.net; > liviu.dudau@arm.com; bhelgaas@google.com; zhichang.yuan02@gmail.com > Subject: Re: [PATCH V5 3/3] ARM64 LPC: LPC driver implementation on > Hip06 > > On Thursday, November 10, 2016 2:40:26 PM CET zhichang.yuan wrote: > > On 2016/11/10 5:34, Arnd Bergmann wrote: > > > On Wednesday, November 9, 2016 12:10:43 PM CET Gabriele Paoloni > wrote: > > >>> On Tuesday, November 8, 2016 11:47:09 AM CET zhichang.yuan wrote: > > >>>> + /* > > >>>> + * The first PCIBIOS_MIN_IO is reserved specifically for > > >>> indirectIO. > > >>>> + * It will separate indirectIO range from pci host > bridge to > > >>>> + * avoid the possible PIO conflict. > > >>>> + * Set the indirectIO range directly here. > > >>>> + */ > > >>>> + lpcdev->io_ops.start = 0; > > >>>> + lpcdev->io_ops.end = PCIBIOS_MIN_IO - 1; > > >>>> + lpcdev->io_ops.devpara = lpcdev; > > >>>> + lpcdev->io_ops.pfin = hisilpc_comm_in; > > >>>> + lpcdev->io_ops.pfout = hisilpc_comm_out; > > >>>> + lpcdev->io_ops.pfins = hisilpc_comm_ins; > > >>>> + lpcdev->io_ops.pfouts = hisilpc_comm_outs; > > >>> > > >>> I have to look at patch 2 in more detail again, after missing a > few > > >>> review > > >>> rounds. I'm still a bit skeptical about hardcoding a logical I/O > port > > >>> range here, and would hope that we can just go through the same > > >>> assignment of logical port ranges that we have for PCI buses, > > >>> decoupling > > >>> the bus addresses from the linux-internal ones. > > >> > > >> The point here is that we want to avoid any conflict/overlap > between > > >> the LPC I/O space and the PCI I/O space. With the assignment above > > >> we make sure that LPC never interfere with PCI I/O space. > > > > > > But we already abstract the PCI I/O space using dynamic > registration. > > > There is no need to hardcode the logical address for ISA, though > > > I think we can hardcode the bus address to start at zero here. > > > > Do you means that we can pick up the maximal I/O address from all > children's > > device resources?? > > The driver should not look at the resources of its children, just > register a range of addresses dynamically, as I suggested in an > earlier review. Where should we get the range from? For LPC we know that it is going Work on anything that is not used by PCI I/O space, and this is why we use [0, PCIBIOS_MIN_IO] > > > Your current version has > > if (arm64_extio_ops->pfout) \ > arm64_extio_ops->pfout(arm64_extio_ops->devpara,\ > addr, value, sizeof(type)); \ > > Instead, just subtract the start of the range from the logical > port number to transform it back into a bus-local port number: These accessors do not operate on IO tokens: If (arm64_extio_ops->start > addr || arm64_extio_ops->end < addr) addr is not going to be an I/O token; in fact patch 2/3 imposes that the I/O tokens will start at PCIBIOS_MIN_IO. So from 0 to PCIBIOS_MIN_IO we have free physical addresses that the accessors can operate on. Thanks Gab > > if (arm64_extio_ops->pfout) \ > arm64_extio_ops->pfout(arm64_extio_ops->devpara,\ > addr - arm64_extio_ops->start, value, > sizeof(type)); \ > > We know that the ISA/LPC bus can only have up to 65536 ports, > so you can register all of those, or possibly limit it further to > 1024 or 4096 ports, whichever matches the bus implementation. > > Arnd
[toc] | [prev] | [next] | [standalone]
| From | Arnd Bergmann <arnd@arndb.de> |
|---|---|
| Date | 2016-11-10 17:10 +0100 |
| Subject | Re: [PATCH V5 3/3] ARM64 LPC: LPC driver implementation on Hip06 |
| Message-ID | <sC05k-8tv-31@gated-at.bofh.it> |
| In reply to | #1519064 |
On Thursday, November 10, 2016 3:36:49 PM CET Gabriele Paoloni wrote: > > Where should we get the range from? For LPC we know that it is going > Work on anything that is not used by PCI I/O space, and this is > why we use [0, PCIBIOS_MIN_IO] It should be allocated the same way we allocate PCI config space segments. This is currently done with the io_range list in drivers/pci/pci.c, which isn't perfect but could be extended if necessary. Based on what others commented here, I'd rather make the differences between ISA/LPC and PCI I/O ranges smaller than larger. > > Your current version has > > > > if (arm64_extio_ops->pfout) \ > > arm64_extio_ops->pfout(arm64_extio_ops->devpara,\ > > addr, value, sizeof(type)); \ > > > > Instead, just subtract the start of the range from the logical > > port number to transform it back into a bus-local port number: > > These accessors do not operate on IO tokens: > > If (arm64_extio_ops->start > addr || arm64_extio_ops->end < addr) > addr is not going to be an I/O token; in fact patch 2/3 imposes that > the I/O tokens will start at PCIBIOS_MIN_IO. So from 0 to PCIBIOS_MIN_IO > we have free physical addresses that the accessors can operate on. Ah, I missed that part. I'd rather not use PCIBIOS_MIN_IO to refer to the logical I/O tokens, the purpose of that macro is really meant for allocating PCI I/O port numbers within the address space of one bus. Note that it's equally likely that whichever next platform needs non-mapped I/O access like this actually needs them for PCI I/O space, and that will use it on addresses registered to a PCI host bridge. If we separate the two steps: a) assign a range of logical I/O port numbers to a bus b) register a set of helpers for redirecting logical I/O port to a helper function then I think the code will get cleaner and more flexible. It should actually then be able to replace the powerpc specific implementation. Arnd
[toc] | [prev] | [next] | [standalone]
| From | "zhichang.yuan" <yuanzhichang@hisilicon.com> |
|---|---|
| Date | 2016-11-11 11:20 +0100 |
| Subject | Re: [PATCH V5 3/3] ARM64 LPC: LPC driver implementation on Hip06 |
| Message-ID | <sCh6a-32E-19@gated-at.bofh.it> |
| In reply to | #1519091 |
Hi, Arnd, On 2016/11/11 0:07, Arnd Bergmann wrote: > On Thursday, November 10, 2016 3:36:49 PM CET Gabriele Paoloni wrote: >> >> Where should we get the range from? For LPC we know that it is going >> Work on anything that is not used by PCI I/O space, and this is >> why we use [0, PCIBIOS_MIN_IO] > > It should be allocated the same way we allocate PCI config space > segments. This is currently done with the io_range list in > drivers/pci/pci.c, which isn't perfect but could be extended > if necessary. Based on what others commented here, I'd rather > make the differences between ISA/LPC and PCI I/O ranges smaller > than larger. > >>> Your current version has >>> >>> if (arm64_extio_ops->pfout) \ >>> arm64_extio_ops->pfout(arm64_extio_ops->devpara,\ >>> addr, value, sizeof(type)); \ >>> >>> Instead, just subtract the start of the range from the logical >>> port number to transform it back into a bus-local port number: >> >> These accessors do not operate on IO tokens: >> >> If (arm64_extio_ops->start > addr || arm64_extio_ops->end < addr) >> addr is not going to be an I/O token; in fact patch 2/3 imposes that >> the I/O tokens will start at PCIBIOS_MIN_IO. So from 0 to PCIBIOS_MIN_IO >> we have free physical addresses that the accessors can operate on. > > Ah, I missed that part. I'd rather not use PCIBIOS_MIN_IO to refer to > the logical I/O tokens, the purpose of that macro is really meant > for allocating PCI I/O port numbers within the address space of > one bus. > > Note that it's equally likely that whichever next platform needs > non-mapped I/O access like this actually needs them for PCI I/O space, > and that will use it on addresses registered to a PCI host bridge. > > If we separate the two steps: > > a) assign a range of logical I/O port numbers to a bus > b) register a set of helpers for redirecting logical I/O > port to a helper function > It seems that we need to add a new bus and the corresponding resource management which can also cover current PCI pio mapping, is it right? Thanks, Zhichang > then I think the code will get cleaner and more flexible. > It should actually then be able to replace the powerpc > specific implementation. > > Arnd > > . >
[toc] | [prev] | [next] | [standalone]
| From | "liviu.dudau@arm.com" <liviu.dudau@arm.com> |
|---|---|
| Date | 2016-11-11 11:50 +0100 |
| Subject | Re: [PATCH V5 3/3] ARM64 LPC: LPC driver implementation on Hip06 |
| Message-ID | <sChzb-3cb-7@gated-at.bofh.it> |
| In reply to | #1519091 |
Hi Arnd,
On Thu, Nov 10, 2016 at 05:07:21PM +0100, Arnd Bergmann wrote:
> On Thursday, November 10, 2016 3:36:49 PM CET Gabriele Paoloni wrote:
> >
> > Where should we get the range from? For LPC we know that it is going
> > Work on anything that is not used by PCI I/O space, and this is
> > why we use [0, PCIBIOS_MIN_IO]
>
> It should be allocated the same way we allocate PCI config space
> segments. This is currently done with the io_range list in
> drivers/pci/pci.c, which isn't perfect but could be extended
> if necessary. Based on what others commented here, I'd rather
> make the differences between ISA/LPC and PCI I/O ranges smaller
> than larger.
>
> > > Your current version has
> > >
> > > if (arm64_extio_ops->pfout) \
> > > arm64_extio_ops->pfout(arm64_extio_ops->devpara,\
> > > addr, value, sizeof(type)); \
> > >
> > > Instead, just subtract the start of the range from the logical
> > > port number to transform it back into a bus-local port number:
> >
> > These accessors do not operate on IO tokens:
> >
> > If (arm64_extio_ops->start > addr || arm64_extio_ops->end < addr)
> > addr is not going to be an I/O token; in fact patch 2/3 imposes that
> > the I/O tokens will start at PCIBIOS_MIN_IO. So from 0 to PCIBIOS_MIN_IO
> > we have free physical addresses that the accessors can operate on.
>
> Ah, I missed that part. I'd rather not use PCIBIOS_MIN_IO to refer to
> the logical I/O tokens, the purpose of that macro is really meant
> for allocating PCI I/O port numbers within the address space of
> one bus.
>
> Note that it's equally likely that whichever next platform needs
> non-mapped I/O access like this actually needs them for PCI I/O space,
> and that will use it on addresses registered to a PCI host bridge.
>
> If we separate the two steps:
>
> a) assign a range of logical I/O port numbers to a bus
Except that currently when we add ranges to io_range_list we don't have
a bus number yet, because the parsing happens before the host bridge
has been created. Maybe register_io_range() can take a bus number as an
argument, but I'm not sure how we are going to use that in pci_pio_to_address()
or pci_address_to_pio().
Best regards,
Liviu
> b) register a set of helpers for redirecting logical I/O
> port to a helper function
>
> then I think the code will get cleaner and more flexible.
> It should actually then be able to replace the powerpc
> specific implementation.
>
> Arnd
--
====================
| I would like to |
| fix the world, |
| but they're not |
| giving me the |
\ source code! /
---------------
¯\_(ツ)_/¯
[toc] | [prev] | [next] | [standalone]
| From | Gabriele Paoloni <gabriele.paoloni@huawei.com> |
|---|---|
| Date | 2016-11-11 14:50 +0100 |
| Subject | RE: [PATCH V5 3/3] ARM64 LPC: LPC driver implementation on Hip06 |
| Message-ID | <sCkno-4Wl-27@gated-at.bofh.it> |
| In reply to | #1519091 |
Hi Arnd > -----Original Message----- > From: Arnd Bergmann [mailto:arnd@arndb.de] > Sent: 10 November 2016 16:07 > To: Gabriele Paoloni > Cc: linux-arm-kernel@lists.infradead.org; Yuanzhichang; > mark.rutland@arm.com; devicetree@vger.kernel.org; > lorenzo.pieralisi@arm.com; minyard@acm.org; linux-pci@vger.kernel.org; > benh@kernel.crashing.org; John Garry; will.deacon@arm.com; linux- > kernel@vger.kernel.org; xuwei (O); Linuxarm; zourongrong@gmail.com; > robh+dt@kernel.org; kantyzc@163.com; linux-serial@vger.kernel.org; > catalin.marinas@arm.com; olof@lixom.net; liviu.dudau@arm.com; > bhelgaas@googl e.com; zhichang.yuan02@gmail.com > Subject: Re: [PATCH V5 3/3] ARM64 LPC: LPC driver implementation on > Hip06 > > On Thursday, November 10, 2016 3:36:49 PM CET Gabriele Paoloni wrote: > > > > Where should we get the range from? For LPC we know that it is going > > Work on anything that is not used by PCI I/O space, and this is > > why we use [0, PCIBIOS_MIN_IO] > > It should be allocated the same way we allocate PCI config space > segments. This is currently done with the io_range list in > drivers/pci/pci.c, which isn't perfect but could be extended > if necessary. Based on what others commented here, I'd rather > make the differences between ISA/LPC and PCI I/O ranges smaller > than larger. I am not sure this would make sense... IMHO all the mechanism around io_range_list is needed to provide the "mapping" between I/O tokens and physical CPU addresses. Currently the available tokens range from 0 to IO_SPACE_LIMIT. As you know the I/O memory accessors operate on whatever __of_address_to_resource sets into the resource (start, end). With this special device in place we cannot know if a resource is assigned with an I/O token or a physical address, unless we forbid the I/O tokens to be in a specific range. So this is why we are changing the offsets of all the functions handling io_range_list (to make sure that a range is forbidden to the tokens and is available to the physical addresses). We have chosen this forbidden range to be [0, PCIBIOS_MIN_IO) because this is the maximum physical I/O range that a non PCI device can operate on and because we believe this does not impose much restriction on the available I/O token range; that now is [PCIBIOS_MIN_IO, IO_SPACE_LIMIT]. So we believe that the chosen forbidden range can accommodate any special ISA bus device with no much constraint on the rest of I/O tokens... > > > > Your current version has > > > > > > if (arm64_extio_ops->pfout) \ > > > arm64_extio_ops->pfout(arm64_extio_ops->devpara,\ > > > addr, value, sizeof(type)); \ > > > > > > Instead, just subtract the start of the range from the logical > > > port number to transform it back into a bus-local port number: > > > > These accessors do not operate on IO tokens: > > > > If (arm64_extio_ops->start > addr || arm64_extio_ops->end < addr) > > addr is not going to be an I/O token; in fact patch 2/3 imposes that > > the I/O tokens will start at PCIBIOS_MIN_IO. So from 0 to > PCIBIOS_MIN_IO > > we have free physical addresses that the accessors can operate on. > > Ah, I missed that part. I'd rather not use PCIBIOS_MIN_IO to refer to > the logical I/O tokens, the purpose of that macro is really meant > for allocating PCI I/O port numbers within the address space of > one bus. As I mentioned above, special devices operate on CPU addresses directly, not I/O tokens. For them there is no way to distinguish.... > > Note that it's equally likely that whichever next platform needs > non-mapped I/O access like this actually needs them for PCI I/O space, > and that will use it on addresses registered to a PCI host bridge. Ok so here you are talking about a platform that has got an I/O range under the PCI host controller, right? And this I/O range cannot be directly memory mapped but needs special redirections for the I/O tokens, right? In this scenario registering the I/O ranges with the forbidden range implemented by the current patch would still allow to redirect I/O tokens as long as arm64_extio_ops->start >= PCIBIOS_MIN_IO So effectively the special PCI host controller 1) knows the physical range that needs special redirection 2) register such range 3) uses pci_pio_to_address() to retrieve the IO tokens for the special accessors 4) sets arm64_extio_ops->start/end to the IO tokens retrieved in 3) So to be honest I think this patch can fit well both with special PCI controllers that need I/O tokens redirection and with special non-PCI controllers that need non-PCI I/O physical address redirection... Thanks (and sorry for the long reply but I didn't know how to make the explanation shorter :) ) Gab > > If we separate the two steps: > > a) assign a range of logical I/O port numbers to a bus > b) register a set of helpers for redirecting logical I/O > port to a helper function > > then I think the code will get cleaner and more flexible. > It should actually then be able to replace the powerpc > specific implementation. > > Arnd
[toc] | [prev] | [next] | [standalone]
| From | "liviu.dudau@arm.com" <liviu.dudau@arm.com> |
|---|---|
| Date | 2016-11-11 15:50 +0100 |
| Subject | Re: [PATCH V5 3/3] ARM64 LPC: LPC driver implementation on Hip06 |
| Message-ID | <sCljs-5Au-15@gated-at.bofh.it> |
| In reply to | #1519803 |
On Fri, Nov 11, 2016 at 01:39:35PM +0000, Gabriele Paoloni wrote:
> Hi Arnd
>
> > -----Original Message-----
> > From: Arnd Bergmann [mailto:arnd@arndb.de]
> > Sent: 10 November 2016 16:07
> > To: Gabriele Paoloni
> > Cc: linux-arm-kernel@lists.infradead.org; Yuanzhichang;
> > mark.rutland@arm.com; devicetree@vger.kernel.org;
> > lorenzo.pieralisi@arm.com; minyard@acm.org; linux-pci@vger.kernel.org;
> > benh@kernel.crashing.org; John Garry; will.deacon@arm.com; linux-
> > kernel@vger.kernel.org; xuwei (O); Linuxarm; zourongrong@gmail.com;
> > robh+dt@kernel.org; kantyzc@163.com; linux-serial@vger.kernel.org;
> > catalin.marinas@arm.com; olof@lixom.net; liviu.dudau@arm.com;
> > bhelgaas@googl e.com; zhichang.yuan02@gmail.com
> > Subject: Re: [PATCH V5 3/3] ARM64 LPC: LPC driver implementation on
> > Hip06
> >
> > On Thursday, November 10, 2016 3:36:49 PM CET Gabriele Paoloni wrote:
> > >
> > > Where should we get the range from? For LPC we know that it is going
> > > Work on anything that is not used by PCI I/O space, and this is
> > > why we use [0, PCIBIOS_MIN_IO]
> >
> > It should be allocated the same way we allocate PCI config space
> > segments. This is currently done with the io_range list in
> > drivers/pci/pci.c, which isn't perfect but could be extended
> > if necessary. Based on what others commented here, I'd rather
> > make the differences between ISA/LPC and PCI I/O ranges smaller
> > than larger.
Gabriele,
>
> I am not sure this would make sense...
>
> IMHO all the mechanism around io_range_list is needed to provide the
> "mapping" between I/O tokens and physical CPU addresses.
>
> Currently the available tokens range from 0 to IO_SPACE_LIMIT.
>
> As you know the I/O memory accessors operate on whatever
> __of_address_to_resource sets into the resource (start, end).
>
> With this special device in place we cannot know if a resource is
> assigned with an I/O token or a physical address, unless we forbid
> the I/O tokens to be in a specific range.
>
> So this is why we are changing the offsets of all the functions
> handling io_range_list (to make sure that a range is forbidden to
> the tokens and is available to the physical addresses).
>
> We have chosen this forbidden range to be [0, PCIBIOS_MIN_IO)
> because this is the maximum physical I/O range that a non PCI device
> can operate on and because we believe this does not impose much
> restriction on the available I/O token range; that now is
> [PCIBIOS_MIN_IO, IO_SPACE_LIMIT].
> So we believe that the chosen forbidden range can accommodate
> any special ISA bus device with no much constraint on the rest
> of I/O tokens...
Your idea is a good one, however you are abusing PCIBIOS_MIN_IO and you
actually need another variable for "reserving" an area in the I/O space
that can be used for physical addresses rather than I/O tokens.
The one good example for using PCIBIOS_MIN_IO is when your platform/architecture
does not support legacy ISA operations *at all*. In that case someone
sets the PCIBIOS_MIN_IO to a non-zero value to reserve that I/O range
so that it doesn't get used. With Zhichang's patch you now start forcing
those platforms to have a valid address below PCIBIOS_MIN_IO.
For the general case you also have to bear in mind that PCIBIOS_MIN_IO could
be zero. In that case, what is your "forbidden" range? [0, 0) ? So it makes
sense to add a new #define that should only be defined by those architectures/
platforms that want to reserve on top of PCIBIOS_MIN_IO another region
where I/O tokens can't be generated for.
Best regards,
Liviu
>
> >
> > > > Your current version has
> > > >
> > > > if (arm64_extio_ops->pfout) \
> > > > arm64_extio_ops->pfout(arm64_extio_ops->devpara,\
> > > > addr, value, sizeof(type)); \
> > > >
> > > > Instead, just subtract the start of the range from the logical
> > > > port number to transform it back into a bus-local port number:
> > >
> > > These accessors do not operate on IO tokens:
> > >
> > > If (arm64_extio_ops->start > addr || arm64_extio_ops->end < addr)
> > > addr is not going to be an I/O token; in fact patch 2/3 imposes that
> > > the I/O tokens will start at PCIBIOS_MIN_IO. So from 0 to
> > PCIBIOS_MIN_IO
> > > we have free physical addresses that the accessors can operate on.
> >
> > Ah, I missed that part. I'd rather not use PCIBIOS_MIN_IO to refer to
> > the logical I/O tokens, the purpose of that macro is really meant
> > for allocating PCI I/O port numbers within the address space of
> > one bus.
>
> As I mentioned above, special devices operate on CPU addresses directly,
> not I/O tokens. For them there is no way to distinguish....
>
> >
> > Note that it's equally likely that whichever next platform needs
> > non-mapped I/O access like this actually needs them for PCI I/O space,
> > and that will use it on addresses registered to a PCI host bridge.
>
> Ok so here you are talking about a platform that has got an I/O range
> under the PCI host controller, right?
> And this I/O range cannot be directly memory mapped but needs special
> redirections for the I/O tokens, right?
>
> In this scenario registering the I/O ranges with the forbidden range
> implemented by the current patch would still allow to redirect I/O
> tokens as long as arm64_extio_ops->start >= PCIBIOS_MIN_IO
>
> So effectively the special PCI host controller
> 1) knows the physical range that needs special redirection
> 2) register such range
> 3) uses pci_pio_to_address() to retrieve the IO tokens for the
> special accessors
> 4) sets arm64_extio_ops->start/end to the IO tokens retrieved in 3)
>
> So to be honest I think this patch can fit well both with
> special PCI controllers that need I/O tokens redirection and with
> special non-PCI controllers that need non-PCI I/O physical
> address redirection...
>
> Thanks (and sorry for the long reply but I didn't know how
> to make the explanation shorter :) )
>
> Gab
>
> >
> > If we separate the two steps:
> >
> > a) assign a range of logical I/O port numbers to a bus
> > b) register a set of helpers for redirecting logical I/O
> > port to a helper function
> >
> > then I think the code will get cleaner and more flexible.
> > It should actually then be able to replace the powerpc
> > specific implementation.
> >
> > Arnd
--
====================
| I would like to |
| fix the world, |
| but they're not |
| giving me the |
\ source code! /
---------------
¯\_(ツ)_/¯
[toc] | [prev] | [next] | [standalone]
| From | Gabriele Paoloni <gabriele.paoloni@huawei.com> |
|---|---|
| Date | 2016-11-11 17:00 +0100 |
| Subject | RE: [PATCH V5 3/3] ARM64 LPC: LPC driver implementation on Hip06 |
| Message-ID | <sCmpb-6c5-15@gated-at.bofh.it> |
| In reply to | #1519839 |
Hi Liviu > -----Original Message----- > From: liviu.dudau@arm.com [mailto:liviu.dudau@arm.com] > Sent: 11 November 2016 14:46 > To: Gabriele Paoloni > Cc: Arnd Bergmann; linux-arm-kernel@lists.infradead.org; Yuanzhichang; > mark.rutland@arm.com; devicetree@vger.kernel.org; > lorenzo.pieralisi@arm.com; minyard@acm.org; linux-pci@vger.kernel.org; > benh@kernel.crashing.org; John Garry; will.deacon@arm.com; linux- > kernel@vger.kernel.org; xuwei (O); Linuxarm; zourongrong@gmail.com; > robh+dt@kernel.org; kantyzc@163.com; linux-serial@vger.kernel.org; > catalin.marinas@arm.com; olof@lixom.net; bhelgaas@googl e.com; > zhichang.yuan02@gmail.com > Subject: Re: [PATCH V5 3/3] ARM64 LPC: LPC driver implementation on > Hip06 > > On Fri, Nov 11, 2016 at 01:39:35PM +0000, Gabriele Paoloni wrote: > > Hi Arnd > > > > > -----Original Message----- > > > From: Arnd Bergmann [mailto:arnd@arndb.de] > > > Sent: 10 November 2016 16:07 > > > To: Gabriele Paoloni > > > Cc: linux-arm-kernel@lists.infradead.org; Yuanzhichang; > > > mark.rutland@arm.com; devicetree@vger.kernel.org; > > > lorenzo.pieralisi@arm.com; minyard@acm.org; linux- > pci@vger.kernel.org; > > > benh@kernel.crashing.org; John Garry; will.deacon@arm.com; linux- > > > kernel@vger.kernel.org; xuwei (O); Linuxarm; zourongrong@gmail.com; > > > robh+dt@kernel.org; kantyzc@163.com; linux-serial@vger.kernel.org; > > > catalin.marinas@arm.com; olof@lixom.net; liviu.dudau@arm.com; > > > bhelgaas@googl e.com; zhichang.yuan02@gmail.com > > > Subject: Re: [PATCH V5 3/3] ARM64 LPC: LPC driver implementation on > > > Hip06 > > > > > > On Thursday, November 10, 2016 3:36:49 PM CET Gabriele Paoloni > wrote: > > > > > > > > Where should we get the range from? For LPC we know that it is > going > > > > Work on anything that is not used by PCI I/O space, and this is > > > > why we use [0, PCIBIOS_MIN_IO] > > > > > > It should be allocated the same way we allocate PCI config space > > > segments. This is currently done with the io_range list in > > > drivers/pci/pci.c, which isn't perfect but could be extended > > > if necessary. Based on what others commented here, I'd rather > > > make the differences between ISA/LPC and PCI I/O ranges smaller > > > than larger. > > Gabriele, > > > > > I am not sure this would make sense... > > > > IMHO all the mechanism around io_range_list is needed to provide the > > "mapping" between I/O tokens and physical CPU addresses. > > > > Currently the available tokens range from 0 to IO_SPACE_LIMIT. > > > > As you know the I/O memory accessors operate on whatever > > __of_address_to_resource sets into the resource (start, end). > > > > With this special device in place we cannot know if a resource is > > assigned with an I/O token or a physical address, unless we forbid > > the I/O tokens to be in a specific range. > > > > So this is why we are changing the offsets of all the functions > > handling io_range_list (to make sure that a range is forbidden to > > the tokens and is available to the physical addresses). > > > > We have chosen this forbidden range to be [0, PCIBIOS_MIN_IO) > > because this is the maximum physical I/O range that a non PCI device > > can operate on and because we believe this does not impose much > > restriction on the available I/O token range; that now is > > [PCIBIOS_MIN_IO, IO_SPACE_LIMIT]. > > So we believe that the chosen forbidden range can accommodate > > any special ISA bus device with no much constraint on the rest > > of I/O tokens... > > Your idea is a good one, however you are abusing PCIBIOS_MIN_IO and you > actually need another variable for "reserving" an area in the I/O space > that can be used for physical addresses rather than I/O tokens. > > The one good example for using PCIBIOS_MIN_IO is when your > platform/architecture > does not support legacy ISA operations *at all*. In that case someone > sets the PCIBIOS_MIN_IO to a non-zero value to reserve that I/O range > so that it doesn't get used. With Zhichang's patch you now start > forcing > those platforms to have a valid address below PCIBIOS_MIN_IO. But if PCIBIOS_MIN_IO is 0 then it means that all I/O space is to be used by PCI controllers only...so if you have a special bus device using an I/O range in this case should be a PCI controller...i.e. I would expect it to fall back into the case of I/O tokens redirection rather than physical addresses redirection (as mentioned below from my previous reply). What do you think? Thanks Gab > > For the general case you also have to bear in mind that PCIBIOS_MIN_IO > could > be zero. In that case, what is your "forbidden" range? [0, 0) ? So it > makes > sense to add a new #define that should only be defined by those > architectures/ > platforms that want to reserve on top of PCIBIOS_MIN_IO another region > where I/O tokens can't be generated for. > > Best regards, > Liviu > > > > > > > > > > > Your current version has > > > > > > > > > > if (arm64_extio_ops->pfout) > \ > > > > > arm64_extio_ops->pfout(arm64_extio_ops- > >devpara,\ > > > > > addr, value, sizeof(type)); > \ > > > > > > > > > > Instead, just subtract the start of the range from the logical > > > > > port number to transform it back into a bus-local port number: > > > > > > > > These accessors do not operate on IO tokens: > > > > > > > > If (arm64_extio_ops->start > addr || arm64_extio_ops->end < addr) > > > > addr is not going to be an I/O token; in fact patch 2/3 imposes > that > > > > the I/O tokens will start at PCIBIOS_MIN_IO. So from 0 to > > > PCIBIOS_MIN_IO > > > > we have free physical addresses that the accessors can operate > on. > > > > > > Ah, I missed that part. I'd rather not use PCIBIOS_MIN_IO to refer > to > > > the logical I/O tokens, the purpose of that macro is really meant > > > for allocating PCI I/O port numbers within the address space of > > > one bus. > > > > As I mentioned above, special devices operate on CPU addresses > directly, > > not I/O tokens. For them there is no way to distinguish.... > > > > > > > > Note that it's equally likely that whichever next platform needs > > > non-mapped I/O access like this actually needs them for PCI I/O > space, > > > and that will use it on addresses registered to a PCI host bridge. > > > > Ok so here you are talking about a platform that has got an I/O range > > under the PCI host controller, right? > > And this I/O range cannot be directly memory mapped but needs special > > redirections for the I/O tokens, right? > > > > In this scenario registering the I/O ranges with the forbidden range > > implemented by the current patch would still allow to redirect I/O > > tokens as long as arm64_extio_ops->start >= PCIBIOS_MIN_IO > > > > So effectively the special PCI host controller > > 1) knows the physical range that needs special redirection > > 2) register such range > > 3) uses pci_pio_to_address() to retrieve the IO tokens for the > > special accessors > > 4) sets arm64_extio_ops->start/end to the IO tokens retrieved in 3) > > > > So to be honest I think this patch can fit well both with > > special PCI controllers that need I/O tokens redirection and with > > special non-PCI controllers that need non-PCI I/O physical > > address redirection... > > > > Thanks (and sorry for the long reply but I didn't know how > > to make the explanation shorter :) ) > > > > Gab > > > > > > > > If we separate the two steps: > > > > > > a) assign a range of logical I/O port numbers to a bus > > > b) register a set of helpers for redirecting logical I/O > > > port to a helper function > > > > > > then I think the code will get cleaner and more flexible. > > > It should actually then be able to replace the powerpc > > > specific implementation. > > > > > > Arnd > > -- > ==================== > | I would like to | > | fix the world, | > | but they're not | > | giving me the | > \ source code! / > --------------- > ¯\_(ツ)_/¯
[toc] | [prev] | [next] | [standalone]
| From | "liviu.dudau@arm.com" <liviu.dudau@arm.com> |
|---|---|
| Date | 2016-11-11 19:20 +0100 |
| Subject | Re: [PATCH V5 3/3] ARM64 LPC: LPC driver implementation on Hip06 |
| Message-ID | <sCoAF-7P3-7@gated-at.bofh.it> |
| In reply to | #1519871 |
On Fri, Nov 11, 2016 at 03:53:53PM +0000, Gabriele Paoloni wrote:
> Hi Liviu
Hi Gabriele,
>
> > -----Original Message-----
> > From: liviu.dudau@arm.com [mailto:liviu.dudau@arm.com]
> > Sent: 11 November 2016 14:46
> > To: Gabriele Paoloni
> > Cc: Arnd Bergmann; linux-arm-kernel@lists.infradead.org; Yuanzhichang;
> > mark.rutland@arm.com; devicetree@vger.kernel.org;
> > lorenzo.pieralisi@arm.com; minyard@acm.org; linux-pci@vger.kernel.org;
> > benh@kernel.crashing.org; John Garry; will.deacon@arm.com; linux-
> > kernel@vger.kernel.org; xuwei (O); Linuxarm; zourongrong@gmail.com;
> > robh+dt@kernel.org; kantyzc@163.com; linux-serial@vger.kernel.org;
> > catalin.marinas@arm.com; olof@lixom.net; bhelgaas@googl e.com;
> > zhichang.yuan02@gmail.com
> > Subject: Re: [PATCH V5 3/3] ARM64 LPC: LPC driver implementation on
> > Hip06
> >
> > On Fri, Nov 11, 2016 at 01:39:35PM +0000, Gabriele Paoloni wrote:
> > > Hi Arnd
> > >
> > > > -----Original Message-----
> > > > From: Arnd Bergmann [mailto:arnd@arndb.de]
> > > > Sent: 10 November 2016 16:07
> > > > To: Gabriele Paoloni
> > > > Cc: linux-arm-kernel@lists.infradead.org; Yuanzhichang;
> > > > mark.rutland@arm.com; devicetree@vger.kernel.org;
> > > > lorenzo.pieralisi@arm.com; minyard@acm.org; linux-
> > pci@vger.kernel.org;
> > > > benh@kernel.crashing.org; John Garry; will.deacon@arm.com; linux-
> > > > kernel@vger.kernel.org; xuwei (O); Linuxarm; zourongrong@gmail.com;
> > > > robh+dt@kernel.org; kantyzc@163.com; linux-serial@vger.kernel.org;
> > > > catalin.marinas@arm.com; olof@lixom.net; liviu.dudau@arm.com;
> > > > bhelgaas@googl e.com; zhichang.yuan02@gmail.com
> > > > Subject: Re: [PATCH V5 3/3] ARM64 LPC: LPC driver implementation on
> > > > Hip06
> > > >
> > > > On Thursday, November 10, 2016 3:36:49 PM CET Gabriele Paoloni
> > wrote:
> > > > >
> > > > > Where should we get the range from? For LPC we know that it is
> > going
> > > > > Work on anything that is not used by PCI I/O space, and this is
> > > > > why we use [0, PCIBIOS_MIN_IO]
> > > >
> > > > It should be allocated the same way we allocate PCI config space
> > > > segments. This is currently done with the io_range list in
> > > > drivers/pci/pci.c, which isn't perfect but could be extended
> > > > if necessary. Based on what others commented here, I'd rather
> > > > make the differences between ISA/LPC and PCI I/O ranges smaller
> > > > than larger.
> >
> > Gabriele,
> >
> > >
> > > I am not sure this would make sense...
> > >
> > > IMHO all the mechanism around io_range_list is needed to provide the
> > > "mapping" between I/O tokens and physical CPU addresses.
> > >
> > > Currently the available tokens range from 0 to IO_SPACE_LIMIT.
> > >
> > > As you know the I/O memory accessors operate on whatever
> > > __of_address_to_resource sets into the resource (start, end).
> > >
> > > With this special device in place we cannot know if a resource is
> > > assigned with an I/O token or a physical address, unless we forbid
> > > the I/O tokens to be in a specific range.
> > >
> > > So this is why we are changing the offsets of all the functions
> > > handling io_range_list (to make sure that a range is forbidden to
> > > the tokens and is available to the physical addresses).
> > >
> > > We have chosen this forbidden range to be [0, PCIBIOS_MIN_IO)
> > > because this is the maximum physical I/O range that a non PCI device
> > > can operate on and because we believe this does not impose much
> > > restriction on the available I/O token range; that now is
> > > [PCIBIOS_MIN_IO, IO_SPACE_LIMIT].
> > > So we believe that the chosen forbidden range can accommodate
> > > any special ISA bus device with no much constraint on the rest
> > > of I/O tokens...
> >
> > Your idea is a good one, however you are abusing PCIBIOS_MIN_IO and you
> > actually need another variable for "reserving" an area in the I/O space
> > that can be used for physical addresses rather than I/O tokens.
> >
> > The one good example for using PCIBIOS_MIN_IO is when your
> > platform/architecture
> > does not support legacy ISA operations *at all*. In that case someone
> > sets the PCIBIOS_MIN_IO to a non-zero value to reserve that I/O range
> > so that it doesn't get used. With Zhichang's patch you now start
> > forcing
> > those platforms to have a valid address below PCIBIOS_MIN_IO.
>
> But if PCIBIOS_MIN_IO is 0 then it means that all I/O space is to be used
> by PCI controllers only...
Nope, that is not what it means. It means that PCI devices can see I/O addresses
on the bus that start from 0. There never was any usage for non-PCI controllers
when PCIBIOS_MIN_IO != 0. That is what Zhichang is trying to do now and what
I think is not the right thing (and not enough anyway).
> so if you have a special bus device using
> an I/O range in this case should be a PCI controller...
That has always been the case. It is this series that wants to introduce the
new meaning.
> i.e. I would
> expect it to fall back into the case of I/O tokens redirection rather than
> physical addresses redirection (as mentioned below from my previous reply).
> What do you think?
I think you have looked too much at the code *with* Zhichang's patches applied.
Take a step back and look at how PCIBIOS_MIN_IO is used now, before you apply
the patches. It is all about PCI addresses and there is no notion of non-PCI
busses using PCI framework. Only platforms and architectures that try to work
around some legacy standards (ISA) or HW restrictions.
Best regards,
Liviu
>
> Thanks
>
> Gab
>
>
> >
> > For the general case you also have to bear in mind that PCIBIOS_MIN_IO
> > could
> > be zero. In that case, what is your "forbidden" range? [0, 0) ? So it
> > makes
> > sense to add a new #define that should only be defined by those
> > architectures/
> > platforms that want to reserve on top of PCIBIOS_MIN_IO another region
> > where I/O tokens can't be generated for.
> >
> > Best regards,
> > Liviu
> >
> > >
> > > >
> > > > > > Your current version has
> > > > > >
> > > > > > if (arm64_extio_ops->pfout)
> > \
> > > > > > arm64_extio_ops->pfout(arm64_extio_ops-
> > >devpara,\
> > > > > > addr, value, sizeof(type));
> > \
> > > > > >
> > > > > > Instead, just subtract the start of the range from the logical
> > > > > > port number to transform it back into a bus-local port number:
> > > > >
> > > > > These accessors do not operate on IO tokens:
> > > > >
> > > > > If (arm64_extio_ops->start > addr || arm64_extio_ops->end < addr)
> > > > > addr is not going to be an I/O token; in fact patch 2/3 imposes
> > that
> > > > > the I/O tokens will start at PCIBIOS_MIN_IO. So from 0 to
> > > > PCIBIOS_MIN_IO
> > > > > we have free physical addresses that the accessors can operate
> > on.
> > > >
> > > > Ah, I missed that part. I'd rather not use PCIBIOS_MIN_IO to refer
> > to
> > > > the logical I/O tokens, the purpose of that macro is really meant
> > > > for allocating PCI I/O port numbers within the address space of
> > > > one bus.
> > >
> > > As I mentioned above, special devices operate on CPU addresses
> > directly,
> > > not I/O tokens. For them there is no way to distinguish....
> > >
> > > >
> > > > Note that it's equally likely that whichever next platform needs
> > > > non-mapped I/O access like this actually needs them for PCI I/O
> > space,
> > > > and that will use it on addresses registered to a PCI host bridge.
> > >
> > > Ok so here you are talking about a platform that has got an I/O range
> > > under the PCI host controller, right?
> > > And this I/O range cannot be directly memory mapped but needs special
> > > redirections for the I/O tokens, right?
> > >
> > > In this scenario registering the I/O ranges with the forbidden range
> > > implemented by the current patch would still allow to redirect I/O
> > > tokens as long as arm64_extio_ops->start >= PCIBIOS_MIN_IO
> > >
> > > So effectively the special PCI host controller
> > > 1) knows the physical range that needs special redirection
> > > 2) register such range
> > > 3) uses pci_pio_to_address() to retrieve the IO tokens for the
> > > special accessors
> > > 4) sets arm64_extio_ops->start/end to the IO tokens retrieved in 3)
> > >
> > > So to be honest I think this patch can fit well both with
> > > special PCI controllers that need I/O tokens redirection and with
> > > special non-PCI controllers that need non-PCI I/O physical
> > > address redirection...
> > >
> > > Thanks (and sorry for the long reply but I didn't know how
> > > to make the explanation shorter :) )
> > >
> > > Gab
> > >
> > > >
> > > > If we separate the two steps:
> > > >
> > > > a) assign a range of logical I/O port numbers to a bus
> > > > b) register a set of helpers for redirecting logical I/O
> > > > port to a helper function
> > > >
> > > > then I think the code will get cleaner and more flexible.
> > > > It should actually then be able to replace the powerpc
> > > > specific implementation.
> > > >
> > > > Arnd
> >
> > --
> > ====================
> > | I would like to |
> > | fix the world, |
> > | but they're not |
> > | giving me the |
> > \ source code! /
> > ---------------
> > ¯\_(ツ)_/¯
--
====================
| I would like to |
| fix the world, |
| but they're not |
| giving me the |
\ source code! /
---------------
¯\_(ツ)_/¯
[toc] | [prev] | [next] | [standalone]
| From | "zhichang.yuan" <zhichang.yuan02@gmail.com> |
|---|---|
| Date | 2016-11-11 18:10 +0100 |
| Subject | Re: [PATCH V5 3/3] ARM64 LPC: LPC driver implementation on Hip06 |
| Message-ID | <sCnuV-77s-5@gated-at.bofh.it> |
| In reply to | #1519839 |
Hi, Liviu, On 11/11/2016 10:45 PM, liviu.dudau@arm.com wrote: > On Fri, Nov 11, 2016 at 01:39:35PM +0000, Gabriele Paoloni wrote: >> Hi Arnd >> >>> -----Original Message----- >>> From: Arnd Bergmann [mailto:arnd@arndb.de] >>> Sent: 10 November 2016 16:07 >>> To: Gabriele Paoloni >>> Cc: linux-arm-kernel@lists.infradead.org; Yuanzhichang; >>> mark.rutland@arm.com; devicetree@vger.kernel.org; >>> lorenzo.pieralisi@arm.com; minyard@acm.org; linux-pci@vger.kernel.org; >>> benh@kernel.crashing.org; John Garry; will.deacon@arm.com; linux- >>> kernel@vger.kernel.org; xuwei (O); Linuxarm; zourongrong@gmail.com; >>> robh+dt@kernel.org; kantyzc@163.com; linux-serial@vger.kernel.org; >>> catalin.marinas@arm.com; olof@lixom.net; liviu.dudau@arm.com; >>> bhelgaas@googl e.com; zhichang.yuan02@gmail.com >>> Subject: Re: [PATCH V5 3/3] ARM64 LPC: LPC driver implementation on >>> Hip06 >>> >>> On Thursday, November 10, 2016 3:36:49 PM CET Gabriele Paoloni wrote: >>>> >>>> Where should we get the range from? For LPC we know that it is going >>>> Work on anything that is not used by PCI I/O space, and this is >>>> why we use [0, PCIBIOS_MIN_IO] >>> >>> It should be allocated the same way we allocate PCI config space >>> segments. This is currently done with the io_range list in >>> drivers/pci/pci.c, which isn't perfect but could be extended >>> if necessary. Based on what others commented here, I'd rather >>> make the differences between ISA/LPC and PCI I/O ranges smaller >>> than larger. > > Gabriele, > >> >> I am not sure this would make sense... >> >> IMHO all the mechanism around io_range_list is needed to provide the >> "mapping" between I/O tokens and physical CPU addresses. >> >> Currently the available tokens range from 0 to IO_SPACE_LIMIT. >> >> As you know the I/O memory accessors operate on whatever >> __of_address_to_resource sets into the resource (start, end). >> >> With this special device in place we cannot know if a resource is >> assigned with an I/O token or a physical address, unless we forbid >> the I/O tokens to be in a specific range. >> >> So this is why we are changing the offsets of all the functions >> handling io_range_list (to make sure that a range is forbidden to >> the tokens and is available to the physical addresses). >> >> We have chosen this forbidden range to be [0, PCIBIOS_MIN_IO) >> because this is the maximum physical I/O range that a non PCI device >> can operate on and because we believe this does not impose much >> restriction on the available I/O token range; that now is >> [PCIBIOS_MIN_IO, IO_SPACE_LIMIT]. >> So we believe that the chosen forbidden range can accommodate >> any special ISA bus device with no much constraint on the rest >> of I/O tokens... > > Your idea is a good one, however you are abusing PCIBIOS_MIN_IO and you > actually need another variable for "reserving" an area in the I/O space > that can be used for physical addresses rather than I/O tokens. > I think selecting PCIBIOS_MIN_IO as the separator of mapped and non-mapped I/O range probably is not so reasonable. PCIBIOS_MIN_IN is specific to PCI devices, it seems as the recommended minimal start I/O address when assigning the pci device I/O region. It is probably not defined in some platforms/architectures when no PCI is needed there. That is why my patch caused some compile error on some archs; But more important thing is that the PCIBIOS_MIN_IO has different value on different platforms/architectures. On Arm64, it is 4K currently, but in other archs, it is not true. And the maximum LPC I/O address should be 64K theoretically, although for compatible ISA, 2K is enough. So, It means using PCIBIOS_MIN_IO on arm64 can match our I/O reservation require. But we can not make this indirectIO work well on other architectures. I am thinking Arnd's suggestion. But I worry about I haven't completely understood his idea. What about create a new bus host for LPC/ISA whose I/O range can be 64KB? This LPC/ISA I/O range works similar to PCI host bridge's I/O window, all the downstream devices under LPC/ISA should request I/O from that root resource. But it seems Arnd want this root resource registered dynamically, I am not sure how to do... Anyway, if we have this root I/O resource, we don't need any new macro or variable for the LPC/ISA I/O reservation. Hope my thought is right. Best, Zhichang > The one good example for using PCIBIOS_MIN_IO is when your platform/architecture > does not support legacy ISA operations *at all*. In that case someone > sets the PCIBIOS_MIN_IO to a non-zero value to reserve that I/O range > so that it doesn't get used. With Zhichang's patch you now start forcing > those platforms to have a valid address below PCIBIOS_MIN_IO. > > For the general case you also have to bear in mind that PCIBIOS_MIN_IO could > be zero. In that case, what is your "forbidden" range? [0, 0) ? So it makes > sense to add a new #define that should only be defined by those architectures/ > platforms that want to reserve on top of PCIBIOS_MIN_IO another region > where I/O tokens can't be generated for. > > Best regards, > Liviu > >> >>> >>>>> Your current version has >>>>> >>>>> if (arm64_extio_ops->pfout) \ >>>>> arm64_extio_ops->pfout(arm64_extio_ops->devpara,\ >>>>> addr, value, sizeof(type)); \ >>>>> >>>>> Instead, just subtract the start of the range from the logical >>>>> port number to transform it back into a bus-local port number: >>>> >>>> These accessors do not operate on IO tokens: >>>> >>>> If (arm64_extio_ops->start > addr || arm64_extio_ops->end < addr) >>>> addr is not going to be an I/O token; in fact patch 2/3 imposes that >>>> the I/O tokens will start at PCIBIOS_MIN_IO. So from 0 to >>> PCIBIOS_MIN_IO >>>> we have free physical addresses that the accessors can operate on. >>> >>> Ah, I missed that part. I'd rather not use PCIBIOS_MIN_IO to refer to >>> the logical I/O tokens, the purpose of that macro is really meant >>> for allocating PCI I/O port numbers within the address space of >>> one bus. >> >> As I mentioned above, special devices operate on CPU addresses directly, >> not I/O tokens. For them there is no way to distinguish.... >> >>> >>> Note that it's equally likely that whichever next platform needs >>> non-mapped I/O access like this actually needs them for PCI I/O space, >>> and that will use it on addresses registered to a PCI host bridge. >> >> Ok so here you are talking about a platform that has got an I/O range >> under the PCI host controller, right? >> And this I/O range cannot be directly memory mapped but needs special >> redirections for the I/O tokens, right? >> >> In this scenario registering the I/O ranges with the forbidden range >> implemented by the current patch would still allow to redirect I/O >> tokens as long as arm64_extio_ops->start >= PCIBIOS_MIN_IO >> >> So effectively the special PCI host controller >> 1) knows the physical range that needs special redirection >> 2) register such range >> 3) uses pci_pio_to_address() to retrieve the IO tokens for the >> special accessors >> 4) sets arm64_extio_ops->start/end to the IO tokens retrieved in 3) >> >> So to be honest I think this patch can fit well both with >> special PCI controllers that need I/O tokens redirection and with >> special non-PCI controllers that need non-PCI I/O physical >> address redirection... >> >> Thanks (and sorry for the long reply but I didn't know how >> to make the explanation shorter :) ) >> >> Gab >> >>> >>> If we separate the two steps: >>> >>> a) assign a range of logical I/O port numbers to a bus >>> b) register a set of helpers for redirecting logical I/O >>> port to a helper function >>> >>> then I think the code will get cleaner and more flexible. >>> It should actually then be able to replace the powerpc >>> specific implementation. >>> >>> Arnd >
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web