| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Copyright (c) 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 | 4 | */ |
|---|
| 13 | 5 | |
|---|
| 14 | 6 | #include <linux/clk.h> |
|---|
| 15 | 7 | #include <linux/delay.h> |
|---|
| 8 | +#include <linux/dma-mapping.h> |
|---|
| 16 | 9 | #include <linux/err.h> |
|---|
| 17 | | -#include <linux/gpio.h> |
|---|
| 18 | 10 | #include <linux/gpio/consumer.h> |
|---|
| 19 | 11 | #include <linux/interrupt.h> |
|---|
| 12 | +#include <linux/mfd/syscon.h> |
|---|
| 20 | 13 | #include <linux/of_device.h> |
|---|
| 21 | | -#include <linux/of_gpio.h> |
|---|
| 14 | +#include <linux/of_graph.h> |
|---|
| 22 | 15 | #include <linux/of_irq.h> |
|---|
| 23 | 16 | #include <linux/pinctrl/consumer.h> |
|---|
| 24 | | -#include <linux/of_graph.h> |
|---|
| 17 | +#include <linux/pm_opp.h> |
|---|
| 18 | +#include <linux/regmap.h> |
|---|
| 25 | 19 | #include <linux/regulator/consumer.h> |
|---|
| 26 | 20 | #include <linux/spinlock.h> |
|---|
| 27 | | -#include <linux/mfd/syscon.h> |
|---|
| 28 | | -#include <linux/regmap.h> |
|---|
| 21 | + |
|---|
| 29 | 22 | #include <video/mipi_display.h> |
|---|
| 30 | 23 | |
|---|
| 31 | 24 | #include "dsi.h" |
|---|
| .. | .. |
|---|
| 118 | 111 | struct clk *byte_clk_src; |
|---|
| 119 | 112 | struct clk *pixel_clk_src; |
|---|
| 120 | 113 | struct clk *byte_intf_clk; |
|---|
| 114 | + |
|---|
| 115 | + struct opp_table *opp_table; |
|---|
| 116 | + bool has_opp_table; |
|---|
| 121 | 117 | |
|---|
| 122 | 118 | u32 byte_clk_rate; |
|---|
| 123 | 119 | u32 pixel_clk_rate; |
|---|
| .. | .. |
|---|
| 513 | 509 | return dsi_bus_clk_enable(msm_host); |
|---|
| 514 | 510 | } |
|---|
| 515 | 511 | |
|---|
| 516 | | -int dsi_link_clk_enable_6g(struct msm_dsi_host *msm_host) |
|---|
| 512 | +int dsi_link_clk_set_rate_6g(struct msm_dsi_host *msm_host) |
|---|
| 517 | 513 | { |
|---|
| 518 | 514 | int ret; |
|---|
| 519 | 515 | |
|---|
| 520 | 516 | DBG("Set clk rates: pclk=%d, byteclk=%d", |
|---|
| 521 | 517 | msm_host->mode->clock, msm_host->byte_clk_rate); |
|---|
| 522 | 518 | |
|---|
| 523 | | - ret = clk_set_rate(msm_host->byte_clk, msm_host->byte_clk_rate); |
|---|
| 519 | + ret = dev_pm_opp_set_rate(&msm_host->pdev->dev, |
|---|
| 520 | + msm_host->byte_clk_rate); |
|---|
| 524 | 521 | if (ret) { |
|---|
| 525 | | - pr_err("%s: Failed to set rate byte clk, %d\n", __func__, ret); |
|---|
| 526 | | - goto error; |
|---|
| 522 | + pr_err("%s: dev_pm_opp_set_rate failed %d\n", __func__, ret); |
|---|
| 523 | + return ret; |
|---|
| 527 | 524 | } |
|---|
| 528 | 525 | |
|---|
| 529 | 526 | ret = clk_set_rate(msm_host->pixel_clk, msm_host->pixel_clk_rate); |
|---|
| 530 | 527 | if (ret) { |
|---|
| 531 | 528 | pr_err("%s: Failed to set rate pixel clk, %d\n", __func__, ret); |
|---|
| 532 | | - goto error; |
|---|
| 529 | + return ret; |
|---|
| 533 | 530 | } |
|---|
| 534 | 531 | |
|---|
| 535 | 532 | if (msm_host->byte_intf_clk) { |
|---|
| .. | .. |
|---|
| 538 | 535 | if (ret) { |
|---|
| 539 | 536 | pr_err("%s: Failed to set rate byte intf clk, %d\n", |
|---|
| 540 | 537 | __func__, ret); |
|---|
| 541 | | - goto error; |
|---|
| 538 | + return ret; |
|---|
| 542 | 539 | } |
|---|
| 543 | 540 | } |
|---|
| 541 | + |
|---|
| 542 | + return 0; |
|---|
| 543 | +} |
|---|
| 544 | + |
|---|
| 545 | + |
|---|
| 546 | +int dsi_link_clk_enable_6g(struct msm_dsi_host *msm_host) |
|---|
| 547 | +{ |
|---|
| 548 | + int ret; |
|---|
| 544 | 549 | |
|---|
| 545 | 550 | ret = clk_prepare_enable(msm_host->esc_clk); |
|---|
| 546 | 551 | if (ret) { |
|---|
| .. | .. |
|---|
| 581 | 586 | return ret; |
|---|
| 582 | 587 | } |
|---|
| 583 | 588 | |
|---|
| 584 | | -int dsi_link_clk_enable_v2(struct msm_dsi_host *msm_host) |
|---|
| 589 | +int dsi_link_clk_set_rate_v2(struct msm_dsi_host *msm_host) |
|---|
| 585 | 590 | { |
|---|
| 586 | 591 | int ret; |
|---|
| 587 | 592 | |
|---|
| .. | .. |
|---|
| 592 | 597 | ret = clk_set_rate(msm_host->byte_clk, msm_host->byte_clk_rate); |
|---|
| 593 | 598 | if (ret) { |
|---|
| 594 | 599 | pr_err("%s: Failed to set rate byte clk, %d\n", __func__, ret); |
|---|
| 595 | | - goto error; |
|---|
| 600 | + return ret; |
|---|
| 596 | 601 | } |
|---|
| 597 | 602 | |
|---|
| 598 | 603 | ret = clk_set_rate(msm_host->esc_clk, msm_host->esc_clk_rate); |
|---|
| 599 | 604 | if (ret) { |
|---|
| 600 | 605 | pr_err("%s: Failed to set rate esc clk, %d\n", __func__, ret); |
|---|
| 601 | | - goto error; |
|---|
| 606 | + return ret; |
|---|
| 602 | 607 | } |
|---|
| 603 | 608 | |
|---|
| 604 | 609 | ret = clk_set_rate(msm_host->src_clk, msm_host->src_clk_rate); |
|---|
| 605 | 610 | if (ret) { |
|---|
| 606 | 611 | pr_err("%s: Failed to set rate src clk, %d\n", __func__, ret); |
|---|
| 607 | | - goto error; |
|---|
| 612 | + return ret; |
|---|
| 608 | 613 | } |
|---|
| 609 | 614 | |
|---|
| 610 | 615 | ret = clk_set_rate(msm_host->pixel_clk, msm_host->pixel_clk_rate); |
|---|
| 611 | 616 | if (ret) { |
|---|
| 612 | 617 | pr_err("%s: Failed to set rate pixel clk, %d\n", __func__, ret); |
|---|
| 613 | | - goto error; |
|---|
| 618 | + return ret; |
|---|
| 614 | 619 | } |
|---|
| 620 | + |
|---|
| 621 | + return 0; |
|---|
| 622 | +} |
|---|
| 623 | + |
|---|
| 624 | +int dsi_link_clk_enable_v2(struct msm_dsi_host *msm_host) |
|---|
| 625 | +{ |
|---|
| 626 | + int ret; |
|---|
| 615 | 627 | |
|---|
| 616 | 628 | ret = clk_prepare_enable(msm_host->byte_clk); |
|---|
| 617 | 629 | if (ret) { |
|---|
| .. | .. |
|---|
| 651 | 663 | |
|---|
| 652 | 664 | void dsi_link_clk_disable_6g(struct msm_dsi_host *msm_host) |
|---|
| 653 | 665 | { |
|---|
| 666 | + /* Drop the performance state vote */ |
|---|
| 667 | + dev_pm_opp_set_rate(&msm_host->pdev->dev, 0); |
|---|
| 654 | 668 | clk_disable_unprepare(msm_host->esc_clk); |
|---|
| 655 | 669 | clk_disable_unprepare(msm_host->pixel_clk); |
|---|
| 656 | 670 | if (msm_host->byte_intf_clk) |
|---|
| .. | .. |
|---|
| 826 | 840 | u32 flags = msm_host->mode_flags; |
|---|
| 827 | 841 | enum mipi_dsi_pixel_format mipi_fmt = msm_host->format; |
|---|
| 828 | 842 | const struct msm_dsi_cfg_handler *cfg_hnd = msm_host->cfg_hnd; |
|---|
| 829 | | - u32 data = 0; |
|---|
| 843 | + u32 data = 0, lane_ctrl = 0; |
|---|
| 830 | 844 | |
|---|
| 831 | 845 | if (!enable) { |
|---|
| 832 | 846 | dsi_write(msm_host, REG_DSI_CTRL, 0); |
|---|
| .. | .. |
|---|
| 914 | 928 | dsi_write(msm_host, REG_DSI_LANE_SWAP_CTRL, |
|---|
| 915 | 929 | DSI_LANE_SWAP_CTRL_DLN_SWAP_SEL(msm_host->dlane_swap)); |
|---|
| 916 | 930 | |
|---|
| 917 | | - if (!(flags & MIPI_DSI_CLOCK_NON_CONTINUOUS)) |
|---|
| 931 | + if (!(flags & MIPI_DSI_CLOCK_NON_CONTINUOUS)) { |
|---|
| 932 | + lane_ctrl = dsi_read(msm_host, REG_DSI_LANE_CTRL); |
|---|
| 918 | 933 | dsi_write(msm_host, REG_DSI_LANE_CTRL, |
|---|
| 919 | | - DSI_LANE_CTRL_CLKLN_HS_FORCE_REQUEST); |
|---|
| 934 | + lane_ctrl | DSI_LANE_CTRL_CLKLN_HS_FORCE_REQUEST); |
|---|
| 935 | + } |
|---|
| 920 | 936 | |
|---|
| 921 | 937 | data |= DSI_CTRL_ENABLE; |
|---|
| 922 | 938 | |
|---|
| .. | .. |
|---|
| 977 | 993 | /* image data and 1 byte write_memory_start cmd */ |
|---|
| 978 | 994 | wc = hdisplay * dsi_get_bpp(msm_host->format) / 8 + 1; |
|---|
| 979 | 995 | |
|---|
| 980 | | - dsi_write(msm_host, REG_DSI_CMD_MDP_STREAM_CTRL, |
|---|
| 981 | | - DSI_CMD_MDP_STREAM_CTRL_WORD_COUNT(wc) | |
|---|
| 982 | | - DSI_CMD_MDP_STREAM_CTRL_VIRTUAL_CHANNEL( |
|---|
| 996 | + dsi_write(msm_host, REG_DSI_CMD_MDP_STREAM0_CTRL, |
|---|
| 997 | + DSI_CMD_MDP_STREAM0_CTRL_WORD_COUNT(wc) | |
|---|
| 998 | + DSI_CMD_MDP_STREAM0_CTRL_VIRTUAL_CHANNEL( |
|---|
| 983 | 999 | msm_host->channel) | |
|---|
| 984 | | - DSI_CMD_MDP_STREAM_CTRL_DATA_TYPE( |
|---|
| 1000 | + DSI_CMD_MDP_STREAM0_CTRL_DATA_TYPE( |
|---|
| 985 | 1001 | MIPI_DSI_DCS_LONG_WRITE)); |
|---|
| 986 | 1002 | |
|---|
| 987 | | - dsi_write(msm_host, REG_DSI_CMD_MDP_STREAM_TOTAL, |
|---|
| 988 | | - DSI_CMD_MDP_STREAM_TOTAL_H_TOTAL(hdisplay) | |
|---|
| 989 | | - DSI_CMD_MDP_STREAM_TOTAL_V_TOTAL(mode->vdisplay)); |
|---|
| 1003 | + dsi_write(msm_host, REG_DSI_CMD_MDP_STREAM0_TOTAL, |
|---|
| 1004 | + DSI_CMD_MDP_STREAM0_TOTAL_H_TOTAL(hdisplay) | |
|---|
| 1005 | + DSI_CMD_MDP_STREAM0_TOTAL_V_TOTAL(mode->vdisplay)); |
|---|
| 990 | 1006 | } |
|---|
| 991 | 1007 | } |
|---|
| 992 | 1008 | |
|---|
| .. | .. |
|---|
| 1051 | 1067 | ret = wait_for_completion_timeout(&msm_host->video_comp, |
|---|
| 1052 | 1068 | msecs_to_jiffies(70)); |
|---|
| 1053 | 1069 | |
|---|
| 1054 | | - if (ret <= 0) |
|---|
| 1055 | | - dev_err(dev, "wait for video done timed out\n"); |
|---|
| 1070 | + if (ret == 0) |
|---|
| 1071 | + DRM_DEV_ERROR(dev, "wait for video done timed out\n"); |
|---|
| 1056 | 1072 | |
|---|
| 1057 | 1073 | dsi_intr_ctrl(msm_host, DSI_IRQ_MASK_VIDEO_DONE, 0); |
|---|
| 1058 | 1074 | } |
|---|
| .. | .. |
|---|
| 1084 | 1100 | msm_host->tx_gem_obj = NULL; |
|---|
| 1085 | 1101 | return PTR_ERR(data); |
|---|
| 1086 | 1102 | } |
|---|
| 1103 | + |
|---|
| 1104 | + msm_gem_object_set_name(msm_host->tx_gem_obj, "tx_gem"); |
|---|
| 1087 | 1105 | |
|---|
| 1088 | 1106 | msm_host->tx_size = msm_host->tx_gem_obj->size; |
|---|
| 1089 | 1107 | |
|---|
| .. | .. |
|---|
| 1120 | 1138 | |
|---|
| 1121 | 1139 | priv = dev->dev_private; |
|---|
| 1122 | 1140 | if (msm_host->tx_gem_obj) { |
|---|
| 1123 | | - msm_gem_put_iova(msm_host->tx_gem_obj, priv->kms->aspace); |
|---|
| 1124 | | - drm_gem_object_put_unlocked(msm_host->tx_gem_obj); |
|---|
| 1141 | + msm_gem_unpin_iova(msm_host->tx_gem_obj, priv->kms->aspace); |
|---|
| 1142 | + drm_gem_object_put(msm_host->tx_gem_obj); |
|---|
| 1125 | 1143 | msm_host->tx_gem_obj = NULL; |
|---|
| 1126 | 1144 | } |
|---|
| 1127 | 1145 | |
|---|
| .. | .. |
|---|
| 1250 | 1268 | if (!dma_base) |
|---|
| 1251 | 1269 | return -EINVAL; |
|---|
| 1252 | 1270 | |
|---|
| 1253 | | - return msm_gem_get_iova(msm_host->tx_gem_obj, |
|---|
| 1271 | + return msm_gem_get_and_pin_iova(msm_host->tx_gem_obj, |
|---|
| 1254 | 1272 | priv->kms->aspace, dma_base); |
|---|
| 1255 | 1273 | } |
|---|
| 1256 | 1274 | |
|---|
| .. | .. |
|---|
| 1299 | 1317 | static int dsi_cmd_dma_rx(struct msm_dsi_host *msm_host, |
|---|
| 1300 | 1318 | u8 *buf, int rx_byte, int pkt_size) |
|---|
| 1301 | 1319 | { |
|---|
| 1302 | | - u32 *lp, *temp, data; |
|---|
| 1320 | + u32 *temp, data; |
|---|
| 1303 | 1321 | int i, j = 0, cnt; |
|---|
| 1304 | 1322 | u32 read_cnt; |
|---|
| 1305 | 1323 | u8 reg[16]; |
|---|
| 1306 | 1324 | int repeated_bytes = 0; |
|---|
| 1307 | 1325 | int buf_offset = buf - msm_host->rx_buf; |
|---|
| 1308 | 1326 | |
|---|
| 1309 | | - lp = (u32 *)buf; |
|---|
| 1310 | 1327 | temp = (u32 *)reg; |
|---|
| 1311 | 1328 | cnt = (rx_byte + 3) >> 2; |
|---|
| 1312 | 1329 | if (cnt > 4) |
|---|
| .. | .. |
|---|
| 1354 | 1371 | dsi_get_bpp(msm_host->format) / 8; |
|---|
| 1355 | 1372 | |
|---|
| 1356 | 1373 | len = dsi_cmd_dma_add(msm_host, msg); |
|---|
| 1357 | | - if (!len) { |
|---|
| 1374 | + if (len < 0) { |
|---|
| 1358 | 1375 | pr_err("%s: failed to add cmd type = 0x%x\n", |
|---|
| 1359 | 1376 | __func__, msg->type); |
|---|
| 1360 | | - return -EINVAL; |
|---|
| 1377 | + return len; |
|---|
| 1361 | 1378 | } |
|---|
| 1362 | 1379 | |
|---|
| 1363 | 1380 | /* for video mode, do not send cmds more than |
|---|
| .. | .. |
|---|
| 1376 | 1393 | } |
|---|
| 1377 | 1394 | |
|---|
| 1378 | 1395 | ret = dsi_cmd_dma_tx(msm_host, len); |
|---|
| 1379 | | - if (ret < len) { |
|---|
| 1380 | | - pr_err("%s: cmd dma tx failed, type=0x%x, data0=0x%x, len=%d\n", |
|---|
| 1381 | | - __func__, msg->type, (*(u8 *)(msg->tx_buf)), len); |
|---|
| 1382 | | - return -ECOMM; |
|---|
| 1396 | + if (ret < 0) { |
|---|
| 1397 | + pr_err("%s: cmd dma tx failed, type=0x%x, data0=0x%x, len=%d, ret=%d\n", |
|---|
| 1398 | + __func__, msg->type, (*(u8 *)(msg->tx_buf)), len, ret); |
|---|
| 1399 | + return ret; |
|---|
| 1400 | + } else if (ret < len) { |
|---|
| 1401 | + pr_err("%s: cmd dma tx failed, type=0x%x, data0=0x%x, ret=%d len=%d\n", |
|---|
| 1402 | + __func__, msg->type, (*(u8 *)(msg->tx_buf)), ret, len); |
|---|
| 1403 | + return -EIO; |
|---|
| 1383 | 1404 | } |
|---|
| 1384 | 1405 | |
|---|
| 1385 | 1406 | return len; |
|---|
| .. | .. |
|---|
| 1598 | 1619 | msm_host->format = dsi->format; |
|---|
| 1599 | 1620 | msm_host->mode_flags = dsi->mode_flags; |
|---|
| 1600 | 1621 | |
|---|
| 1601 | | - msm_dsi_manager_attach_dsi_device(msm_host->id, dsi->mode_flags); |
|---|
| 1602 | | - |
|---|
| 1603 | 1622 | /* Some gpios defined in panel DT need to be controlled by host */ |
|---|
| 1604 | 1623 | ret = dsi_host_init_panel_gpios(msm_host, &dsi->dev); |
|---|
| 1605 | 1624 | if (ret) |
|---|
| .. | .. |
|---|
| 1675 | 1694 | |
|---|
| 1676 | 1695 | prop = of_find_property(ep, "data-lanes", &len); |
|---|
| 1677 | 1696 | if (!prop) { |
|---|
| 1678 | | - dev_dbg(dev, |
|---|
| 1697 | + DRM_DEV_DEBUG(dev, |
|---|
| 1679 | 1698 | "failed to find data lane mapping, using default\n"); |
|---|
| 1680 | 1699 | /* Set the number of date lanes to 4 by default. */ |
|---|
| 1681 | 1700 | msm_host->num_data_lanes = 4; |
|---|
| .. | .. |
|---|
| 1685 | 1704 | num_lanes = len / sizeof(u32); |
|---|
| 1686 | 1705 | |
|---|
| 1687 | 1706 | if (num_lanes < 1 || num_lanes > 4) { |
|---|
| 1688 | | - dev_err(dev, "bad number of data lanes\n"); |
|---|
| 1707 | + DRM_DEV_ERROR(dev, "bad number of data lanes\n"); |
|---|
| 1689 | 1708 | return -EINVAL; |
|---|
| 1690 | 1709 | } |
|---|
| 1691 | 1710 | |
|---|
| .. | .. |
|---|
| 1694 | 1713 | ret = of_property_read_u32_array(ep, "data-lanes", lane_map, |
|---|
| 1695 | 1714 | num_lanes); |
|---|
| 1696 | 1715 | if (ret) { |
|---|
| 1697 | | - dev_err(dev, "failed to read lane data\n"); |
|---|
| 1716 | + DRM_DEV_ERROR(dev, "failed to read lane data\n"); |
|---|
| 1698 | 1717 | return ret; |
|---|
| 1699 | 1718 | } |
|---|
| 1700 | 1719 | |
|---|
| .. | .. |
|---|
| 1715 | 1734 | */ |
|---|
| 1716 | 1735 | for (j = 0; j < num_lanes; j++) { |
|---|
| 1717 | 1736 | if (lane_map[j] < 0 || lane_map[j] > 3) |
|---|
| 1718 | | - dev_err(dev, "bad physical lane entry %u\n", |
|---|
| 1737 | + DRM_DEV_ERROR(dev, "bad physical lane entry %u\n", |
|---|
| 1719 | 1738 | lane_map[j]); |
|---|
| 1720 | 1739 | |
|---|
| 1721 | 1740 | if (swap[lane_map[j]] != j) |
|---|
| .. | .. |
|---|
| 1746 | 1765 | */ |
|---|
| 1747 | 1766 | endpoint = of_graph_get_endpoint_by_regs(np, 1, -1); |
|---|
| 1748 | 1767 | if (!endpoint) { |
|---|
| 1749 | | - dev_dbg(dev, "%s: no endpoint\n", __func__); |
|---|
| 1768 | + DRM_DEV_DEBUG(dev, "%s: no endpoint\n", __func__); |
|---|
| 1750 | 1769 | return 0; |
|---|
| 1751 | 1770 | } |
|---|
| 1752 | 1771 | |
|---|
| 1753 | 1772 | ret = dsi_host_parse_lane_data(msm_host, endpoint); |
|---|
| 1754 | 1773 | if (ret) { |
|---|
| 1755 | | - dev_err(dev, "%s: invalid lane configuration %d\n", |
|---|
| 1774 | + DRM_DEV_ERROR(dev, "%s: invalid lane configuration %d\n", |
|---|
| 1756 | 1775 | __func__, ret); |
|---|
| 1776 | + ret = -EINVAL; |
|---|
| 1757 | 1777 | goto err; |
|---|
| 1758 | 1778 | } |
|---|
| 1759 | 1779 | |
|---|
| 1760 | 1780 | /* Get panel node from the output port's endpoint data */ |
|---|
| 1761 | 1781 | device_node = of_graph_get_remote_node(np, 1, 0); |
|---|
| 1762 | 1782 | if (!device_node) { |
|---|
| 1763 | | - dev_dbg(dev, "%s: no valid device\n", __func__); |
|---|
| 1783 | + DRM_DEV_DEBUG(dev, "%s: no valid device\n", __func__); |
|---|
| 1784 | + ret = -ENODEV; |
|---|
| 1764 | 1785 | goto err; |
|---|
| 1765 | 1786 | } |
|---|
| 1766 | 1787 | |
|---|
| .. | .. |
|---|
| 1770 | 1791 | msm_host->sfpb = syscon_regmap_lookup_by_phandle(np, |
|---|
| 1771 | 1792 | "syscon-sfpb"); |
|---|
| 1772 | 1793 | if (IS_ERR(msm_host->sfpb)) { |
|---|
| 1773 | | - dev_err(dev, "%s: failed to get sfpb regmap\n", |
|---|
| 1794 | + DRM_DEV_ERROR(dev, "%s: failed to get sfpb regmap\n", |
|---|
| 1774 | 1795 | __func__); |
|---|
| 1775 | 1796 | ret = PTR_ERR(msm_host->sfpb); |
|---|
| 1776 | 1797 | } |
|---|
| .. | .. |
|---|
| 1871 | 1892 | goto fail; |
|---|
| 1872 | 1893 | } |
|---|
| 1873 | 1894 | |
|---|
| 1895 | + msm_host->opp_table = dev_pm_opp_set_clkname(&pdev->dev, "byte"); |
|---|
| 1896 | + if (IS_ERR(msm_host->opp_table)) |
|---|
| 1897 | + return PTR_ERR(msm_host->opp_table); |
|---|
| 1898 | + /* OPP table is optional */ |
|---|
| 1899 | + ret = dev_pm_opp_of_add_table(&pdev->dev); |
|---|
| 1900 | + if (!ret) { |
|---|
| 1901 | + msm_host->has_opp_table = true; |
|---|
| 1902 | + } else if (ret != -ENODEV) { |
|---|
| 1903 | + dev_err(&pdev->dev, "invalid OPP table in device tree\n"); |
|---|
| 1904 | + dev_pm_opp_put_clkname(msm_host->opp_table); |
|---|
| 1905 | + return ret; |
|---|
| 1906 | + } |
|---|
| 1907 | + |
|---|
| 1874 | 1908 | init_completion(&msm_host->dma_comp); |
|---|
| 1875 | 1909 | init_completion(&msm_host->video_comp); |
|---|
| 1876 | 1910 | mutex_init(&msm_host->dev_mutex); |
|---|
| .. | .. |
|---|
| 1879 | 1913 | |
|---|
| 1880 | 1914 | /* setup workqueue */ |
|---|
| 1881 | 1915 | msm_host->workqueue = alloc_ordered_workqueue("dsi_drm_work", 0); |
|---|
| 1916 | + if (!msm_host->workqueue) |
|---|
| 1917 | + return -ENOMEM; |
|---|
| 1918 | + |
|---|
| 1882 | 1919 | INIT_WORK(&msm_host->err_work, dsi_err_worker); |
|---|
| 1883 | 1920 | INIT_WORK(&msm_host->hpd_work, dsi_hpd_worker); |
|---|
| 1884 | 1921 | |
|---|
| .. | .. |
|---|
| 1906 | 1943 | mutex_destroy(&msm_host->cmd_mutex); |
|---|
| 1907 | 1944 | mutex_destroy(&msm_host->dev_mutex); |
|---|
| 1908 | 1945 | |
|---|
| 1946 | + if (msm_host->has_opp_table) |
|---|
| 1947 | + dev_pm_opp_of_remove_table(&msm_host->pdev->dev); |
|---|
| 1948 | + dev_pm_opp_put_clkname(msm_host->opp_table); |
|---|
| 1909 | 1949 | pm_runtime_disable(&msm_host->pdev->dev); |
|---|
| 1910 | 1950 | } |
|---|
| 1911 | 1951 | |
|---|
| .. | .. |
|---|
| 1920 | 1960 | msm_host->irq = irq_of_parse_and_map(pdev->dev.of_node, 0); |
|---|
| 1921 | 1961 | if (msm_host->irq < 0) { |
|---|
| 1922 | 1962 | ret = msm_host->irq; |
|---|
| 1923 | | - dev_err(dev->dev, "failed to get irq: %d\n", ret); |
|---|
| 1963 | + DRM_DEV_ERROR(dev->dev, "failed to get irq: %d\n", ret); |
|---|
| 1924 | 1964 | return ret; |
|---|
| 1925 | 1965 | } |
|---|
| 1926 | 1966 | |
|---|
| .. | .. |
|---|
| 1928 | 1968 | dsi_host_irq, IRQF_TRIGGER_HIGH | IRQF_ONESHOT, |
|---|
| 1929 | 1969 | "dsi_isr", msm_host); |
|---|
| 1930 | 1970 | if (ret < 0) { |
|---|
| 1931 | | - dev_err(&pdev->dev, "failed to request IRQ%u: %d\n", |
|---|
| 1971 | + DRM_DEV_ERROR(&pdev->dev, "failed to request IRQ%u: %d\n", |
|---|
| 1932 | 1972 | msm_host->irq, ret); |
|---|
| 1933 | 1973 | return ret; |
|---|
| 1934 | 1974 | } |
|---|
| .. | .. |
|---|
| 2005 | 2045 | * mdp clock need to be enabled to receive dsi interrupt |
|---|
| 2006 | 2046 | */ |
|---|
| 2007 | 2047 | pm_runtime_get_sync(&msm_host->pdev->dev); |
|---|
| 2048 | + cfg_hnd->ops->link_clk_set_rate(msm_host); |
|---|
| 2008 | 2049 | cfg_hnd->ops->link_clk_enable(msm_host); |
|---|
| 2009 | 2050 | |
|---|
| 2010 | 2051 | /* TODO: vote for bus bandwidth */ |
|---|
| .. | .. |
|---|
| 2105 | 2146 | } |
|---|
| 2106 | 2147 | |
|---|
| 2107 | 2148 | ret = dsi_cmds2buf_tx(msm_host, msg); |
|---|
| 2108 | | - if (ret < msg->tx_len) { |
|---|
| 2149 | + if (ret < 0) { |
|---|
| 2109 | 2150 | pr_err("%s: Read cmd Tx failed, %d\n", __func__, ret); |
|---|
| 2110 | 2151 | return ret; |
|---|
| 2152 | + } else if (ret < msg->tx_len) { |
|---|
| 2153 | + pr_err("%s: Read cmd Tx failed, too short: %d\n", __func__, ret); |
|---|
| 2154 | + return -ECOMM; |
|---|
| 2111 | 2155 | } |
|---|
| 2112 | 2156 | |
|---|
| 2113 | 2157 | /* |
|---|
| .. | .. |
|---|
| 2353 | 2397 | } |
|---|
| 2354 | 2398 | |
|---|
| 2355 | 2399 | pm_runtime_get_sync(&msm_host->pdev->dev); |
|---|
| 2356 | | - ret = cfg_hnd->ops->link_clk_enable(msm_host); |
|---|
| 2400 | + ret = cfg_hnd->ops->link_clk_set_rate(msm_host); |
|---|
| 2401 | + if (!ret) |
|---|
| 2402 | + ret = cfg_hnd->ops->link_clk_enable(msm_host); |
|---|
| 2357 | 2403 | if (ret) { |
|---|
| 2358 | 2404 | pr_err("%s: failed to enable link clocks. ret=%d\n", |
|---|
| 2359 | 2405 | __func__, ret); |
|---|
| .. | .. |
|---|
| 2424 | 2470 | } |
|---|
| 2425 | 2471 | |
|---|
| 2426 | 2472 | int msm_dsi_host_set_display_mode(struct mipi_dsi_host *host, |
|---|
| 2427 | | - struct drm_display_mode *mode) |
|---|
| 2473 | + const struct drm_display_mode *mode) |
|---|
| 2428 | 2474 | { |
|---|
| 2429 | 2475 | struct msm_dsi_host *msm_host = to_msm_dsi_host(host); |
|---|
| 2430 | 2476 | |
|---|
| .. | .. |
|---|
| 2442 | 2488 | return 0; |
|---|
| 2443 | 2489 | } |
|---|
| 2444 | 2490 | |
|---|
| 2445 | | -struct drm_panel *msm_dsi_host_get_panel(struct mipi_dsi_host *host, |
|---|
| 2446 | | - unsigned long *panel_flags) |
|---|
| 2491 | +struct drm_panel *msm_dsi_host_get_panel(struct mipi_dsi_host *host) |
|---|
| 2447 | 2492 | { |
|---|
| 2448 | | - struct msm_dsi_host *msm_host = to_msm_dsi_host(host); |
|---|
| 2449 | | - struct drm_panel *panel; |
|---|
| 2493 | + return of_drm_find_panel(to_msm_dsi_host(host)->device_node); |
|---|
| 2494 | +} |
|---|
| 2450 | 2495 | |
|---|
| 2451 | | - panel = of_drm_find_panel(msm_host->device_node); |
|---|
| 2452 | | - if (panel_flags) |
|---|
| 2453 | | - *panel_flags = msm_host->mode_flags; |
|---|
| 2454 | | - |
|---|
| 2455 | | - return panel; |
|---|
| 2496 | +unsigned long msm_dsi_host_get_mode_flags(struct mipi_dsi_host *host) |
|---|
| 2497 | +{ |
|---|
| 2498 | + return to_msm_dsi_host(host)->mode_flags; |
|---|
| 2456 | 2499 | } |
|---|
| 2457 | 2500 | |
|---|
| 2458 | 2501 | struct drm_bridge *msm_dsi_host_get_bridge(struct mipi_dsi_host *host) |
|---|