aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThierry Reding <treding@nvidia.com>2014-11-07 11:25:26 -0500
committerThierry Reding <treding@nvidia.com>2014-11-13 10:12:36 -0500
commit0fffdf6ca9926243db9ca17701fcdc0a38c67d48 (patch)
treefc55a5a797d239fc6c44783fd2edb06cd4b2bb7c
parente94236cde4d519cdecd45e2435defba33abdc99f (diff)
drm/tegra: dsi: Implement host transfers
Add support for sending MIPI DSI command packets from the host to a peripheral. This is required for panels that need configuration before they accept video data. Signed-off-by: Thierry Reding <treding@nvidia.com>
-rw-r--r--drivers/gpu/drm/tegra/dsi.c267
-rw-r--r--drivers/gpu/drm/tegra/dsi.h13
2 files changed, 279 insertions, 1 deletions
diff --git a/drivers/gpu/drm/tegra/dsi.c b/drivers/gpu/drm/tegra/dsi.c
index 66816104ba72..6646fa2adc38 100644
--- a/drivers/gpu/drm/tegra/dsi.c
+++ b/drivers/gpu/drm/tegra/dsi.c
@@ -993,6 +993,272 @@ static int tegra_dsi_setup_clocks(struct tegra_dsi *dsi)
993 return 0; 993 return 0;
994} 994}
995 995
996static const char * const error_report[16] = {
997 "SoT Error",
998 "SoT Sync Error",
999 "EoT Sync Error",
1000 "Escape Mode Entry Command Error",
1001 "Low-Power Transmit Sync Error",
1002 "Peripheral Timeout Error",
1003 "False Control Error",
1004 "Contention Detected",
1005 "ECC Error, single-bit",
1006 "ECC Error, multi-bit",
1007 "Checksum Error",
1008 "DSI Data Type Not Recognized",
1009 "DSI VC ID Invalid",
1010 "Invalid Transmission Length",
1011 "Reserved",
1012 "DSI Protocol Violation",
1013};
1014
1015static ssize_t tegra_dsi_read_response(struct tegra_dsi *dsi,
1016 const struct mipi_dsi_msg *msg,
1017 size_t count)
1018{
1019 u8 *rx = msg->rx_buf;
1020 unsigned int i, j, k;
1021 size_t size = 0;
1022 u16 errors;
1023 u32 value;
1024
1025 /* read and parse packet header */
1026 value = tegra_dsi_readl(dsi, DSI_RD_DATA);
1027
1028 switch (value & 0x3f) {
1029 case MIPI_DSI_RX_ACKNOWLEDGE_AND_ERROR_REPORT:
1030 errors = (value >> 8) & 0xffff;
1031 dev_dbg(dsi->dev, "Acknowledge and error report: %04x\n",
1032 errors);
1033 for (i = 0; i < ARRAY_SIZE(error_report); i++)
1034 if (errors & BIT(i))
1035 dev_dbg(dsi->dev, " %2u: %s\n", i,
1036 error_report[i]);
1037 break;
1038
1039 case MIPI_DSI_RX_DCS_SHORT_READ_RESPONSE_1BYTE:
1040 rx[0] = (value >> 8) & 0xff;
1041 size = 1;
1042 break;
1043
1044 case MIPI_DSI_RX_DCS_SHORT_READ_RESPONSE_2BYTE:
1045 rx[0] = (value >> 8) & 0xff;
1046 rx[1] = (value >> 16) & 0xff;
1047 size = 2;
1048 break;
1049
1050 case MIPI_DSI_RX_DCS_LONG_READ_RESPONSE:
1051 size = ((value >> 8) & 0xff00) | ((value >> 8) & 0xff);
1052 break;
1053
1054 case MIPI_DSI_RX_GENERIC_LONG_READ_RESPONSE:
1055 size = ((value >> 8) & 0xff00) | ((value >> 8) & 0xff);
1056 break;
1057
1058 default:
1059 dev_err(dsi->dev, "unhandled response type: %02x\n",
1060 value & 0x3f);
1061 return -EPROTO;
1062 }
1063
1064 size = min(size, msg->rx_len);
1065
1066 if (msg->rx_buf && size > 0) {
1067 for (i = 0, j = 0; i < count - 1; i++, j += 4) {
1068 u8 *rx = msg->rx_buf + j;
1069
1070 value = tegra_dsi_readl(dsi, DSI_RD_DATA);
1071
1072 for (k = 0; k < 4 && (j + k) < msg->rx_len; k++)
1073 rx[j + k] = (value >> (k << 3)) & 0xff;
1074 }
1075 }
1076
1077 return size;
1078}
1079
1080static int tegra_dsi_transmit(struct tegra_dsi *dsi, unsigned long timeout)
1081{
1082 tegra_dsi_writel(dsi, DSI_TRIGGER_HOST, DSI_TRIGGER);
1083
1084 timeout = jiffies + msecs_to_jiffies(timeout);
1085
1086 while (time_before(jiffies, timeout)) {
1087 u32 value = tegra_dsi_readl(dsi, DSI_TRIGGER);
1088 if ((value & DSI_TRIGGER_HOST) == 0)
1089 return 0;
1090
1091 usleep_range(1000, 2000);
1092 }
1093
1094 DRM_DEBUG_KMS("timeout waiting for transmission to complete\n");
1095 return -ETIMEDOUT;
1096}
1097
1098static int tegra_dsi_wait_for_response(struct tegra_dsi *dsi,
1099 unsigned long timeout)
1100{
1101 timeout = jiffies + msecs_to_jiffies(250);
1102
1103 while (time_before(jiffies, timeout)) {
1104 u32 value = tegra_dsi_readl(dsi, DSI_STATUS);
1105 u8 count = value & 0x1f;
1106
1107 if (count > 0)
1108 return count;
1109
1110 usleep_range(1000, 2000);
1111 }
1112
1113 DRM_DEBUG_KMS("peripheral returned no data\n");
1114 return -ETIMEDOUT;
1115}
1116
1117static void tegra_dsi_writesl(struct tegra_dsi *dsi, unsigned long offset,
1118 const void *buffer, size_t size)
1119{
1120 const u8 *buf = buffer;
1121 size_t i, j;
1122 u32 value;
1123
1124 for (j = 0; j < size; j += 4) {
1125 value = 0;
1126
1127 for (i = 0; i < 4 && j + i < size; i++)
1128 value |= buf[j + i] << (i << 3);
1129
1130 tegra_dsi_writel(dsi, value, DSI_WR_DATA);
1131 }
1132}
1133
1134static ssize_t tegra_dsi_host_transfer(struct mipi_dsi_host *host,
1135 const struct mipi_dsi_msg *msg)
1136{
1137 struct tegra_dsi *dsi = host_to_tegra(host);
1138 struct mipi_dsi_packet packet;
1139 const u8 *header;
1140 size_t count;
1141 ssize_t err;
1142 u32 value;
1143
1144 err = mipi_dsi_create_packet(&packet, msg);
1145 if (err < 0)
1146 return err;
1147
1148 header = packet.header;
1149
1150 /* maximum FIFO depth is 1920 words */
1151 if (packet.size > dsi->video_fifo_depth * 4)
1152 return -ENOSPC;
1153
1154 /* reset underflow/overflow flags */
1155 value = tegra_dsi_readl(dsi, DSI_STATUS);
1156 if (value & (DSI_STATUS_UNDERFLOW | DSI_STATUS_OVERFLOW)) {
1157 value = DSI_HOST_CONTROL_FIFO_RESET;
1158 tegra_dsi_writel(dsi, value, DSI_HOST_CONTROL);
1159 usleep_range(10, 20);
1160 }
1161
1162 value = tegra_dsi_readl(dsi, DSI_POWER_CONTROL);
1163 value |= DSI_POWER_CONTROL_ENABLE;
1164 tegra_dsi_writel(dsi, value, DSI_POWER_CONTROL);
1165
1166 usleep_range(5000, 10000);
1167
1168 value = DSI_HOST_CONTROL_CRC_RESET | DSI_HOST_CONTROL_TX_TRIG_HOST |
1169 DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC;
1170
1171 if ((msg->flags & MIPI_DSI_MSG_USE_LPM) == 0)
1172 value |= DSI_HOST_CONTROL_HS;
1173
1174 /*
1175 * The host FIFO has a maximum of 64 words, so larger transmissions
1176 * need to use the video FIFO.
1177 */
1178 if (packet.size > dsi->host_fifo_depth * 4)
1179 value |= DSI_HOST_CONTROL_FIFO_SEL;
1180
1181 tegra_dsi_writel(dsi, value, DSI_HOST_CONTROL);
1182
1183 /*
1184 * For reads and messages with explicitly requested ACK, generate a
1185 * BTA sequence after the transmission of the packet.
1186 */
1187 if ((msg->flags & MIPI_DSI_MSG_REQ_ACK) ||
1188 (msg->rx_buf && msg->rx_len > 0)) {
1189 value = tegra_dsi_readl(dsi, DSI_HOST_CONTROL);
1190 value |= DSI_HOST_CONTROL_PKT_BTA;
1191 tegra_dsi_writel(dsi, value, DSI_HOST_CONTROL);
1192 }
1193
1194 value = DSI_CONTROL_LANES(0) | DSI_CONTROL_HOST_ENABLE;
1195 tegra_dsi_writel(dsi, value, DSI_CONTROL);
1196
1197 /* write packet header, ECC is generated by hardware */
1198 value = header[2] << 16 | header[1] << 8 | header[0];
1199 tegra_dsi_writel(dsi, value, DSI_WR_DATA);
1200
1201 /* write payload (if any) */
1202 if (packet.payload_length > 0)
1203 tegra_dsi_writesl(dsi, DSI_WR_DATA, packet.payload,
1204 packet.payload_length);
1205
1206 err = tegra_dsi_transmit(dsi, 250);
1207 if (err < 0)
1208 return err;
1209
1210 if ((msg->flags & MIPI_DSI_MSG_REQ_ACK) ||
1211 (msg->rx_buf && msg->rx_len > 0)) {
1212 err = tegra_dsi_wait_for_response(dsi, 250);
1213 if (err < 0)
1214 return err;
1215
1216 count = err;
1217
1218 value = tegra_dsi_readl(dsi, DSI_RD_DATA);
1219 switch (value) {
1220 case 0x84:
1221 /*
1222 dev_dbg(dsi->dev, "ACK\n");
1223 */
1224 break;
1225
1226 case 0x87:
1227 /*
1228 dev_dbg(dsi->dev, "ESCAPE\n");
1229 */
1230 break;
1231
1232 default:
1233 dev_err(dsi->dev, "unknown status: %08x\n", value);
1234 break;
1235 }
1236
1237 if (count > 1) {
1238 err = tegra_dsi_read_response(dsi, msg, count);
1239 if (err < 0)
1240 dev_err(dsi->dev,
1241 "failed to parse response: %zd\n",
1242 err);
1243 else {
1244 /*
1245 * For read commands, return the number of
1246 * bytes returned by the peripheral.
1247 */
1248 count = err;
1249 }
1250 }
1251 } else {
1252 /*
1253 * For write commands, we have transmitted the 4-byte header
1254 * plus the variable-length payload.
1255 */
1256 count = 4 + packet.payload_length;
1257 }
1258
1259 return count;
1260}
1261
996static int tegra_dsi_ganged_setup(struct tegra_dsi *dsi) 1262static int tegra_dsi_ganged_setup(struct tegra_dsi *dsi)
997{ 1263{
998 struct clk *parent; 1264 struct clk *parent;
@@ -1069,6 +1335,7 @@ static int tegra_dsi_host_detach(struct mipi_dsi_host *host,
1069static const struct mipi_dsi_host_ops tegra_dsi_host_ops = { 1335static const struct mipi_dsi_host_ops tegra_dsi_host_ops = {
1070 .attach = tegra_dsi_host_attach, 1336 .attach = tegra_dsi_host_attach,
1071 .detach = tegra_dsi_host_detach, 1337 .detach = tegra_dsi_host_detach,
1338 .transfer = tegra_dsi_host_transfer,
1072}; 1339};
1073 1340
1074static int tegra_dsi_ganged_probe(struct tegra_dsi *dsi) 1341static int tegra_dsi_ganged_probe(struct tegra_dsi *dsi)
diff --git a/drivers/gpu/drm/tegra/dsi.h b/drivers/gpu/drm/tegra/dsi.h
index 1f6ca68108d8..bad1006a5150 100644
--- a/drivers/gpu/drm/tegra/dsi.h
+++ b/drivers/gpu/drm/tegra/dsi.h
@@ -21,9 +21,16 @@
21#define DSI_INT_STATUS 0x0d 21#define DSI_INT_STATUS 0x0d
22#define DSI_INT_MASK 0x0e 22#define DSI_INT_MASK 0x0e
23#define DSI_HOST_CONTROL 0x0f 23#define DSI_HOST_CONTROL 0x0f
24#define DSI_HOST_CONTROL_FIFO_RESET (1 << 21)
25#define DSI_HOST_CONTROL_CRC_RESET (1 << 20)
26#define DSI_HOST_CONTROL_TX_TRIG_SOL (0 << 12)
27#define DSI_HOST_CONTROL_TX_TRIG_FIFO (1 << 12)
28#define DSI_HOST_CONTROL_TX_TRIG_HOST (2 << 12)
24#define DSI_HOST_CONTROL_RAW (1 << 6) 29#define DSI_HOST_CONTROL_RAW (1 << 6)
25#define DSI_HOST_CONTROL_HS (1 << 5) 30#define DSI_HOST_CONTROL_HS (1 << 5)
26#define DSI_HOST_CONTROL_BTA (1 << 2) 31#define DSI_HOST_CONTROL_FIFO_SEL (1 << 4)
32#define DSI_HOST_CONTROL_IMM_BTA (1 << 3)
33#define DSI_HOST_CONTROL_PKT_BTA (1 << 2)
27#define DSI_HOST_CONTROL_CS (1 << 1) 34#define DSI_HOST_CONTROL_CS (1 << 1)
28#define DSI_HOST_CONTROL_ECC (1 << 0) 35#define DSI_HOST_CONTROL_ECC (1 << 0)
29#define DSI_CONTROL 0x10 36#define DSI_CONTROL 0x10
@@ -39,9 +46,13 @@
39#define DSI_SOL_DELAY 0x11 46#define DSI_SOL_DELAY 0x11
40#define DSI_MAX_THRESHOLD 0x12 47#define DSI_MAX_THRESHOLD 0x12
41#define DSI_TRIGGER 0x13 48#define DSI_TRIGGER 0x13
49#define DSI_TRIGGER_HOST (1 << 1)
50#define DSI_TRIGGER_VIDEO (1 << 0)
42#define DSI_TX_CRC 0x14 51#define DSI_TX_CRC 0x14
43#define DSI_STATUS 0x15 52#define DSI_STATUS 0x15
44#define DSI_STATUS_IDLE (1 << 10) 53#define DSI_STATUS_IDLE (1 << 10)
54#define DSI_STATUS_UNDERFLOW (1 << 9)
55#define DSI_STATUS_OVERFLOW (1 << 8)
45#define DSI_INIT_SEQ_CONTROL 0x1a 56#define DSI_INIT_SEQ_CONTROL 0x1a
46#define DSI_INIT_SEQ_DATA_0 0x1b 57#define DSI_INIT_SEQ_DATA_0 0x1b
47#define DSI_INIT_SEQ_DATA_1 0x1c 58#define DSI_INIT_SEQ_DATA_1 0x1c