aboutsummaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/msm/dp
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/msm/dp')
-rw-r--r--drivers/gpu/drm/msm/dp/dp_clk_util.c120
-rw-r--r--drivers/gpu/drm/msm/dp/dp_clk_util.h38
-rw-r--r--drivers/gpu/drm/msm/dp/dp_ctrl.c15
-rw-r--r--drivers/gpu/drm/msm/dp/dp_display.c100
-rw-r--r--drivers/gpu/drm/msm/dp/dp_display.h1
-rw-r--r--drivers/gpu/drm/msm/dp/dp_drm.c8
-rw-r--r--drivers/gpu/drm/msm/dp/dp_drm.h2
-rw-r--r--drivers/gpu/drm/msm/dp/dp_parser.c67
-rw-r--r--drivers/gpu/drm/msm/dp/dp_parser.h10
-rw-r--r--drivers/gpu/drm/msm/dp/dp_power.c199
10 files changed, 87 insertions, 473 deletions
diff --git a/drivers/gpu/drm/msm/dp/dp_clk_util.c b/drivers/gpu/drm/msm/dp/dp_clk_util.c
deleted file mode 100644
index 44a4fc59ff31..000000000000
--- a/drivers/gpu/drm/msm/dp/dp_clk_util.c
+++ /dev/null
@@ -1,120 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/* Copyright (c) 2012-2015, 2017-2018, The Linux Foundation.
- * All rights reserved.
- */
-
-#include <linux/clk.h>
-#include <linux/clk/clk-conf.h>
-#include <linux/err.h>
-#include <linux/delay.h>
-#include <linux/of.h>
-
-#include <drm/drm_print.h>
-
-#include "dp_clk_util.h"
-
-void msm_dss_put_clk(struct dss_clk *clk_arry, int num_clk)
-{
- int i;
-
- for (i = num_clk - 1; i >= 0; i--) {
- if (clk_arry[i].clk)
- clk_put(clk_arry[i].clk);
- clk_arry[i].clk = NULL;
- }
-}
-
-int msm_dss_get_clk(struct device *dev, struct dss_clk *clk_arry, int num_clk)
-{
- int i, rc = 0;
-
- for (i = 0; i < num_clk; i++) {
- clk_arry[i].clk = clk_get(dev, clk_arry[i].clk_name);
- rc = PTR_ERR_OR_ZERO(clk_arry[i].clk);
- if (rc) {
- DEV_ERR("%pS->%s: '%s' get failed. rc=%d\n",
- __builtin_return_address(0), __func__,
- clk_arry[i].clk_name, rc);
- goto error;
- }
- }
-
- return rc;
-
-error:
- for (i--; i >= 0; i--) {
- if (clk_arry[i].clk)
- clk_put(clk_arry[i].clk);
- clk_arry[i].clk = NULL;
- }
-
- return rc;
-}
-
-int msm_dss_clk_set_rate(struct dss_clk *clk_arry, int num_clk)
-{
- int i, rc = 0;
-
- for (i = 0; i < num_clk; i++) {
- if (clk_arry[i].clk) {
- if (clk_arry[i].type != DSS_CLK_AHB) {
- DEV_DBG("%pS->%s: '%s' rate %ld\n",
- __builtin_return_address(0), __func__,
- clk_arry[i].clk_name,
- clk_arry[i].rate);
- rc = clk_set_rate(clk_arry[i].clk,
- clk_arry[i].rate);
- if (rc) {
- DEV_ERR("%pS->%s: %s failed. rc=%d\n",
- __builtin_return_address(0),
- __func__,
- clk_arry[i].clk_name, rc);
- break;
- }
- }
- } else {
- DEV_ERR("%pS->%s: '%s' is not available\n",
- __builtin_return_address(0), __func__,
- clk_arry[i].clk_name);
- rc = -EPERM;
- break;
- }
- }
-
- return rc;
-}
-
-int msm_dss_enable_clk(struct dss_clk *clk_arry, int num_clk, int enable)
-{
- int i, rc = 0;
-
- if (enable) {
- for (i = 0; i < num_clk; i++) {
- DEV_DBG("%pS->%s: enable '%s'\n",
- __builtin_return_address(0), __func__,
- clk_arry[i].clk_name);
- rc = clk_prepare_enable(clk_arry[i].clk);
- if (rc)
- DEV_ERR("%pS->%s: %s en fail. rc=%d\n",
- __builtin_return_address(0),
- __func__,
- clk_arry[i].clk_name, rc);
-
- if (rc && i) {
- msm_dss_enable_clk(&clk_arry[i - 1],
- i - 1, false);
- break;
- }
- }
- } else {
- for (i = num_clk - 1; i >= 0; i--) {
- DEV_DBG("%pS->%s: disable '%s'\n",
- __builtin_return_address(0), __func__,
- clk_arry[i].clk_name);
-
- clk_disable_unprepare(clk_arry[i].clk);
- }
- }
-
- return rc;
-}
diff --git a/drivers/gpu/drm/msm/dp/dp_clk_util.h b/drivers/gpu/drm/msm/dp/dp_clk_util.h
deleted file mode 100644
index 067bf87f3d97..000000000000
--- a/drivers/gpu/drm/msm/dp/dp_clk_util.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/* Copyright (c) 2012, 2017-2018, The Linux Foundation. All rights reserved.
- */
-
-#ifndef __DP_CLK_UTIL_H__
-#define __DP_CLK_UTIL_H__
-
-#include <linux/platform_device.h>
-#include <linux/types.h>
-
-#define DEV_DBG(fmt, args...) pr_debug(fmt, ##args)
-#define DEV_INFO(fmt, args...) pr_info(fmt, ##args)
-#define DEV_WARN(fmt, args...) pr_warn(fmt, ##args)
-#define DEV_ERR(fmt, args...) pr_err(fmt, ##args)
-
-enum dss_clk_type {
- DSS_CLK_AHB, /* no set rate. rate controlled through rpm */
- DSS_CLK_PCLK,
-};
-
-struct dss_clk {
- struct clk *clk; /* clk handle */
- char clk_name[32];
- enum dss_clk_type type;
- unsigned long rate;
- unsigned long max_rate;
-};
-
-struct dss_module_power {
- unsigned int num_clk;
- struct dss_clk *clk_config;
-};
-
-int msm_dss_get_clk(struct device *dev, struct dss_clk *clk_arry, int num_clk);
-void msm_dss_put_clk(struct dss_clk *clk_arry, int num_clk);
-int msm_dss_clk_set_rate(struct dss_clk *clk_arry, int num_clk);
-int msm_dss_enable_clk(struct dss_clk *clk_arry, int num_clk, int enable);
-#endif /* __DP_CLK_UTIL_H__ */
diff --git a/drivers/gpu/drm/msm/dp/dp_ctrl.c b/drivers/gpu/drm/msm/dp/dp_ctrl.c
index 703249384e7c..013ca02e17cb 100644
--- a/drivers/gpu/drm/msm/dp/dp_ctrl.c
+++ b/drivers/gpu/drm/msm/dp/dp_ctrl.c
@@ -1214,7 +1214,7 @@ static int dp_ctrl_link_train_2(struct dp_ctrl_private *ctrl,
if (ret)
return ret;
- dp_ctrl_train_pattern_set(ctrl, pattern | DP_RECOVERED_CLOCK_OUT_EN);
+ dp_ctrl_train_pattern_set(ctrl, pattern);
for (tries = 0; tries <= maximum_retries; tries++) {
drm_dp_link_train_channel_eq_delay(ctrl->aux, ctrl->panel->dpcd);
@@ -1321,9 +1321,9 @@ static void dp_ctrl_set_clock_rate(struct dp_ctrl_private *ctrl,
enum dp_pm_type module, char *name, unsigned long rate)
{
u32 num = ctrl->parser->mp[module].num_clk;
- struct dss_clk *cfg = ctrl->parser->mp[module].clk_config;
+ struct clk_bulk_data *cfg = ctrl->parser->mp[module].clocks;
- while (num && strcmp(cfg->clk_name, name)) {
+ while (num && strcmp(cfg->id, name)) {
num--;
cfg++;
}
@@ -1332,7 +1332,7 @@ static void dp_ctrl_set_clock_rate(struct dp_ctrl_private *ctrl,
rate, name);
if (num)
- cfg->rate = rate;
+ clk_set_rate(cfg->clk, rate);
else
DRM_ERROR("%s clock doesn't exit to set rate %lu\n",
name, rate);
@@ -1349,12 +1349,11 @@ static int dp_ctrl_enable_mainlink_clocks(struct dp_ctrl_private *ctrl)
opts_dp->lanes = ctrl->link->link_params.num_lanes;
opts_dp->link_rate = ctrl->link->link_params.rate / 100;
opts_dp->ssc = drm_dp_max_downspread(dpcd);
- dp_ctrl_set_clock_rate(ctrl, DP_CTRL_PM, "ctrl_link",
- ctrl->link->link_params.rate * 1000);
phy_configure(phy, &dp_io->phy_opts);
phy_power_on(phy);
+ dev_pm_opp_set_rate(ctrl->dev, ctrl->link->link_params.rate * 1000);
ret = dp_power_clk_enable(ctrl->power, DP_CTRL_PM, true);
if (ret)
DRM_ERROR("Unable to start link clocks. ret=%d\n", ret);
@@ -1462,6 +1461,7 @@ static int dp_ctrl_reinitialize_mainlink(struct dp_ctrl_private *ctrl)
* link clock might have been adjusted as part of the
* link maintenance.
*/
+ dev_pm_opp_set_rate(ctrl->dev, 0);
ret = dp_power_clk_enable(ctrl->power, DP_CTRL_PM, false);
if (ret) {
DRM_ERROR("Failed to disable clocks. ret=%d\n", ret);
@@ -1493,6 +1493,7 @@ static int dp_ctrl_deinitialize_mainlink(struct dp_ctrl_private *ctrl)
dp_catalog_ctrl_reset(ctrl->catalog);
+ dev_pm_opp_set_rate(ctrl->dev, 0);
ret = dp_power_clk_enable(ctrl->power, DP_CTRL_PM, false);
if (ret) {
DRM_ERROR("Failed to disable link clocks. ret=%d\n", ret);
@@ -1929,6 +1930,7 @@ int dp_ctrl_off_link_stream(struct dp_ctrl *dp_ctrl)
}
}
+ dev_pm_opp_set_rate(ctrl->dev, 0);
ret = dp_power_clk_enable(ctrl->power, DP_CTRL_PM, false);
if (ret) {
DRM_ERROR("Failed to disable link clocks. ret=%d\n", ret);
@@ -1997,6 +1999,7 @@ int dp_ctrl_off(struct dp_ctrl *dp_ctrl)
if (ret)
DRM_ERROR("Failed to disable pixel clocks. ret=%d\n", ret);
+ dev_pm_opp_set_rate(ctrl->dev, 0);
ret = dp_power_clk_enable(ctrl->power, DP_CTRL_PM, false);
if (ret) {
DRM_ERROR("Failed to disable link clocks. ret=%d\n", ret);
diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c
index 239c8e3f2fbd..bfd0aeff3f0d 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.c
+++ b/drivers/gpu/drm/msm/dp/dp_display.c
@@ -131,35 +131,43 @@ struct msm_dp_config {
size_t num_descs;
};
+static const struct msm_dp_desc sc7180_dp_descs[] = {
+ [MSM_DP_CONTROLLER_0] = { .io_start = 0x0ae90000, .connector_type = DRM_MODE_CONNECTOR_DisplayPort },
+};
+
static const struct msm_dp_config sc7180_dp_cfg = {
- .descs = (const struct msm_dp_desc[]) {
- [MSM_DP_CONTROLLER_0] = { .io_start = 0x0ae90000, .connector_type = DRM_MODE_CONNECTOR_DisplayPort },
- },
- .num_descs = 1,
+ .descs = sc7180_dp_descs,
+ .num_descs = ARRAY_SIZE(sc7180_dp_descs),
+};
+
+static const struct msm_dp_desc sc7280_dp_descs[] = {
+ [MSM_DP_CONTROLLER_0] = { .io_start = 0x0ae90000, .connector_type = DRM_MODE_CONNECTOR_DisplayPort, .wide_bus_en = true },
+ [MSM_DP_CONTROLLER_1] = { .io_start = 0x0aea0000, .connector_type = DRM_MODE_CONNECTOR_eDP, .wide_bus_en = true },
};
static const struct msm_dp_config sc7280_dp_cfg = {
- .descs = (const struct msm_dp_desc[]) {
- [MSM_DP_CONTROLLER_0] = { .io_start = 0x0ae90000, .connector_type = DRM_MODE_CONNECTOR_DisplayPort, .wide_bus_en = true },
- [MSM_DP_CONTROLLER_1] = { .io_start = 0x0aea0000, .connector_type = DRM_MODE_CONNECTOR_eDP, .wide_bus_en = true },
- },
- .num_descs = 2,
+ .descs = sc7280_dp_descs,
+ .num_descs = ARRAY_SIZE(sc7280_dp_descs),
+};
+
+static const struct msm_dp_desc sc8180x_dp_descs[] = {
+ [MSM_DP_CONTROLLER_0] = { .io_start = 0x0ae90000, .connector_type = DRM_MODE_CONNECTOR_DisplayPort },
+ [MSM_DP_CONTROLLER_1] = { .io_start = 0x0ae98000, .connector_type = DRM_MODE_CONNECTOR_DisplayPort },
+ [MSM_DP_CONTROLLER_2] = { .io_start = 0x0ae9a000, .connector_type = DRM_MODE_CONNECTOR_eDP },
};
static const struct msm_dp_config sc8180x_dp_cfg = {
- .descs = (const struct msm_dp_desc[]) {
- [MSM_DP_CONTROLLER_0] = { .io_start = 0x0ae90000, .connector_type = DRM_MODE_CONNECTOR_DisplayPort },
- [MSM_DP_CONTROLLER_1] = { .io_start = 0x0ae98000, .connector_type = DRM_MODE_CONNECTOR_DisplayPort },
- [MSM_DP_CONTROLLER_2] = { .io_start = 0x0ae9a000, .connector_type = DRM_MODE_CONNECTOR_eDP },
- },
- .num_descs = 3,
+ .descs = sc8180x_dp_descs,
+ .num_descs = ARRAY_SIZE(sc8180x_dp_descs),
+};
+
+static const struct msm_dp_desc sm8350_dp_descs[] = {
+ [MSM_DP_CONTROLLER_0] = { .io_start = 0x0ae90000, .connector_type = DRM_MODE_CONNECTOR_DisplayPort },
};
static const struct msm_dp_config sm8350_dp_cfg = {
- .descs = (const struct msm_dp_desc[]) {
- [MSM_DP_CONTROLLER_0] = { .io_start = 0x0ae90000, .connector_type = DRM_MODE_CONNECTOR_DisplayPort },
- },
- .num_descs = 1,
+ .descs = sm8350_dp_descs,
+ .num_descs = ARRAY_SIZE(sm8350_dp_descs),
};
static const struct of_device_id dp_dt_match[] = {
@@ -610,9 +618,6 @@ static int dp_hpd_plug_handle(struct dp_display_private *dp, u32 data)
return 0;
};
-static int dp_display_enable(struct dp_display_private *dp, u32 data);
-static int dp_display_disable(struct dp_display_private *dp, u32 data);
-
static void dp_display_handle_plugged_change(struct msm_dp *dp_display,
bool plugged)
{
@@ -859,12 +864,7 @@ static int dp_display_set_mode(struct msm_dp *dp_display,
return 0;
}
-static int dp_display_prepare(struct msm_dp *dp_display)
-{
- return 0;
-}
-
-static int dp_display_enable(struct dp_display_private *dp, u32 data)
+static int dp_display_enable(struct dp_display_private *dp, bool force_link_train)
{
int rc = 0;
struct msm_dp *dp_display = &dp->dp_display;
@@ -875,7 +875,7 @@ static int dp_display_enable(struct dp_display_private *dp, u32 data)
return 0;
}
- rc = dp_ctrl_on_stream(dp->ctrl, data);
+ rc = dp_ctrl_on_stream(dp->ctrl, force_link_train);
if (!rc)
dp_display->power_on = true;
@@ -901,7 +901,7 @@ static int dp_display_post_enable(struct msm_dp *dp_display)
return 0;
}
-static int dp_display_disable(struct dp_display_private *dp, u32 data)
+static int dp_display_disable(struct dp_display_private *dp)
{
struct msm_dp *dp_display = &dp->dp_display;
@@ -940,11 +940,6 @@ static int dp_display_disable(struct dp_display_private *dp, u32 data)
return 0;
}
-static int dp_display_unprepare(struct msm_dp *dp_display)
-{
- return 0;
-}
-
int dp_display_set_plugged_cb(struct msm_dp *dp_display,
hdmi_codec_plugged_cb fn, struct device *codec_dev)
{
@@ -992,7 +987,7 @@ enum drm_mode_status dp_bridge_mode_valid(struct drm_bridge *bridge,
return MODE_OK;
if (mode->clock > DP_MAX_PIXEL_CLK_KHZ)
- return MODE_BAD;
+ return MODE_CLOCK_HIGH;
dp_display = container_of(dp, struct dp_display_private, dp_display);
link_info = &dp_display->panel->link_info;
@@ -1460,21 +1455,9 @@ static int dp_pm_suspend(struct device *dev)
return 0;
}
-static int dp_pm_prepare(struct device *dev)
-{
- return 0;
-}
-
-static void dp_pm_complete(struct device *dev)
-{
-
-}
-
static const struct dev_pm_ops dp_pm_ops = {
.suspend = dp_pm_suspend,
.resume = dp_pm_resume,
- .prepare = dp_pm_prepare,
- .complete = dp_pm_complete,
};
static struct platform_driver dp_display_driver = {
@@ -1624,8 +1607,6 @@ int msm_dp_modeset_init(struct msm_dp *dp_display, struct drm_device *dev,
return ret;
}
- dp_display->encoder = encoder;
-
ret = dp_display_get_next_bridge(dp_display);
if (ret)
return ret;
@@ -1641,7 +1622,7 @@ int msm_dp_modeset_init(struct msm_dp *dp_display, struct drm_device *dev,
priv->bridges[priv->num_bridges++] = dp_display->bridge;
- dp_display->connector = dp_drm_connector_init(dp_display);
+ dp_display->connector = dp_drm_connector_init(dp_display, encoder);
if (IS_ERR(dp_display->connector)) {
ret = PTR_ERR(dp_display->connector);
DRM_DEV_ERROR(dev->dev,
@@ -1688,13 +1669,6 @@ void dp_bridge_enable(struct drm_bridge *drm_bridge)
return;
}
- rc = dp_display_prepare(dp);
- if (rc) {
- DRM_ERROR("DP display prepare failed, rc=%d\n", rc);
- mutex_unlock(&dp_display->event_mutex);
- return;
- }
-
state = dp_display->hpd_state;
if (state == ST_DISPLAY_OFF) {
@@ -1707,8 +1681,7 @@ void dp_bridge_enable(struct drm_bridge *drm_bridge)
rc = dp_display_post_enable(dp);
if (rc) {
DRM_ERROR("DP display post enable failed, rc=%d\n", rc);
- dp_display_disable(dp_display, 0);
- dp_display_unprepare(dp);
+ dp_display_disable(dp_display);
}
/* completed connection */
@@ -1733,7 +1706,6 @@ void dp_bridge_post_disable(struct drm_bridge *drm_bridge)
{
struct msm_dp_bridge *dp_bridge = to_dp_bridge(drm_bridge);
struct msm_dp *dp = dp_bridge->dp_display;
- int rc = 0;
u32 state;
struct dp_display_private *dp_display;
@@ -1750,11 +1722,7 @@ void dp_bridge_post_disable(struct drm_bridge *drm_bridge)
return;
}
- dp_display_disable(dp_display, 0);
-
- rc = dp_display_unprepare(dp);
- if (rc)
- DRM_ERROR("DP display unprepare failed, rc=%d\n", rc);
+ dp_display_disable(dp_display);
state = dp_display->hpd_state;
if (state == ST_DISCONNECT_PENDING) {
diff --git a/drivers/gpu/drm/msm/dp/dp_display.h b/drivers/gpu/drm/msm/dp/dp_display.h
index 4f9fe4d7610b..dcedf021f7fe 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.h
+++ b/drivers/gpu/drm/msm/dp/dp_display.h
@@ -15,7 +15,6 @@ struct msm_dp {
struct device *codec_dev;
struct drm_bridge *bridge;
struct drm_connector *connector;
- struct drm_encoder *encoder;
struct drm_bridge *next_bridge;
bool is_connected;
bool audio_enabled;
diff --git a/drivers/gpu/drm/msm/dp/dp_drm.c b/drivers/gpu/drm/msm/dp/dp_drm.c
index 62d58b9c4647..6df25f7662e7 100644
--- a/drivers/gpu/drm/msm/dp/dp_drm.c
+++ b/drivers/gpu/drm/msm/dp/dp_drm.c
@@ -116,7 +116,7 @@ struct drm_bridge *dp_bridge_init(struct msm_dp *dp_display, struct drm_device *
}
if (dp_display->next_bridge) {
- rc = drm_bridge_attach(dp_display->encoder,
+ rc = drm_bridge_attach(encoder,
dp_display->next_bridge, bridge,
DRM_BRIDGE_ATTACH_NO_CONNECTOR);
if (rc < 0) {
@@ -130,15 +130,15 @@ struct drm_bridge *dp_bridge_init(struct msm_dp *dp_display, struct drm_device *
}
/* connector initialization */
-struct drm_connector *dp_drm_connector_init(struct msm_dp *dp_display)
+struct drm_connector *dp_drm_connector_init(struct msm_dp *dp_display, struct drm_encoder *encoder)
{
struct drm_connector *connector = NULL;
- connector = drm_bridge_connector_init(dp_display->drm_dev, dp_display->encoder);
+ connector = drm_bridge_connector_init(dp_display->drm_dev, encoder);
if (IS_ERR(connector))
return connector;
- drm_connector_attach_encoder(connector, dp_display->encoder);
+ drm_connector_attach_encoder(connector, encoder);
return connector;
}
diff --git a/drivers/gpu/drm/msm/dp/dp_drm.h b/drivers/gpu/drm/msm/dp/dp_drm.h
index f4b1ed1e24f7..82035dbb0578 100644
--- a/drivers/gpu/drm/msm/dp/dp_drm.h
+++ b/drivers/gpu/drm/msm/dp/dp_drm.h
@@ -19,7 +19,7 @@ struct msm_dp_bridge {
#define to_dp_bridge(x) container_of((x), struct msm_dp_bridge, bridge)
-struct drm_connector *dp_drm_connector_init(struct msm_dp *dp_display);
+struct drm_connector *dp_drm_connector_init(struct msm_dp *dp_display, struct drm_encoder *encoder);
struct drm_bridge *dp_bridge_init(struct msm_dp *dp_display, struct drm_device *dev,
struct drm_encoder *encoder);
diff --git a/drivers/gpu/drm/msm/dp/dp_parser.c b/drivers/gpu/drm/msm/dp/dp_parser.c
index 8f9fed9fdafc..dd732215d55b 100644
--- a/drivers/gpu/drm/msm/dp/dp_parser.c
+++ b/drivers/gpu/drm/msm/dp/dp_parser.c
@@ -22,14 +22,6 @@
#define DP_DEFAULT_P0_OFFSET 0x1000
#define DP_DEFAULT_P0_SIZE 0x0400
-static const struct dp_regulator_cfg sdm845_dp_reg_cfg = {
- .num = 2,
- .regs = {
- {"vdda-1p2", 21800, 4 }, /* 1.2 V */
- {"vdda-0p9", 36000, 32 }, /* 0.9 V */
- },
-};
-
static void __iomem *dp_ioremap(struct platform_device *pdev, int idx, size_t *len)
{
struct resource *res;
@@ -102,14 +94,12 @@ static int dp_parser_ctrl_res(struct dp_parser *parser)
static int dp_parser_misc(struct dp_parser *parser)
{
struct device_node *of_node = parser->pdev->dev.of_node;
- int len = 0;
- const char *data_lane_property = "data-lanes";
+ int len;
- len = of_property_count_elems_of_size(of_node,
- data_lane_property, sizeof(u32));
+ len = drm_of_get_data_lanes_count(of_node, 1, DP_MAX_NUM_DP_LANES);
if (len < 0) {
- DRM_WARN("Invalid property %s, default max DP lanes = %d\n",
- data_lane_property, DP_MAX_NUM_DP_LANES);
+ DRM_WARN("Invalid property \"data-lanes\", default max DP lanes = %d\n",
+ DP_MAX_NUM_DP_LANES);
len = DP_MAX_NUM_DP_LANES;
}
@@ -162,11 +152,11 @@ static int dp_parser_init_clk_data(struct dp_parser *parser)
}
core_power->num_clk = core_clk_count;
- core_power->clk_config = devm_kzalloc(dev,
- sizeof(struct dss_clk) * core_power->num_clk,
+ core_power->clocks = devm_kcalloc(dev,
+ core_power->num_clk, sizeof(struct clk_bulk_data),
GFP_KERNEL);
- if (!core_power->clk_config)
- return -EINVAL;
+ if (!core_power->clocks)
+ return -ENOMEM;
/* Initialize the CTRL power module */
if (ctrl_clk_count == 0) {
@@ -175,12 +165,12 @@ static int dp_parser_init_clk_data(struct dp_parser *parser)
}
ctrl_power->num_clk = ctrl_clk_count;
- ctrl_power->clk_config = devm_kzalloc(dev,
- sizeof(struct dss_clk) * ctrl_power->num_clk,
+ ctrl_power->clocks = devm_kcalloc(dev,
+ ctrl_power->num_clk, sizeof(struct clk_bulk_data),
GFP_KERNEL);
- if (!ctrl_power->clk_config) {
+ if (!ctrl_power->clocks) {
ctrl_power->num_clk = 0;
- return -EINVAL;
+ return -ENOMEM;
}
/* Initialize the STREAM power module */
@@ -190,12 +180,12 @@ static int dp_parser_init_clk_data(struct dp_parser *parser)
}
stream_power->num_clk = stream_clk_count;
- stream_power->clk_config = devm_kzalloc(dev,
- sizeof(struct dss_clk) * stream_power->num_clk,
+ stream_power->clocks = devm_kcalloc(dev,
+ stream_power->num_clk, sizeof(struct clk_bulk_data),
GFP_KERNEL);
- if (!stream_power->clk_config) {
+ if (!stream_power->clocks) {
stream_power->num_clk = 0;
- return -EINVAL;
+ return -ENOMEM;
}
return 0;
@@ -234,29 +224,16 @@ static int dp_parser_clock(struct dp_parser *parser)
}
if (dp_parser_check_prefix("core", clk_name) &&
core_clk_index < core_clk_count) {
- struct dss_clk *clk =
- &core_power->clk_config[core_clk_index];
- strlcpy(clk->clk_name, clk_name, sizeof(clk->clk_name));
- clk->type = DSS_CLK_AHB;
+ core_power->clocks[core_clk_index].id = devm_kstrdup(dev, clk_name, GFP_KERNEL);
core_clk_index++;
} else if (dp_parser_check_prefix("stream", clk_name) &&
stream_clk_index < stream_clk_count) {
- struct dss_clk *clk =
- &stream_power->clk_config[stream_clk_index];
- strlcpy(clk->clk_name, clk_name, sizeof(clk->clk_name));
- clk->type = DSS_CLK_PCLK;
+ stream_power->clocks[stream_clk_index].id = devm_kstrdup(dev, clk_name, GFP_KERNEL);
stream_clk_index++;
} else if (dp_parser_check_prefix("ctrl", clk_name) &&
ctrl_clk_index < ctrl_clk_count) {
- struct dss_clk *clk =
- &ctrl_power->clk_config[ctrl_clk_index];
- strlcpy(clk->clk_name, clk_name, sizeof(clk->clk_name));
+ ctrl_power->clocks[ctrl_clk_index].id = devm_kstrdup(dev, clk_name, GFP_KERNEL);
ctrl_clk_index++;
- if (dp_parser_check_prefix("ctrl_link", clk_name) ||
- dp_parser_check_prefix("stream_pixel", clk_name))
- clk->type = DSS_CLK_PCLK;
- else
- clk->type = DSS_CLK_AHB;
}
}
@@ -298,12 +275,6 @@ static int dp_parser_parse(struct dp_parser *parser)
if (rc)
return rc;
- /* Map the corresponding regulator information according to
- * version. Currently, since we only have one supported platform,
- * mapping the regulator directly.
- */
- parser->regulator_cfg = &sdm845_dp_reg_cfg;
-
return 0;
}
diff --git a/drivers/gpu/drm/msm/dp/dp_parser.h b/drivers/gpu/drm/msm/dp/dp_parser.h
index 3a4d7972c069..866c1a82bf1a 100644
--- a/drivers/gpu/drm/msm/dp/dp_parser.h
+++ b/drivers/gpu/drm/msm/dp/dp_parser.h
@@ -10,7 +10,6 @@
#include <linux/phy/phy.h>
#include <linux/phy/phy-dp.h>
-#include "dp_clk_util.h"
#include "msm_drv.h"
#define DP_LABEL "MDSS DP DISPLAY"
@@ -92,8 +91,6 @@ struct dp_pinctrl {
struct pinctrl_state *state_suspend;
};
-#define DP_DEV_REGULATOR_MAX 4
-
/* Regulators for DP devices */
struct dp_reg_entry {
char name[32];
@@ -101,9 +98,9 @@ struct dp_reg_entry {
int disable_load;
};
-struct dp_regulator_cfg {
- int num;
- struct dp_reg_entry regs[DP_DEV_REGULATOR_MAX];
+struct dss_module_power {
+ unsigned int num_clk;
+ struct clk_bulk_data *clocks;
};
/**
@@ -121,7 +118,6 @@ struct dp_parser {
struct dp_pinctrl pinctrl;
struct dp_io io;
struct dp_display_data disp_data;
- const struct dp_regulator_cfg *regulator_cfg;
u32 max_dp_lanes;
struct drm_bridge *next_bridge;
diff --git a/drivers/gpu/drm/msm/dp/dp_power.c b/drivers/gpu/drm/msm/dp/dp_power.c
index d9e011775ad8..c0aaabb03389 100644
--- a/drivers/gpu/drm/msm/dp/dp_power.c
+++ b/drivers/gpu/drm/msm/dp/dp_power.c
@@ -20,82 +20,10 @@ struct dp_power_private {
struct clk *link_clk_src;
struct clk *pixel_provider;
struct clk *link_provider;
- struct regulator_bulk_data supplies[DP_DEV_REGULATOR_MAX];
struct dp_power dp_power;
};
-static void dp_power_regulator_disable(struct dp_power_private *power)
-{
- struct regulator_bulk_data *s = power->supplies;
- const struct dp_reg_entry *regs = power->parser->regulator_cfg->regs;
- int num = power->parser->regulator_cfg->num;
- int i;
-
- DBG("");
- for (i = num - 1; i >= 0; i--)
- if (regs[i].disable_load >= 0)
- regulator_set_load(s[i].consumer,
- regs[i].disable_load);
-
- regulator_bulk_disable(num, s);
-}
-
-static int dp_power_regulator_enable(struct dp_power_private *power)
-{
- struct regulator_bulk_data *s = power->supplies;
- const struct dp_reg_entry *regs = power->parser->regulator_cfg->regs;
- int num = power->parser->regulator_cfg->num;
- int ret, i;
-
- DBG("");
- for (i = 0; i < num; i++) {
- if (regs[i].enable_load >= 0) {
- ret = regulator_set_load(s[i].consumer,
- regs[i].enable_load);
- if (ret < 0) {
- pr_err("regulator %d set op mode failed, %d\n",
- i, ret);
- goto fail;
- }
- }
- }
-
- ret = regulator_bulk_enable(num, s);
- if (ret < 0) {
- pr_err("regulator enable failed, %d\n", ret);
- goto fail;
- }
-
- return 0;
-
-fail:
- for (i--; i >= 0; i--)
- regulator_set_load(s[i].consumer, regs[i].disable_load);
- return ret;
-}
-
-static int dp_power_regulator_init(struct dp_power_private *power)
-{
- struct regulator_bulk_data *s = power->supplies;
- const struct dp_reg_entry *regs = power->parser->regulator_cfg->regs;
- struct platform_device *pdev = power->pdev;
- int num = power->parser->regulator_cfg->num;
- int i, ret;
-
- for (i = 0; i < num; i++)
- s[i].supply = regs[i].name;
-
- ret = devm_regulator_bulk_get(&pdev->dev, num, s);
- if (ret < 0) {
- pr_err("%s: failed to init regulator, ret=%d\n",
- __func__, ret);
- return ret;
- }
-
- return 0;
-}
-
static int dp_power_clk_init(struct dp_power_private *power)
{
int rc = 0;
@@ -106,107 +34,30 @@ static int dp_power_clk_init(struct dp_power_private *power)
ctrl = &power->parser->mp[DP_CTRL_PM];
stream = &power->parser->mp[DP_STREAM_PM];
- rc = msm_dss_get_clk(dev, core->clk_config, core->num_clk);
+ rc = devm_clk_bulk_get(dev, core->num_clk, core->clocks);
if (rc) {
DRM_ERROR("failed to get %s clk. err=%d\n",
dp_parser_pm_name(DP_CORE_PM), rc);
return rc;
}
- rc = msm_dss_get_clk(dev, ctrl->clk_config, ctrl->num_clk);
+ rc = devm_clk_bulk_get(dev, ctrl->num_clk, ctrl->clocks);
if (rc) {
DRM_ERROR("failed to get %s clk. err=%d\n",
dp_parser_pm_name(DP_CTRL_PM), rc);
- msm_dss_put_clk(core->clk_config, core->num_clk);
return -ENODEV;
}
- rc = msm_dss_get_clk(dev, stream->clk_config, stream->num_clk);
+ rc = devm_clk_bulk_get(dev, stream->num_clk, stream->clocks);
if (rc) {
DRM_ERROR("failed to get %s clk. err=%d\n",
dp_parser_pm_name(DP_CTRL_PM), rc);
- msm_dss_put_clk(core->clk_config, core->num_clk);
return -ENODEV;
}
return 0;
}
-static int dp_power_clk_deinit(struct dp_power_private *power)
-{
- struct dss_module_power *core, *ctrl, *stream;
-
- core = &power->parser->mp[DP_CORE_PM];
- ctrl = &power->parser->mp[DP_CTRL_PM];
- stream = &power->parser->mp[DP_STREAM_PM];
-
- if (!core || !ctrl || !stream) {
- DRM_ERROR("invalid power_data\n");
- return -EINVAL;
- }
-
- msm_dss_put_clk(ctrl->clk_config, ctrl->num_clk);
- msm_dss_put_clk(core->clk_config, core->num_clk);
- msm_dss_put_clk(stream->clk_config, stream->num_clk);
- return 0;
-}
-
-static int dp_power_clk_set_link_rate(struct dp_power_private *power,
- struct dss_clk *clk_arry, int num_clk, int enable)
-{
- u32 rate;
- int i, rc = 0;
-
- for (i = 0; i < num_clk; i++) {
- if (clk_arry[i].clk) {
- if (clk_arry[i].type == DSS_CLK_PCLK) {
- if (enable)
- rate = clk_arry[i].rate;
- else
- rate = 0;
-
- rc = dev_pm_opp_set_rate(power->dev, rate);
- if (rc)
- break;
- }
-
- }
- }
- return rc;
-}
-
-static int dp_power_clk_set_rate(struct dp_power_private *power,
- enum dp_pm_type module, bool enable)
-{
- int rc = 0;
- struct dss_module_power *mp = &power->parser->mp[module];
-
- if (module == DP_CTRL_PM) {
- rc = dp_power_clk_set_link_rate(power, mp->clk_config, mp->num_clk, enable);
- if (rc) {
- DRM_ERROR("failed to set link clks rate\n");
- return rc;
- }
- } else {
-
- if (enable) {
- rc = msm_dss_clk_set_rate(mp->clk_config, mp->num_clk);
- if (rc) {
- DRM_ERROR("failed to set clks rate\n");
- return rc;
- }
- }
- }
-
- rc = msm_dss_enable_clk(mp->clk_config, mp->num_clk, enable);
- if (rc) {
- DRM_ERROR("failed to %d clks, err: %d\n", enable, rc);
- return rc;
- }
-
- return 0;
-}
-
int dp_power_clk_status(struct dp_power *dp_power, enum dp_pm_type pm_type)
{
struct dp_power_private *power;
@@ -234,6 +85,7 @@ int dp_power_clk_enable(struct dp_power *dp_power,
{
int rc = 0;
struct dp_power_private *power;
+ struct dss_module_power *mp;
power = container_of(dp_power, struct dp_power_private, dp_power);
@@ -266,8 +118,9 @@ int dp_power_clk_enable(struct dp_power *dp_power,
if ((pm_type == DP_CTRL_PM) && (!dp_power->core_clks_on)) {
drm_dbg_dp(power->drm_dev,
"Enable core clks before link clks\n");
+ mp = &power->parser->mp[DP_CORE_PM];
- rc = dp_power_clk_set_rate(power, DP_CORE_PM, enable);
+ rc = clk_bulk_prepare_enable(mp->num_clk, mp->clocks);
if (rc) {
DRM_ERROR("fail to enable clks: %s. err=%d\n",
dp_parser_pm_name(DP_CORE_PM), rc);
@@ -277,12 +130,15 @@ int dp_power_clk_enable(struct dp_power *dp_power,
}
}
- rc = dp_power_clk_set_rate(power, pm_type, enable);
- if (rc) {
- DRM_ERROR("failed to '%s' clks for: %s. err=%d\n",
- enable ? "enable" : "disable",
- dp_parser_pm_name(pm_type), rc);
- return rc;
+ mp = &power->parser->mp[pm_type];
+ if (enable) {
+ rc = clk_bulk_prepare_enable(mp->num_clk, mp->clocks);
+ if (rc) {
+ DRM_ERROR("failed to enable clks, err: %d\n", rc);
+ return rc;
+ }
+ } else {
+ clk_bulk_disable_unprepare(mp->num_clk, mp->clocks);
}
if (pm_type == DP_CORE_PM)
@@ -318,21 +174,10 @@ int dp_power_client_init(struct dp_power *dp_power)
pm_runtime_enable(&power->pdev->dev);
- rc = dp_power_regulator_init(power);
- if (rc) {
- DRM_ERROR("failed to init regulators %d\n", rc);
- goto error;
- }
-
rc = dp_power_clk_init(power);
- if (rc) {
+ if (rc)
DRM_ERROR("failed to init clocks %d\n", rc);
- goto error;
- }
- return 0;
-error:
- pm_runtime_disable(&power->pdev->dev);
return rc;
}
@@ -347,9 +192,7 @@ void dp_power_client_deinit(struct dp_power *dp_power)
power = container_of(dp_power, struct dp_power_private, dp_power);
- dp_power_clk_deinit(power);
pm_runtime_disable(&power->pdev->dev);
-
}
int dp_power_init(struct dp_power *dp_power, bool flip)
@@ -365,22 +208,15 @@ int dp_power_init(struct dp_power *dp_power, bool flip)
power = container_of(dp_power, struct dp_power_private, dp_power);
pm_runtime_get_sync(&power->pdev->dev);
- rc = dp_power_regulator_enable(power);
- if (rc) {
- DRM_ERROR("failed to enable regulators, %d\n", rc);
- goto exit;
- }
rc = dp_power_clk_enable(dp_power, DP_CORE_PM, true);
if (rc) {
DRM_ERROR("failed to enable DP core clocks, %d\n", rc);
- goto err_clk;
+ goto exit;
}
return 0;
-err_clk:
- dp_power_regulator_disable(power);
exit:
pm_runtime_put_sync(&power->pdev->dev);
return rc;
@@ -393,7 +229,6 @@ int dp_power_deinit(struct dp_power *dp_power)
power = container_of(dp_power, struct dp_power_private, dp_power);
dp_power_clk_enable(dp_power, DP_CORE_PM, false);
- dp_power_regulator_disable(power);
pm_runtime_put_sync(&power->pdev->dev);
return 0;
}