summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/msm/dsi/dsi_host.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/msm/dsi/dsi_host.c')
-rw-r--r--drivers/gpu/drm/msm/dsi/dsi_host.c120
1 files changed, 67 insertions, 53 deletions
diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c
index 649d20d29f92..de0400923303 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_host.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
@@ -15,6 +15,7 @@
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
#include <linux/interrupt.h>
#include <linux/of_device.h>
#include <linux/of_gpio.h>
@@ -36,35 +37,19 @@
#define DSI_6G_REG_SHIFT 4
-#define DSI_REGULATOR_MAX 8
-struct dsi_reg_entry {
- char name[32];
- int min_voltage;
- int max_voltage;
- int enable_load;
- int disable_load;
-};
-
-struct dsi_reg_config {
- int num;
- struct dsi_reg_entry regs[DSI_REGULATOR_MAX];
-};
-
struct dsi_config {
u32 major;
u32 minor;
u32 io_offset;
- enum msm_dsi_phy_type phy_type;
struct dsi_reg_config reg_cfg;
};
static const struct dsi_config dsi_cfgs[] = {
- {MSM_DSI_VER_MAJOR_V2, 0, 0, MSM_DSI_PHY_UNKNOWN},
+ {MSM_DSI_VER_MAJOR_V2, 0, 0, {0,} },
{ /* 8974 v1 */
.major = MSM_DSI_VER_MAJOR_6G,
.minor = MSM_DSI_6G_VER_MINOR_V1_0,
.io_offset = DSI_6G_REG_SHIFT,
- .phy_type = MSM_DSI_PHY_28NM,
.reg_cfg = {
.num = 4,
.regs = {
@@ -79,7 +64,6 @@ static const struct dsi_config dsi_cfgs[] = {
.major = MSM_DSI_VER_MAJOR_6G,
.minor = MSM_DSI_6G_VER_MINOR_V1_1,
.io_offset = DSI_6G_REG_SHIFT,
- .phy_type = MSM_DSI_PHY_28NM,
.reg_cfg = {
.num = 4,
.regs = {
@@ -94,7 +78,6 @@ static const struct dsi_config dsi_cfgs[] = {
.major = MSM_DSI_VER_MAJOR_6G,
.minor = MSM_DSI_6G_VER_MINOR_V1_1_1,
.io_offset = DSI_6G_REG_SHIFT,
- .phy_type = MSM_DSI_PHY_28NM,
.reg_cfg = {
.num = 4,
.regs = {
@@ -109,7 +92,6 @@ static const struct dsi_config dsi_cfgs[] = {
.major = MSM_DSI_VER_MAJOR_6G,
.minor = MSM_DSI_6G_VER_MINOR_V1_2,
.io_offset = DSI_6G_REG_SHIFT,
- .phy_type = MSM_DSI_PHY_28NM,
.reg_cfg = {
.num = 4,
.regs = {
@@ -124,7 +106,6 @@ static const struct dsi_config dsi_cfgs[] = {
.major = MSM_DSI_VER_MAJOR_6G,
.minor = MSM_DSI_6G_VER_MINOR_V1_3_1,
.io_offset = DSI_6G_REG_SHIFT,
- .phy_type = MSM_DSI_PHY_28NM,
.reg_cfg = {
.num = 4,
.regs = {
@@ -197,7 +178,7 @@ struct msm_dsi_host {
int id;
void __iomem *ctrl_base;
- struct regulator_bulk_data supplies[DSI_REGULATOR_MAX];
+ struct regulator_bulk_data supplies[DSI_DEV_REGULATOR_MAX];
struct clk *mdp_core_clk;
struct clk *ahb_clk;
struct clk *axi_clk;
@@ -205,6 +186,9 @@ struct msm_dsi_host {
struct clk *byte_clk;
struct clk *esc_clk;
struct clk *pixel_clk;
+ struct clk *byte_clk_src;
+ struct clk *pixel_clk_src;
+
u32 byte_clk_rate;
struct gpio_desc *disp_en_gpio;
@@ -273,7 +257,7 @@ static const struct dsi_config *dsi_get_config(struct msm_dsi_host *msm_host)
u32 major = 0, minor = 0;
gdsc_reg = regulator_get(&msm_host->pdev->dev, "gdsc");
- if (IS_ERR_OR_NULL(gdsc_reg)) {
+ if (IS_ERR(gdsc_reg)) {
pr_err("%s: cannot get gdsc\n", __func__);
goto fail;
}
@@ -463,6 +447,22 @@ static int dsi_clk_init(struct msm_dsi_host *msm_host)
goto exit;
}
+ msm_host->byte_clk_src = devm_clk_get(dev, "byte_clk_src");
+ if (IS_ERR(msm_host->byte_clk_src)) {
+ ret = PTR_ERR(msm_host->byte_clk_src);
+ pr_err("%s: can't find byte_clk_src. ret=%d\n", __func__, ret);
+ msm_host->byte_clk_src = NULL;
+ goto exit;
+ }
+
+ msm_host->pixel_clk_src = devm_clk_get(dev, "pixel_clk_src");
+ if (IS_ERR(msm_host->pixel_clk_src)) {
+ ret = PTR_ERR(msm_host->pixel_clk_src);
+ pr_err("%s: can't find pixel_clk_src. ret=%d\n", __func__, ret);
+ msm_host->pixel_clk_src = NULL;
+ goto exit;
+ }
+
exit:
return ret;
}
@@ -787,6 +787,11 @@ static void dsi_ctrl_config(struct msm_dsi_host *msm_host, bool enable,
dsi_write(msm_host, REG_DSI_LANE_SWAP_CTRL,
DSI_LANE_SWAP_CTRL_DLN_SWAP_SEL(LANE_SWAP_0123));
}
+
+ if (!(flags & MIPI_DSI_CLOCK_NON_CONTINUOUS))
+ dsi_write(msm_host, REG_DSI_LANE_CTRL,
+ DSI_LANE_CTRL_CLKLN_HS_FORCE_REQUEST);
+
data |= DSI_CTRL_ENABLE;
dsi_write(msm_host, REG_DSI_CTRL, data);
@@ -1345,36 +1350,19 @@ static irqreturn_t dsi_host_irq(int irq, void *ptr)
static int dsi_host_init_panel_gpios(struct msm_dsi_host *msm_host,
struct device *panel_device)
{
- int ret;
-
- msm_host->disp_en_gpio = devm_gpiod_get(panel_device,
- "disp-enable");
+ msm_host->disp_en_gpio = devm_gpiod_get_optional(panel_device,
+ "disp-enable",
+ GPIOD_OUT_LOW);
if (IS_ERR(msm_host->disp_en_gpio)) {
DBG("cannot get disp-enable-gpios %ld",
PTR_ERR(msm_host->disp_en_gpio));
- msm_host->disp_en_gpio = NULL;
- }
- if (msm_host->disp_en_gpio) {
- ret = gpiod_direction_output(msm_host->disp_en_gpio, 0);
- if (ret) {
- pr_err("cannot set dir to disp-en-gpios %d\n", ret);
- return ret;
- }
+ return PTR_ERR(msm_host->disp_en_gpio);
}
- msm_host->te_gpio = devm_gpiod_get(panel_device, "disp-te");
+ msm_host->te_gpio = devm_gpiod_get(panel_device, "disp-te", GPIOD_IN);
if (IS_ERR(msm_host->te_gpio)) {
DBG("cannot get disp-te-gpios %ld", PTR_ERR(msm_host->te_gpio));
- msm_host->te_gpio = NULL;
- }
-
- if (msm_host->te_gpio) {
- ret = gpiod_direction_input(msm_host->te_gpio);
- if (ret) {
- pr_err("%s: cannot set dir to disp-te-gpios, %d\n",
- __func__, ret);
- return ret;
- }
+ return PTR_ERR(msm_host->te_gpio);
}
return 0;
@@ -1508,13 +1496,6 @@ int msm_dsi_host_init(struct msm_dsi *msm_dsi)
msm_host->workqueue = alloc_ordered_workqueue("dsi_drm_work", 0);
INIT_WORK(&msm_host->err_work, dsi_err_worker);
- msm_dsi->phy = msm_dsi_phy_init(pdev, msm_host->cfg->phy_type,
- msm_host->id);
- if (!msm_dsi->phy) {
- ret = -EINVAL;
- pr_err("%s: phy init failed\n", __func__);
- goto fail;
- }
msm_dsi->host = &msm_host->base;
msm_dsi->id = msm_host->id;
@@ -1824,6 +1805,39 @@ void msm_dsi_host_cmd_xfer_commit(struct mipi_dsi_host *host, u32 iova, u32 len)
wmb();
}
+int msm_dsi_host_set_src_pll(struct mipi_dsi_host *host,
+ struct msm_dsi_pll *src_pll)
+{
+ struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
+ struct clk *byte_clk_provider, *pixel_clk_provider;
+ int ret;
+
+ ret = msm_dsi_pll_get_clk_provider(src_pll,
+ &byte_clk_provider, &pixel_clk_provider);
+ if (ret) {
+ pr_info("%s: can't get provider from pll, don't set parent\n",
+ __func__);
+ return 0;
+ }
+
+ ret = clk_set_parent(msm_host->byte_clk_src, byte_clk_provider);
+ if (ret) {
+ pr_err("%s: can't set parent to byte_clk_src. ret=%d\n",
+ __func__, ret);
+ goto exit;
+ }
+
+ ret = clk_set_parent(msm_host->pixel_clk_src, pixel_clk_provider);
+ if (ret) {
+ pr_err("%s: can't set parent to pixel_clk_src. ret=%d\n",
+ __func__, ret);
+ goto exit;
+ }
+
+exit:
+ return ret;
+}
+
int msm_dsi_host_enable(struct mipi_dsi_host *host)
{
struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
OpenPOWER on IntegriCloud