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