Commit 14975cff authored by Chandan Uddaraju's avatar Chandan Uddaraju Committed by Rob Clark
Browse files

drm/msm/dp: add support for DP PLL driver



Add the needed DP PLL specific files to support
display port interface on msm targets.

The DP driver calls the DP PLL driver registration.
The DP driver sets the link and pixel clock sources.

Changes in v2:
-- Update copyright markings on all relevant files.
-- Use DRM_DEBUG_DP for debug msgs.

Changes in v4:
-- Update the DP link clock provider names

Changes in V5:
-- Addressed comments from Stephen Boyd, Rob clark.

Changes in V6:
-- Remove PLL as separate driver and include PLL as DP module
-- Remove redundant clock parsing from PLL module and make DP as
   clock provider
-- Map USB3 DPCOM and PHY IO using hardcoded register address and
   move mapping form parser to PLL module
-- Access DP PHY modules from same base address using offsets instead of
   deriving base address of individual module from device tree.
-- Remove dp_pll_10nm_util.c and include its functionality in
   dp_pll_10nm.c
-- Introduce new data structures private to PLL module

Changes in v7:

-- Remove DRM_MSM_DP_PLL config from Makefile and Kconfig
-- Remove set_parent from determin_rate API
-- Remove phy_pll_vco_div_clk from parent list
-- Remove flag CLK_DIVIDER_ONE_BASED
-- Remove redundant cell-index property parsing

Changes in v8:

-- Unregister hardware clocks during driver cleanup

Changes in v9:

-- Remove redundant Kconfig option DRM_MSM_DP_10NM_PLL

Changes in v10:

-- Limit 10nm PLL function scope

Signed-off-by: default avatarChandan Uddaraju <chandanu@codeaurora.org>
Signed-off-by: default avatarVara Reddy <varar@codeaurora.org>
Signed-off-by: default avatarTanmay Shah <tanmay@codeaurora.org>
Signed-off-by: default avatarRob Clark <robdclark@chromium.org>
parent c943b494
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -61,6 +61,7 @@ config DRM_MSM_HDMI_HDCP
config DRM_MSM_DP
	bool "Enable DisplayPort support in MSM DRM driver"
	depends on DRM_MSM
	default y
	help
	  Compile in support for DP driver in MSM DRM driver. DP external
	  display support is enabled through this config option. It can
+3 −1
Original line number Diff line number Diff line
@@ -109,7 +109,9 @@ msm-$(CONFIG_DRM_MSM_DP)+= dp/dp_aux.o \
	dp/dp_link.o \
	dp/dp_panel.o \
	dp/dp_parser.o \
	dp/dp_power.o
	dp/dp_power.o \
	dp/dp_pll.o \
	dp/dp_pll_10nm.o

msm-$(CONFIG_DRM_FBDEV_EMULATION) += msm_fbdev.o
msm-$(CONFIG_COMMON_CLK) += disp/mdp4/mdp4_lvds_pll.o
+21 −10
Original line number Diff line number Diff line
@@ -5,6 +5,7 @@

#define pr_fmt(fmt)	"[drm-dp] %s: " fmt, __func__

