diff options
Diffstat (limited to 'drivers/gpu/drm/msm/dsi')
-rw-r--r-- | drivers/gpu/drm/msm/dsi/dsi.h | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/msm/dsi/dsi_cfg.c | 52 | ||||
-rw-r--r-- | drivers/gpu/drm/msm/dsi/dsi_cfg.h | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/msm/dsi/dsi_host.c | 73 | ||||
-rw-r--r-- | drivers/gpu/drm/msm/dsi/dsi_manager.c | 64 | ||||
-rw-r--r-- | drivers/gpu/drm/msm/dsi/phy/dsi_phy.c | 20 | ||||
-rw-r--r-- | drivers/gpu/drm/msm/dsi/phy/dsi_phy.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c | 60 | ||||
-rw-r--r-- | drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/msm/dsi/pll/dsi_pll.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/msm/dsi/pll/dsi_pll_10nm.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/msm/dsi/pll/dsi_pll_28nm.c | 4 |
13 files changed, 217 insertions, 73 deletions
diff --git a/drivers/gpu/drm/msm/dsi/dsi.h b/drivers/gpu/drm/msm/dsi/dsi.h index 0da8a4e428ad..4de771d6f0be 100644 --- a/drivers/gpu/drm/msm/dsi/dsi.h +++ b/drivers/gpu/drm/msm/dsi/dsi.h @@ -9,6 +9,7 @@ #include <linux/of_platform.h> #include <linux/platform_device.h> +#include <drm/drm_bridge.h> #include <drm/drm_crtc.h> #include <drm/drm_mipi_dsi.h> #include <drm/drm_panel.h> @@ -177,6 +178,8 @@ int msm_dsi_host_modeset_init(struct mipi_dsi_host *host, int msm_dsi_host_init(struct msm_dsi *msm_dsi); int msm_dsi_runtime_suspend(struct device *dev); int msm_dsi_runtime_resume(struct device *dev); +int dsi_link_clk_set_rate_6g(struct msm_dsi_host *msm_host); +int dsi_link_clk_set_rate_v2(struct msm_dsi_host *msm_host); int dsi_link_clk_enable_6g(struct msm_dsi_host *msm_host); int dsi_link_clk_enable_v2(struct msm_dsi_host *msm_host); void dsi_link_clk_disable_6g(struct msm_dsi_host *msm_host); diff --git a/drivers/gpu/drm/msm/dsi/dsi_cfg.c b/drivers/gpu/drm/msm/dsi/dsi_cfg.c index b7b7c1a9164a..813d69deb5e8 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_cfg.c +++ b/drivers/gpu/drm/msm/dsi/dsi_cfg.c @@ -66,6 +66,26 @@ static const struct msm_dsi_config msm8916_dsi_cfg = { .num_dsi = 1, }; +static const char * const dsi_8976_bus_clk_names[] = { + "mdp_core", "iface", "bus", +}; + +static const struct msm_dsi_config msm8976_dsi_cfg = { + .io_offset = DSI_6G_REG_SHIFT, + .reg_cfg = { + .num = 3, + .regs = { + {"gdsc", -1, -1}, + {"vdda", 100000, 100}, /* 1.2 V */ + {"vddio", 100000, 100}, /* 1.8 V */ + }, + }, + .bus_clk_names = dsi_8976_bus_clk_names, + .num_bus_clks = ARRAY_SIZE(dsi_8976_bus_clk_names), + .io_start = { 0x1a94000, 0x1a96000 }, + .num_dsi = 2, +}; + static const struct msm_dsi_config msm8994_dsi_cfg = { .io_offset = DSI_6G_REG_SHIFT, .reg_cfg = { @@ -133,6 +153,10 @@ static const char * const dsi_sdm845_bus_clk_names[] = { "iface", "bus", }; +static const char * const dsi_sc7180_bus_clk_names[] = { + "iface", "bus", +}; + static const struct msm_dsi_config sdm845_dsi_cfg = { .io_offset = DSI_6G_REG_SHIFT, .reg_cfg = { @@ -147,7 +171,22 @@ static const struct msm_dsi_config sdm845_dsi_cfg = { .num_dsi = 2, }; -const static struct msm_dsi_host_cfg_ops msm_dsi_v2_host_ops = { +static const struct msm_dsi_config sc7180_dsi_cfg = { + .io_offset = DSI_6G_REG_SHIFT, + .reg_cfg = { + .num = 1, + .regs = { + {"vdda", 21800, 4 }, /* 1.2 V */ + }, + }, + .bus_clk_names = dsi_sc7180_bus_clk_names, + .num_bus_clks = ARRAY_SIZE(dsi_sc7180_bus_clk_names), + .io_start = { 0xae94000 }, + .num_dsi = 1, +}; + +static const struct msm_dsi_host_cfg_ops msm_dsi_v2_host_ops = { + .link_clk_set_rate = dsi_link_clk_set_rate_v2, .link_clk_enable = dsi_link_clk_enable_v2, .link_clk_disable = dsi_link_clk_disable_v2, .clk_init_ver = dsi_clk_init_v2, @@ -158,7 +197,8 @@ const static struct msm_dsi_host_cfg_ops msm_dsi_v2_host_ops = { .calc_clk_rate = dsi_calc_clk_rate_v2, }; -const static struct msm_dsi_host_cfg_ops msm_dsi_6g_host_ops = { +static const struct msm_dsi_host_cfg_ops msm_dsi_6g_host_ops = { + .link_clk_set_rate = dsi_link_clk_set_rate_6g, .link_clk_enable = dsi_link_clk_enable_6g, .link_clk_disable = dsi_link_clk_disable_6g, .clk_init_ver = NULL, @@ -169,7 +209,8 @@ const static struct msm_dsi_host_cfg_ops msm_dsi_6g_host_ops = { .calc_clk_rate = dsi_calc_clk_rate_6g, }; -const static struct msm_dsi_host_cfg_ops msm_dsi_6g_v2_host_ops = { +static const struct msm_dsi_host_cfg_ops msm_dsi_6g_v2_host_ops = { + .link_clk_set_rate = dsi_link_clk_set_rate_6g, .link_clk_enable = dsi_link_clk_enable_6g, .link_clk_disable = dsi_link_clk_disable_6g, .clk_init_ver = dsi_clk_init_6g_v2, @@ -197,10 +238,15 @@ static const struct msm_dsi_cfg_handler dsi_cfg_handlers[] = { &msm8916_dsi_cfg, &msm_dsi_6g_host_ops}, {MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V1_4_1, &msm8996_dsi_cfg, &msm_dsi_6g_host_ops}, + {MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V1_4_2, + &msm8976_dsi_cfg, &msm_dsi_6g_host_ops}, {MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V2_2_0, &msm8998_dsi_cfg, &msm_dsi_6g_v2_host_ops}, {MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V2_2_1, &sdm845_dsi_cfg, &msm_dsi_6g_v2_host_ops}, + {MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V2_4_1, + &sc7180_dsi_cfg, &msm_dsi_6g_v2_host_ops}, + }; const struct msm_dsi_cfg_handler *msm_dsi_cfg_get(u32 major, u32 minor) diff --git a/drivers/gpu/drm/msm/dsi/dsi_cfg.h b/drivers/gpu/drm/msm/dsi/dsi_cfg.h index e2b7a7dfbe49..217e24a65178 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_cfg.h +++ b/drivers/gpu/drm/msm/dsi/dsi_cfg.h @@ -17,8 +17,10 @@ #define MSM_DSI_6G_VER_MINOR_V1_3 0x10030000 #define MSM_DSI_6G_VER_MINOR_V1_3_1 0x10030001 #define MSM_DSI_6G_VER_MINOR_V1_4_1 0x10040001 +#define MSM_DSI_6G_VER_MINOR_V1_4_2 0x10040002 #define MSM_DSI_6G_VER_MINOR_V2_2_0 0x20000000 #define MSM_DSI_6G_VER_MINOR_V2_2_1 0x20020001 +#define MSM_DSI_6G_VER_MINOR_V2_4_1 0x20040001 #define MSM_DSI_V2_VER_MINOR_8064 0x0 @@ -34,6 +36,7 @@ struct msm_dsi_config { }; struct msm_dsi_host_cfg_ops { + int (*link_clk_set_rate)(struct msm_dsi_host *msm_host); int (*link_clk_enable)(struct msm_dsi_host *msm_host); void (*link_clk_disable)(struct msm_dsi_host *msm_host); int (*clk_init_ver)(struct msm_dsi_host *msm_host); diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c index aa35d18ab43c..11ae5b8444c3 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_host.c +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c @@ -5,19 +5,19 @@ #include <linux/clk.h> #include <linux/delay.h> +#include <linux/dma-mapping.h> #include <linux/err.h> -#include <linux/gpio.h> #include <linux/gpio/consumer.h> #include <linux/interrupt.h> +#include <linux/mfd/syscon.h> #include <linux/of_device.h> -#include <linux/of_gpio.h> +#include <linux/of_graph.h> #include <linux/of_irq.h> #include <linux/pinctrl/consumer.h> -#include <linux/of_graph.h> +#include <linux/regmap.h> #include <linux/regulator/consumer.h> #include <linux/spinlock.h> -#include <linux/mfd/syscon.h> -#include <linux/regmap.h> + #include <video/mipi_display.h> #include "dsi.h" @@ -26,6 +26,8 @@ #include "dsi_cfg.h" #include "msm_kms.h" +#define DSI_RESET_TOGGLE_DELAY_MS 20 + static int dsi_get_version(const void __iomem *base, u32 *major, u32 *minor) { u32 ver; @@ -421,15 +423,15 @@ static int dsi_clk_init(struct msm_dsi_host *msm_host) } msm_host->byte_clk_src = clk_get_parent(msm_host->byte_clk); - if (!msm_host->byte_clk_src) { - ret = -ENODEV; + if (IS_ERR(msm_host->byte_clk_src)) { + ret = PTR_ERR(msm_host->byte_clk_src); pr_err("%s: can't find byte_clk clock. ret=%d\n", __func__, ret); goto exit; } msm_host->pixel_clk_src = clk_get_parent(msm_host->pixel_clk); - if (!msm_host->pixel_clk_src) { - ret = -ENODEV; + if (IS_ERR(msm_host->pixel_clk_src)) { + ret = PTR_ERR(msm_host->pixel_clk_src); pr_err("%s: can't find pixel_clk clock. ret=%d\n", __func__, ret); goto exit; } @@ -503,7 +505,7 @@ int msm_dsi_runtime_resume(struct device *dev) return dsi_bus_clk_enable(msm_host); } -int dsi_link_clk_enable_6g(struct msm_dsi_host *msm_host) +int dsi_link_clk_set_rate_6g(struct msm_dsi_host *msm_host) { int ret; @@ -513,13 +515,13 @@ int dsi_link_clk_enable_6g(struct msm_dsi_host *msm_host) ret = clk_set_rate(msm_host->byte_clk, msm_host->byte_clk_rate); if (ret) { pr_err("%s: Failed to set rate byte clk, %d\n", __func__, ret); - goto error; + return ret; } ret = clk_set_rate(msm_host->pixel_clk, msm_host->pixel_clk_rate); if (ret) { pr_err("%s: Failed to set rate pixel clk, %d\n", __func__, ret); - goto error; + return ret; } if (msm_host->byte_intf_clk) { @@ -528,10 +530,18 @@ int dsi_link_clk_enable_6g(struct msm_dsi_host *msm_host) if (ret) { pr_err("%s: Failed to set rate byte intf clk, %d\n", __func__, ret); - goto error; + return ret; } } + return 0; +} + + +int dsi_link_clk_enable_6g(struct msm_dsi_host *msm_host) +{ + int ret; + ret = clk_prepare_enable(msm_host->esc_clk); if (ret) { pr_err("%s: Failed to enable dsi esc clk\n", __func__); @@ -571,7 +581,7 @@ error: return ret; } -int dsi_link_clk_enable_v2(struct msm_dsi_host *msm_host) +int dsi_link_clk_set_rate_v2(struct msm_dsi_host *msm_host) { int ret; @@ -582,27 +592,34 @@ int dsi_link_clk_enable_v2(struct msm_dsi_host *msm_host) ret = clk_set_rate(msm_host->byte_clk, msm_host->byte_clk_rate); if (ret) { pr_err("%s: Failed to set rate byte clk, %d\n", __func__, ret); - goto error; + return ret; } ret = clk_set_rate(msm_host->esc_clk, msm_host->esc_clk_rate); if (ret) { pr_err("%s: Failed to set rate esc clk, %d\n", __func__, ret); - goto error; + return ret; } ret = clk_set_rate(msm_host->src_clk, msm_host->src_clk_rate); if (ret) { pr_err("%s: Failed to set rate src clk, %d\n", __func__, ret); - goto error; + return ret; } ret = clk_set_rate(msm_host->pixel_clk, msm_host->pixel_clk_rate); if (ret) { pr_err("%s: Failed to set rate pixel clk, %d\n", __func__, ret); - goto error; + return ret; } + return 0; +} + +int dsi_link_clk_enable_v2(struct msm_dsi_host *msm_host) +{ + int ret; + ret = clk_prepare_enable(msm_host->byte_clk); if (ret) { pr_err("%s: Failed to enable dsi byte clk\n", __func__); @@ -816,7 +833,7 @@ static void dsi_ctrl_config(struct msm_dsi_host *msm_host, bool enable, u32 flags = msm_host->mode_flags; enum mipi_dsi_pixel_format mipi_fmt = msm_host->format; const struct msm_dsi_cfg_handler *cfg_hnd = msm_host->cfg_hnd; - u32 data = 0; + u32 data = 0, lane_ctrl = 0; if (!enable) { dsi_write(msm_host, REG_DSI_CTRL, 0); @@ -904,9 +921,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(msm_host->dlane_swap)); - if (!(flags & MIPI_DSI_CLOCK_NON_CONTINUOUS)) + if (!(flags & MIPI_DSI_CLOCK_NON_CONTINUOUS)) { + lane_ctrl = dsi_read(msm_host, REG_DSI_LANE_CTRL); dsi_write(msm_host, REG_DSI_LANE_CTRL, - DSI_LANE_CTRL_CLKLN_HS_FORCE_REQUEST); + lane_ctrl | DSI_LANE_CTRL_CLKLN_HS_FORCE_REQUEST); + } data |= DSI_CTRL_ENABLE; @@ -986,7 +1005,7 @@ static void dsi_sw_reset(struct msm_dsi_host *msm_host) wmb(); /* clocks need to be enabled before reset */ dsi_write(msm_host, REG_DSI_RESET, 1); - wmb(); /* make sure reset happen */ + msleep(DSI_RESET_TOGGLE_DELAY_MS); /* make sure reset happen */ dsi_write(msm_host, REG_DSI_RESET, 0); } @@ -1291,14 +1310,13 @@ static int dsi_cmd_dma_tx(struct msm_dsi_host *msm_host, int len) static int dsi_cmd_dma_rx(struct msm_dsi_host *msm_host, u8 *buf, int rx_byte, int pkt_size) { - u32 *lp, *temp, data; + u32 *temp, data; int i, j = 0, cnt; u32 read_cnt; u8 reg[16]; int repeated_bytes = 0; int buf_offset = buf - msm_host->rx_buf; - lp = (u32 *)buf; temp = (u32 *)reg; cnt = (rx_byte + 3) >> 2; if (cnt > 4) @@ -1396,7 +1414,7 @@ static void dsi_sw_reset_restore(struct msm_dsi_host *msm_host) /* dsi controller can only be reset while clocks are running */ dsi_write(msm_host, REG_DSI_RESET, 1); - wmb(); /* make sure reset happen */ + msleep(DSI_RESET_TOGGLE_DELAY_MS); /* make sure reset happen */ dsi_write(msm_host, REG_DSI_RESET, 0); wmb(); /* controller out of reset */ dsi_write(msm_host, REG_DSI_CTRL, data0); @@ -1995,6 +2013,7 @@ int msm_dsi_host_xfer_prepare(struct mipi_dsi_host *host, * mdp clock need to be enabled to receive dsi interrupt */ pm_runtime_get_sync(&msm_host->pdev->dev); + cfg_hnd->ops->link_clk_set_rate(msm_host); cfg_hnd->ops->link_clk_enable(msm_host); /* TODO: vote for bus bandwidth */ @@ -2343,7 +2362,9 @@ int msm_dsi_host_power_on(struct mipi_dsi_host *host, } pm_runtime_get_sync(&msm_host->pdev->dev); - ret = cfg_hnd->ops->link_clk_enable(msm_host); + ret = cfg_hnd->ops->link_clk_set_rate(msm_host); + if (!ret) + ret = cfg_hnd->ops->link_clk_enable(msm_host); if (ret) { pr_err("%s: failed to enable link clocks. ret=%d\n", __func__, ret); diff --git a/drivers/gpu/drm/msm/dsi/dsi_manager.c b/drivers/gpu/drm/msm/dsi/dsi_manager.c index 271aa7bbca92..104115d112eb 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_manager.c +++ b/drivers/gpu/drm/msm/dsi/dsi_manager.c @@ -329,7 +329,7 @@ static int dsi_mgr_connector_get_modes(struct drm_connector *connector) * attached to the drm_panel. */ drm_panel_attach(panel, connector); - num = drm_panel_get_modes(panel); + num = drm_panel_get_modes(panel, connector); if (!num) return 0; @@ -432,20 +432,8 @@ static void dsi_mgr_bridge_pre_enable(struct drm_bridge *bridge) } } - if (panel) { - ret = drm_panel_enable(panel); - if (ret) { - pr_err("%s: enable panel %d failed, %d\n", __func__, id, - ret); - goto panel_en_fail; - } - } - return; -panel_en_fail: - if (is_dual_dsi && msm_dsi1) - msm_dsi_host_disable(msm_dsi1->host); host1_en_fail: msm_dsi_host_disable(host); host_en_fail: @@ -464,12 +452,51 @@ phy_en_fail: static void dsi_mgr_bridge_enable(struct drm_bridge *bridge) { - DBG(""); + int id = dsi_mgr_bridge_get_id(bridge); + struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id); + struct drm_panel *panel = msm_dsi->panel; + bool is_dual_dsi = IS_DUAL_DSI(); + int ret; + + DBG("id=%d", id); + if (!msm_dsi_device_connected(msm_dsi)) + return; + + /* Do nothing with the host if it is slave-DSI in case of dual DSI */ + if (is_dual_dsi && !IS_MASTER_DSI_LINK(id)) + return; + + if (panel) { + ret = drm_panel_enable(panel); + if (ret) { + pr_err("%s: enable panel %d failed, %d\n", __func__, id, + ret); + } + } } static void dsi_mgr_bridge_disable(struct drm_bridge *bridge) { - DBG(""); + int id = dsi_mgr_bridge_get_id(bridge); + struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id); + struct drm_panel *panel = msm_dsi->panel; + bool is_dual_dsi = IS_DUAL_DSI(); + int ret; + + DBG("id=%d", id); + if (!msm_dsi_device_connected(msm_dsi)) + return; + + /* Do nothing with the host if it is slave-DSI in case of dual DSI */ + if (is_dual_dsi && !IS_MASTER_DSI_LINK(id)) + return; + + if (panel) { + ret = drm_panel_disable(panel); + if (ret) + pr_err("%s: Panel %d OFF failed, %d\n", __func__, id, + ret); + } } static void dsi_mgr_bridge_post_disable(struct drm_bridge *bridge) @@ -495,13 +522,6 @@ static void dsi_mgr_bridge_post_disable(struct drm_bridge *bridge) if (is_dual_dsi && !IS_MASTER_DSI_LINK(id)) goto disable_phy; - if (panel) { - ret = drm_panel_disable(panel); - if (ret) - pr_err("%s: Panel %d OFF failed, %d\n", __func__, id, - ret); - } - ret = msm_dsi_host_disable(host); if (ret) pr_err("%s: host %d disable failed, %d\n", __func__, id, ret); diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c index 4097eca1b3ef..b0cfa67d2a57 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c @@ -145,7 +145,7 @@ int msm_dsi_dphy_timing_calc_v2(struct msm_dsi_dphy_timing *timing, { const unsigned long bit_rate = clk_req->bitclk_rate; const unsigned long esc_rate = clk_req->escclk_rate; - s32 ui, ui_x8, lpx; + s32 ui, ui_x8; s32 tmax, tmin; s32 pcnt0 = 50; s32 pcnt1 = 50; @@ -175,7 +175,6 @@ int msm_dsi_dphy_timing_calc_v2(struct msm_dsi_dphy_timing *timing, ui = mult_frac(NSEC_PER_MSEC, coeff, bit_rate / 1000); ui_x8 = ui << 3; - lpx = mult_frac(NSEC_PER_MSEC, coeff, esc_rate / 1000); temp = S_DIV_ROUND_UP(38 * coeff - val_ckln * ui, ui_x8); tmin = max_t(s32, temp, 0); @@ -262,7 +261,7 @@ int msm_dsi_dphy_timing_calc_v3(struct msm_dsi_dphy_timing *timing, { const unsigned long bit_rate = clk_req->bitclk_rate; const unsigned long esc_rate = clk_req->escclk_rate; - s32 ui, ui_x8, lpx; + s32 ui, ui_x8; s32 tmax, tmin; s32 pcnt0 = 50; s32 pcnt1 = 50; @@ -284,7 +283,6 @@ int msm_dsi_dphy_timing_calc_v3(struct msm_dsi_dphy_timing *timing, ui = mult_frac(NSEC_PER_MSEC, coeff, bit_rate / 1000); ui_x8 = ui << 3; - lpx = mult_frac(NSEC_PER_MSEC, coeff, esc_rate / 1000); temp = S_DIV_ROUND_UP(38 * coeff, ui_x8); tmin = max_t(s32, temp, 0); @@ -396,8 +394,12 @@ static int dsi_phy_regulator_init(struct msm_dsi_phy *phy) ret = devm_regulator_bulk_get(dev, num, s); if (ret < 0) { - DRM_DEV_ERROR(dev, "%s: failed to init regulator, ret=%d\n", - __func__, ret); + if (ret != -EPROBE_DEFER) { + DRM_DEV_ERROR(dev, + "%s: failed to init regulator, ret=%d\n", + __func__, ret); + } + return ret; } @@ -481,6 +483,8 @@ static const struct of_device_id dsi_phy_dt_match[] = { #ifdef CONFIG_DRM_MSM_DSI_28NM_PHY { .compatible = "qcom,dsi-phy-28nm-hpm", .data = &dsi_phy_28nm_hpm_cfgs }, + { .compatible = "qcom,dsi-phy-28nm-hpm-fam-b", + .data = &dsi_phy_28nm_hpm_famb_cfgs }, { .compatible = "qcom,dsi-phy-28nm-lp", .data = &dsi_phy_28nm_lp_cfgs }, #endif @@ -584,10 +588,8 @@ static int dsi_phy_driver_probe(struct platform_device *pdev) } ret = dsi_phy_regulator_init(phy); - if (ret) { - DRM_DEV_ERROR(dev, "%s: failed to init regulator\n", __func__); + if (ret) goto fail; - } phy->ahb_clk = msm_clk_get(pdev, "iface"); if (IS_ERR(phy->ahb_clk)) { diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h index c4069ce6afe6..24b294ed3059 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h @@ -40,6 +40,7 @@ struct msm_dsi_phy_cfg { }; extern const struct msm_dsi_phy_cfg dsi_phy_28nm_hpm_cfgs; +extern const struct msm_dsi_phy_cfg dsi_phy_28nm_hpm_famb_cfgs; extern const struct msm_dsi_phy_cfg dsi_phy_28nm_lp_cfgs; extern const struct msm_dsi_phy_cfg dsi_phy_20nm_cfgs; extern const struct msm_dsi_phy_cfg dsi_phy_28nm_8960_cfgs; diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c index c3a61876470f..1594f1422372 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c @@ -3,6 +3,8 @@ * Copyright (c) 2016, The Linux Foundation. All rights reserved. */ +#include <linux/delay.h> + #include "dsi_phy.h" #include "dsi.xml.h" diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c index b3f678f6c2aa..c3c580cfd8b1 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c @@ -39,15 +39,10 @@ static void dsi_28nm_dphy_set_timing(struct msm_dsi_phy *phy, DSI_28nm_PHY_TIMING_CTRL_11_TRIG3_CMD(0)); } -static void dsi_28nm_phy_regulator_ctrl(struct msm_dsi_phy *phy, bool enable) +static void dsi_28nm_phy_regulator_enable_dcdc(struct msm_dsi_phy *phy) { void __iomem *base = phy->reg_base; - if (!enable) { - dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CAL_PWR_CFG, 0); - return; - } - dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CTRL_0, 0x0); dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CAL_PWR_CFG, 1); dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CTRL_5, 0); @@ -56,6 +51,39 @@ static void dsi_28nm_phy_regulator_ctrl(struct msm_dsi_phy *phy, bool enable) dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CTRL_1, 0x9); dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CTRL_0, 0x7); dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CTRL_4, 0x20); + dsi_phy_write(phy->base + REG_DSI_28nm_PHY_LDO_CNTRL, 0x00); +} + +static void dsi_28nm_phy_regulator_enable_ldo(struct msm_dsi_phy *phy) +{ + void __iomem *base = phy->reg_base; + + dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CTRL_0, 0x0); + dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CAL_PWR_CFG, 0); + dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CTRL_5, 0x7); + dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CTRL_3, 0); + dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CTRL_2, 0x1); + dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CTRL_1, 0x1); + dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CTRL_4, 0x20); + + if (phy->cfg->type == MSM_DSI_PHY_28NM_LP) + dsi_phy_write(phy->base + REG_DSI_28nm_PHY_LDO_CNTRL, 0x05); + else + dsi_phy_write(phy->base + REG_DSI_28nm_PHY_LDO_CNTRL, 0x0d); +} + +static void dsi_28nm_phy_regulator_ctrl(struct msm_dsi_phy *phy, bool enable) +{ + if (!enable) { + dsi_phy_write(phy->reg_base + + REG_DSI_28nm_PHY_REGULATOR_CAL_PWR_CFG, 0); + return; + } + + if (phy->regulator_ldo_mode) + dsi_28nm_phy_regulator_enable_ldo(phy); + else + dsi_28nm_phy_regulator_enable_dcdc(phy); } static int dsi_28nm_phy_enable(struct msm_dsi_phy *phy, int src_pll_id, @@ -77,8 +105,6 @@ static int dsi_28nm_phy_enable(struct msm_dsi_phy *phy, int src_pll_id, dsi_28nm_phy_regulator_ctrl(phy, true); - dsi_phy_write(base + REG_DSI_28nm_PHY_LDO_CNTRL, 0x00); - dsi_28nm_dphy_set_timing(phy, timing); dsi_phy_write(base + REG_DSI_28nm_PHY_CTRL_1, 0x00); @@ -142,6 +168,24 @@ const struct msm_dsi_phy_cfg dsi_phy_28nm_hpm_cfgs = { .num_dsi_phy = 2, }; +const struct msm_dsi_phy_cfg dsi_phy_28nm_hpm_famb_cfgs = { + .type = MSM_DSI_PHY_28NM_HPM, + .src_pll_truthtable = { {true, true}, {false, true} }, + .reg_cfg = { + .num = 1, + .regs = { + {"vddio", 100000, 100}, + }, + }, + .ops = { + .enable = dsi_28nm_phy_enable, + .disable = dsi_28nm_phy_disable, + .init = msm_dsi_phy_init_common, + }, + .io_start = { 0x1a94400, 0x1a96400 }, + .num_dsi_phy = 2, +}; + const struct msm_dsi_phy_cfg dsi_phy_28nm_lp_cfgs = { .type = MSM_DSI_PHY_28NM_LP, .src_pll_truthtable = { {true, true}, {true, true} }, diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c index a198f51d47b4..f22583353957 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c @@ -3,6 +3,8 @@ * Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. */ +#include <linux/delay.h> + #include "dsi_phy.h" #include "dsi.xml.h" diff --git a/drivers/gpu/drm/msm/dsi/pll/dsi_pll.h b/drivers/gpu/drm/msm/dsi/pll/dsi_pll.h index 118bebe53de3..c6a3623f905d 100644 --- a/drivers/gpu/drm/msm/dsi/pll/dsi_pll.h +++ b/drivers/gpu/drm/msm/dsi/pll/dsi_pll.h @@ -6,8 +6,8 @@ #ifndef __DSI_PLL_H__ #define __DSI_PLL_H__ -#include <linux/clk.h> #include <linux/clk-provider.h> +#include <linux/delay.h> #include "dsi.h" diff --git a/drivers/gpu/drm/msm/dsi/pll/dsi_pll_10nm.c b/drivers/gpu/drm/msm/dsi/pll/dsi_pll_10nm.c index 8f6100db90ed..1c894548dd72 100644 --- a/drivers/gpu/drm/msm/dsi/pll/dsi_pll_10nm.c +++ b/drivers/gpu/drm/msm/dsi/pll/dsi_pll_10nm.c @@ -751,9 +751,9 @@ static int pll_10nm_register(struct dsi_pll_10nm *pll_10nm) snprintf(parent4, 32, "dsi%d_pll_post_out_div_clk", pll_10nm->id); hw = clk_hw_register_mux(dev, clk_name, - (const char *[]){ + ((const char *[]){ parent, parent2, parent3, parent4 - }, 4, 0, pll_10nm->phy_cmn_mmio + + }), 4, 0, pll_10nm->phy_cmn_mmio + REG_DSI_10nm_PHY_CMN_CLK_CFG1, 0, 2, 0, NULL); if (IS_ERR(hw)) { diff --git a/drivers/gpu/drm/msm/dsi/pll/dsi_pll_28nm.c b/drivers/gpu/drm/msm/dsi/pll/dsi_pll_28nm.c index 8c99e01ae332..6dffd7f4a99b 100644 --- a/drivers/gpu/drm/msm/dsi/pll/dsi_pll_28nm.c +++ b/drivers/gpu/drm/msm/dsi/pll/dsi_pll_28nm.c @@ -554,9 +554,9 @@ static int pll_28nm_register(struct dsi_pll_28nm *pll_28nm) snprintf(parent1, 32, "dsi%dvco_clk", pll_28nm->id); snprintf(parent2, 32, "dsi%dindirect_path_div2_clk", pll_28nm->id); clks[num++] = clk_register_mux(dev, clk_name, - (const char *[]){ + ((const char *[]){ parent1, parent2 - }, 2, CLK_SET_RATE_PARENT, pll_28nm->mmio + + }), 2, CLK_SET_RATE_PARENT, pll_28nm->mmio + REG_DSI_28nm_PHY_PLL_VREG_CFG, 1, 1, 0, NULL); snprintf(clk_name, 32, "dsi%dpllbyte", pll_28nm->id); |