drm/msm/dsi: Add skeleton 10nm PHY/PLL code
authorArchit Taneja <architt@codeaurora.org>
Wed, 17 Jan 2018 06:05:25 +0000 (11:35 +0530)
committerRob Clark <robdclark@gmail.com>
Tue, 20 Feb 2018 15:41:20 +0000 (10:41 -0500)
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>
drivers/gpu/drm/msm/Kconfig
drivers/gpu/drm/msm/Makefile
drivers/gpu/drm/msm/dsi/dsi.h
drivers/gpu/drm/msm/dsi/phy/dsi_phy.c
drivers/gpu/drm/msm/dsi/phy/dsi_phy.h
drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c [new file with mode: 0644]
drivers/gpu/drm/msm/dsi/pll/dsi_pll.c
drivers/gpu/drm/msm/dsi/pll/dsi_pll.h
drivers/gpu/drm/msm/dsi/pll/dsi_pll_10nm.c [new file with mode: 0644]

index 3065cb290aa8e56b3383030a274aa89af79290ec..38cbde971b48cdc24f0f435602459d22dec58656 100644 (file)
@@ -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.
index ebe0c3d0b1263c6f7e37eb72420f95137706dc6e..f74d449476f40a4dedfdd41a4fb9dcc9072dd200 100644 (file)
@@ -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
index 2302046197a8afdebdca9eea6b751f25c68d7bcd..70d9a9a47acd53bbed826f05ee30a49d50a92fc6 100644 (file)
@@ -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
 };
 
index c8bfaa78065114e857508417b5f8e55a2cabde90..8e9d5c255820272ebe0a759ed51e4aa0ee6047b9 100644 (file)
@@ -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
        {}
 };
index 1733f6608a0913005dc322c2e5e333988887ea85..c56268cbdb3d81925410be764515d0f6be8a9864 100644 (file)
@@ -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;
diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c
new file mode 100644 (file)
index 0000000..b7545fb
--- /dev/null
@@ -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,
+};
index 491f08dce96901d1a28555f72edaf30b717d1ee8..613e206fa4fc2ce8295fa8df3aa029e8811e9423 100644 (file)
@@ -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;
index f63e7ada74a8a602abc620b1ea4770e98ce6785d..8b32271cbc2481e727be631cc6a605241d73f0a7 100644 (file)
@@ -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__ */
 
diff --git a/drivers/gpu/drm/msm/dsi/pll/dsi_pll_10nm.c b/drivers/gpu/drm/msm/dsi/pll/dsi_pll_10nm.c
new file mode 100644 (file)
index 0000000..34c2444
--- /dev/null
@@ -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;
+}