@@ -3,11 +3,10 @@ Device tree configuration for the I2C busses on the AST24XX and AST25XX SoCs.
Required Properties:
- #address-cells : should be 1
- #size-cells : should be 0
-- reg : address offset and range of bus registers and buffer
-- reg-names : "bus-regs" and "buf" are recognized by Aspeed I2C
- driver. "bus-regs" is default. "buf" is optional in
- case of enabling I2C dedicated SRAM for buffer mode
- transfer support
+- reg : Address offset and range of bus registers.
+ An additional SRAM buffer address offset and range is
+ optional in case of enabling I2C dedicated SRAM for
+ buffer mode transfer support.
- compatible : should be "aspeed,ast2400-i2c-bus"
or "aspeed,ast2500-i2c-bus"
- clocks : root clock of bus, should reference the APB
@@ -20,7 +19,7 @@ Optional Properties:
- bus-frequency : frequency of the bus clock in Hz defaults to 100 kHz when not
specified
- multi-master : states that there is another master active on this bus.
-- aspeed,dma-buf-size : should be 4096 in case of AST2500.
+- 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
@@ -61,7 +60,6 @@ i2c {
#size-cells = <0>;
#interrupt-cells = <1>;
reg = <0x40 0x40>;
- reg-names = "bus-regs";
compatible = "aspeed,ast2500-i2c-bus";
clocks = <&syscon ASPEED_CLK_APB>;
resets = <&syscon ASPEED_RESET_I2C>;
@@ -76,7 +74,6 @@ i2c {
#size-cells = <0>;
#interrupt-cells = <1>;
reg = <0x80 0x40>, <0x210 0x10>;
- reg-names = "bus-regs", "buf";
compatible = "aspeed,ast2500-i2c-bus";
clocks = <&syscon ASPEED_CLK_APB>;
resets = <&syscon ASPEED_RESET_I2C>;
@@ -91,7 +88,6 @@ i2c {
#size-cells = <0>;
#interrupt-cells = <1>;
reg = <0xc0 0x40>;
- reg-names = "bus-regs";
aspeed,dma-buf-size = <4095>;
compatible = "aspeed,ast2500-i2c-bus";
clocks = <&syscon ASPEED_CLK_APB>;
@@ -140,6 +140,7 @@
#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 {
@@ -303,10 +304,12 @@ static u32 aspeed_i2c_slave_irq(struct aspeed_i2c_bus *bus, u32 irq_status)
/* Slave was sent something. */
if (irq_status & ASPEED_I2CD_INTR_RX_DONE) {
if (bus->dma_buf &&
- bus->slave_state == ASPEED_I2C_SLAVE_WRITE_RECEIVED)
+ 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)
+ bus->slave_state == ASPEED_I2C_SLAVE_WRITE_RECEIVED &&
+ !(irq_status & ASPEED_I2CD_INTR_NORMAL_STOP))
value = readb(bus->buf_base);
else
value = readl(bus->base + ASPEED_I2C_BYTE_BUF_REG) >> 8;
@@ -324,28 +327,29 @@ static u32 aspeed_i2c_slave_irq(struct aspeed_i2c_bus *bus, u32 irq_status)
/* Slave was asked to stop. */
if (irq_status & ASPEED_I2CD_INTR_NORMAL_STOP) {
- if (bus->dma_buf &&
- bus->slave_state == ASPEED_I2C_SLAVE_WRITE_RECEIVED) {
- len = bus->dma_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(slave,
- I2C_SLAVE_WRITE_RECEIVED,
- &value);
- }
- } else if (bus->buf_base &&
- bus->slave_state == ASPEED_I2C_SLAVE_WRITE_RECEIVED) {
- len = FIELD_GET(ASPEED_I2CD_BUF_RX_COUNT_MASK,
- readl(bus->base +
- ASPEED_I2C_BUF_CTRL_REG));
- for (i = 0; i < len; i++) {
- value = readb(bus->buf_base + i);
- i2c_slave_event(slave,
- I2C_SLAVE_WRITE_RECEIVED,
- &value);
+ if (bus->slave_state == ASPEED_I2C_SLAVE_WRITE_RECEIVED &&
+ irq_status & ASPEED_I2CD_INTR_RX_DONE) {
+ if (bus->dma_buf) {
+ len = bus->dma_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(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));
+ for (i = 0; i < len; i++) {
+ value = readb(bus->buf_base + i);
+ i2c_slave_event(slave,
+ I2C_SLAVE_WRITE_RECEIVED,
+ &value);
+ }
}
}
irq_handled |= ASPEED_I2CD_INTR_NORMAL_STOP;
@@ -1280,15 +1284,13 @@ static int aspeed_i2c_probe_bus(struct platform_device *pdev)
struct aspeed_i2c_bus *bus;
bool sram_enabled = true;
struct clk *parent_clk;
- struct resource *res;
int irq, ret;
bus = devm_kzalloc(&pdev->dev, sizeof(*bus), GFP_KERNEL);
if (!bus)
return -ENOMEM;
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "bus-regs");
- bus->base = devm_ioremap_resource(&pdev->dev, res);
+ bus->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(bus->base))
return PTR_ERR(bus->base);
@@ -1351,11 +1353,14 @@ static int aspeed_i2c_probe_bus(struct platform_device *pdev)
if (sram_enabled && !IS_ENABLED(CONFIG_USB_UHCI_ASPEED) &&
of_device_is_compatible(pdev->dev.of_node,
"aspeed,ast2500-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->dma_buf_size);
- if (!ret && bus->dma_buf_size > ASPEED_I2CD_DMA_LEN_MASK)
- bus->dma_buf_size = ASPEED_I2CD_DMA_LEN_MASK;
+ if (!ret && bus->dma_buf_size > dma_len_max)
+ bus->dma_buf_size = dma_len_max;
}
if (bus->dma_buf_size) {
@@ -1381,7 +1386,9 @@ static int aspeed_i2c_probe_bus(struct platform_device *pdev)
}
if (!bus->dma_buf && sram_enabled) {
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "buf");
+ struct resource *res = platform_get_resource(pdev,
+ IORESOURCE_MEM, 1);
+
bus->buf_base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(bus->buf_base) || resource_size(res) < 2) {
bus->buf_base = NULL;
This moves the aspeed i2c driver to the v3 RFC that Jae posted. This version has backwards compatibility with the old device tree binding, allowing us to disable the changes until the Qemu model has been updated to support buffer mode. Signed-off-by: Joel Stanley <joel@jms.id.au> --- .../devicetree/bindings/i2c/i2c-aspeed.txt | 14 ++-- drivers/i2c/busses/i2c-aspeed.c | 67 ++++++++++--------- 2 files changed, 42 insertions(+), 39 deletions(-)