drm/msm/dsi: Add skeleton 10nm PHY/PLL code
Add new 10nm DSI PLL/PHY files that will be used on SDM845. Just populate empty pll/phy funcs for now. These will be filled up later. Signed-off-by: Archit Taneja <architt@codeaurora.org> Signed-off-by: Rob Clark <robdclark@gmail.com>
This commit is contained in:
parent
6d5796af71
commit
973e02db35
|
@ -94,3 +94,10 @@ config DRM_MSM_DSI_14NM_PHY
|
|||
default y
|
||||
help
|
||||
Choose this option if DSI PHY on 8996 is used on the platform.
|
||||
|
||||
config DRM_MSM_DSI_10NM_PHY
|
||||
bool "Enable DSI 10nm PHY driver in MSM DRM (used by SDM845)"
|
||||
depends on DRM_MSM_DSI
|
||||
default y
|
||||
help
|
||||
Choose this option if DSI PHY on SDM845 is used on the platform.
|
||||
|
|
|
@ -83,12 +83,14 @@ msm-$(CONFIG_DRM_MSM_DSI_28NM_PHY) += dsi/phy/dsi_phy_28nm.o
|
|||
msm-$(CONFIG_DRM_MSM_DSI_20NM_PHY) += dsi/phy/dsi_phy_20nm.o
|
||||
msm-$(CONFIG_DRM_MSM_DSI_28NM_8960_PHY) += dsi/phy/dsi_phy_28nm_8960.o
|
||||
msm-$(CONFIG_DRM_MSM_DSI_14NM_PHY) += dsi/phy/dsi_phy_14nm.o
|
||||
msm-$(CONFIG_DRM_MSM_DSI_10NM_PHY) += dsi/phy/dsi_phy_10nm.o
|
||||
|
||||
ifeq ($(CONFIG_DRM_MSM_DSI_PLL),y)
|
||||
msm-y += dsi/pll/dsi_pll.o
|
||||
msm-$(CONFIG_DRM_MSM_DSI_28NM_PHY) += dsi/pll/dsi_pll_28nm.o
|
||||
msm-$(CONFIG_DRM_MSM_DSI_28NM_8960_PHY) += dsi/pll/dsi_pll_28nm_8960.o
|
||||
msm-$(CONFIG_DRM_MSM_DSI_14NM_PHY) += dsi/pll/dsi_pll_14nm.o
|
||||
msm-$(CONFIG_DRM_MSM_DSI_10NM_PHY) += dsi/pll/dsi_pll_10nm.o
|
||||
endif
|
||||
|
||||
obj-$(CONFIG_DRM_MSM) += msm.o
|
||||
|
|
|
@ -36,6 +36,7 @@ enum msm_dsi_phy_type {
|
|||
MSM_DSI_PHY_20NM,
|
||||
MSM_DSI_PHY_28NM_8960,
|
||||
MSM_DSI_PHY_14NM,
|
||||
MSM_DSI_PHY_10NM,
|
||||
MSM_DSI_PHY_MAX
|
||||
};
|
||||
|
||||
|
|
|
@ -394,6 +394,10 @@ static const struct of_device_id dsi_phy_dt_match[] = {
|
|||
#ifdef CONFIG_DRM_MSM_DSI_14NM_PHY
|
||||
{ .compatible = "qcom,dsi-phy-14nm",
|
||||
.data = &dsi_phy_14nm_cfgs },
|
||||
#endif
|
||||
#ifdef CONFIG_DRM_MSM_DSI_10NM_PHY
|
||||
{ .compatible = "qcom,dsi-phy-10nm",
|
||||
.data = &dsi_phy_10nm_cfgs },
|
||||
#endif
|
||||
{}
|
||||
};
|
||||
|
|
|
@ -48,6 +48,7 @@ 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;
|
||||
extern const struct msm_dsi_phy_cfg dsi_phy_14nm_cfgs;
|
||||
extern const struct msm_dsi_phy_cfg dsi_phy_10nm_cfgs;
|
||||
|
||||
struct msm_dsi_dphy_timing {
|
||||
u32 clk_pre;
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* SPDX-License-Identifier: GPL-2.0
|
||||
* Copyright (c) 2018, The Linux Foundation
|
||||
*/
|
||||
|
||||
#include <linux/iopoll.h>
|
||||
|
||||
#include "dsi_phy.h"
|
||||
#include "dsi.xml.h"
|
||||
|
||||
static int dsi_10nm_phy_enable(struct msm_dsi_phy *phy, int src_pll_id,
|
||||
struct msm_dsi_phy_clk_request *clk_req)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void dsi_10nm_phy_disable(struct msm_dsi_phy *phy)
|
||||
{
|
||||
}
|
||||
|
||||
static int dsi_10nm_phy_init(struct msm_dsi_phy *phy)
|
||||
{
|
||||
struct platform_device *pdev = phy->pdev;
|
||||
|
||||
phy->lane_base = msm_ioremap(pdev, "dsi_phy_lane",
|
||||
"DSI_PHY_LANE");
|
||||
if (IS_ERR(phy->lane_base)) {
|
||||
dev_err(&pdev->dev, "%s: failed to map phy lane base\n",
|
||||
__func__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const struct msm_dsi_phy_cfg dsi_phy_10nm_cfgs = {
|
||||
.type = MSM_DSI_PHY_10NM,
|
||||
.src_pll_truthtable = { {false, false}, {true, false} },
|
||||
.reg_cfg = {
|
||||
.num = 1,
|
||||
.regs = {
|
||||
{"vdds", 36000, 32},
|
||||
},
|
||||
},
|
||||
.ops = {
|
||||
.enable = dsi_10nm_phy_enable,
|
||||
.disable = dsi_10nm_phy_disable,
|
||||
.init = dsi_10nm_phy_init,
|
||||
},
|
||||
.io_start = { 0xae94400, 0xae96400 },
|
||||
.num_dsi_phy = 2,
|
||||
};
|
|
@ -166,6 +166,9 @@ struct msm_dsi_pll *msm_dsi_pll_init(struct platform_device *pdev,
|
|||
case MSM_DSI_PHY_14NM:
|
||||
pll = msm_dsi_pll_14nm_init(pdev, id);
|
||||
break;
|
||||
case MSM_DSI_PHY_10NM:
|
||||
pll = msm_dsi_pll_10nm_init(pdev, id);
|
||||
break;
|
||||
default:
|
||||
pll = ERR_PTR(-ENXIO);
|
||||
break;
|
||||
|
|
|
@ -115,5 +115,14 @@ msm_dsi_pll_14nm_init(struct platform_device *pdev, int id)
|
|||
return ERR_PTR(-ENODEV);
|
||||
}
|
||||
#endif
|
||||
#ifdef CONFIG_DRM_MSM_DSI_10NM_PHY
|
||||
struct msm_dsi_pll *msm_dsi_pll_10nm_init(struct platform_device *pdev, int id);
|
||||
#else
|
||||
static inline struct msm_dsi_pll *
|
||||
msm_dsi_pll_10nm_init(struct platform_device *pdev, int id)
|
||||
{
|
||||
return ERR_PTR(-ENODEV);
|
||||
}
|
||||
#endif
|
||||
#endif /* __DSI_PLL_H__ */
|
||||
|
||||
|
|
|
@ -0,0 +1,176 @@
|
|||
/*
|
||||
* SPDX-License-Identifier: GPL-2.0
|
||||
* Copyright (c) 2018, The Linux Foundation
|
||||
*/
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/iopoll.h>
|
||||
|
||||
#include "dsi_pll.h"
|
||||
#include "dsi.xml.h"
|
||||
|
||||
struct dsi_pll_10nm {
|
||||
struct msm_dsi_pll base;
|
||||
|
||||
int id;
|
||||
struct platform_device *pdev;
|
||||
|
||||
void __iomem *phy_cmn_mmio;
|
||||
void __iomem *mmio;
|
||||
|
||||
int vco_delay;
|
||||
|
||||
enum msm_dsi_phy_usecase uc;
|
||||
struct dsi_pll_10nm *slave;
|
||||
};
|
||||
|
||||
#define to_pll_10nm(x) container_of(x, struct dsi_pll_10nm, base)
|
||||
|
||||
/*
|
||||
* Global list of private DSI PLL struct pointers. We need this for Dual DSI
|
||||
* mode, where the master PLL's clk_ops needs access the slave's private data
|
||||
*/
|
||||
static struct dsi_pll_10nm *pll_10nm_list[DSI_MAX];
|
||||
|
||||
static int dsi_pll_10nm_vco_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct msm_dsi_pll *pll = hw_clk_to_pll(hw);
|
||||
struct dsi_pll_10nm *pll_10nm = to_pll_10nm(pll);
|
||||
|
||||
DBG("DSI PLL%d rate=%lu, parent's=%lu", pll_10nm->id, rate,
|
||||
parent_rate);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned long dsi_pll_10nm_vco_recalc_rate(struct clk_hw *hw,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct msm_dsi_pll *pll = hw_clk_to_pll(hw);
|
||||
struct dsi_pll_10nm *pll_10nm = to_pll_10nm(pll);
|
||||
u64 vco_rate = 0x0;
|
||||
|
||||
DBG("DSI PLL%d returning vco rate = %lu", pll_10nm->id,
|
||||
(unsigned long)vco_rate);
|
||||
|
||||
return (unsigned long)vco_rate;
|
||||
}
|
||||
|
||||
static const struct clk_ops clk_ops_dsi_pll_10nm_vco = {
|
||||
.round_rate = msm_dsi_pll_helper_clk_round_rate,
|
||||
.set_rate = dsi_pll_10nm_vco_set_rate,
|
||||
.recalc_rate = dsi_pll_10nm_vco_recalc_rate,
|
||||
.prepare = msm_dsi_pll_helper_clk_prepare,
|
||||
.unprepare = msm_dsi_pll_helper_clk_unprepare,
|
||||
};
|
||||
|
||||
/*
|
||||
* PLL Callbacks
|
||||
*/
|
||||
|
||||
static void dsi_pll_10nm_save_state(struct msm_dsi_pll *pll)
|
||||
{
|
||||
struct dsi_pll_10nm *pll_10nm = to_pll_10nm(pll);
|
||||
|
||||
DBG("DSI PLL%d", pll_10nm->id);
|
||||
}
|
||||
|
||||
static int dsi_pll_10nm_restore_state(struct msm_dsi_pll *pll)
|
||||
{
|
||||
struct dsi_pll_10nm *pll_10nm = to_pll_10nm(pll);
|
||||
|
||||
DBG("DSI PLL%d", pll_10nm->id);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dsi_pll_10nm_set_usecase(struct msm_dsi_pll *pll,
|
||||
enum msm_dsi_phy_usecase uc)
|
||||
{
|
||||
struct dsi_pll_10nm *pll_10nm = to_pll_10nm(pll);
|
||||
|
||||
DBG("DSI PLL%d", pll_10nm->id);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dsi_pll_10nm_get_provider(struct msm_dsi_pll *pll,
|
||||
struct clk **byte_clk_provider,
|
||||
struct clk **pixel_clk_provider)
|
||||
{
|
||||
struct dsi_pll_10nm *pll_10nm = to_pll_10nm(pll);
|
||||
|
||||
DBG("DSI PLL%d", pll_10nm->id);
|
||||
|
||||
if (byte_clk_provider)
|
||||
*byte_clk_provider = NULL;
|
||||
if (pixel_clk_provider)
|
||||
*pixel_clk_provider = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void dsi_pll_10nm_destroy(struct msm_dsi_pll *pll)
|
||||
{
|
||||
struct dsi_pll_10nm *pll_10nm = to_pll_10nm(pll);
|
||||
|
||||
DBG("DSI PLL%d", pll_10nm->id);
|
||||
}
|
||||
|
||||
static int pll_10nm_register(struct dsi_pll_10nm *pll_10nm)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct msm_dsi_pll *msm_dsi_pll_10nm_init(struct platform_device *pdev, int id)
|
||||
{
|
||||
struct dsi_pll_10nm *pll_10nm;
|
||||
struct msm_dsi_pll *pll;
|
||||
int ret;
|
||||
|
||||
if (!pdev)
|
||||
return ERR_PTR(-ENODEV);
|
||||
|
||||
pll_10nm = devm_kzalloc(&pdev->dev, sizeof(*pll_10nm), GFP_KERNEL);
|
||||
if (!pll_10nm)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
DBG("DSI PLL%d", id);
|
||||
|
||||
pll_10nm->pdev = pdev;
|
||||
pll_10nm->id = id;
|
||||
pll_10nm_list[id] = pll_10nm;
|
||||
|
||||
pll_10nm->phy_cmn_mmio = msm_ioremap(pdev, "dsi_phy", "DSI_PHY");
|
||||
if (IS_ERR_OR_NULL(pll_10nm->phy_cmn_mmio)) {
|
||||
dev_err(&pdev->dev, "failed to map CMN PHY base\n");
|
||||
return ERR_PTR(-ENOMEM);
|
||||
}
|
||||
|
||||
pll_10nm->mmio = msm_ioremap(pdev, "dsi_pll", "DSI_PLL");
|
||||
if (IS_ERR_OR_NULL(pll_10nm->mmio)) {
|
||||
dev_err(&pdev->dev, "failed to map PLL base\n");
|
||||
return ERR_PTR(-ENOMEM);
|
||||
}
|
||||
|
||||
pll = &pll_10nm->base;
|
||||
pll->min_rate = 1000000000UL;
|
||||
pll->max_rate = 3500000000UL;
|
||||
pll->get_provider = dsi_pll_10nm_get_provider;
|
||||
pll->destroy = dsi_pll_10nm_destroy;
|
||||
pll->save_state = dsi_pll_10nm_save_state;
|
||||
pll->restore_state = dsi_pll_10nm_restore_state;
|
||||
pll->set_usecase = dsi_pll_10nm_set_usecase;
|
||||
|
||||
pll_10nm->vco_delay = 1;
|
||||
|
||||
ret = pll_10nm_register(pll_10nm);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "failed to register PLL: %d\n", ret);
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
|
||||
return pll;
|
||||
}
|
Loading…
Reference in New Issue