1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. 4 */ 5 6#include "edp.h" 7#include "edp.xml.h" 8 9#define AUX_CMD_FIFO_LEN 144 10#define AUX_CMD_NATIVE_MAX 16 11#define AUX_CMD_I2C_MAX 128 12 13#define EDP_INTR_AUX_I2C_ERR \ 14 (EDP_INTERRUPT_REG_1_WRONG_ADDR | EDP_INTERRUPT_REG_1_TIMEOUT | \ 15 EDP_INTERRUPT_REG_1_NACK_DEFER | EDP_INTERRUPT_REG_1_WRONG_DATA_CNT | \ 16 EDP_INTERRUPT_REG_1_I2C_NACK | EDP_INTERRUPT_REG_1_I2C_DEFER) 17#define EDP_INTR_TRANS_STATUS \ 18 (EDP_INTERRUPT_REG_1_AUX_I2C_DONE | EDP_INTR_AUX_I2C_ERR) 19 20struct edp_aux { 21 void __iomem *base; 22 bool msg_err; 23 24 struct completion msg_comp; 25 26 /* To prevent the message transaction routine from reentry. */ 27 struct mutex msg_mutex; 28 29 struct drm_dp_aux drm_aux; 30}; 31#define to_edp_aux(x) container_of(x, struct edp_aux, drm_aux) 32 33static int edp_msg_fifo_tx(struct edp_aux *aux, struct drm_dp_aux_msg *msg) 34{ 35 u32 data[4]; 36 u32 reg, len; 37 bool native = msg->request & (DP_AUX_NATIVE_WRITE & DP_AUX_NATIVE_READ); 38 bool read = msg->request & (DP_AUX_I2C_READ & DP_AUX_NATIVE_READ); 39 u8 *msgdata = msg->buffer; 40 int i; 41 42 if (read) 43 len = 4; 44 else 45 len = msg->size + 4; 46 47 /* 48 * cmd fifo only has depth of 144 bytes 49 */ 50 if (len > AUX_CMD_FIFO_LEN) 51 return -EINVAL; 52 53 /* Pack cmd and write to HW */ 54 data[0] = (msg->address >> 16) & 0xf; /* addr[19:16] */ 55 if (read) 56 data[0] |= BIT(4); /* R/W */ 57 58 data[1] = (msg->address >> 8) & 0xff; /* addr[15:8] */ 59 data[2] = msg->address & 0xff; /* addr[7:0] */ 60 data[3] = (msg->size - 1) & 0xff; /* len[7:0] */ 61 62 for (i = 0; i < len; i++) { 63 reg = (i < 4) ? data[i] : msgdata[i - 4]; 64 reg = EDP_AUX_DATA_DATA(reg); /* index = 0, write */ 65 if (i == 0) 66 reg |= EDP_AUX_DATA_INDEX_WRITE; 67 edp_write(aux->base + REG_EDP_AUX_DATA, reg); 68 } 69 70 reg = 0; /* Transaction number is always 1 */ 71 if (!native) /* i2c */ 72 reg |= EDP_AUX_TRANS_CTRL_I2C; 73 74 reg |= EDP_AUX_TRANS_CTRL_GO; 75 edp_write(aux->base + REG_EDP_AUX_TRANS_CTRL, reg); 76 77 return 0; 78} 79 80static int edp_msg_fifo_rx(struct edp_aux *aux, struct drm_dp_aux_msg *msg) 81{ 82 u32 data; 83 u8 *dp; 84 int i; 85 u32 len = msg->size; 86 87 edp_write(aux->base + REG_EDP_AUX_DATA, 88 EDP_AUX_DATA_INDEX_WRITE | EDP_AUX_DATA_READ); /* index = 0 */ 89 90 dp = msg->buffer; 91 92 /* discard first byte */ 93 data = edp_read(aux->base + REG_EDP_AUX_DATA); 94 for (i = 0; i < len; i++) { 95 data = edp_read(aux->base + REG_EDP_AUX_DATA); 96 dp[i] = (u8)((data >> 8) & 0xff); 97 } 98 99 return 0; 100} 101 102/* 103 * This function does the real job to process an AUX transaction. 104 * It will call msm_edp_aux_ctrl() function to reset the AUX channel, 105 * if the waiting is timeout. 106 * The caller who triggers the transaction should avoid the 107 * msm_edp_aux_ctrl() running concurrently in other threads, i.e. 108 * start transaction only when AUX channel is fully enabled. 109 */ 110static ssize_t edp_aux_transfer(struct drm_dp_aux *drm_aux, 111 struct drm_dp_aux_msg *msg) 112{ 113 struct edp_aux *aux = to_edp_aux(drm_aux); 114 ssize_t ret; 115 unsigned long time_left; 116 bool native = msg->request & (DP_AUX_NATIVE_WRITE & DP_AUX_NATIVE_READ); 117 bool read = msg->request & (DP_AUX_I2C_READ & DP_AUX_NATIVE_READ); 118 119 /* Ignore address only message */ 120 if ((msg->size == 0) || (msg->buffer == NULL)) { 121 msg->reply = native ? 122 DP_AUX_NATIVE_REPLY_ACK : DP_AUX_I2C_REPLY_ACK; 123 return msg->size; 124 } 125 126 /* msg sanity check */ 127 if ((native && (msg->size > AUX_CMD_NATIVE_MAX)) || 128 (msg->size > AUX_CMD_I2C_MAX)) { 129 pr_err("%s: invalid msg: size(%zu), request(%x)\n", 130 __func__, msg->size, msg->request); 131 return -EINVAL; 132 } 133 134 mutex_lock(&aux->msg_mutex); 135 136 aux->msg_err = false; 137 reinit_completion(&aux->msg_comp); 138 139 ret = edp_msg_fifo_tx(aux, msg); 140 if (ret < 0) 141 goto unlock_exit; 142 143 DBG("wait_for_completion"); 144 time_left = wait_for_completion_timeout(&aux->msg_comp, 145 msecs_to_jiffies(300)); 146 if (!time_left) { 147 /* 148 * Clear GO and reset AUX channel 149 * to cancel the current transaction. 150 */ 151 edp_write(aux->base + REG_EDP_AUX_TRANS_CTRL, 0); 152 msm_edp_aux_ctrl(aux, 1); 153 pr_err("%s: aux timeout,\n", __func__); 154 ret = -ETIMEDOUT; 155 goto unlock_exit; 156 } 157 DBG("completion"); 158 159 if (!aux->msg_err) { 160 if (read) { 161 ret = edp_msg_fifo_rx(aux, msg); 162 if (ret < 0) 163 goto unlock_exit; 164 } 165 166 msg->reply = native ? 167 DP_AUX_NATIVE_REPLY_ACK : DP_AUX_I2C_REPLY_ACK; 168 } else { 169 /* Reply defer to retry */ 170 msg->reply = native ? 171 DP_AUX_NATIVE_REPLY_DEFER : DP_AUX_I2C_REPLY_DEFER; 172 /* 173 * The sleep time in caller is not long enough to make sure 174 * our H/W completes transactions. Add more defer time here. 175 */ 176 msleep(100); 177 } 178 179 /* Return requested size for success or retry */ 180 ret = msg->size; 181 182unlock_exit: 183 mutex_unlock(&aux->msg_mutex); 184 return ret; 185} 186 187void *msm_edp_aux_init(struct device *dev, void __iomem *regbase, 188 struct drm_dp_aux **drm_aux) 189{ 190 struct edp_aux *aux = NULL; 191 int ret; 192 193 DBG(""); 194 aux = devm_kzalloc(dev, sizeof(*aux), GFP_KERNEL); 195 if (!aux) 196 return NULL; 197 198 aux->base = regbase; 199 mutex_init(&aux->msg_mutex); 200 init_completion(&aux->msg_comp); 201 202 aux->drm_aux.name = "msm_edp_aux"; 203 aux->drm_aux.dev = dev; 204 aux->drm_aux.transfer = edp_aux_transfer; 205 ret = drm_dp_aux_register(&aux->drm_aux); 206 if (ret) { 207 pr_err("%s: failed to register drm aux: %d\n", __func__, ret); 208 mutex_destroy(&aux->msg_mutex); 209 } 210 211 if (drm_aux && aux) 212 *drm_aux = &aux->drm_aux; 213 214 return aux; 215} 216 217void msm_edp_aux_destroy(struct device *dev, struct edp_aux *aux) 218{ 219 if (aux) { 220 drm_dp_aux_unregister(&aux->drm_aux); 221 mutex_destroy(&aux->msg_mutex); 222 } 223} 224 225irqreturn_t msm_edp_aux_irq(struct edp_aux *aux, u32 isr) 226{ 227 if (isr & EDP_INTR_TRANS_STATUS) { 228 DBG("isr=%x", isr); 229 edp_write(aux->base + REG_EDP_AUX_TRANS_CTRL, 0); 230 231 if (isr & EDP_INTR_AUX_I2C_ERR) 232 aux->msg_err = true; 233 else 234 aux->msg_err = false; 235 236 complete(&aux->msg_comp); 237 } 238 239 return IRQ_HANDLED; 240} 241 242void msm_edp_aux_ctrl(struct edp_aux *aux, int enable) 243{ 244 u32 data; 245 246 DBG("enable=%d", enable); 247 data = edp_read(aux->base + REG_EDP_AUX_CTRL); 248 249 if (enable) { 250 data |= EDP_AUX_CTRL_RESET; 251 edp_write(aux->base + REG_EDP_AUX_CTRL, data); 252 /* Make sure full reset */ 253 wmb(); 254 usleep_range(500, 1000); 255 256 data &= ~EDP_AUX_CTRL_RESET; 257 data |= EDP_AUX_CTRL_ENABLE; 258 edp_write(aux->base + REG_EDP_AUX_CTRL, data); 259 } else { 260 data &= ~EDP_AUX_CTRL_ENABLE; 261 edp_write(aux->base + REG_EDP_AUX_CTRL, data); 262 } 263} 264 265