diff options
-rw-r--r-- | drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 58 |
1 files changed, 45 insertions, 13 deletions
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c index d098e2329868..f0b2c736145f 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | |||
@@ -391,18 +391,46 @@ static int dw_mipi_dsi_write(struct dw_mipi_dsi *dsi, | |||
391 | return dw_mipi_dsi_gen_pkt_hdr_write(dsi, le32_to_cpu(word)); | 391 | return dw_mipi_dsi_gen_pkt_hdr_write(dsi, le32_to_cpu(word)); |
392 | } | 392 | } |
393 | 393 | ||
394 | static int dw_mipi_dsi_read(struct dw_mipi_dsi *dsi, | ||
395 | const struct mipi_dsi_msg *msg) | ||
396 | { | ||
397 | int i, j, ret, len = msg->rx_len; | ||
398 | u8 *buf = msg->rx_buf; | ||
399 | u32 val; | ||
400 | |||
401 | /* Wait end of the read operation */ | ||
402 | ret = readl_poll_timeout(dsi->base + DSI_CMD_PKT_STATUS, | ||
403 | val, !(val & GEN_RD_CMD_BUSY), | ||
404 | 1000, CMD_PKT_STATUS_TIMEOUT_US); | ||
405 | if (ret) { | ||
406 | dev_err(dsi->dev, "Timeout during read operation\n"); | ||
407 | return ret; | ||
408 | } | ||
409 | |||
410 | for (i = 0; i < len; i += 4) { | ||
411 | /* Read fifo must not be empty before all bytes are read */ | ||
412 | ret = readl_poll_timeout(dsi->base + DSI_CMD_PKT_STATUS, | ||
413 | val, !(val & GEN_PLD_R_EMPTY), | ||
414 | 1000, CMD_PKT_STATUS_TIMEOUT_US); | ||
415 | if (ret) { | ||
416 | dev_err(dsi->dev, "Read payload FIFO is empty\n"); | ||
417 | return ret; | ||
418 | } | ||
419 | |||
420 | val = dsi_read(dsi, DSI_GEN_PLD_DATA); | ||
421 | for (j = 0; j < 4 && j + i < len; j++) | ||
422 | buf[i + j] = val >> (8 * j); | ||
423 | } | ||
424 | |||
425 | return ret; | ||
426 | } | ||
427 | |||
394 | static ssize_t dw_mipi_dsi_host_transfer(struct mipi_dsi_host *host, | 428 | static ssize_t dw_mipi_dsi_host_transfer(struct mipi_dsi_host *host, |
395 | const struct mipi_dsi_msg *msg) | 429 | const struct mipi_dsi_msg *msg) |
396 | { | 430 | { |
397 | struct dw_mipi_dsi *dsi = host_to_dsi(host); | 431 | struct dw_mipi_dsi *dsi = host_to_dsi(host); |
398 | struct mipi_dsi_packet packet; | 432 | struct mipi_dsi_packet packet; |
399 | int ret; | 433 | int ret, nb_bytes; |
400 | |||
401 | if (msg->rx_buf || msg->rx_len) { | ||
402 | /* TODO dw drv improvements: implement read feature */ | ||
403 | dev_warn(dsi->dev, "read operations not yet implemented\n"); | ||
404 | return -EINVAL; | ||
405 | } | ||
406 | 434 | ||
407 | ret = mipi_dsi_create_packet(&packet, msg); | 435 | ret = mipi_dsi_create_packet(&packet, msg); |
408 | if (ret) { | 436 | if (ret) { |
@@ -416,12 +444,16 @@ static ssize_t dw_mipi_dsi_host_transfer(struct mipi_dsi_host *host, | |||
416 | if (ret) | 444 | if (ret) |
417 | return ret; | 445 | return ret; |
418 | 446 | ||
419 | /* | 447 | if (msg->rx_buf && msg->rx_len) { |
420 | * TODO Only transmitted size is returned as actual driver does | 448 | ret = dw_mipi_dsi_read(dsi, msg); |
421 | * not support dcs/generic reads. Please update return value when | 449 | if (ret) |
422 | * delivering the read feature. | 450 | return ret; |
423 | */ | 451 | nb_bytes = msg->rx_len; |
424 | return packet.size; | 452 | } else { |
453 | nb_bytes = packet.size; | ||
454 | } | ||
455 | |||
456 | return nb_bytes; | ||
425 | } | 457 | } |
426 | 458 | ||
427 | static const struct mipi_dsi_host_ops dw_mipi_dsi_host_ops = { | 459 | static const struct mipi_dsi_host_ops dw_mipi_dsi_host_ops = { |