From 82dbc15a05125a812c140a3c8cff81c366482229 Mon Sep 17 00:00:00 2001 From: "Jason M. Bills" Date: Mon, 7 Dec 2020 13:45:20 -0800 Subject: Update to internal 0.26 Signed-off-by: Jason M. Bills --- ...-i2c-aspeed-add-DMA-mode-transfer-support.patch | 491 --------------------- 1 file changed, 491 deletions(-) delete mode 100644 meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0062-i2c-aspeed-add-DMA-mode-transfer-support.patch (limited to 'meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0062-i2c-aspeed-add-DMA-mode-transfer-support.patch') diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0062-i2c-aspeed-add-DMA-mode-transfer-support.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0062-i2c-aspeed-add-DMA-mode-transfer-support.patch deleted file mode 100644 index 994c20b18..000000000 --- a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0062-i2c-aspeed-add-DMA-mode-transfer-support.patch +++ /dev/null @@ -1,491 +0,0 @@ -From 5bf7a202eb0af455675a85a4f1bdad863fd8805d Mon Sep 17 00:00:00 2001 -From: Jae Hyun Yoo -Date: Tue, 18 Jun 2019 08:47:50 -0700 -Subject: [PATCH] i2c: aspeed: add DMA mode transfer support - -This commit adds DMA mode transfer support. - -Only AST2500 supports DMA mode under some limitations: -I2C is sharing the DMA H/W with UHCI host controller and MCTP -controller. Since those controllers operate with DMA mode only, I2C -has to use buffer mode or byte mode instead if one of those -controllers is enabled. Also make sure that if SD/eMMC or Port80 -snoop uses DMA mode instead of PIO or FIFO respectively, I2C can't -use DMA mode. - -Signed-off-by: Jae Hyun Yoo ---- - .../devicetree/bindings/i2c/i2c-aspeed.txt | 25 ++ - drivers/i2c/busses/i2c-aspeed.c | 253 +++++++++++++++++---- - 2 files changed, 234 insertions(+), 44 deletions(-) - -diff --git a/Documentation/devicetree/bindings/i2c/i2c-aspeed.txt b/Documentation/devicetree/bindings/i2c/i2c-aspeed.txt -index 0ff3539cee95..d3f4a39f7ba6 100644 ---- a/Documentation/devicetree/bindings/i2c/i2c-aspeed.txt -+++ b/Documentation/devicetree/bindings/i2c/i2c-aspeed.txt -@@ -22,6 +22,16 @@ Optional Properties: - - bus-timeout-ms: bus timeout in milliseconds defaults to 1 second when not - specified. - - #retries : Number of retries for master transfer. -+- aspeed,dma-buf-size : size of DMA buffer (from 2 to 4095 in case of AST2500) -+ Only AST2500 supports DMA mode under some limitations: -+ I2C is sharing the DMA H/W with UHCI host controller -+ and MCTP controller. Since those controllers operate -+ with DMA mode only, I2C has to use buffer mode or byte -+ mode instead if one of those controllers is enabled. -+ Also make sure that if SD/eMMC or Port80 snoop uses -+ DMA mode instead of PIO or FIFO respectively, I2C -+ can't use DMA mode. IF both DMA and buffer modes are -+ enabled, DMA mode will be selected. - - Example: - -@@ -74,4 +84,19 @@ i2c { - interrupts = <1>; - interrupt-parent = <&i2c_ic>; - }; -+ -+ /* DMA mode transfer enabled */ -+ i2c2: i2c-bus@c0 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ #interrupt-cells = <1>; -+ reg = <0xc0 0x40>; -+ aspeed,dma-buf-size = <4095>; -+ compatible = "aspeed,ast2500-i2c-bus"; -+ clocks = <&syscon ASPEED_CLK_APB>; -+ resets = <&syscon ASPEED_RESET_I2C>; -+ bus-frequency = <100000>; -+ interrupts = <2>; -+ interrupt-parent = <&i2c_ic>; -+ }; - }; -diff --git a/drivers/i2c/busses/i2c-aspeed.c b/drivers/i2c/busses/i2c-aspeed.c -index bf72e151d11f..3c9e491cbe4e 100644 ---- a/drivers/i2c/busses/i2c-aspeed.c -+++ b/drivers/i2c/busses/i2c-aspeed.c -@@ -10,6 +10,8 @@ - #include - #include - #include -+#include -+#include - #include - #include - #include -@@ -47,6 +49,8 @@ - #define ASPEED_I2C_DEV_ADDR_REG 0x18 - #define ASPEED_I2C_BUF_CTRL_REG 0x1c - #define ASPEED_I2C_BYTE_BUF_REG 0x20 -+#define ASPEED_I2C_DMA_ADDR_REG 0x24 -+#define ASPEED_I2C_DMA_LEN_REG 0x28 - - /* Device Register Definition */ - /* 0x00 : I2CD Function Control Register */ -@@ -110,6 +114,8 @@ - #define ASPEED_I2CD_BUS_RECOVER_CMD BIT(11) - - /* Command Bit */ -+#define ASPEED_I2CD_RX_DMA_ENABLE BIT(9) -+#define ASPEED_I2CD_TX_DMA_ENABLE BIT(8) - #define ASPEED_I2CD_RX_BUFF_ENABLE BIT(7) - #define ASPEED_I2CD_TX_BUFF_ENABLE BIT(6) - #define ASPEED_I2CD_M_STOP_CMD BIT(5) -@@ -135,6 +141,14 @@ - #define ASPEED_I2CD_BUF_TX_COUNT_MASK GENMASK(15, 8) - #define ASPEED_I2CD_BUF_OFFSET_MASK GENMASK(5, 0) - -+/* 0x24 : I2CD DMA Mode Buffer Address Register */ -+#define ASPEED_I2CD_DMA_ADDR_MASK GENMASK(31, 2) -+#define ASPEED_I2CD_DMA_ALIGN 4 -+ -+/* 0x28 : I2CD DMA Transfer Length Register */ -+#define ASPEED_I2CD_DMA_LEN_SHIFT 0 -+#define ASPEED_I2CD_DMA_LEN_MASK GENMASK(11, 0) -+ - enum aspeed_i2c_master_state { - ASPEED_I2C_MASTER_INACTIVE, - ASPEED_I2C_MASTER_PENDING, -@@ -184,6 +198,12 @@ struct aspeed_i2c_bus { - void __iomem *buf_base; - u8 buf_offset; - u8 buf_page; -+ /* DMA mode */ -+ struct dma_pool *dma_pool; -+ dma_addr_t dma_handle; -+ u8 *dma_buf; -+ size_t dma_len; -+ /* Buffer/DMA mode */ - size_t buf_size; - #if IS_ENABLED(CONFIG_I2C_SLAVE) - struct i2c_client *slave; -@@ -281,7 +301,11 @@ static inline void - aspeed_i2c_slave_handle_rx_done(struct aspeed_i2c_bus *bus, u32 irq_status, - u8 *value) - { -- if (bus->buf_base && -+ if (bus->dma_buf && -+ bus->slave_state == ASPEED_I2C_SLAVE_WRITE_RECEIVED && -+ !(irq_status & ASPEED_I2CD_INTR_NORMAL_STOP)) -+ *value = bus->dma_buf[0]; -+ else if (bus->buf_base && - bus->slave_state == ASPEED_I2C_SLAVE_WRITE_RECEIVED && - !(irq_status & ASPEED_I2CD_INTR_NORMAL_STOP)) - *value = readb(bus->buf_base); -@@ -297,7 +321,18 @@ aspeed_i2c_slave_handle_normal_stop(struct aspeed_i2c_bus *bus, u32 irq_status, - - if (bus->slave_state == ASPEED_I2C_SLAVE_WRITE_RECEIVED && - irq_status & ASPEED_I2CD_INTR_RX_DONE) { -- if (bus->buf_base) { -+ if (bus->dma_buf) { -+ len = bus->buf_size - -+ FIELD_GET(ASPEED_I2CD_DMA_LEN_MASK, -+ readl(bus->base + -+ ASPEED_I2C_DMA_LEN_REG)); -+ for (i = 0; i < len; i++) { -+ *value = bus->dma_buf[i]; -+ i2c_slave_event(bus->slave, -+ I2C_SLAVE_WRITE_RECEIVED, -+ value); -+ } -+ } else if (bus->buf_base) { - len = FIELD_GET(ASPEED_I2CD_BUF_RX_COUNT_MASK, - readl(bus->base + - ASPEED_I2C_BUF_CTRL_REG)); -@@ -314,7 +349,14 @@ aspeed_i2c_slave_handle_normal_stop(struct aspeed_i2c_bus *bus, u32 irq_status, - static inline void - aspeed_i2c_slave_handle_write_requested(struct aspeed_i2c_bus *bus, u8 *value) - { -- if (bus->buf_base) { -+ if (bus->dma_buf) { -+ writel(bus->dma_handle & ASPEED_I2CD_DMA_ADDR_MASK, -+ bus->base + ASPEED_I2C_DMA_ADDR_REG); -+ writel(FIELD_PREP(ASPEED_I2CD_DMA_LEN_MASK, bus->buf_size), -+ bus->base + ASPEED_I2C_DMA_LEN_REG); -+ writel(ASPEED_I2CD_RX_DMA_ENABLE, -+ bus->base + ASPEED_I2C_CMD_REG); -+ } else if (bus->buf_base) { - writel(FIELD_PREP(ASPEED_I2CD_BUF_RX_SIZE_MASK, - bus->buf_size - 1) | - FIELD_PREP(ASPEED_I2CD_BUF_OFFSET_MASK, -@@ -330,7 +372,23 @@ aspeed_i2c_slave_handle_write_received(struct aspeed_i2c_bus *bus, u8 *value) - { - int i, len; - -- if (bus->buf_base) { -+ if (bus->dma_buf) { -+ len = bus->buf_size - -+ FIELD_GET(ASPEED_I2CD_DMA_LEN_MASK, -+ readl(bus->base + -+ ASPEED_I2C_DMA_LEN_REG)); -+ for (i = 1; i < len; i++) { -+ *value = bus->dma_buf[i]; -+ i2c_slave_event(bus->slave, I2C_SLAVE_WRITE_RECEIVED, -+ value); -+ } -+ writel(bus->dma_handle & ASPEED_I2CD_DMA_ADDR_MASK, -+ bus->base + ASPEED_I2C_DMA_ADDR_REG); -+ writel(FIELD_PREP(ASPEED_I2CD_DMA_LEN_MASK, bus->buf_size), -+ bus->base + ASPEED_I2C_DMA_LEN_REG); -+ writel(ASPEED_I2CD_RX_DMA_ENABLE, -+ bus->base + ASPEED_I2C_CMD_REG); -+ } else if (bus->buf_base) { - len = FIELD_GET(ASPEED_I2CD_BUF_RX_COUNT_MASK, - readl(bus->base + - ASPEED_I2C_BUF_CTRL_REG)); -@@ -460,7 +518,15 @@ aspeed_i2c_prepare_rx_buf(struct aspeed_i2c_bus *bus, struct i2c_msg *msg) - command |= ASPEED_I2CD_M_S_RX_CMD_LAST; - } - -- if (bus->buf_base) { -+ if (bus->dma_buf) { -+ command |= ASPEED_I2CD_RX_DMA_ENABLE; -+ -+ writel(bus->dma_handle & ASPEED_I2CD_DMA_ADDR_MASK, -+ bus->base + ASPEED_I2C_DMA_ADDR_REG); -+ writel(FIELD_PREP(ASPEED_I2CD_DMA_LEN_MASK, len), -+ bus->base + ASPEED_I2C_DMA_LEN_REG); -+ bus->dma_len = len; -+ } else { - command |= ASPEED_I2CD_RX_BUFF_ENABLE; - - writel(FIELD_PREP(ASPEED_I2CD_BUF_RX_SIZE_MASK, len - 1) | -@@ -483,7 +549,18 @@ aspeed_i2c_prepare_tx_buf(struct aspeed_i2c_bus *bus, struct i2c_msg *msg) - else - len = msg->len + 1; - -- if (bus->buf_base) { -+ if (bus->dma_buf) { -+ command |= ASPEED_I2CD_TX_DMA_ENABLE; -+ -+ bus->dma_buf[0] = slave_addr; -+ memcpy(bus->dma_buf + 1, msg->buf, len); -+ -+ writel(bus->dma_handle & ASPEED_I2CD_DMA_ADDR_MASK, -+ bus->base + ASPEED_I2C_DMA_ADDR_REG); -+ writel(FIELD_PREP(ASPEED_I2CD_DMA_LEN_MASK, len), -+ bus->base + ASPEED_I2C_DMA_LEN_REG); -+ bus->dma_len = len; -+ } else { - u8 wbuf[4]; - int i; - -@@ -536,18 +613,19 @@ static void aspeed_i2c_do_start(struct aspeed_i2c_bus *bus) - if (msg->flags & I2C_M_RD) { - command |= ASPEED_I2CD_M_RX_CMD; - if (!(msg->flags & I2C_M_RECV_LEN)) { -- if (msg->len && bus->buf_base) -+ if (msg->len && (bus->dma_buf || bus->buf_base)) - command |= aspeed_i2c_prepare_rx_buf(bus, msg); - - /* Need to let the hardware know to NACK after RX. */ - if (msg->len <= 1) - command |= ASPEED_I2CD_M_S_RX_CMD_LAST; - } -- } else if (msg->len && bus->buf_base) { -+ } else if (msg->len && (bus->dma_buf || bus->buf_base)) { - command |= aspeed_i2c_prepare_tx_buf(bus, msg); - } - -- if (!(command & ASPEED_I2CD_TX_BUFF_ENABLE)) -+ if (!(command & (ASPEED_I2CD_TX_BUFF_ENABLE | -+ ASPEED_I2CD_TX_DMA_ENABLE))) - writel(i2c_8bit_addr_from_msg(msg), - bus->base + ASPEED_I2C_BYTE_BUF_REG); - writel(command, bus->base + ASPEED_I2C_CMD_REG); -@@ -590,39 +668,52 @@ aspeed_i2c_master_handle_tx_first(struct aspeed_i2c_bus *bus, - { - u32 command = 0; - -- if (bus->buf_base) { -- u8 wbuf[4]; -+ if (bus->dma_buf || bus->buf_base) { - int len; -- int i; - - if (msg->len - bus->buf_index > bus->buf_size) - len = bus->buf_size; - else - len = msg->len - bus->buf_index; - -+ if (bus->dma_buf) { -+ command |= ASPEED_I2CD_TX_DMA_ENABLE; - -- command |= ASPEED_I2CD_TX_BUFF_ENABLE; -+ memcpy(bus->dma_buf, msg->buf + bus->buf_index, len); - -- if (msg->len - bus->buf_index > bus->buf_size) -- len = bus->buf_size; -- else -- len = msg->len - bus->buf_index; - -- for (i = 0; i < len; i++) { -- wbuf[i % 4] = msg->buf[bus->buf_index + i]; -- if (i % 4 == 3) -+ writel(bus->dma_handle & ASPEED_I2CD_DMA_ADDR_MASK, -+ bus->base + ASPEED_I2C_DMA_ADDR_REG); -+ writel(FIELD_PREP(ASPEED_I2CD_DMA_LEN_MASK, len), -+ bus->base + ASPEED_I2C_DMA_LEN_REG); -+ bus->dma_len = len; -+ } else { -+ u8 wbuf[4]; -+ int i; -+ -+ command |= ASPEED_I2CD_TX_BUFF_ENABLE; -+ -+ if (msg->len - bus->buf_index > bus->buf_size) -+ len = bus->buf_size; -+ else -+ len = msg->len - bus->buf_index; -+ -+ for (i = 0; i < len; i++) { -+ wbuf[i % 4] = msg->buf[bus->buf_index + i]; -+ if (i % 4 == 3) -+ writel(*(u32 *)wbuf, -+ bus->buf_base + i - 3); -+ } -+ if (--i % 4 != 3) - writel(*(u32 *)wbuf, -- bus->buf_base + i - 3); -- } -- if (--i % 4 != 3) -- writel(*(u32 *)wbuf, -- bus->buf_base + i - (i % 4)); -+ bus->buf_base + i - (i % 4)); - -- writel(FIELD_PREP(ASPEED_I2CD_BUF_TX_COUNT_MASK, -- len - 1) | -- FIELD_PREP(ASPEED_I2CD_BUF_OFFSET_MASK, -- bus->buf_offset), -- bus->base + ASPEED_I2C_BUF_CTRL_REG); -+ writel(FIELD_PREP(ASPEED_I2CD_BUF_TX_COUNT_MASK, -+ len - 1) | -+ FIELD_PREP(ASPEED_I2CD_BUF_OFFSET_MASK, -+ bus->buf_offset), -+ bus->base + ASPEED_I2C_BUF_CTRL_REG); -+ } - - bus->buf_index += len; - } else { -@@ -639,7 +730,14 @@ aspeed_i2c_master_handle_rx(struct aspeed_i2c_bus *bus, struct i2c_msg *msg) - u8 recv_byte; - int len; - -- if (bus->buf_base) { -+ if (bus->dma_buf) { -+ len = bus->dma_len - -+ FIELD_GET(ASPEED_I2CD_DMA_LEN_MASK, -+ readl(bus->base + ASPEED_I2C_DMA_LEN_REG)); -+ -+ memcpy(msg->buf + bus->buf_index, bus->dma_buf, len); -+ bus->buf_index += len; -+ } else if (bus->buf_base) { - len = FIELD_GET(ASPEED_I2CD_BUF_RX_COUNT_MASK, - readl(bus->base + ASPEED_I2C_BUF_CTRL_REG)); - memcpy_fromio(msg->buf + bus->buf_index, bus->buf_base, len); -@@ -656,7 +754,7 @@ aspeed_i2c_master_handle_rx_next(struct aspeed_i2c_bus *bus, - { - u32 command = 0; - -- if (bus->buf_base) { -+ if (bus->dma_buf || bus->buf_base) { - int len; - - if (msg->len - bus->buf_index > bus->buf_size) { -@@ -666,14 +764,24 @@ aspeed_i2c_master_handle_rx_next(struct aspeed_i2c_bus *bus, - command |= ASPEED_I2CD_M_S_RX_CMD_LAST; - } - -- command |= ASPEED_I2CD_RX_BUFF_ENABLE; -+ if (bus->dma_buf) { -+ command |= ASPEED_I2CD_RX_DMA_ENABLE; - -- writel(FIELD_PREP(ASPEED_I2CD_BUF_RX_SIZE_MASK, -- len - 1) | -- FIELD_PREP(ASPEED_I2CD_BUF_TX_COUNT_MASK, 0) | -- FIELD_PREP(ASPEED_I2CD_BUF_OFFSET_MASK, -- bus->buf_offset), -- bus->base + ASPEED_I2C_BUF_CTRL_REG); -+ writel(bus->dma_handle & ASPEED_I2CD_DMA_ADDR_MASK, -+ bus->base + ASPEED_I2C_DMA_ADDR_REG); -+ writel(FIELD_PREP(ASPEED_I2CD_DMA_LEN_MASK, len), -+ bus->base + ASPEED_I2C_DMA_LEN_REG); -+ bus->dma_len = len; -+ } else { -+ command |= ASPEED_I2CD_RX_BUFF_ENABLE; -+ -+ writel(FIELD_PREP(ASPEED_I2CD_BUF_RX_SIZE_MASK, -+ len - 1) | -+ FIELD_PREP(ASPEED_I2CD_BUF_TX_COUNT_MASK, 0) | -+ FIELD_PREP(ASPEED_I2CD_BUF_OFFSET_MASK, -+ bus->buf_offset), -+ bus->base + ASPEED_I2C_BUF_CTRL_REG); -+ } - } else { - if (bus->buf_index + 1 == msg->len) - command |= ASPEED_I2CD_M_S_RX_CMD_LAST; -@@ -1260,7 +1368,51 @@ static void aspeed_i2c_set_xfer_mode(struct aspeed_i2c_bus *bus) - sram_enabled = false; - } - -- if (sram_enabled) { -+ /* -+ * Only AST2500 and AST2600 support DMA mode under some limitations: -+ * I2C is sharing the DMA H/W with UHCI host controller and MCTP -+ * controller. Since those controllers operate with DMA mode only, I2C -+ * has to use buffer mode or byte mode instead if one of those -+ * controllers is enabled. Also make sure that if SD/eMMC or Port80 -+ * snoop uses DMA mode instead of PIO or FIFO respectively, I2C can't -+ * use DMA mode. -+ */ -+ if (sram_enabled && !IS_ENABLED(CONFIG_USB_UHCI_ASPEED) && -+ !of_device_is_compatible(pdev->dev.of_node, -+ "aspeed,ast2400-i2c-bus")) { -+ u32 dma_len_max = ASPEED_I2CD_DMA_LEN_MASK >> -+ ASPEED_I2CD_DMA_LEN_SHIFT; -+ -+ ret = device_property_read_u32(&pdev->dev, -+ "aspeed,dma-buf-size", -+ &bus->buf_size); -+ if (!ret && bus->buf_size > dma_len_max) -+ bus->buf_size = dma_len_max; -+ } -+ -+ if (bus->buf_size) { -+ if (dma_set_mask(&pdev->dev, DMA_BIT_MASK(32))) { -+ dev_warn(&pdev->dev, "No suitable DMA available\n"); -+ } else { -+ bus->dma_pool = dma_pool_create("i2c-aspeed", -+ &pdev->dev, -+ bus->buf_size, -+ ASPEED_I2CD_DMA_ALIGN, -+ 0); -+ if (bus->dma_pool) -+ bus->dma_buf = dma_pool_alloc(bus->dma_pool, -+ GFP_KERNEL, -+ &bus->dma_handle); -+ -+ if (!bus->dma_buf) { -+ dev_warn(&pdev->dev, -+ "Cannot allocate DMA buffer\n"); -+ dma_pool_destroy(bus->dma_pool); -+ } -+ } -+ } -+ -+ if (!bus->dma_buf && sram_enabled) { - struct resource *res = platform_get_resource(pdev, - IORESOURCE_MEM, 1); - -@@ -1365,24 +1517,33 @@ static int aspeed_i2c_probe_bus(struct platform_device *pdev) - */ - ret = aspeed_i2c_init(bus, pdev); - if (ret < 0) -- return ret; -+ goto out_free_dma_buf; - - irq = irq_of_parse_and_map(pdev->dev.of_node, 0); - ret = devm_request_irq(&pdev->dev, irq, aspeed_i2c_bus_irq, - 0, dev_name(&pdev->dev), bus); - if (ret < 0) -- return ret; -+ goto out_free_dma_buf; - - ret = i2c_add_adapter(&bus->adap); - if (ret < 0) -- return ret; -+ goto out_free_dma_buf; - - platform_set_drvdata(pdev, bus); - - dev_info(bus->dev, "i2c bus %d registered (%s mode), irq %d\n", -- bus->adap.nr, bus->buf_base ? "buffer" : "byte", irq); -+ bus->adap.nr, bus->dma_buf ? "dma" : -+ bus->buf_base ? "buffer" : "byte", -+ irq); - - return 0; -+ -+out_free_dma_buf: -+ if (bus->dma_buf) -+ dma_pool_free(bus->dma_pool, bus->dma_buf, bus->dma_handle); -+ dma_pool_destroy(bus->dma_pool); -+ -+ return ret; - } - - static int aspeed_i2c_remove_bus(struct platform_device *pdev) -@@ -1400,6 +1561,10 @@ static int aspeed_i2c_remove_bus(struct platform_device *pdev) - - reset_control_assert(bus->rst); - -+ if (bus->dma_buf) -+ dma_pool_free(bus->dma_pool, bus->dma_buf, bus->dma_handle); -+ dma_pool_destroy(bus->dma_pool); -+ - i2c_del_adapter(&bus->adap); - - return 0; --- -2.7.4 - -- cgit v1.2.3