Commit 5d134596 authored by Dmitry Baryshkov's avatar Dmitry Baryshkov Committed by Rob Clark
Browse files

drm/msm/dsi: push provided clocks handling into a generic code



All MSM DSI PHYs provide two clocks: byte and pixel ones.
Register/unregister provided clocks from the generic place, removing
boilerplate code from all MSM DSI PHY drivers.

Signed-off-by: default avatarDmitry Baryshkov <dmitry.baryshkov@linaro.org>
Reviewed-by: default avatarAbhinav Kumar <abhinavk@codeaurora.org>
Tested-by: Stephen Boyd <swboyd@chromium.org> # on sc7180 lazor
Link: https://lore.kernel.org/r/20210331105735.3690009-11-dmitry.baryshkov@linaro.org


Signed-off-by: default avatarRob Clark <robdclark@chromium.org>
parent 95b814e4
Loading
Loading
Loading
Loading
+3 −8
Original line number Diff line number Diff line
@@ -96,19 +96,12 @@ struct drm_encoder *msm_dsi_get_encoder(struct msm_dsi *msm_dsi);
struct msm_dsi_pll;
#ifdef CONFIG_DRM_MSM_DSI_PLL
void msm_dsi_pll_destroy(struct msm_dsi_pll *pll);
int msm_dsi_pll_get_clk_provider(struct msm_dsi_pll *pll,
	struct clk **byte_clk_provider, struct clk **pixel_clk_provider);
void msm_dsi_pll_save_state(struct msm_dsi_pll *pll);
int msm_dsi_pll_restore_state(struct msm_dsi_pll *pll);
#else
static inline void msm_dsi_pll_destroy(struct msm_dsi_pll *pll)
{
}
static inline int msm_dsi_pll_get_clk_provider(struct msm_dsi_pll *pll,
	struct clk **byte_clk_provider, struct clk **pixel_clk_provider)
{
	return -ENODEV;
}
static inline void msm_dsi_pll_save_state(struct msm_dsi_pll *pll)
{
}
@@ -144,7 +137,7 @@ struct drm_bridge *msm_dsi_host_get_bridge(struct mipi_dsi_host *host);
int msm_dsi_host_register(struct mipi_dsi_host *host, bool check_defer);
void msm_dsi_host_unregister(struct mipi_dsi_host *host);
int msm_dsi_host_set_src_pll(struct mipi_dsi_host *host,
			struct msm_dsi_pll *src_pll);
			struct msm_dsi_phy *src_phy);
