^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (c) 2018 Synopsys, Inc. and/or its affiliates.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Author: Vitor Soares <vitor.soares@synopsys.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/bitops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/completion.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/i3c/master.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/ioport.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/iopoll.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/list.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/reset.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define DEVICE_CTRL 0x0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define DEV_CTRL_ENABLE BIT(31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define DEV_CTRL_RESUME BIT(30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define DEV_CTRL_HOT_JOIN_NACK BIT(8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define DEV_CTRL_I2C_SLAVE_PRESENT BIT(7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define DEVICE_ADDR 0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define DEV_ADDR_DYNAMIC_ADDR_VALID BIT(31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define DEV_ADDR_DYNAMIC(x) (((x) << 16) & GENMASK(22, 16))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define HW_CAPABILITY 0x8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define COMMAND_QUEUE_PORT 0xc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define COMMAND_PORT_TOC BIT(30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define COMMAND_PORT_READ_TRANSFER BIT(28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define COMMAND_PORT_SDAP BIT(27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define COMMAND_PORT_ROC BIT(26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define COMMAND_PORT_SPEED(x) (((x) << 21) & GENMASK(23, 21))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define COMMAND_PORT_DEV_INDEX(x) (((x) << 16) & GENMASK(20, 16))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define COMMAND_PORT_CP BIT(15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define COMMAND_PORT_CMD(x) (((x) << 7) & GENMASK(14, 7))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define COMMAND_PORT_TID(x) (((x) << 3) & GENMASK(6, 3))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define COMMAND_PORT_ARG_DATA_LEN(x) (((x) << 16) & GENMASK(31, 16))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define COMMAND_PORT_ARG_DATA_LEN_MAX 65536
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define COMMAND_PORT_TRANSFER_ARG 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define COMMAND_PORT_SDA_DATA_BYTE_3(x) (((x) << 24) & GENMASK(31, 24))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define COMMAND_PORT_SDA_DATA_BYTE_2(x) (((x) << 16) & GENMASK(23, 16))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define COMMAND_PORT_SDA_DATA_BYTE_1(x) (((x) << 8) & GENMASK(15, 8))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define COMMAND_PORT_SDA_BYTE_STRB_3 BIT(5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define COMMAND_PORT_SDA_BYTE_STRB_2 BIT(4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define COMMAND_PORT_SDA_BYTE_STRB_1 BIT(3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define COMMAND_PORT_SHORT_DATA_ARG 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #define COMMAND_PORT_DEV_COUNT(x) (((x) << 21) & GENMASK(25, 21))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #define COMMAND_PORT_ADDR_ASSGN_CMD 0x03
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define RESPONSE_QUEUE_PORT 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define RESPONSE_PORT_ERR_STATUS(x) (((x) & GENMASK(31, 28)) >> 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define RESPONSE_NO_ERROR 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define RESPONSE_ERROR_CRC 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define RESPONSE_ERROR_PARITY 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #define RESPONSE_ERROR_FRAME 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #define RESPONSE_ERROR_IBA_NACK 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #define RESPONSE_ERROR_ADDRESS_NACK 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #define RESPONSE_ERROR_OVER_UNDER_FLOW 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #define RESPONSE_ERROR_TRANSF_ABORT 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define RESPONSE_ERROR_I2C_W_NACK_ERR 9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define RESPONSE_PORT_TID(x) (((x) & GENMASK(27, 24)) >> 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define RESPONSE_PORT_DATA_LEN(x) ((x) & GENMASK(15, 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #define RX_TX_DATA_PORT 0x14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #define IBI_QUEUE_STATUS 0x18
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #define QUEUE_THLD_CTRL 0x1c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #define QUEUE_THLD_CTRL_RESP_BUF_MASK GENMASK(15, 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #define QUEUE_THLD_CTRL_RESP_BUF(x) (((x) - 1) << 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) #define DATA_BUFFER_THLD_CTRL 0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #define DATA_BUFFER_THLD_CTRL_RX_BUF GENMASK(11, 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #define IBI_QUEUE_CTRL 0x24
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) #define IBI_MR_REQ_REJECT 0x2C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) #define IBI_SIR_REQ_REJECT 0x30
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) #define IBI_REQ_REJECT_ALL GENMASK(31, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) #define RESET_CTRL 0x34
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) #define RESET_CTRL_IBI_QUEUE BIT(5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) #define RESET_CTRL_RX_FIFO BIT(4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) #define RESET_CTRL_TX_FIFO BIT(3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) #define RESET_CTRL_RESP_QUEUE BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) #define RESET_CTRL_CMD_QUEUE BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) #define RESET_CTRL_SOFT BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) #define SLV_EVENT_CTRL 0x38
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) #define INTR_STATUS 0x3c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) #define INTR_STATUS_EN 0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) #define INTR_SIGNAL_EN 0x44
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) #define INTR_FORCE 0x48
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) #define INTR_BUSOWNER_UPDATE_STAT BIT(13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) #define INTR_IBI_UPDATED_STAT BIT(12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) #define INTR_READ_REQ_RECV_STAT BIT(11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) #define INTR_DEFSLV_STAT BIT(10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) #define INTR_TRANSFER_ERR_STAT BIT(9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) #define INTR_DYN_ADDR_ASSGN_STAT BIT(8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) #define INTR_CCC_UPDATED_STAT BIT(6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) #define INTR_TRANSFER_ABORT_STAT BIT(5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) #define INTR_RESP_READY_STAT BIT(4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) #define INTR_CMD_QUEUE_READY_STAT BIT(3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) #define INTR_IBI_THLD_STAT BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) #define INTR_RX_THLD_STAT BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) #define INTR_TX_THLD_STAT BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) #define INTR_ALL (INTR_BUSOWNER_UPDATE_STAT | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) INTR_IBI_UPDATED_STAT | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) INTR_READ_REQ_RECV_STAT | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) INTR_DEFSLV_STAT | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) INTR_TRANSFER_ERR_STAT | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) INTR_DYN_ADDR_ASSGN_STAT | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) INTR_CCC_UPDATED_STAT | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) INTR_TRANSFER_ABORT_STAT | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) INTR_RESP_READY_STAT | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) INTR_CMD_QUEUE_READY_STAT | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) INTR_IBI_THLD_STAT | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) INTR_TX_THLD_STAT | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) INTR_RX_THLD_STAT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) #define INTR_MASTER_MASK (INTR_TRANSFER_ERR_STAT | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) INTR_RESP_READY_STAT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) #define QUEUE_STATUS_LEVEL 0x4c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) #define QUEUE_STATUS_IBI_STATUS_CNT(x) (((x) & GENMASK(28, 24)) >> 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) #define QUEUE_STATUS_IBI_BUF_BLR(x) (((x) & GENMASK(23, 16)) >> 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) #define QUEUE_STATUS_LEVEL_RESP(x) (((x) & GENMASK(15, 8)) >> 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) #define QUEUE_STATUS_LEVEL_CMD(x) ((x) & GENMASK(7, 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) #define DATA_BUFFER_STATUS_LEVEL 0x50
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) #define DATA_BUFFER_STATUS_LEVEL_TX(x) ((x) & GENMASK(7, 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) #define PRESENT_STATE 0x54
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) #define CCC_DEVICE_STATUS 0x58
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) #define DEVICE_ADDR_TABLE_POINTER 0x5c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) #define DEVICE_ADDR_TABLE_DEPTH(x) (((x) & GENMASK(31, 16)) >> 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) #define DEVICE_ADDR_TABLE_ADDR(x) ((x) & GENMASK(7, 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) #define DEV_CHAR_TABLE_POINTER 0x60
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) #define VENDOR_SPECIFIC_REG_POINTER 0x6c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) #define SLV_PID_VALUE 0x74
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) #define SLV_CHAR_CTRL 0x78
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) #define SLV_MAX_LEN 0x7c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) #define MAX_READ_TURNAROUND 0x80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) #define MAX_DATA_SPEED 0x84
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) #define SLV_DEBUG_STATUS 0x88
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) #define SLV_INTR_REQ 0x8c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) #define DEVICE_CTRL_EXTENDED 0xb0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) #define SCL_I3C_OD_TIMING 0xb4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) #define SCL_I3C_PP_TIMING 0xb8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) #define SCL_I3C_TIMING_HCNT(x) (((x) << 16) & GENMASK(23, 16))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) #define SCL_I3C_TIMING_LCNT(x) ((x) & GENMASK(7, 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) #define SCL_I3C_TIMING_CNT_MIN 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) #define SCL_I2C_FM_TIMING 0xbc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) #define SCL_I2C_FM_TIMING_HCNT(x) (((x) << 16) & GENMASK(31, 16))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) #define SCL_I2C_FM_TIMING_LCNT(x) ((x) & GENMASK(15, 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) #define SCL_I2C_FMP_TIMING 0xc0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) #define SCL_I2C_FMP_TIMING_HCNT(x) (((x) << 16) & GENMASK(23, 16))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) #define SCL_I2C_FMP_TIMING_LCNT(x) ((x) & GENMASK(15, 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) #define SCL_EXT_LCNT_TIMING 0xc8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) #define SCL_EXT_LCNT_4(x) (((x) << 24) & GENMASK(31, 24))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) #define SCL_EXT_LCNT_3(x) (((x) << 16) & GENMASK(23, 16))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) #define SCL_EXT_LCNT_2(x) (((x) << 8) & GENMASK(15, 8))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) #define SCL_EXT_LCNT_1(x) ((x) & GENMASK(7, 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) #define SCL_EXT_TERMN_LCNT_TIMING 0xcc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) #define BUS_FREE_TIMING 0xd4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) #define BUS_I3C_MST_FREE(x) ((x) & GENMASK(15, 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) #define BUS_IDLE_TIMING 0xd8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) #define I3C_VER_ID 0xe0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) #define I3C_VER_TYPE 0xe4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) #define EXTENDED_CAPABILITY 0xe8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) #define SLAVE_CONFIG 0xec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) #define DEV_ADDR_TABLE_LEGACY_I2C_DEV BIT(31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) #define DEV_ADDR_TABLE_DYNAMIC_ADDR(x) (((x) << 16) & GENMASK(23, 16))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) #define DEV_ADDR_TABLE_STATIC_ADDR(x) ((x) & GENMASK(6, 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) #define DEV_ADDR_TABLE_LOC(start, idx) ((start) + ((idx) << 2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) #define MAX_DEVS 32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) #define I3C_BUS_SDR1_SCL_RATE 8000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) #define I3C_BUS_SDR2_SCL_RATE 6000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) #define I3C_BUS_SDR3_SCL_RATE 4000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) #define I3C_BUS_SDR4_SCL_RATE 2000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) #define I3C_BUS_I2C_FM_TLOW_MIN_NS 1300
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) #define I3C_BUS_I2C_FMP_TLOW_MIN_NS 500
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) #define I3C_BUS_THIGH_MAX_NS 41
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) #define XFER_TIMEOUT (msecs_to_jiffies(1000))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) struct dw_i3c_master_caps {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) u8 cmdfifodepth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) u8 datafifodepth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) struct dw_i3c_cmd {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) u32 cmd_lo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) u32 cmd_hi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) u16 tx_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) const void *tx_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) u16 rx_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) void *rx_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) u8 error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) struct dw_i3c_xfer {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) struct list_head node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) struct completion comp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) unsigned int ncmds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) struct dw_i3c_cmd cmds[];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) struct dw_i3c_master {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) struct i3c_master_controller base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) u16 maxdevs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) u16 datstartaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) u32 free_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) struct list_head list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) struct dw_i3c_xfer *cur;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) spinlock_t lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) } xferqueue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) struct dw_i3c_master_caps caps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) void __iomem *regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) struct reset_control *core_rst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) struct clk *core_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) char version[5];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) char type[5];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) u8 addrs[MAX_DEVS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) struct dw_i3c_i2c_dev_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) u8 index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) static u8 even_parity(u8 p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) p ^= p >> 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) p &= 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) return (0x9669 >> p) & 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) static bool dw_i3c_master_supports_ccc_cmd(struct i3c_master_controller *m,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) const struct i3c_ccc_cmd *cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) if (cmd->ndests > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) switch (cmd->id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) case I3C_CCC_ENEC(true):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) case I3C_CCC_ENEC(false):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) case I3C_CCC_DISEC(true):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) case I3C_CCC_DISEC(false):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) case I3C_CCC_ENTAS(0, true):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) case I3C_CCC_ENTAS(0, false):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) case I3C_CCC_RSTDAA(true):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) case I3C_CCC_RSTDAA(false):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) case I3C_CCC_ENTDAA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) case I3C_CCC_SETMWL(true):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) case I3C_CCC_SETMWL(false):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) case I3C_CCC_SETMRL(true):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) case I3C_CCC_SETMRL(false):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) case I3C_CCC_ENTHDR(0):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) case I3C_CCC_SETDASA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) case I3C_CCC_SETNEWDA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) case I3C_CCC_GETMWL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) case I3C_CCC_GETMRL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) case I3C_CCC_GETPID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) case I3C_CCC_GETBCR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) case I3C_CCC_GETDCR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) case I3C_CCC_GETSTATUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) case I3C_CCC_GETMXDS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) case I3C_CCC_GETHDRCAP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) static inline struct dw_i3c_master *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) to_dw_i3c_master(struct i3c_master_controller *master)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) return container_of(master, struct dw_i3c_master, base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) static void dw_i3c_master_disable(struct dw_i3c_master *master)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) writel(readl(master->regs + DEVICE_CTRL) & ~DEV_CTRL_ENABLE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) master->regs + DEVICE_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) static void dw_i3c_master_enable(struct dw_i3c_master *master)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) writel(readl(master->regs + DEVICE_CTRL) | DEV_CTRL_ENABLE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) master->regs + DEVICE_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) static int dw_i3c_master_get_addr_pos(struct dw_i3c_master *master, u8 addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) int pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) for (pos = 0; pos < master->maxdevs; pos++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) if (addr == master->addrs[pos])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) return pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) static int dw_i3c_master_get_free_pos(struct dw_i3c_master *master)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) if (!(master->free_pos & GENMASK(master->maxdevs - 1, 0)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) return -ENOSPC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) return ffs(master->free_pos) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) static void dw_i3c_master_wr_tx_fifo(struct dw_i3c_master *master,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) const u8 *bytes, int nbytes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) writesl(master->regs + RX_TX_DATA_PORT, bytes, nbytes / 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) if (nbytes & 3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) u32 tmp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) memcpy(&tmp, bytes + (nbytes & ~3), nbytes & 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) writesl(master->regs + RX_TX_DATA_PORT, &tmp, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) static void dw_i3c_master_read_rx_fifo(struct dw_i3c_master *master,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) u8 *bytes, int nbytes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) readsl(master->regs + RX_TX_DATA_PORT, bytes, nbytes / 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) if (nbytes & 3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) u32 tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) readsl(master->regs + RX_TX_DATA_PORT, &tmp, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) memcpy(bytes + (nbytes & ~3), &tmp, nbytes & 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) static struct dw_i3c_xfer *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) dw_i3c_master_alloc_xfer(struct dw_i3c_master *master, unsigned int ncmds)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) struct dw_i3c_xfer *xfer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) xfer = kzalloc(struct_size(xfer, cmds, ncmds), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) if (!xfer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) INIT_LIST_HEAD(&xfer->node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) xfer->ncmds = ncmds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) xfer->ret = -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) return xfer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) static void dw_i3c_master_free_xfer(struct dw_i3c_xfer *xfer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) kfree(xfer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) static void dw_i3c_master_start_xfer_locked(struct dw_i3c_master *master)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) struct dw_i3c_xfer *xfer = master->xferqueue.cur;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) u32 thld_ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) if (!xfer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) for (i = 0; i < xfer->ncmds; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) struct dw_i3c_cmd *cmd = &xfer->cmds[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) dw_i3c_master_wr_tx_fifo(master, cmd->tx_buf, cmd->tx_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) thld_ctrl = readl(master->regs + QUEUE_THLD_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) thld_ctrl &= ~QUEUE_THLD_CTRL_RESP_BUF_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) thld_ctrl |= QUEUE_THLD_CTRL_RESP_BUF(xfer->ncmds);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) writel(thld_ctrl, master->regs + QUEUE_THLD_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) for (i = 0; i < xfer->ncmds; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) struct dw_i3c_cmd *cmd = &xfer->cmds[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) writel(cmd->cmd_hi, master->regs + COMMAND_QUEUE_PORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) writel(cmd->cmd_lo, master->regs + COMMAND_QUEUE_PORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) static void dw_i3c_master_enqueue_xfer(struct dw_i3c_master *master,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) struct dw_i3c_xfer *xfer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) init_completion(&xfer->comp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) spin_lock_irqsave(&master->xferqueue.lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) if (master->xferqueue.cur) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) list_add_tail(&xfer->node, &master->xferqueue.list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) master->xferqueue.cur = xfer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) dw_i3c_master_start_xfer_locked(master);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) spin_unlock_irqrestore(&master->xferqueue.lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) static void dw_i3c_master_dequeue_xfer_locked(struct dw_i3c_master *master,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) struct dw_i3c_xfer *xfer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) if (master->xferqueue.cur == xfer) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) u32 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) master->xferqueue.cur = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) writel(RESET_CTRL_RX_FIFO | RESET_CTRL_TX_FIFO |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) RESET_CTRL_RESP_QUEUE | RESET_CTRL_CMD_QUEUE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) master->regs + RESET_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) readl_poll_timeout_atomic(master->regs + RESET_CTRL, status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) !status, 10, 1000000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) list_del_init(&xfer->node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) static void dw_i3c_master_dequeue_xfer(struct dw_i3c_master *master,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) struct dw_i3c_xfer *xfer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) spin_lock_irqsave(&master->xferqueue.lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) dw_i3c_master_dequeue_xfer_locked(master, xfer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) spin_unlock_irqrestore(&master->xferqueue.lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) static void dw_i3c_master_end_xfer_locked(struct dw_i3c_master *master, u32 isr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) struct dw_i3c_xfer *xfer = master->xferqueue.cur;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) int i, ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) u32 nresp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) if (!xfer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) nresp = readl(master->regs + QUEUE_STATUS_LEVEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) nresp = QUEUE_STATUS_LEVEL_RESP(nresp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) for (i = 0; i < nresp; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) struct dw_i3c_cmd *cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) u32 resp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) resp = readl(master->regs + RESPONSE_QUEUE_PORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) cmd = &xfer->cmds[RESPONSE_PORT_TID(resp)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) cmd->rx_len = RESPONSE_PORT_DATA_LEN(resp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) cmd->error = RESPONSE_PORT_ERR_STATUS(resp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) if (cmd->rx_len && !cmd->error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) dw_i3c_master_read_rx_fifo(master, cmd->rx_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) cmd->rx_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) for (i = 0; i < nresp; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) switch (xfer->cmds[i].error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) case RESPONSE_NO_ERROR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) case RESPONSE_ERROR_PARITY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) case RESPONSE_ERROR_IBA_NACK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) case RESPONSE_ERROR_TRANSF_ABORT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) case RESPONSE_ERROR_CRC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) case RESPONSE_ERROR_FRAME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) case RESPONSE_ERROR_OVER_UNDER_FLOW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) ret = -ENOSPC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) case RESPONSE_ERROR_I2C_W_NACK_ERR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) case RESPONSE_ERROR_ADDRESS_NACK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) xfer->ret = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) complete(&xfer->comp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) dw_i3c_master_dequeue_xfer_locked(master, xfer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) writel(readl(master->regs + DEVICE_CTRL) | DEV_CTRL_RESUME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) master->regs + DEVICE_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) xfer = list_first_entry_or_null(&master->xferqueue.list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) struct dw_i3c_xfer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) if (xfer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) list_del_init(&xfer->node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) master->xferqueue.cur = xfer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) dw_i3c_master_start_xfer_locked(master);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) static int dw_i3c_clk_cfg(struct dw_i3c_master *master)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) unsigned long core_rate, core_period;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) u32 scl_timing;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) u8 hcnt, lcnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) core_rate = clk_get_rate(master->core_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) if (!core_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) core_period = DIV_ROUND_UP(1000000000, core_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) hcnt = DIV_ROUND_UP(I3C_BUS_THIGH_MAX_NS, core_period) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) if (hcnt < SCL_I3C_TIMING_CNT_MIN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) hcnt = SCL_I3C_TIMING_CNT_MIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) lcnt = DIV_ROUND_UP(core_rate, I3C_BUS_TYP_I3C_SCL_RATE) - hcnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) if (lcnt < SCL_I3C_TIMING_CNT_MIN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) lcnt = SCL_I3C_TIMING_CNT_MIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) scl_timing = SCL_I3C_TIMING_HCNT(hcnt) | SCL_I3C_TIMING_LCNT(lcnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) writel(scl_timing, master->regs + SCL_I3C_PP_TIMING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) if (!(readl(master->regs + DEVICE_CTRL) & DEV_CTRL_I2C_SLAVE_PRESENT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) writel(BUS_I3C_MST_FREE(lcnt), master->regs + BUS_FREE_TIMING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) lcnt = DIV_ROUND_UP(I3C_BUS_TLOW_OD_MIN_NS, core_period);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) scl_timing = SCL_I3C_TIMING_HCNT(hcnt) | SCL_I3C_TIMING_LCNT(lcnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) writel(scl_timing, master->regs + SCL_I3C_OD_TIMING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) lcnt = DIV_ROUND_UP(core_rate, I3C_BUS_SDR1_SCL_RATE) - hcnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) scl_timing = SCL_EXT_LCNT_1(lcnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) lcnt = DIV_ROUND_UP(core_rate, I3C_BUS_SDR2_SCL_RATE) - hcnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) scl_timing |= SCL_EXT_LCNT_2(lcnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) lcnt = DIV_ROUND_UP(core_rate, I3C_BUS_SDR3_SCL_RATE) - hcnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) scl_timing |= SCL_EXT_LCNT_3(lcnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) lcnt = DIV_ROUND_UP(core_rate, I3C_BUS_SDR4_SCL_RATE) - hcnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) scl_timing |= SCL_EXT_LCNT_4(lcnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) writel(scl_timing, master->regs + SCL_EXT_LCNT_TIMING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) static int dw_i2c_clk_cfg(struct dw_i3c_master *master)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) unsigned long core_rate, core_period;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) u16 hcnt, lcnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) u32 scl_timing;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) core_rate = clk_get_rate(master->core_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) if (!core_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) core_period = DIV_ROUND_UP(1000000000, core_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) lcnt = DIV_ROUND_UP(I3C_BUS_I2C_FMP_TLOW_MIN_NS, core_period);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) hcnt = DIV_ROUND_UP(core_rate, I3C_BUS_I2C_FM_PLUS_SCL_RATE) - lcnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) scl_timing = SCL_I2C_FMP_TIMING_HCNT(hcnt) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) SCL_I2C_FMP_TIMING_LCNT(lcnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) writel(scl_timing, master->regs + SCL_I2C_FMP_TIMING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) lcnt = DIV_ROUND_UP(I3C_BUS_I2C_FM_TLOW_MIN_NS, core_period);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) hcnt = DIV_ROUND_UP(core_rate, I3C_BUS_I2C_FM_SCL_RATE) - lcnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) scl_timing = SCL_I2C_FM_TIMING_HCNT(hcnt) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) SCL_I2C_FM_TIMING_LCNT(lcnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) writel(scl_timing, master->regs + SCL_I2C_FM_TIMING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) writel(BUS_I3C_MST_FREE(lcnt), master->regs + BUS_FREE_TIMING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) writel(readl(master->regs + DEVICE_CTRL) | DEV_CTRL_I2C_SLAVE_PRESENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) master->regs + DEVICE_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) static int dw_i3c_master_bus_init(struct i3c_master_controller *m)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) struct dw_i3c_master *master = to_dw_i3c_master(m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) struct i3c_bus *bus = i3c_master_get_bus(m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) struct i3c_device_info info = { };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) u32 thld_ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) switch (bus->mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) case I3C_BUS_MODE_MIXED_FAST:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) case I3C_BUS_MODE_MIXED_LIMITED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) ret = dw_i2c_clk_cfg(master);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) case I3C_BUS_MODE_PURE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) ret = dw_i3c_clk_cfg(master);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) thld_ctrl = readl(master->regs + QUEUE_THLD_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) thld_ctrl &= ~QUEUE_THLD_CTRL_RESP_BUF_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) writel(thld_ctrl, master->regs + QUEUE_THLD_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) thld_ctrl = readl(master->regs + DATA_BUFFER_THLD_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) thld_ctrl &= ~DATA_BUFFER_THLD_CTRL_RX_BUF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) writel(thld_ctrl, master->regs + DATA_BUFFER_THLD_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) writel(INTR_ALL, master->regs + INTR_STATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) writel(INTR_MASTER_MASK, master->regs + INTR_STATUS_EN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) writel(INTR_MASTER_MASK, master->regs + INTR_SIGNAL_EN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) ret = i3c_master_get_free_addr(m, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) writel(DEV_ADDR_DYNAMIC_ADDR_VALID | DEV_ADDR_DYNAMIC(ret),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) master->regs + DEVICE_ADDR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) memset(&info, 0, sizeof(info));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) info.dyn_addr = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) ret = i3c_master_set_info(&master->base, &info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) writel(IBI_REQ_REJECT_ALL, master->regs + IBI_SIR_REQ_REJECT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) writel(IBI_REQ_REJECT_ALL, master->regs + IBI_MR_REQ_REJECT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) /* For now don't support Hot-Join */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) writel(readl(master->regs + DEVICE_CTRL) | DEV_CTRL_HOT_JOIN_NACK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) master->regs + DEVICE_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) dw_i3c_master_enable(master);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) static void dw_i3c_master_bus_cleanup(struct i3c_master_controller *m)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) struct dw_i3c_master *master = to_dw_i3c_master(m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) dw_i3c_master_disable(master);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) static int dw_i3c_ccc_set(struct dw_i3c_master *master,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) struct i3c_ccc_cmd *ccc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) struct dw_i3c_xfer *xfer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) struct dw_i3c_cmd *cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) int ret, pos = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) if (ccc->id & I3C_CCC_DIRECT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) pos = dw_i3c_master_get_addr_pos(master, ccc->dests[0].addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) if (pos < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) return pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) xfer = dw_i3c_master_alloc_xfer(master, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) if (!xfer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) cmd = xfer->cmds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) cmd->tx_buf = ccc->dests[0].payload.data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) cmd->tx_len = ccc->dests[0].payload.len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) cmd->cmd_hi = COMMAND_PORT_ARG_DATA_LEN(ccc->dests[0].payload.len) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) COMMAND_PORT_TRANSFER_ARG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) cmd->cmd_lo = COMMAND_PORT_CP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) COMMAND_PORT_DEV_INDEX(pos) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) COMMAND_PORT_CMD(ccc->id) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) COMMAND_PORT_TOC |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) COMMAND_PORT_ROC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) dw_i3c_master_enqueue_xfer(master, xfer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) if (!wait_for_completion_timeout(&xfer->comp, XFER_TIMEOUT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) dw_i3c_master_dequeue_xfer(master, xfer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) ret = xfer->ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) if (xfer->cmds[0].error == RESPONSE_ERROR_IBA_NACK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) ccc->err = I3C_ERROR_M2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) dw_i3c_master_free_xfer(xfer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) static int dw_i3c_ccc_get(struct dw_i3c_master *master, struct i3c_ccc_cmd *ccc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) struct dw_i3c_xfer *xfer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) struct dw_i3c_cmd *cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) int ret, pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) pos = dw_i3c_master_get_addr_pos(master, ccc->dests[0].addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) if (pos < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) return pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) xfer = dw_i3c_master_alloc_xfer(master, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) if (!xfer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) cmd = xfer->cmds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) cmd->rx_buf = ccc->dests[0].payload.data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) cmd->rx_len = ccc->dests[0].payload.len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) cmd->cmd_hi = COMMAND_PORT_ARG_DATA_LEN(ccc->dests[0].payload.len) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) COMMAND_PORT_TRANSFER_ARG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) cmd->cmd_lo = COMMAND_PORT_READ_TRANSFER |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) COMMAND_PORT_CP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) COMMAND_PORT_DEV_INDEX(pos) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) COMMAND_PORT_CMD(ccc->id) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) COMMAND_PORT_TOC |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) COMMAND_PORT_ROC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) dw_i3c_master_enqueue_xfer(master, xfer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) if (!wait_for_completion_timeout(&xfer->comp, XFER_TIMEOUT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) dw_i3c_master_dequeue_xfer(master, xfer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) ret = xfer->ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) if (xfer->cmds[0].error == RESPONSE_ERROR_IBA_NACK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) ccc->err = I3C_ERROR_M2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) dw_i3c_master_free_xfer(xfer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) static int dw_i3c_master_send_ccc_cmd(struct i3c_master_controller *m,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) struct i3c_ccc_cmd *ccc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) struct dw_i3c_master *master = to_dw_i3c_master(m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) if (ccc->id == I3C_CCC_ENTDAA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) if (ccc->rnw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) ret = dw_i3c_ccc_get(master, ccc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) ret = dw_i3c_ccc_set(master, ccc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) static int dw_i3c_master_daa(struct i3c_master_controller *m)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) struct dw_i3c_master *master = to_dw_i3c_master(m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) struct dw_i3c_xfer *xfer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) struct dw_i3c_cmd *cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) u32 olddevs, newdevs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) u8 p, last_addr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) int ret, pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) olddevs = ~(master->free_pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) /* Prepare DAT before launching DAA. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) for (pos = 0; pos < master->maxdevs; pos++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) if (olddevs & BIT(pos))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) ret = i3c_master_get_free_addr(m, last_addr + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) return -ENOSPC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) master->addrs[pos] = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) p = even_parity(ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) last_addr = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) ret |= (p << 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) writel(DEV_ADDR_TABLE_DYNAMIC_ADDR(ret),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) master->regs +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) DEV_ADDR_TABLE_LOC(master->datstartaddr, pos));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) xfer = dw_i3c_master_alloc_xfer(master, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) if (!xfer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) pos = dw_i3c_master_get_free_pos(master);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) cmd = &xfer->cmds[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) cmd->cmd_hi = 0x1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) cmd->cmd_lo = COMMAND_PORT_DEV_COUNT(master->maxdevs - pos) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) COMMAND_PORT_DEV_INDEX(pos) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) COMMAND_PORT_CMD(I3C_CCC_ENTDAA) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) COMMAND_PORT_ADDR_ASSGN_CMD |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) COMMAND_PORT_TOC |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) COMMAND_PORT_ROC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) dw_i3c_master_enqueue_xfer(master, xfer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) if (!wait_for_completion_timeout(&xfer->comp, XFER_TIMEOUT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) dw_i3c_master_dequeue_xfer(master, xfer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) newdevs = GENMASK(master->maxdevs - cmd->rx_len - 1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) newdevs &= ~olddevs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) for (pos = 0; pos < master->maxdevs; pos++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) if (newdevs & BIT(pos))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) i3c_master_add_i3c_dev_locked(m, master->addrs[pos]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) dw_i3c_master_free_xfer(xfer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) i3c_master_disec_locked(m, I3C_BROADCAST_ADDR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) I3C_CCC_EVENT_HJ |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) I3C_CCC_EVENT_MR |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) I3C_CCC_EVENT_SIR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) static int dw_i3c_master_priv_xfers(struct i3c_dev_desc *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) struct i3c_priv_xfer *i3c_xfers,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) int i3c_nxfers)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) struct dw_i3c_i2c_dev_data *data = i3c_dev_get_master_data(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) struct i3c_master_controller *m = i3c_dev_get_master(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) struct dw_i3c_master *master = to_dw_i3c_master(m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) unsigned int nrxwords = 0, ntxwords = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) struct dw_i3c_xfer *xfer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) int i, ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) if (!i3c_nxfers)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) if (i3c_nxfers > master->caps.cmdfifodepth)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) return -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) for (i = 0; i < i3c_nxfers; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) if (i3c_xfers[i].rnw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) nrxwords += DIV_ROUND_UP(i3c_xfers[i].len, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) ntxwords += DIV_ROUND_UP(i3c_xfers[i].len, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) if (ntxwords > master->caps.datafifodepth ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) nrxwords > master->caps.datafifodepth)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) return -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) xfer = dw_i3c_master_alloc_xfer(master, i3c_nxfers);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) if (!xfer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) for (i = 0; i < i3c_nxfers; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) struct dw_i3c_cmd *cmd = &xfer->cmds[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) cmd->cmd_hi = COMMAND_PORT_ARG_DATA_LEN(i3c_xfers[i].len) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) COMMAND_PORT_TRANSFER_ARG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) if (i3c_xfers[i].rnw) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) cmd->rx_buf = i3c_xfers[i].data.in;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) cmd->rx_len = i3c_xfers[i].len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) cmd->cmd_lo = COMMAND_PORT_READ_TRANSFER |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) COMMAND_PORT_SPEED(dev->info.max_read_ds);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) cmd->tx_buf = i3c_xfers[i].data.out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) cmd->tx_len = i3c_xfers[i].len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) cmd->cmd_lo =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) COMMAND_PORT_SPEED(dev->info.max_write_ds);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) cmd->cmd_lo |= COMMAND_PORT_TID(i) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) COMMAND_PORT_DEV_INDEX(data->index) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) COMMAND_PORT_ROC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) if (i == (i3c_nxfers - 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) cmd->cmd_lo |= COMMAND_PORT_TOC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) dw_i3c_master_enqueue_xfer(master, xfer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) if (!wait_for_completion_timeout(&xfer->comp, XFER_TIMEOUT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) dw_i3c_master_dequeue_xfer(master, xfer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) ret = xfer->ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) dw_i3c_master_free_xfer(xfer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) static int dw_i3c_master_reattach_i3c_dev(struct i3c_dev_desc *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) u8 old_dyn_addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) struct dw_i3c_i2c_dev_data *data = i3c_dev_get_master_data(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) struct i3c_master_controller *m = i3c_dev_get_master(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) struct dw_i3c_master *master = to_dw_i3c_master(m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) int pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) pos = dw_i3c_master_get_free_pos(master);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) if (data->index > pos && pos > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) writel(0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) master->regs +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) DEV_ADDR_TABLE_LOC(master->datstartaddr, data->index));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) master->addrs[data->index] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) master->free_pos |= BIT(data->index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) data->index = pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) master->addrs[pos] = dev->info.dyn_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) master->free_pos &= ~BIT(pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) writel(DEV_ADDR_TABLE_DYNAMIC_ADDR(dev->info.dyn_addr),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) master->regs +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) DEV_ADDR_TABLE_LOC(master->datstartaddr, data->index));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) master->addrs[data->index] = dev->info.dyn_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) static int dw_i3c_master_attach_i3c_dev(struct i3c_dev_desc *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) struct i3c_master_controller *m = i3c_dev_get_master(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) struct dw_i3c_master *master = to_dw_i3c_master(m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) struct dw_i3c_i2c_dev_data *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) int pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) pos = dw_i3c_master_get_free_pos(master);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) if (pos < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) return pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) data = kzalloc(sizeof(*data), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) if (!data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) data->index = pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) master->addrs[pos] = dev->info.dyn_addr ? : dev->info.static_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) master->free_pos &= ~BIT(pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) i3c_dev_set_master_data(dev, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) writel(DEV_ADDR_TABLE_DYNAMIC_ADDR(master->addrs[pos]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) master->regs +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) DEV_ADDR_TABLE_LOC(master->datstartaddr, data->index));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) static void dw_i3c_master_detach_i3c_dev(struct i3c_dev_desc *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) struct dw_i3c_i2c_dev_data *data = i3c_dev_get_master_data(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) struct i3c_master_controller *m = i3c_dev_get_master(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) struct dw_i3c_master *master = to_dw_i3c_master(m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) writel(0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) master->regs +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) DEV_ADDR_TABLE_LOC(master->datstartaddr, data->index));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) i3c_dev_set_master_data(dev, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) master->addrs[data->index] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) master->free_pos |= BIT(data->index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) kfree(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) static int dw_i3c_master_i2c_xfers(struct i2c_dev_desc *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) const struct i2c_msg *i2c_xfers,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) int i2c_nxfers)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) struct dw_i3c_i2c_dev_data *data = i2c_dev_get_master_data(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) struct i3c_master_controller *m = i2c_dev_get_master(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) struct dw_i3c_master *master = to_dw_i3c_master(m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) unsigned int nrxwords = 0, ntxwords = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) struct dw_i3c_xfer *xfer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) int i, ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) if (!i2c_nxfers)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) if (i2c_nxfers > master->caps.cmdfifodepth)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) return -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) for (i = 0; i < i2c_nxfers; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) if (i2c_xfers[i].flags & I2C_M_RD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) nrxwords += DIV_ROUND_UP(i2c_xfers[i].len, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) ntxwords += DIV_ROUND_UP(i2c_xfers[i].len, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) if (ntxwords > master->caps.datafifodepth ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) nrxwords > master->caps.datafifodepth)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) return -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) xfer = dw_i3c_master_alloc_xfer(master, i2c_nxfers);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) if (!xfer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) for (i = 0; i < i2c_nxfers; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) struct dw_i3c_cmd *cmd = &xfer->cmds[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) cmd->cmd_hi = COMMAND_PORT_ARG_DATA_LEN(i2c_xfers[i].len) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) COMMAND_PORT_TRANSFER_ARG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) cmd->cmd_lo = COMMAND_PORT_TID(i) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) COMMAND_PORT_DEV_INDEX(data->index) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) COMMAND_PORT_ROC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) if (i2c_xfers[i].flags & I2C_M_RD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) cmd->cmd_lo |= COMMAND_PORT_READ_TRANSFER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) cmd->rx_buf = i2c_xfers[i].buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) cmd->rx_len = i2c_xfers[i].len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) cmd->tx_buf = i2c_xfers[i].buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) cmd->tx_len = i2c_xfers[i].len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) if (i == (i2c_nxfers - 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) cmd->cmd_lo |= COMMAND_PORT_TOC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) dw_i3c_master_enqueue_xfer(master, xfer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) if (!wait_for_completion_timeout(&xfer->comp, XFER_TIMEOUT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) dw_i3c_master_dequeue_xfer(master, xfer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) ret = xfer->ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) dw_i3c_master_free_xfer(xfer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) static int dw_i3c_master_attach_i2c_dev(struct i2c_dev_desc *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) struct i3c_master_controller *m = i2c_dev_get_master(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) struct dw_i3c_master *master = to_dw_i3c_master(m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) struct dw_i3c_i2c_dev_data *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) int pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) pos = dw_i3c_master_get_free_pos(master);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) if (pos < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) return pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) data = kzalloc(sizeof(*data), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) if (!data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) data->index = pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) master->addrs[pos] = dev->addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) master->free_pos &= ~BIT(pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) i2c_dev_set_master_data(dev, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) writel(DEV_ADDR_TABLE_LEGACY_I2C_DEV |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) DEV_ADDR_TABLE_STATIC_ADDR(dev->addr),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) master->regs +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) DEV_ADDR_TABLE_LOC(master->datstartaddr, data->index));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) static void dw_i3c_master_detach_i2c_dev(struct i2c_dev_desc *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) struct dw_i3c_i2c_dev_data *data = i2c_dev_get_master_data(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) struct i3c_master_controller *m = i2c_dev_get_master(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) struct dw_i3c_master *master = to_dw_i3c_master(m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) writel(0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) master->regs +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) DEV_ADDR_TABLE_LOC(master->datstartaddr, data->index));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) i2c_dev_set_master_data(dev, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) master->addrs[data->index] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) master->free_pos |= BIT(data->index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) kfree(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) static irqreturn_t dw_i3c_master_irq_handler(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) struct dw_i3c_master *master = dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) u32 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) status = readl(master->regs + INTR_STATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) if (!(status & readl(master->regs + INTR_STATUS_EN))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) writel(INTR_ALL, master->regs + INTR_STATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) return IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) spin_lock(&master->xferqueue.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) dw_i3c_master_end_xfer_locked(master, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) if (status & INTR_TRANSFER_ERR_STAT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) writel(INTR_TRANSFER_ERR_STAT, master->regs + INTR_STATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) spin_unlock(&master->xferqueue.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) static const struct i3c_master_controller_ops dw_mipi_i3c_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) .bus_init = dw_i3c_master_bus_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) .bus_cleanup = dw_i3c_master_bus_cleanup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) .attach_i3c_dev = dw_i3c_master_attach_i3c_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) .reattach_i3c_dev = dw_i3c_master_reattach_i3c_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) .detach_i3c_dev = dw_i3c_master_detach_i3c_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) .do_daa = dw_i3c_master_daa,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) .supports_ccc_cmd = dw_i3c_master_supports_ccc_cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) .send_ccc_cmd = dw_i3c_master_send_ccc_cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) .priv_xfers = dw_i3c_master_priv_xfers,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) .attach_i2c_dev = dw_i3c_master_attach_i2c_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) .detach_i2c_dev = dw_i3c_master_detach_i2c_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) .i2c_xfers = dw_i3c_master_i2c_xfers,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) static int dw_i3c_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) struct dw_i3c_master *master;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) int ret, irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) master = devm_kzalloc(&pdev->dev, sizeof(*master), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) if (!master)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) master->regs = devm_platform_ioremap_resource(pdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) if (IS_ERR(master->regs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) return PTR_ERR(master->regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) master->core_clk = devm_clk_get(&pdev->dev, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) if (IS_ERR(master->core_clk))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) return PTR_ERR(master->core_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) master->core_rst = devm_reset_control_get_optional_exclusive(&pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) "core_rst");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) if (IS_ERR(master->core_rst))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) return PTR_ERR(master->core_rst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) ret = clk_prepare_enable(master->core_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) goto err_disable_core_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) reset_control_deassert(master->core_rst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) spin_lock_init(&master->xferqueue.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) INIT_LIST_HEAD(&master->xferqueue.list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) writel(INTR_ALL, master->regs + INTR_STATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) irq = platform_get_irq(pdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) ret = devm_request_irq(&pdev->dev, irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) dw_i3c_master_irq_handler, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) dev_name(&pdev->dev), master);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) goto err_assert_rst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) platform_set_drvdata(pdev, master);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) /* Information regarding the FIFOs/QUEUEs depth */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) ret = readl(master->regs + QUEUE_STATUS_LEVEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) master->caps.cmdfifodepth = QUEUE_STATUS_LEVEL_CMD(ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) ret = readl(master->regs + DATA_BUFFER_STATUS_LEVEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) master->caps.datafifodepth = DATA_BUFFER_STATUS_LEVEL_TX(ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) ret = readl(master->regs + DEVICE_ADDR_TABLE_POINTER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) master->datstartaddr = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) master->maxdevs = ret >> 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) master->free_pos = GENMASK(master->maxdevs - 1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) ret = i3c_master_register(&master->base, &pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) &dw_mipi_i3c_ops, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) goto err_assert_rst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) err_assert_rst:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) reset_control_assert(master->core_rst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) err_disable_core_clk:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) clk_disable_unprepare(master->core_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) static int dw_i3c_remove(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) struct dw_i3c_master *master = platform_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) ret = i3c_master_unregister(&master->base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) reset_control_assert(master->core_rst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) clk_disable_unprepare(master->core_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) static const struct of_device_id dw_i3c_master_of_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) { .compatible = "snps,dw-i3c-master-1.00a", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) {},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) MODULE_DEVICE_TABLE(of, dw_i3c_master_of_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) static struct platform_driver dw_i3c_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) .probe = dw_i3c_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) .remove = dw_i3c_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) .name = "dw-i3c-master",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) .of_match_table = of_match_ptr(dw_i3c_master_of_match),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) module_platform_driver(dw_i3c_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) MODULE_AUTHOR("Vitor Soares <vitor.soares@synopsys.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) MODULE_DESCRIPTION("DesignWare MIPI I3C driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) MODULE_LICENSE("GPL v2");