#include <linux/rational.h>
#include <linux/delay.h>
#include <linux/iopoll.h>
#include <linux/rational.h>
@@ -131,51 +132,58 @@ static inline void dp_write_ahb(struct dp_catalog_private *catalog,
static inline void dp_write_phy(struct dp_catalog_private *catalog,
			       u32 offset, u32 data)
{
	offset += DP_PHY_REG_OFFSET;
	/*
	 * To make sure phy reg writes happens before any other operation,
	 * this function uses writel() instread of writel_relaxed()
	 */
	writel(data, catalog->io->phy_io.base + offset);
	writel(data, catalog->io->phy_reg.base + offset);
}

static inline u32 dp_read_phy(struct dp_catalog_private *catalog,
			       u32 offset)
{
	offset += DP_PHY_REG_OFFSET;
	/*
	 * To make sure phy reg writes happens before any other operation,
	 * this function uses writel() instread of writel_relaxed()
	 */
	return readl_relaxed(catalog->io->phy_io.base + offset);
	return readl_relaxed(catalog->io->phy_reg.base + offset);
}

static inline void dp_write_pll(struct dp_catalog_private *catalog,
			       u32 offset, u32 data)
{
	writel_relaxed(data, catalog->io->dp_pll_io.base + offset);
	offset += DP_PHY_PLL_OFFSET;
	writel_relaxed(data, catalog->io->phy_reg.base + offset);
}

static inline void dp_write_ln_tx0(struct dp_catalog_private *catalog,
			       u32 offset, u32 data)
{
	writel_relaxed(data, catalog->io->ln_tx0_io.base + offset);
	offset += DP_PHY_LN_TX0_OFFSET;
	writel_relaxed(data, catalog->io->phy_reg.base + offset);
}

static inline void dp_write_ln_tx1(struct dp_catalog_private *catalog,
			       u32 offset, u32 data)
{
	writel_relaxed(data, catalog->io->ln_tx1_io.base + offset);
	offset += DP_PHY_LN_TX1_OFFSET;
	writel_relaxed(data, catalog->io->phy_reg.base + offset);
}

static inline u32 dp_read_ln_tx0(struct dp_catalog_private *catalog,
			       u32 offset)
{
	return readl_relaxed(catalog->io->ln_tx0_io.base + offset);
	offset += DP_PHY_LN_TX0_OFFSET;
	return readl_relaxed(catalog->io->phy_reg.base + offset);
}

static inline u32 dp_read_ln_tx1(struct dp_catalog_private *catalog,
			       u32 offset)
{
	return readl_relaxed(catalog->io->ln_tx1_io.base + offset);
	offset += DP_PHY_LN_TX1_OFFSET;
	return readl_relaxed(catalog->io->phy_reg.base + offset);
}

static inline void dp_write_usb_cm(struct dp_catalog_private *catalog,
@@ -398,13 +406,16 @@ void dp_catalog_dump_regs(struct dp_catalog *dp_catalog)
	dump_regs(catalog->io->usb3_dp_com.base, catalog->io->usb3_dp_com.len);

	pr_info("LN TX0 regs\n");
	dump_regs(catalog->io->ln_tx0_io.base, catalog->io->ln_tx0_io.len);
	dump_regs(catalog->io->phy_reg.base + DP_PHY_LN_TX0_OFFSET,
						DP_PHY_LN_TX0_SIZE);

	pr_info("LN TX1 regs\n");
	dump_regs(catalog->io->ln_tx1_io.base, catalog->io->ln_tx1_io.len);
	dump_regs(catalog->io->phy_reg.base + DP_PHY_LN_TX1_OFFSET,
						DP_PHY_LN_TX1_SIZE);

	pr_info("DP PHY regs\n");
	dump_regs(catalog->io->phy_io.base, catalog->io->phy_io.len);
	dump_regs(catalog->io->phy_reg.base + DP_PHY_REG_OFFSET,
						DP_PHY_REG_SIZE);
}

void dp_catalog_aux_setup(struct dp_catalog *dp_catalog)
+17 −1
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@
#include "dp_ctrl.h"
#include "dp_display.h"
#include "dp_drm.h"
#include "dp_pll.h"

static struct msm_dp *g_dp_display;
#define HPD_STRING_SIZE 30
@@ -42,6 +43,7 @@ struct dp_display_private {

	struct dp_usbpd   *usbpd;
	struct dp_parser  *parser;
	struct msm_dp_pll *pll;
	struct dp_power   *power;
	struct dp_catalog *catalog;
	struct drm_dp_aux *aux;
@@ -232,7 +234,6 @@ static int dp_display_process_hpd_high(struct dp_display_private *dp)
	edid = dp->panel->edid;

	dp->audio_supported = drm_detect_monitor_audio(edid);

	dp_panel_handle_sink_request(dp->panel);

	dp->dp_display.max_pclk_khz = DP_MAX_PIXEL_CLK_KHZ;
@@ -410,6 +411,7 @@ static void dp_display_deinit_sub_modules(struct dp_display_private *dp)
	dp_ctrl_put(dp->ctrl);
	dp_panel_put(dp->panel);
	dp_aux_put(dp->aux);
	dp_pll_put(dp->pll);
}

static int dp_init_sub_modules(struct dp_display_private *dp)
@@ -420,6 +422,9 @@ static int dp_init_sub_modules(struct dp_display_private *dp)
	struct dp_panel_in panel_in = {
		.dev = dev,
	};
	struct dp_pll_in pll_in = {
		.pdev = dp->pdev,
	};

	/* Callback APIs used for cable status change event */
	cb->configure  = dp_display_usbpd_configure_cb;
@@ -450,6 +455,17 @@ static int dp_init_sub_modules(struct dp_display_private *dp)
		goto error;
	}

	pll_in.parser = dp->parser;
	dp->pll = dp_pll_get(&pll_in);
	if (IS_ERR_OR_NULL(dp->pll)) {
		rc = -EINVAL;
		DRM_ERROR("failed to initialize pll, rc = %d\n", rc);
		dp->pll = NULL;
		goto error;
	}

	dp->parser->pll = dp->pll;

	dp->power = dp_power_get(dp->parser);
	if (IS_ERR(dp->power)) {
		rc = PTR_ERR(dp->power);
+3 −0
Original line number Diff line number Diff line
@@ -25,4 +25,7 @@ int dp_display_request_irq(struct msm_dp *dp_display);
bool dp_display_check_video_test(struct msm_dp *dp_display);
int dp_display_get_test_bpp(struct msm_dp *dp_display);

void __init msm_dp_pll_driver_register(void);
void __exit msm_dp_pll_driver_unregister(void);

#endif /* _DP_DISPLAY_H_ */
Loading