void msm_dsi_host_reset_phy(struct mipi_dsi_host *host);
void msm_dsi_host_get_phy_clk_req(struct mipi_dsi_host *host,
	struct msm_dsi_phy_clk_request *clk_req,
@@ -196,6 +189,8 @@ void msm_dsi_phy_get_shared_timings(struct msm_dsi_phy *phy,
struct msm_dsi_pll *msm_dsi_phy_get_pll(struct msm_dsi_phy *phy);
void msm_dsi_phy_set_usecase(struct msm_dsi_phy *phy,
			     enum msm_dsi_phy_usecase uc);
int msm_dsi_phy_get_clk_provider(struct msm_dsi_phy *phy,
	struct clk **byte_clk_provider, struct clk **pixel_clk_provider);

#endif /* __DSI_CONNECTOR_H__ */
+2 −2
Original line number Diff line number Diff line
@@ -2224,13 +2224,13 @@ void msm_dsi_host_cmd_xfer_commit(struct mipi_dsi_host *host, u32 dma_base,
}

int msm_dsi_host_set_src_pll(struct mipi_dsi_host *host,
	struct msm_dsi_pll *src_pll)
	struct msm_dsi_phy *src_phy)
{
	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,
	ret = msm_dsi_phy_get_clk_provider(src_phy,
				&byte_clk_provider, &pixel_clk_provider);
	if (ret) {
		pr_info("%s: can't get provider from pll, don't set parent\n",
+3 −10
Original line number Diff line number Diff line
@@ -70,7 +70,6 @@ static int dsi_mgr_setup_components(int id)
	struct msm_dsi *other_dsi = dsi_mgr_get_other_dsi(id);
	struct msm_dsi *clk_master_dsi = dsi_mgr_get_dsi(DSI_CLOCK_MASTER);
	struct msm_dsi *clk_slave_dsi = dsi_mgr_get_dsi(DSI_CLOCK_SLAVE);
	struct msm_dsi_pll *src_pll;
	int ret;

	if (!IS_DUAL_DSI()) {
@@ -79,10 +78,7 @@ static int dsi_mgr_setup_components(int id)
			return ret;

		msm_dsi_phy_set_usecase(msm_dsi->phy, MSM_DSI_PHY_STANDALONE);
		src_pll = msm_dsi_phy_get_pll(msm_dsi->phy);
		if (IS_ERR(src_pll))
			return PTR_ERR(src_pll);
		ret = msm_dsi_host_set_src_pll(msm_dsi->host, src_pll);
		ret = msm_dsi_host_set_src_pll(msm_dsi->host, msm_dsi->phy);
	} else if (!other_dsi) {
		ret = 0;
	} else {
@@ -109,13 +105,10 @@ static int dsi_mgr_setup_components(int id)
					MSM_DSI_PHY_MASTER);
		msm_dsi_phy_set_usecase(clk_slave_dsi->phy,
					MSM_DSI_PHY_SLAVE);
		src_pll = msm_dsi_phy_get_pll(clk_master_dsi->phy);
		if (IS_ERR(src_pll))
			return PTR_ERR(src_pll);
		ret = msm_dsi_host_set_src_pll(msm_dsi->host, src_pll);
		ret = msm_dsi_host_set_src_pll(msm_dsi->host, clk_master_dsi->phy);
		if (ret)
			return ret;
		ret = msm_dsi_host_set_src_pll(other_dsi->host, src_pll);
		ret = msm_dsi_host_set_src_pll(other_dsi->host, clk_master_dsi->phy);
	}

	return ret;
+34 −0
Original line number Diff line number Diff line
@@ -3,6 +3,7 @@
 * Copyright (c) 2015, The Linux Foundation. All rights reserved.
 */

#include <linux/clk-provider.h>
#include <linux/platform_device.h>

#include "dsi_phy.h"
@@ -652,6 +653,14 @@ static int dsi_phy_driver_probe(struct platform_device *pdev)
	if (!match)
		return -ENODEV;

	phy->provided_clocks = devm_kzalloc(dev,
			struct_size(phy->provided_clocks, hws, NUM_PROVIDED_CLKS),
			GFP_KERNEL);
	if (!phy->provided_clocks)
		return -ENOMEM;

	phy->provided_clocks->num = NUM_PROVIDED_CLKS;

	phy->cfg = match->data;
	phy->pdev = pdev;

@@ -719,6 +728,13 @@ static int dsi_phy_driver_probe(struct platform_device *pdev)
		}
	}

	ret = of_clk_add_hw_provider(dev->of_node, of_clk_hw_onecell_get,
				     phy->provided_clocks);
	if (ret) {
		DRM_DEV_ERROR(dev, "%s: failed to register clk provider: %d\n", __func__, ret);
		goto fail;
	}

	dsi_phy_disable_resource(phy);

	platform_set_drvdata(pdev, phy);
@@ -726,6 +742,12 @@ static int dsi_phy_driver_probe(struct platform_device *pdev)
	return 0;

fail:
	if (phy->pll) {
		of_clk_del_provider(dev->of_node);
		msm_dsi_pll_destroy(phy->pll);
		phy->pll = NULL;
	}

	return ret;
}

@@ -734,6 +756,7 @@ static int dsi_phy_driver_remove(struct platform_device *pdev)
	struct msm_dsi_phy *phy = platform_get_drvdata(pdev);

	if (phy && phy->pll) {
		of_clk_del_provider(pdev->dev.of_node);
		msm_dsi_pll_destroy(phy->pll);
		phy->pll = NULL;
	}
@@ -851,3 +874,14 @@ void msm_dsi_phy_set_usecase(struct msm_dsi_phy *phy,
	if (phy)
		phy->usecase = uc;
}

int msm_dsi_phy_get_clk_provider(struct msm_dsi_phy *phy,
	struct clk **byte_clk_provider, struct clk **pixel_clk_provider)
{
	if (byte_clk_provider)
		*byte_clk_provider = phy->provided_clocks->hws[DSI_BYTE_PLL_CLK]->clk;
	if (pixel_clk_provider)
		*pixel_clk_provider = phy->provided_clocks->hws[DSI_PIXEL_PLL_CLK]->clk;

	return -EINVAL;
}
+6 −3
Original line number Diff line number Diff line
@@ -23,9 +23,6 @@ struct msm_dsi_phy_ops {
struct msm_dsi_pll_ops {
	int (*enable_seq)(struct msm_dsi_pll *pll);
	void (*disable_seq)(struct msm_dsi_pll *pll);
	int (*get_provider)(struct msm_dsi_pll *pll,
			struct clk **byte_clk_provider,
			struct clk **pixel_clk_provider);
	void (*destroy)(struct msm_dsi_pll *pll);
	void (*save_state)(struct msm_dsi_pll *pll);
	int (*restore_state)(struct msm_dsi_pll *pll);
@@ -87,6 +84,10 @@ struct msm_dsi_dphy_timing {
	u8 hs_halfbyte_en_ckln;
};

#define DSI_BYTE_PLL_CLK		0
#define DSI_PIXEL_PLL_CLK		1
#define NUM_PROVIDED_CLKS		2

struct msm_dsi_phy {
	struct platform_device *pdev;
	void __iomem *base;
@@ -104,6 +105,8 @@ struct msm_dsi_phy {
	bool regulator_ldo_mode;

	struct msm_dsi_pll *pll;

	struct clk_hw_onecell_data *provided_clocks;
};

/*
Loading