From: Wangyan Wang <[email protected]>
V6 adopt maintainer's suggestion.
Here is the change list between V5 & V6
1. change "unsigned char mux_flags;" to "u8 mux_flags;" to
match with the struct in " clk: mediatek: add MUX_GATE_FLAGS_2".
chunhui dai (8):
drm/mediatek: recalculate hdmi phy clock of MT2701 by querying
hardware
drm/mediatek: move the setting of fixed divider
drm/mediatek: using different flags of clk for HDMI phy
drm/mediatek: fix the rate and divder of hdmi phy for MT2701
clk: mediatek: add MUX_GATE_FLAGS_2
clk: mediatek: using CLK_MUX_ROUND_CLOSEST for the clock of dpi1_sel
drm/mediatek: using new factor for tvdpll in MT2701
drm/mediatek: fix the rate of parent for hdmi phy in MT2701
drivers/clk/mediatek/clk-mt2701.c | 4 +-
drivers/clk/mediatek/clk-mtk.c | 2 +-
drivers/clk/mediatek/clk-mtk.h | 20 ++++++---
drivers/gpu/drm/mediatek/mtk_dpi.c | 8 ++--
drivers/gpu/drm/mediatek/mtk_hdmi_phy.c | 34 ++++------------
drivers/gpu/drm/mediatek/mtk_hdmi_phy.h | 7 +---
drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c | 56 +++++++++++++++++++++++---
drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c | 23 +++++++++++
8 files changed, 102 insertions(+), 52 deletions(-)
--
2.14.1
From: chunhui dai <[email protected]>
Recalculate the rate of this clock, by querying hardware.
Signed-off-by: chunhui dai <[email protected]>
Signed-off-by: wangyan wang <[email protected]>
---
drivers/gpu/drm/mediatek/mtk_hdmi_phy.c | 7 ++----
drivers/gpu/drm/mediatek/mtk_hdmi_phy.h | 3 +--
drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c | 35 ++++++++++++++++++++++++++
drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c | 8 ++++++
4 files changed, 46 insertions(+), 7 deletions(-)
diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c
index 4ef9c57ffd44..13c5e65b9ead 100644
--- a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c
+++ b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c
@@ -29,12 +29,9 @@ long mtk_hdmi_pll_round_rate(struct clk_hw *hw, unsigned long rate,
return rate;
}
-unsigned long mtk_hdmi_pll_recalc_rate(struct clk_hw *hw,
- unsigned long parent_rate)
+u32 mtk_hdmi_phy_read(struct mtk_hdmi_phy *hdmi_phy, u32 offset)
{
- struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw);
-
- return hdmi_phy->pll_rate;
+ return readl(hdmi_phy->regs + offset);
}
void mtk_hdmi_phy_clear_bits(struct mtk_hdmi_phy *hdmi_phy, u32 offset,
diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h
index f39b1fc66612..fdad8b17a915 100644
--- a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h
+++ b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h
@@ -41,6 +41,7 @@ struct mtk_hdmi_phy {
unsigned int ibias_up;
};
+u32 mtk_hdmi_phy_read(struct mtk_hdmi_phy *hdmi_phy, u32 offset);
void mtk_hdmi_phy_clear_bits(struct mtk_hdmi_phy *hdmi_phy, u32 offset,
u32 bits);
void mtk_hdmi_phy_set_bits(struct mtk_hdmi_phy *hdmi_phy, u32 offset,
@@ -50,8 +51,6 @@ void mtk_hdmi_phy_mask(struct mtk_hdmi_phy *hdmi_phy, u32 offset,
struct mtk_hdmi_phy *to_mtk_hdmi_phy(struct clk_hw *hw);
long mtk_hdmi_pll_round_rate(struct clk_hw *hw, unsigned long rate,
unsigned long *parent_rate);
-unsigned long mtk_hdmi_pll_recalc_rate(struct clk_hw *hw,
- unsigned long parent_rate);
extern struct platform_driver mtk_hdmi_phy_driver;
extern struct mtk_hdmi_phy_conf mtk_hdmi_phy_8173_conf;
diff --git a/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c b/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c
index fcc42dc6ea7f..b25c9dfc432a 100644
--- a/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c
+++ b/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c
@@ -153,6 +153,41 @@ static int mtk_hdmi_pll_set_rate(struct clk_hw *hw, unsigned long rate,
RG_HDMITX_DRV_IBIAS_MASK);
return 0;
}
+static unsigned long mtk_hdmi_pll_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw);
+ unsigned long out_rate, val;
+
+ val = (mtk_hdmi_phy_read(hdmi_phy, HDMI_CON6)
+ & RG_HTPLL_PREDIV_MASK) >> RG_HTPLL_PREDIV;
+ switch (val) {
+ case 0x00:
+ out_rate = parent_rate;
+ break;
+ case 0x01:
+ out_rate = parent_rate / 2;
+ break;
+ default:
+ out_rate = parent_rate / 4;
+ break;
+ }
+
+ val = (mtk_hdmi_phy_read(hdmi_phy, HDMI_CON6)
+ & RG_HTPLL_FBKDIV_MASK) >> RG_HTPLL_FBKDIV;
+ out_rate *= (val + 1) * 2;
+ val = (mtk_hdmi_phy_read(hdmi_phy, HDMI_CON2)
+ & RG_HDMITX_TX_POSDIV_MASK);
+
+ out_rate >>= (val >> RG_HDMITX_TX_POSDIV);
+
+ if (mtk_hdmi_phy_read(hdmi_phy, HDMI_CON2) & RG_HDMITX_EN_TX_POSDIV)
+ out_rate = out_rate / 5;
+
+ hdmi_phy->pll_rate = out_rate;
+
+ return hdmi_phy->pll_rate;
+}
static const struct clk_ops mtk_hdmi_phy_pll_ops = {
.prepare = mtk_hdmi_pll_prepare,
diff --git a/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c b/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c
index ed5916b27658..cb23c1e4692a 100644
--- a/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c
+++ b/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c
@@ -285,6 +285,14 @@ static int mtk_hdmi_pll_set_rate(struct clk_hw *hw, unsigned long rate,
return 0;
}
+static unsigned long mtk_hdmi_pll_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw);
+
+ return hdmi_phy->pll_rate;
+}
+
static const struct clk_ops mtk_hdmi_phy_pll_ops = {
.prepare = mtk_hdmi_pll_prepare,
.unprepare = mtk_hdmi_pll_unprepare,
--
2.14.1
From: chunhui dai <[email protected]>
The parent rate of hdmi phy had set by DPI driver.
We should not set or change the parent rate of MT2701 hdmi phy,
as a result we should remove the flags of "CLK_SET_RATE_PARENT"
from the clock of MT2701 hdmi phy.
Signed-off-by: chunhui dai <[email protected]>
Signed-off-by: wangyan wang <[email protected]>
---
drivers/gpu/drm/mediatek/mtk_hdmi_phy.c | 13 +++++--------
drivers/gpu/drm/mediatek/mtk_hdmi_phy.h | 1 +
drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c | 1 +
drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c | 1 +
4 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c
index 13c5e65b9ead..370309d684ec 100644
--- a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c
+++ b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c
@@ -107,13 +107,11 @@ mtk_hdmi_phy_dev_get_ops(const struct mtk_hdmi_phy *hdmi_phy)
return NULL;
}
-static void mtk_hdmi_phy_clk_get_ops(struct mtk_hdmi_phy *hdmi_phy,
- const struct clk_ops **ops)
+static void mtk_hdmi_phy_clk_get_data(struct mtk_hdmi_phy *hdmi_phy,
+ struct clk_init_data *clk_init)
{
- if (hdmi_phy && hdmi_phy->conf && hdmi_phy->conf->hdmi_phy_clk_ops)
- *ops = hdmi_phy->conf->hdmi_phy_clk_ops;
- else
- dev_err(hdmi_phy->dev, "Failed to get clk ops of phy\n");
+ clk_init->flags = hdmi_phy->conf->flags;
+ clk_init->ops = hdmi_phy->conf->hdmi_phy_clk_ops;
}
static int mtk_hdmi_phy_probe(struct platform_device *pdev)
@@ -126,7 +124,6 @@ static int mtk_hdmi_phy_probe(struct platform_device *pdev)
struct clk_init_data clk_init = {
.num_parents = 1,
.parent_names = (const char * const *)&ref_clk_name,
- .flags = CLK_SET_RATE_PARENT | CLK_SET_RATE_GATE,
};
struct phy *phy;
@@ -164,7 +161,7 @@ static int mtk_hdmi_phy_probe(struct platform_device *pdev)
hdmi_phy->dev = dev;
hdmi_phy->conf =
(struct mtk_hdmi_phy_conf *)of_device_get_match_data(dev);
- mtk_hdmi_phy_clk_get_ops(hdmi_phy, &clk_init.ops);
+ mtk_hdmi_phy_clk_get_data(hdmi_phy, &clk_init);
hdmi_phy->pll_hw.init = &clk_init;
hdmi_phy->pll = devm_clk_register(dev, &hdmi_phy->pll_hw);
if (IS_ERR(hdmi_phy->pll)) {
diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h
index fdad8b17a915..446e2acd1926 100644
--- a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h
+++ b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h
@@ -21,6 +21,7 @@ struct mtk_hdmi_phy;
struct mtk_hdmi_phy_conf {
bool tz_disabled;
+ unsigned long flags;
const struct clk_ops *hdmi_phy_clk_ops;
void (*hdmi_phy_enable_tmds)(struct mtk_hdmi_phy *hdmi_phy);
void (*hdmi_phy_disable_tmds)(struct mtk_hdmi_phy *hdmi_phy);
diff --git a/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c b/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c
index b26fb7dbdb28..43bc058d5528 100644
--- a/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c
+++ b/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c
@@ -234,6 +234,7 @@ static void mtk_hdmi_phy_disable_tmds(struct mtk_hdmi_phy *hdmi_phy)
struct mtk_hdmi_phy_conf mtk_hdmi_phy_2701_conf = {
.tz_disabled = true,
+ .flags = CLK_SET_RATE_NO_REPARENT | CLK_SET_RATE_GATE,
.hdmi_phy_clk_ops = &mtk_hdmi_phy_pll_ops,
.hdmi_phy_enable_tmds = mtk_hdmi_phy_enable_tmds,
.hdmi_phy_disable_tmds = mtk_hdmi_phy_disable_tmds,
diff --git a/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c b/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c
index cb23c1e4692a..63dde42521b8 100644
--- a/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c
+++ b/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c
@@ -317,6 +317,7 @@ static void mtk_hdmi_phy_disable_tmds(struct mtk_hdmi_phy *hdmi_phy)
}
struct mtk_hdmi_phy_conf mtk_hdmi_phy_8173_conf = {
+ .flags = CLK_SET_RATE_PARENT | CLK_SET_RATE_GATE,
.hdmi_phy_clk_ops = &mtk_hdmi_phy_pll_ops,
.hdmi_phy_enable_tmds = mtk_hdmi_phy_enable_tmds,
.hdmi_phy_disable_tmds = mtk_hdmi_phy_disable_tmds,
--
2.14.1
From: chunhui dai <[email protected]>
Due to a clerical error,there is one zero less for 12800000.
Fix it for 128000000.
Fixes: 0fc721b2968e ("drm/mediatek: add hdmi driver for MT2701 and MT7623")
Reviewed-by: CK Hu <[email protected]>
Signed-off-by: chunhui dai <[email protected]>
Signed-off-by: wangyan wang <[email protected]>
---
drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c b/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c
index 43bc058d5528..88dd9e812ca0 100644
--- a/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c
+++ b/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c
@@ -114,8 +114,8 @@ static int mtk_hdmi_pll_set_rate(struct clk_hw *hw, unsigned long rate,
if (rate <= 64000000)
pos_div = 3;
- else if (rate <= 12800000)
- pos_div = 1;
+ else if (rate <= 128000000)
+ pos_div = 2;
else
pos_div = 1;
--
2.14.1
From: chunhui dai <[email protected]>
move the setting of fixed divider from enable/disable
to the function of setting rate.
the patch is for hdmi pll divider, the divder should
be configured before clock calculation to ensure the
clock is right.
Signed-off-by: chunhui dai <[email protected]>
Signed-off-by: wangyan wang <[email protected]>
---
drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c b/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c
index b25c9dfc432a..b26fb7dbdb28 100644
--- a/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c
+++ b/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c
@@ -79,7 +79,6 @@ static int mtk_hdmi_pll_prepare(struct clk_hw *hw)
mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_SLDO_MASK);
usleep_range(80, 100);
mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_MBIAS_LPF_EN);
- mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_EN_TX_POSDIV);
mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_SER_MASK);
mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_PRED_MASK);
mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_DRV_MASK);
@@ -94,7 +93,6 @@ static void mtk_hdmi_pll_unprepare(struct clk_hw *hw)
mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_DRV_MASK);
mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_PRED_MASK);
mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_SER_MASK);
- mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_EN_TX_POSDIV);
mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_MBIAS_LPF_EN);
usleep_range(80, 100);
mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_SLDO_MASK);
@@ -123,6 +121,7 @@ static int mtk_hdmi_pll_set_rate(struct clk_hw *hw, unsigned long rate,
mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_PREDIV_MASK);
mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_POSDIV_MASK);
+ mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_EN_TX_POSDIV);
mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON6, (0x1 << RG_HTPLL_IC),
RG_HTPLL_IC_MASK);
mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON6, (0x1 << RG_HTPLL_IR),
@@ -209,7 +208,6 @@ static void mtk_hdmi_phy_enable_tmds(struct mtk_hdmi_phy *hdmi_phy)
mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_SLDO_MASK);
usleep_range(80, 100);
mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_MBIAS_LPF_EN);
- mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_EN_TX_POSDIV);
mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_SER_MASK);
mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_PRED_MASK);
mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_DRV_MASK);
@@ -221,7 +219,6 @@ static void mtk_hdmi_phy_disable_tmds(struct mtk_hdmi_phy *hdmi_phy)
mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_DRV_MASK);
mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_PRED_MASK);
mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_SER_MASK);
- mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_EN_TX_POSDIV);
mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_MBIAS_LPF_EN);
usleep_range(80, 100);
mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_SLDO_MASK);
--
2.14.1
From: chunhui dai <[email protected]>
We should not change the rate of parent for hdmi phy when
doing round_rate for this clock. The parent clock of hdmi
phy must be the same as it. We change it when doing set_rate
only.
Signed-off-by: chunhui dai <[email protected]>
Signed-off-by: wangyan wang <[email protected]>
---
drivers/gpu/drm/mediatek/mtk_hdmi_phy.c | 14 --------------
drivers/gpu/drm/mediatek/mtk_hdmi_phy.h | 3 ---
drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c | 11 +++++++++++
drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c | 14 ++++++++++++++
4 files changed, 25 insertions(+), 17 deletions(-)
diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c
index 370309d684ec..ca8bc1489f37 100644
--- a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c
+++ b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c
@@ -15,20 +15,6 @@ static const struct phy_ops mtk_hdmi_phy_dev_ops = {
.owner = THIS_MODULE,
};
-long mtk_hdmi_pll_round_rate(struct clk_hw *hw, unsigned long rate,
- unsigned long *parent_rate)
-{
- struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw);
-
- hdmi_phy->pll_rate = rate;
- if (rate <= 74250000)
- *parent_rate = rate;
- else
- *parent_rate = rate / 2;
-
- return rate;
-}
-
u32 mtk_hdmi_phy_read(struct mtk_hdmi_phy *hdmi_phy, u32 offset)
{
return readl(hdmi_phy->regs + offset);
diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h
index 446e2acd1926..c6061ad15ff0 100644
--- a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h
+++ b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h
@@ -50,9 +50,6 @@ void mtk_hdmi_phy_set_bits(struct mtk_hdmi_phy *hdmi_phy, u32 offset,
void mtk_hdmi_phy_mask(struct mtk_hdmi_phy *hdmi_phy, u32 offset,
u32 val, u32 mask);
struct mtk_hdmi_phy *to_mtk_hdmi_phy(struct clk_hw *hw);
-long mtk_hdmi_pll_round_rate(struct clk_hw *hw, unsigned long rate,
- unsigned long *parent_rate);
-
extern struct platform_driver mtk_hdmi_phy_driver;
extern struct mtk_hdmi_phy_conf mtk_hdmi_phy_8173_conf;
extern struct mtk_hdmi_phy_conf mtk_hdmi_phy_2701_conf;
diff --git a/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c b/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c
index 88dd9e812ca0..33893a180c2e 100644
--- a/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c
+++ b/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c
@@ -152,6 +152,17 @@ static int mtk_hdmi_pll_set_rate(struct clk_hw *hw, unsigned long rate,
RG_HDMITX_DRV_IBIAS_MASK);
return 0;
}
+
+static long mtk_hdmi_pll_round_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long *parent_rate)
+{
+ struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw);
+
+ hdmi_phy->pll_rate = rate;
+
+ return rate;
+}
+
static unsigned long mtk_hdmi_pll_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
diff --git a/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c b/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c
index 63dde42521b8..3a339f516613 100644
--- a/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c
+++ b/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c
@@ -285,6 +285,20 @@ static int mtk_hdmi_pll_set_rate(struct clk_hw *hw, unsigned long rate,
return 0;
}
+static long mtk_hdmi_pll_round_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long *parent_rate)
+{
+ struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw);
+
+ hdmi_phy->pll_rate = rate;
+ if (rate <= 74250000)
+ *parent_rate = rate;
+ else
+ *parent_rate = rate / 2;
+
+ return rate;
+}
+
static unsigned long mtk_hdmi_pll_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
--
2.14.1
From: chunhui dai <[email protected]>
The MUX clock of dpi1_sel should select the closet clock for itself.
We could add this flag to enable this function of MUX in CCF.
Signed-off-by: chunhui dai <[email protected]>
Signed-off-by: wangyan wang <[email protected]>
---
drivers/clk/mediatek/clk-mt2701.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/clk/mediatek/clk-mt2701.c b/drivers/clk/mediatek/clk-mt2701.c
index ab6ab07f53e6..905a2316f6a7 100644
--- a/drivers/clk/mediatek/clk-mt2701.c
+++ b/drivers/clk/mediatek/clk-mt2701.c
@@ -535,8 +535,8 @@ static const struct mtk_composite top_muxes[] = {
0x0080, 8, 2, 15),
MUX_GATE(CLK_TOP_DPI0_SEL, "dpi0_sel", dpi0_parents,
0x0080, 16, 3, 23),
- MUX_GATE(CLK_TOP_DPI1_SEL, "dpi1_sel", dpi1_parents,
- 0x0080, 24, 2, 31),
+ MUX_GATE_FLAGS_2(CLK_TOP_DPI1_SEL, "dpi1_sel", dpi1_parents,
+ 0x0080, 24, 2, 31, 0, CLK_MUX_ROUND_CLOSEST),
MUX_GATE(CLK_TOP_TVE_SEL, "tve_sel", tve_parents,
0x0090, 0, 3, 7),
--
2.14.1
From: chunhui dai <[email protected]>
The factor depends on the divider of DPI in MT2701, therefore,
we should fix this factor to the right and new one.
Signed-off-by: chunhui dai <[email protected]>
Signed-off-by: wangyan wang <[email protected]>
---
drivers/gpu/drm/mediatek/mtk_dpi.c | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c
index 69c6e42dad6b..4a2f4a650494 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
@@ -662,13 +662,11 @@ static unsigned int mt8173_calculate_factor(int clock)
static unsigned int mt2701_calculate_factor(int clock)
{
if (clock <= 64000)
- return 16;
- else if (clock <= 128000)
- return 8;
- else if (clock <= 256000)
return 4;
- else
+ else if (clock <= 128000)
return 2;
+ else
+ return 1;
}
static const struct mtk_dpi_conf mt8173_conf = {
--
2.14.1
From: chunhui dai <[email protected]>
Add MUX_GATE_FLAGS_2 for the clock which needs to set two falgs.
Such as some mux need to set the flags of "CLK_MUX_ROUND_CLOSEST".
Signed-off-by: chunhui dai <[email protected]>
Signed-off-by: wangyan wang <[email protected]>
---
drivers/clk/mediatek/clk-mtk.c | 2 +-
drivers/clk/mediatek/clk-mtk.h | 20 ++++++++++++++------
2 files changed, 15 insertions(+), 7 deletions(-)
diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c
index 9c0ae4278a94..2ed996404804 100644
--- a/drivers/clk/mediatek/clk-mtk.c
+++ b/drivers/clk/mediatek/clk-mtk.c
@@ -167,7 +167,7 @@ struct clk *mtk_clk_register_composite(const struct mtk_composite *mc,
mux->mask = BIT(mc->mux_width) - 1;
mux->shift = mc->mux_shift;
mux->lock = lock;
-
+ mux->flags = mc->mux_flags;
mux_hw = &mux->hw;
mux_ops = &clk_mux_ops;
diff --git a/drivers/clk/mediatek/clk-mtk.h b/drivers/clk/mediatek/clk-mtk.h
index f83c2bbb677e..4b88d196d52f 100644
--- a/drivers/clk/mediatek/clk-mtk.h
+++ b/drivers/clk/mediatek/clk-mtk.h
@@ -81,15 +81,13 @@ struct mtk_composite {
signed char divider_shift;
signed char divider_width;
+ u8 mux_flags;
+
signed char num_parents;
};
-/*
- * In case the rate change propagation to parent clocks is undesirable,
- * this macro allows to specify the clock flags manually.
- */
-#define MUX_GATE_FLAGS(_id, _name, _parents, _reg, _shift, _width, \
- _gate, _flags) { \
+#define MUX_GATE_FLAGS_2(_id, _name, _parents, _reg, _shift, \
+ _width, _gate, _flags, _muxflags) { \
.id = _id, \
.name = _name, \
.mux_reg = _reg, \
@@ -101,8 +99,18 @@ struct mtk_composite {
.parent_names = _parents, \
.num_parents = ARRAY_SIZE(_parents), \
.flags = _flags, \
+ .mux_flags = _muxflags, \
}
+/*
+ * In case the rate change propagation to parent clocks is undesirable,
+ * this macro allows to specify the clock flags manually.
+ */
+#define MUX_GATE_FLAGS(_id, _name, _parents, _reg, _shift, _width, \
+ _gate, _flags) \
+ MUX_GATE_FLAGS_2(_id, _name, _parents, _reg, \
+ _shift, _width, _gate, _flags, 0)
+
/*
* Unless necessary, all MUX_GATE clocks propagate rate changes to their
* parent clock by default.
--
2.14.1
Quoting wangyan wang (2019-02-24 18:09:09)
> From: chunhui dai <[email protected]>
>
> Add MUX_GATE_FLAGS_2 for the clock which needs to set two falgs.
> Such as some mux need to set the flags of "CLK_MUX_ROUND_CLOSEST".
>
> Signed-off-by: chunhui dai <[email protected]>
> Signed-off-by: wangyan wang <[email protected]>
> ---
Applied to clk-next
Quoting wangyan wang (2019-02-24 18:09:10)
> From: chunhui dai <[email protected]>
>
> The MUX clock of dpi1_sel should select the closet clock for itself.
> We could add this flag to enable this function of MUX in CCF.
>
> Signed-off-by: chunhui dai <[email protected]>
> Signed-off-by: wangyan wang <[email protected]>
> ---
Applied to clk-next
On Mon, 2019-02-25 at 10:09 +0800, wangyan wang wrote:
> From: Wangyan Wang <[email protected]>
>
> V6 adopt maintainer's suggestion.
> Here is the change list between V5 & V6
> 1. change "unsigned char mux_flags;" to "u8 mux_flags;" to
> match with the struct in " clk: mediatek: add MUX_GATE_FLAGS_2".
>
Hi, Wangyan:
I'm not familiar with this clock system, so I still have some question
about it, if you could describe more clear, it would help us to speed up
this review process.
In [1], I find the clock that dpi and hdmi_phy controls,
dpi0: dpi@14014000 {
clocks = <&mmsys CLK_MM_DPI1_DIGL>,
<&mmsys CLK_MM_DPI1_ENGINE>,
<&topckgen CLK_TOP_TVDPLL>;
clock-names = "pixel", "engine", "pll";
};
hdmi_phy: phy@10209100 {
clocks = <&apmixedsys CLK_APMIXED_HDMI_REF>;
clock-names = "pll_ref";
};
In [2], You say that to prevent changing tvdpll would let hdmi stable,
and this clock is controlled by dpi, why do you modify the control flow
in hdmi_phy? If these two have relationship, please describe more clear
because I'm not familiar with this clock system.
And I think that patch 'drm/mediatek: using new factor for tvdpll in
MT2701' is the major patch to prevent modifying tvdpll because it reduce
the factor case. Does MT8173 has the same problem? Just ask, I does not
require you to modify MT8173 part.
[1]
https://github.com/frank-w/BPI-R2-4.14/blob/663f7def421952eb49b2d698eadaff12d02622d2/arch/arm/boot/dts/mt7623.dtsi
[2]
http://lists.infradead.org/pipermail/linux-mediatek/2019-February/017693.html
Regards,
CK
>
> chunhui dai (8):
> drm/mediatek: recalculate hdmi phy clock of MT2701 by querying
> hardware
> drm/mediatek: move the setting of fixed divider
> drm/mediatek: using different flags of clk for HDMI phy
> drm/mediatek: fix the rate and divder of hdmi phy for MT2701
> clk: mediatek: add MUX_GATE_FLAGS_2
> clk: mediatek: using CLK_MUX_ROUND_CLOSEST for the clock of dpi1_sel
> drm/mediatek: using new factor for tvdpll in MT2701
> drm/mediatek: fix the rate of parent for hdmi phy in MT2701
>
> drivers/clk/mediatek/clk-mt2701.c | 4 +-
> drivers/clk/mediatek/clk-mtk.c | 2 +-
> drivers/clk/mediatek/clk-mtk.h | 20 ++++++---
> drivers/gpu/drm/mediatek/mtk_dpi.c | 8 ++--
> drivers/gpu/drm/mediatek/mtk_hdmi_phy.c | 34 ++++------------
> drivers/gpu/drm/mediatek/mtk_hdmi_phy.h | 7 +---
> drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c | 56 +++++++++++++++++++++++---
> drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c | 23 +++++++++++
> 8 files changed, 102 insertions(+), 52 deletions(-)
>
Hi, Wangyan:
On Wed, 2019-03-06 at 09:52 +0800, CK Hu wrote:
> On Mon, 2019-02-25 at 10:09 +0800, wangyan wang wrote:
> > From: Wangyan Wang <[email protected]>
> >
> > V6 adopt maintainer's suggestion.
> > Here is the change list between V5 & V6
> > 1. change "unsigned char mux_flags;" to "u8 mux_flags;" to
> > match with the struct in " clk: mediatek: add MUX_GATE_FLAGS_2".
> >
>
> Hi, Wangyan:
>
> I'm not familiar with this clock system, so I still have some question
> about it, if you could describe more clear, it would help us to speed up
> this review process.
>
> In [1], I find the clock that dpi and hdmi_phy controls,
>
> dpi0: dpi@14014000 {
> clocks = <&mmsys CLK_MM_DPI1_DIGL>,
> <&mmsys CLK_MM_DPI1_ENGINE>,
> <&topckgen CLK_TOP_TVDPLL>;
> clock-names = "pixel", "engine", "pll";
> };
>
>
> hdmi_phy: phy@10209100 {
> clocks = <&apmixedsys CLK_APMIXED_HDMI_REF>;
> clock-names = "pll_ref";
> };
>
> In [2], You say that to prevent changing tvdpll would let hdmi stable,
> and this clock is controlled by dpi, why do you modify the control flow
> in hdmi_phy? If these two have relationship, please describe more clear
> because I'm not familiar with this clock system.
>
As discuss offline, in [3] we can find out that CLK_APMIXED_HDMI_REF is
derived from tvdpll, so tvdpll is the parent clock of hdmi_phy_pll.
Therefore, this series should modify hdmi_phy flow as well.
[3]
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/clk/mediatek/clk-mt2701.c?h=v5.0#n973
Regards,
CK
> And I think that patch 'drm/mediatek: using new factor for tvdpll in
> MT2701' is the major patch to prevent modifying tvdpll because it reduce
> the factor case. Does MT8173 has the same problem? Just ask, I does not
> require you to modify MT8173 part.
> [1]
> https://github.com/frank-w/BPI-R2-4.14/blob/663f7def421952eb49b2d698eadaff12d02622d2/arch/arm/boot/dts/mt7623.dtsi
> [2]
> http://lists.infradead.org/pipermail/linux-mediatek/2019-February/017693.html
>
>
> Regards,
> CK
>
>
> >
> > chunhui dai (8):
> > drm/mediatek: recalculate hdmi phy clock of MT2701 by querying
> > hardware
> > drm/mediatek: move the setting of fixed divider
> > drm/mediatek: using different flags of clk for HDMI phy
> > drm/mediatek: fix the rate and divder of hdmi phy for MT2701
> > clk: mediatek: add MUX_GATE_FLAGS_2
> > clk: mediatek: using CLK_MUX_ROUND_CLOSEST for the clock of dpi1_sel
> > drm/mediatek: using new factor for tvdpll in MT2701
> > drm/mediatek: fix the rate of parent for hdmi phy in MT2701
> >
> > drivers/clk/mediatek/clk-mt2701.c | 4 +-
> > drivers/clk/mediatek/clk-mtk.c | 2 +-
> > drivers/clk/mediatek/clk-mtk.h | 20 ++++++---
> > drivers/gpu/drm/mediatek/mtk_dpi.c | 8 ++--
> > drivers/gpu/drm/mediatek/mtk_hdmi_phy.c | 34 ++++------------
> > drivers/gpu/drm/mediatek/mtk_hdmi_phy.h | 7 +---
> > drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c | 56 +++++++++++++++++++++++---
> > drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c | 23 +++++++++++
> > 8 files changed, 102 insertions(+), 52 deletions(-)
> >
>
Hi, Wangyan:
On Mon, 2019-02-25 at 10:09 +0800, wangyan wang wrote:
> From: chunhui dai <[email protected]>
>
> Recalculate the rate of this clock, by querying hardware.
>
> Signed-off-by: chunhui dai <[email protected]>
> Signed-off-by: wangyan wang <[email protected]>
> ---
> drivers/gpu/drm/mediatek/mtk_hdmi_phy.c | 7 ++----
> drivers/gpu/drm/mediatek/mtk_hdmi_phy.h | 3 +--
> drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c | 35 ++++++++++++++++++++++++++
> drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c | 8 ++++++
> 4 files changed, 46 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c
> index 4ef9c57ffd44..13c5e65b9ead 100644
> --- a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c
> +++ b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c
> @@ -29,12 +29,9 @@ long mtk_hdmi_pll_round_rate(struct clk_hw *hw, unsigned long rate,
> return rate;
> }
>
> -unsigned long mtk_hdmi_pll_recalc_rate(struct clk_hw *hw,
> - unsigned long parent_rate)
> +u32 mtk_hdmi_phy_read(struct mtk_hdmi_phy *hdmi_phy, u32 offset)
> {
> - struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw);
> -
> - return hdmi_phy->pll_rate;
> + return readl(hdmi_phy->regs + offset);
> }
>
> void mtk_hdmi_phy_clear_bits(struct mtk_hdmi_phy *hdmi_phy, u32 offset,
> diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h
> index f39b1fc66612..fdad8b17a915 100644
> --- a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h
> +++ b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h
> @@ -41,6 +41,7 @@ struct mtk_hdmi_phy {
> unsigned int ibias_up;
> };
>
> +u32 mtk_hdmi_phy_read(struct mtk_hdmi_phy *hdmi_phy, u32 offset);
> void mtk_hdmi_phy_clear_bits(struct mtk_hdmi_phy *hdmi_phy, u32 offset,
> u32 bits);
> void mtk_hdmi_phy_set_bits(struct mtk_hdmi_phy *hdmi_phy, u32 offset,
> @@ -50,8 +51,6 @@ void mtk_hdmi_phy_mask(struct mtk_hdmi_phy *hdmi_phy, u32 offset,
> struct mtk_hdmi_phy *to_mtk_hdmi_phy(struct clk_hw *hw);
> long mtk_hdmi_pll_round_rate(struct clk_hw *hw, unsigned long rate,
> unsigned long *parent_rate);
> -unsigned long mtk_hdmi_pll_recalc_rate(struct clk_hw *hw,
> - unsigned long parent_rate);
>
> extern struct platform_driver mtk_hdmi_phy_driver;
> extern struct mtk_hdmi_phy_conf mtk_hdmi_phy_8173_conf;
> diff --git a/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c b/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c
> index fcc42dc6ea7f..b25c9dfc432a 100644
> --- a/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c
> +++ b/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c
> @@ -153,6 +153,41 @@ static int mtk_hdmi_pll_set_rate(struct clk_hw *hw, unsigned long rate,
> RG_HDMITX_DRV_IBIAS_MASK);
> return 0;
> }
> +static unsigned long mtk_hdmi_pll_recalc_rate(struct clk_hw *hw,
> + unsigned long parent_rate)
> +{
> + struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw);
> + unsigned long out_rate, val;
> +
> + val = (mtk_hdmi_phy_read(hdmi_phy, HDMI_CON6)
> + & RG_HTPLL_PREDIV_MASK) >> RG_HTPLL_PREDIV;
> + switch (val) {
> + case 0x00:
> + out_rate = parent_rate;
> + break;
> + case 0x01:
> + out_rate = parent_rate / 2;
> + break;
> + default:
> + out_rate = parent_rate / 4;
> + break;
> + }
> +
> + val = (mtk_hdmi_phy_read(hdmi_phy, HDMI_CON6)
> + & RG_HTPLL_FBKDIV_MASK) >> RG_HTPLL_FBKDIV;
> + out_rate *= (val + 1) * 2;
> + val = (mtk_hdmi_phy_read(hdmi_phy, HDMI_CON2)
> + & RG_HDMITX_TX_POSDIV_MASK);
> +
> + out_rate >>= (val >> RG_HDMITX_TX_POSDIV);
> +
> + if (mtk_hdmi_phy_read(hdmi_phy, HDMI_CON2) & RG_HDMITX_EN_TX_POSDIV)
> + out_rate = out_rate / 5;
> +
All the register you read here is set in mtk_hdmi_pll_set_rate(), so I
think you could determine the out_rate in mtk_hdmi_pll_set_rate().
Regards,
CK
> + hdmi_phy->pll_rate = out_rate;
> +
> + return hdmi_phy->pll_rate;
> +}
>
> static const struct clk_ops mtk_hdmi_phy_pll_ops = {
> .prepare = mtk_hdmi_pll_prepare,
> diff --git a/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c b/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c
> index ed5916b27658..cb23c1e4692a 100644
> --- a/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c
> +++ b/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c
> @@ -285,6 +285,14 @@ static int mtk_hdmi_pll_set_rate(struct clk_hw *hw, unsigned long rate,
> return 0;
> }
>
> +static unsigned long mtk_hdmi_pll_recalc_rate(struct clk_hw *hw,
> + unsigned long parent_rate)
> +{
> + struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw);
> +
> + return hdmi_phy->pll_rate;
> +}
> +
> static const struct clk_ops mtk_hdmi_phy_pll_ops = {
> .prepare = mtk_hdmi_pll_prepare,
> .unprepare = mtk_hdmi_pll_unprepare,
Hi, Wangyan:
On Mon, 2019-02-25 at 10:09 +0800, wangyan wang wrote:
> From: chunhui dai <[email protected]>
>
> We should not change the rate of parent for hdmi phy when
> doing round_rate for this clock. The parent clock of hdmi
> phy must be the same as it. We change it when doing set_rate
> only.
>
> Signed-off-by: chunhui dai <[email protected]>
> Signed-off-by: wangyan wang <[email protected]>
> ---
> drivers/gpu/drm/mediatek/mtk_hdmi_phy.c | 14 --------------
> drivers/gpu/drm/mediatek/mtk_hdmi_phy.h | 3 ---
> drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c | 11 +++++++++++
> drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c | 14 ++++++++++++++
> 4 files changed, 25 insertions(+), 17 deletions(-)
>
> diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c
> index 370309d684ec..ca8bc1489f37 100644
> --- a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c
> +++ b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c
> @@ -15,20 +15,6 @@ static const struct phy_ops mtk_hdmi_phy_dev_ops = {
> .owner = THIS_MODULE,
> };
>
> -long mtk_hdmi_pll_round_rate(struct clk_hw *hw, unsigned long rate,
> - unsigned long *parent_rate)
> -{
> - struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw);
> -
> - hdmi_phy->pll_rate = rate;
> - if (rate <= 74250000)
> - *parent_rate = rate;
> - else
> - *parent_rate = rate / 2;
> -
> - return rate;
> -}
> -
> u32 mtk_hdmi_phy_read(struct mtk_hdmi_phy *hdmi_phy, u32 offset)
> {
> return readl(hdmi_phy->regs + offset);
> diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h
> index 446e2acd1926..c6061ad15ff0 100644
> --- a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h
> +++ b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h
> @@ -50,9 +50,6 @@ void mtk_hdmi_phy_set_bits(struct mtk_hdmi_phy *hdmi_phy, u32 offset,
> void mtk_hdmi_phy_mask(struct mtk_hdmi_phy *hdmi_phy, u32 offset,
> u32 val, u32 mask);
> struct mtk_hdmi_phy *to_mtk_hdmi_phy(struct clk_hw *hw);
> -long mtk_hdmi_pll_round_rate(struct clk_hw *hw, unsigned long rate,
> - unsigned long *parent_rate);
> -
> extern struct platform_driver mtk_hdmi_phy_driver;
> extern struct mtk_hdmi_phy_conf mtk_hdmi_phy_8173_conf;
> extern struct mtk_hdmi_phy_conf mtk_hdmi_phy_2701_conf;
> diff --git a/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c b/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c
> index 88dd9e812ca0..33893a180c2e 100644
> --- a/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c
> +++ b/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c
> @@ -152,6 +152,17 @@ static int mtk_hdmi_pll_set_rate(struct clk_hw *hw, unsigned long rate,
> RG_HDMITX_DRV_IBIAS_MASK);
> return 0;
> }
> +
> +static long mtk_hdmi_pll_round_rate(struct clk_hw *hw, unsigned long rate,
> + unsigned long *parent_rate)
> +{
> + struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw);
> +
> + hdmi_phy->pll_rate = rate;
I think you don't need to save the rate into pll_rate here, pll_rate
would be set in set_rate() or recalc_rate().
Regards,
CK
> +
> + return rate;
> +}
> +
> static unsigned long mtk_hdmi_pll_recalc_rate(struct clk_hw *hw,
> unsigned long parent_rate)
> {
> diff --git a/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c b/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c
> index 63dde42521b8..3a339f516613 100644
> --- a/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c
> +++ b/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c
> @@ -285,6 +285,20 @@ static int mtk_hdmi_pll_set_rate(struct clk_hw *hw, unsigned long rate,
> return 0;
> }
>
> +static long mtk_hdmi_pll_round_rate(struct clk_hw *hw, unsigned long rate,
> + unsigned long *parent_rate)
> +{
> + struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw);
> +
> + hdmi_phy->pll_rate = rate;
> + if (rate <= 74250000)
> + *parent_rate = rate;
> + else
> + *parent_rate = rate / 2;
> +
> + return rate;
> +}
> +
> static unsigned long mtk_hdmi_pll_recalc_rate(struct clk_hw *hw,
> unsigned long parent_rate)
> {
Hi, Wangyan:
On Wed, 2019-03-06 at 18:07 +0800, CK Hu wrote:
> Hi, Wangyan:
>
> On Mon, 2019-02-25 at 10:09 +0800, wangyan wang wrote:
> > From: chunhui dai <[email protected]>
> >
> > Recalculate the rate of this clock, by querying hardware.
> >
> > Signed-off-by: chunhui dai <[email protected]>
> > Signed-off-by: wangyan wang <[email protected]>
> > ---
> > drivers/gpu/drm/mediatek/mtk_hdmi_phy.c | 7 ++----
> > drivers/gpu/drm/mediatek/mtk_hdmi_phy.h | 3 +--
> > drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c | 35 ++++++++++++++++++++++++++
> > drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c | 8 ++++++
> > 4 files changed, 46 insertions(+), 7 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c
> > index 4ef9c57ffd44..13c5e65b9ead 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c
> > @@ -29,12 +29,9 @@ long mtk_hdmi_pll_round_rate(struct clk_hw *hw, unsigned long rate,
> > return rate;
> > }
> >
> > -unsigned long mtk_hdmi_pll_recalc_rate(struct clk_hw *hw,
> > - unsigned long parent_rate)
> > +u32 mtk_hdmi_phy_read(struct mtk_hdmi_phy *hdmi_phy, u32 offset)
> > {
> > - struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw);
> > -
> > - return hdmi_phy->pll_rate;
> > + return readl(hdmi_phy->regs + offset);
> > }
> >
> > void mtk_hdmi_phy_clear_bits(struct mtk_hdmi_phy *hdmi_phy, u32 offset,
> > diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h
> > index f39b1fc66612..fdad8b17a915 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h
> > +++ b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h
> > @@ -41,6 +41,7 @@ struct mtk_hdmi_phy {
> > unsigned int ibias_up;
> > };
> >
> > +u32 mtk_hdmi_phy_read(struct mtk_hdmi_phy *hdmi_phy, u32 offset);
> > void mtk_hdmi_phy_clear_bits(struct mtk_hdmi_phy *hdmi_phy, u32 offset,
> > u32 bits);
> > void mtk_hdmi_phy_set_bits(struct mtk_hdmi_phy *hdmi_phy, u32 offset,
> > @@ -50,8 +51,6 @@ void mtk_hdmi_phy_mask(struct mtk_hdmi_phy *hdmi_phy, u32 offset,
> > struct mtk_hdmi_phy *to_mtk_hdmi_phy(struct clk_hw *hw);
> > long mtk_hdmi_pll_round_rate(struct clk_hw *hw, unsigned long rate,
> > unsigned long *parent_rate);
> > -unsigned long mtk_hdmi_pll_recalc_rate(struct clk_hw *hw,
> > - unsigned long parent_rate);
> >
> > extern struct platform_driver mtk_hdmi_phy_driver;
> > extern struct mtk_hdmi_phy_conf mtk_hdmi_phy_8173_conf;
> > diff --git a/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c b/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c
> > index fcc42dc6ea7f..b25c9dfc432a 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c
> > @@ -153,6 +153,41 @@ static int mtk_hdmi_pll_set_rate(struct clk_hw *hw, unsigned long rate,
> > RG_HDMITX_DRV_IBIAS_MASK);
> > return 0;
> > }
> > +static unsigned long mtk_hdmi_pll_recalc_rate(struct clk_hw *hw,
> > + unsigned long parent_rate)
> > +{
> > + struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw);
> > + unsigned long out_rate, val;
> > +
> > + val = (mtk_hdmi_phy_read(hdmi_phy, HDMI_CON6)
> > + & RG_HTPLL_PREDIV_MASK) >> RG_HTPLL_PREDIV;
> > + switch (val) {
> > + case 0x00:
> > + out_rate = parent_rate;
> > + break;
> > + case 0x01:
> > + out_rate = parent_rate / 2;
> > + break;
> > + default:
> > + out_rate = parent_rate / 4;
> > + break;
> > + }
> > +
> > + val = (mtk_hdmi_phy_read(hdmi_phy, HDMI_CON6)
> > + & RG_HTPLL_FBKDIV_MASK) >> RG_HTPLL_FBKDIV;
> > + out_rate *= (val + 1) * 2;
> > + val = (mtk_hdmi_phy_read(hdmi_phy, HDMI_CON2)
> > + & RG_HDMITX_TX_POSDIV_MASK);
> > +
> > + out_rate >>= (val >> RG_HDMITX_TX_POSDIV);
> > +
> > + if (mtk_hdmi_phy_read(hdmi_phy, HDMI_CON2) & RG_HDMITX_EN_TX_POSDIV)
> > + out_rate = out_rate / 5;
> > +
>
> All the register you read here is set in mtk_hdmi_pll_set_rate(), so I
> think you could determine the out_rate in mtk_hdmi_pll_set_rate().
As offline discuss, you mention that when
cat /sys/kernel/debug/ckl/clk_summary, mtk_hdmi_pll_recalc_rate() is
called, so read register to get the real clock. The clk_summary call
clk_core_get_rate() to get rate, and clk_core_get_rate() would check the
flag CLK_GET_RATE_NOCACHE to call __clk_recalc_rates(), but mtk_hdmi_phy
does not have this flag, so this function would not be called when
clk_summary. So I still think you could determine the out_rate in
mtk_hdmi_pll_set_rate().
Regards,
CK
>
> Regards,
> CK
>
> > + hdmi_phy->pll_rate = out_rate;
> > +
> > + return hdmi_phy->pll_rate;
> > +}
> >
> > static const struct clk_ops mtk_hdmi_phy_pll_ops = {
> > .prepare = mtk_hdmi_pll_prepare,
> > diff --git a/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c b/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c
> > index ed5916b27658..cb23c1e4692a 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c
> > @@ -285,6 +285,14 @@ static int mtk_hdmi_pll_set_rate(struct clk_hw *hw, unsigned long rate,
> > return 0;
> > }
> >
> > +static unsigned long mtk_hdmi_pll_recalc_rate(struct clk_hw *hw,
> > + unsigned long parent_rate)
> > +{
> > + struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw);
> > +
> > + return hdmi_phy->pll_rate;
> > +}
> > +
> > static const struct clk_ops mtk_hdmi_phy_pll_ops = {
> > .prepare = mtk_hdmi_pll_prepare,
> > .unprepare = mtk_hdmi_pll_unprepare,
>
Hi, Wangyan:
On Wed, 2019-03-06 at 18:13 +0800, CK Hu wrote:
> Hi, Wangyan:
>
> On Mon, 2019-02-25 at 10:09 +0800, wangyan wang wrote:
> > From: chunhui dai <[email protected]>
> >
> > We should not change the rate of parent for hdmi phy when
> > doing round_rate for this clock. The parent clock of hdmi
> > phy must be the same as it. We change it when doing set_rate
> > only.
> >
> > Signed-off-by: chunhui dai <[email protected]>
> > Signed-off-by: wangyan wang <[email protected]>
> > ---
> > drivers/gpu/drm/mediatek/mtk_hdmi_phy.c | 14 --------------
> > drivers/gpu/drm/mediatek/mtk_hdmi_phy.h | 3 ---
> > drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c | 11 +++++++++++
> > drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c | 14 ++++++++++++++
> > 4 files changed, 25 insertions(+), 17 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c
> > index 370309d684ec..ca8bc1489f37 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c
> > @@ -15,20 +15,6 @@ static const struct phy_ops mtk_hdmi_phy_dev_ops = {
> > .owner = THIS_MODULE,
> > };
> >
> > -long mtk_hdmi_pll_round_rate(struct clk_hw *hw, unsigned long rate,
> > - unsigned long *parent_rate)
> > -{
> > - struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw);
> > -
> > - hdmi_phy->pll_rate = rate;
> > - if (rate <= 74250000)
> > - *parent_rate = rate;
> > - else
> > - *parent_rate = rate / 2;
> > -
> > - return rate;
> > -}
> > -
> > u32 mtk_hdmi_phy_read(struct mtk_hdmi_phy *hdmi_phy, u32 offset)
> > {
> > return readl(hdmi_phy->regs + offset);
> > diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h
> > index 446e2acd1926..c6061ad15ff0 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h
> > +++ b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h
> > @@ -50,9 +50,6 @@ void mtk_hdmi_phy_set_bits(struct mtk_hdmi_phy *hdmi_phy, u32 offset,
> > void mtk_hdmi_phy_mask(struct mtk_hdmi_phy *hdmi_phy, u32 offset,
> > u32 val, u32 mask);
> > struct mtk_hdmi_phy *to_mtk_hdmi_phy(struct clk_hw *hw);
> > -long mtk_hdmi_pll_round_rate(struct clk_hw *hw, unsigned long rate,
> > - unsigned long *parent_rate);
> > -
> > extern struct platform_driver mtk_hdmi_phy_driver;
> > extern struct mtk_hdmi_phy_conf mtk_hdmi_phy_8173_conf;
> > extern struct mtk_hdmi_phy_conf mtk_hdmi_phy_2701_conf;
> > diff --git a/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c b/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c
> > index 88dd9e812ca0..33893a180c2e 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c
> > @@ -152,6 +152,17 @@ static int mtk_hdmi_pll_set_rate(struct clk_hw *hw, unsigned long rate,
> > RG_HDMITX_DRV_IBIAS_MASK);
> > return 0;
> > }
> > +
> > +static long mtk_hdmi_pll_round_rate(struct clk_hw *hw, unsigned long rate,
> > + unsigned long *parent_rate)
> > +{
> > + struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw);
> > +
> > + hdmi_phy->pll_rate = rate;
>
> I think you don't need to save the rate into pll_rate here, pll_rate
> would be set in set_rate() or recalc_rate().
As offline discuss, you mention that this function just need to return
current rate. I think you could just remove this line
'hdmi_phy->pll_rate = rate;' and return rate only. You don't need to
assign hdmi_phy->pll_rate here because it would be set later in
set_rate().
Regards,
CK
>
> Regards,
> CK
>
> > +
> > + return rate;
> > +}
> > +
> > static unsigned long mtk_hdmi_pll_recalc_rate(struct clk_hw *hw,
> > unsigned long parent_rate)
> > {
> > diff --git a/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c b/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c
> > index 63dde42521b8..3a339f516613 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c
> > @@ -285,6 +285,20 @@ static int mtk_hdmi_pll_set_rate(struct clk_hw *hw, unsigned long rate,
> > return 0;
> > }
> >
> > +static long mtk_hdmi_pll_round_rate(struct clk_hw *hw, unsigned long rate,
> > + unsigned long *parent_rate)
> > +{
> > + struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw);
> > +
> > + hdmi_phy->pll_rate = rate;
> > + if (rate <= 74250000)
> > + *parent_rate = rate;
> > + else
> > + *parent_rate = rate / 2;
> > +
> > + return rate;
> > +}
> > +
> > static unsigned long mtk_hdmi_pll_recalc_rate(struct clk_hw *hw,
> > unsigned long parent_rate)
> > {
>
Hi, Wangyan:
On Thu, 2019-03-21 at 13:32 +0800, CK Hu wrote:
> Hi, Wangyan:
>
> On Wed, 2019-03-06 at 18:13 +0800, CK Hu wrote:
> > Hi, Wangyan:
> >
> > On Mon, 2019-02-25 at 10:09 +0800, wangyan wang wrote:
> > > From: chunhui dai <[email protected]>
> > >
> > > We should not change the rate of parent for hdmi phy when
> > > doing round_rate for this clock. The parent clock of hdmi
> > > phy must be the same as it. We change it when doing set_rate
> > > only.
> > >
> > > Signed-off-by: chunhui dai <[email protected]>
> > > Signed-off-by: wangyan wang <[email protected]>
> > > ---
> > > drivers/gpu/drm/mediatek/mtk_hdmi_phy.c | 14 --------------
> > > drivers/gpu/drm/mediatek/mtk_hdmi_phy.h | 3 ---
> > > drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c | 11 +++++++++++
> > > drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c | 14 ++++++++++++++
> > > 4 files changed, 25 insertions(+), 17 deletions(-)
> > >
> > > diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c
> > > index 370309d684ec..ca8bc1489f37 100644
> > > --- a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c
> > > +++ b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c
> > > @@ -15,20 +15,6 @@ static const struct phy_ops mtk_hdmi_phy_dev_ops = {
> > > .owner = THIS_MODULE,
> > > };
> > >
> > > -long mtk_hdmi_pll_round_rate(struct clk_hw *hw, unsigned long rate,
> > > - unsigned long *parent_rate)
> > > -{
> > > - struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw);
> > > -
> > > - hdmi_phy->pll_rate = rate;
> > > - if (rate <= 74250000)
> > > - *parent_rate = rate;
> > > - else
> > > - *parent_rate = rate / 2;
> > > -
> > > - return rate;
> > > -}
> > > -
> > > u32 mtk_hdmi_phy_read(struct mtk_hdmi_phy *hdmi_phy, u32 offset)
> > > {
> > > return readl(hdmi_phy->regs + offset);
> > > diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h
> > > index 446e2acd1926..c6061ad15ff0 100644
> > > --- a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h
> > > +++ b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h
> > > @@ -50,9 +50,6 @@ void mtk_hdmi_phy_set_bits(struct mtk_hdmi_phy *hdmi_phy, u32 offset,
> > > void mtk_hdmi_phy_mask(struct mtk_hdmi_phy *hdmi_phy, u32 offset,
> > > u32 val, u32 mask);
> > > struct mtk_hdmi_phy *to_mtk_hdmi_phy(struct clk_hw *hw);
> > > -long mtk_hdmi_pll_round_rate(struct clk_hw *hw, unsigned long rate,
> > > - unsigned long *parent_rate);
> > > -
> > > extern struct platform_driver mtk_hdmi_phy_driver;
> > > extern struct mtk_hdmi_phy_conf mtk_hdmi_phy_8173_conf;
> > > extern struct mtk_hdmi_phy_conf mtk_hdmi_phy_2701_conf;
> > > diff --git a/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c b/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c
> > > index 88dd9e812ca0..33893a180c2e 100644
> > > --- a/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c
> > > +++ b/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c
> > > @@ -152,6 +152,17 @@ static int mtk_hdmi_pll_set_rate(struct clk_hw *hw, unsigned long rate,
> > > RG_HDMITX_DRV_IBIAS_MASK);
> > > return 0;
> > > }
> > > +
> > > +static long mtk_hdmi_pll_round_rate(struct clk_hw *hw, unsigned long rate,
> > > + unsigned long *parent_rate)
> > > +{
> > > + struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw);
> > > +
> > > + hdmi_phy->pll_rate = rate;
> >
> > I think you don't need to save the rate into pll_rate here, pll_rate
> > would be set in set_rate() or recalc_rate().
>
> As offline discuss, you mention that this function just need to return
> current rate. I think you could just remove this line
> 'hdmi_phy->pll_rate = rate;' and return rate only. You don't need to
> assign hdmi_phy->pll_rate here because it would be set later in
> set_rate().
If you do not do any thing in mtk_hdmi_pll_round_rate(), I think you
could just don't implement round_rate() callback function because ccf
would not call round_rate() if it is not implemented.
Regards,
CK
>
> Regards,
> CK
>
> >
> > Regards,
> > CK
> >
> > > +
> > > + return rate;
> > > +}
> > > +
> > > static unsigned long mtk_hdmi_pll_recalc_rate(struct clk_hw *hw,
> > > unsigned long parent_rate)
> > > {
> > > diff --git a/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c b/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c
> > > index 63dde42521b8..3a339f516613 100644
> > > --- a/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c
> > > +++ b/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c
> > > @@ -285,6 +285,20 @@ static int mtk_hdmi_pll_set_rate(struct clk_hw *hw, unsigned long rate,
> > > return 0;
> > > }
> > >
> > > +static long mtk_hdmi_pll_round_rate(struct clk_hw *hw, unsigned long rate,
> > > + unsigned long *parent_rate)
> > > +{
> > > + struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw);
> > > +
> > > + hdmi_phy->pll_rate = rate;
> > > + if (rate <= 74250000)
> > > + *parent_rate = rate;
> > > + else
> > > + *parent_rate = rate / 2;
> > > +
> > > + return rate;
> > > +}
> > > +
> > > static unsigned long mtk_hdmi_pll_recalc_rate(struct clk_hw *hw,
> > > unsigned long parent_rate)
> > > {
> >
>
Hi, Wangyan:
On Thu, 2019-03-21 at 11:23 +0800, CK Hu wrote:
> Hi, Wangyan:
>
> On Wed, 2019-03-06 at 18:07 +0800, CK Hu wrote:
> > Hi, Wangyan:
> >
> > On Mon, 2019-02-25 at 10:09 +0800, wangyan wang wrote:
> > > From: chunhui dai <[email protected]>
> > >
> > > Recalculate the rate of this clock, by querying hardware.
> > >
> > > Signed-off-by: chunhui dai <[email protected]>
> > > Signed-off-by: wangyan wang <[email protected]>
> > > ---
> > > drivers/gpu/drm/mediatek/mtk_hdmi_phy.c | 7 ++----
> > > drivers/gpu/drm/mediatek/mtk_hdmi_phy.h | 3 +--
> > > drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c | 35 ++++++++++++++++++++++++++
> > > drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c | 8 ++++++
> > > 4 files changed, 46 insertions(+), 7 deletions(-)
> > >
> > > diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c
> > > index 4ef9c57ffd44..13c5e65b9ead 100644
> > > --- a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c
> > > +++ b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c
> > > @@ -29,12 +29,9 @@ long mtk_hdmi_pll_round_rate(struct clk_hw *hw, unsigned long rate,
> > > return rate;
> > > }
> > >
> > > -unsigned long mtk_hdmi_pll_recalc_rate(struct clk_hw *hw,
> > > - unsigned long parent_rate)
> > > +u32 mtk_hdmi_phy_read(struct mtk_hdmi_phy *hdmi_phy, u32 offset)
> > > {
> > > - struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw);
> > > -
> > > - return hdmi_phy->pll_rate;
> > > + return readl(hdmi_phy->regs + offset);
Inside mtk_hdmi_pll_recalc_rate(), there is just one function, why not
directly call readl() in the caller function?
> > > }
> > >
> > > void mtk_hdmi_phy_clear_bits(struct mtk_hdmi_phy *hdmi_phy, u32 offset,
> > > diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h
> > > index f39b1fc66612..fdad8b17a915 100644
> > > --- a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h
> > > +++ b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h
> > > @@ -41,6 +41,7 @@ struct mtk_hdmi_phy {
> > > unsigned int ibias_up;
> > > };
> > >
> > > +u32 mtk_hdmi_phy_read(struct mtk_hdmi_phy *hdmi_phy, u32 offset);
> > > void mtk_hdmi_phy_clear_bits(struct mtk_hdmi_phy *hdmi_phy, u32 offset,
> > > u32 bits);
> > > void mtk_hdmi_phy_set_bits(struct mtk_hdmi_phy *hdmi_phy, u32 offset,
> > > @@ -50,8 +51,6 @@ void mtk_hdmi_phy_mask(struct mtk_hdmi_phy *hdmi_phy, u32 offset,
> > > struct mtk_hdmi_phy *to_mtk_hdmi_phy(struct clk_hw *hw);
> > > long mtk_hdmi_pll_round_rate(struct clk_hw *hw, unsigned long rate,
> > > unsigned long *parent_rate);
> > > -unsigned long mtk_hdmi_pll_recalc_rate(struct clk_hw *hw,
> > > - unsigned long parent_rate);
> > >
> > > extern struct platform_driver mtk_hdmi_phy_driver;
> > > extern struct mtk_hdmi_phy_conf mtk_hdmi_phy_8173_conf;
> > > diff --git a/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c b/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c
> > > index fcc42dc6ea7f..b25c9dfc432a 100644
> > > --- a/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c
> > > +++ b/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c
> > > @@ -153,6 +153,41 @@ static int mtk_hdmi_pll_set_rate(struct clk_hw *hw, unsigned long rate,
> > > RG_HDMITX_DRV_IBIAS_MASK);
> > > return 0;
> > > }
> > > +static unsigned long mtk_hdmi_pll_recalc_rate(struct clk_hw *hw,
> > > + unsigned long parent_rate)
> > > +{
> > > + struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw);
> > > + unsigned long out_rate, val;
> > > +
> > > + val = (mtk_hdmi_phy_read(hdmi_phy, HDMI_CON6)
> > > + & RG_HTPLL_PREDIV_MASK) >> RG_HTPLL_PREDIV;
> > > + switch (val) {
> > > + case 0x00:
> > > + out_rate = parent_rate;
> > > + break;
> > > + case 0x01:
> > > + out_rate = parent_rate / 2;
> > > + break;
> > > + default:
> > > + out_rate = parent_rate / 4;
> > > + break;
> > > + }
> > > +
> > > + val = (mtk_hdmi_phy_read(hdmi_phy, HDMI_CON6)
> > > + & RG_HTPLL_FBKDIV_MASK) >> RG_HTPLL_FBKDIV;
> > > + out_rate *= (val + 1) * 2;
> > > + val = (mtk_hdmi_phy_read(hdmi_phy, HDMI_CON2)
> > > + & RG_HDMITX_TX_POSDIV_MASK);
> > > +
> > > + out_rate >>= (val >> RG_HDMITX_TX_POSDIV);
> > > +
> > > + if (mtk_hdmi_phy_read(hdmi_phy, HDMI_CON2) & RG_HDMITX_EN_TX_POSDIV)
> > > + out_rate = out_rate / 5;
> > > +
> >
> > All the register you read here is set in mtk_hdmi_pll_set_rate(), so I
> > think you could determine the out_rate in mtk_hdmi_pll_set_rate().
>
> As offline discuss, you mention that when
> cat /sys/kernel/debug/ckl/clk_summary, mtk_hdmi_pll_recalc_rate() is
> called, so read register to get the real clock. The clk_summary call
> clk_core_get_rate() to get rate, and clk_core_get_rate() would check the
> flag CLK_GET_RATE_NOCACHE to call __clk_recalc_rates(), but mtk_hdmi_phy
> does not have this flag, so this function would not be called when
> clk_summary. So I still think you could determine the out_rate in
> mtk_hdmi_pll_set_rate().
As offline discuss, recalc_rate is defined as follow:
* @recalc_rate Recalculate the rate of this clock, by querying
hardware. The
* parent rate is an input parameter. It is up to the caller to
* ensure that the prepare_mutex is held across this call.
* Returns the calculated rate. Optional, but recommended - if
* this op is not set then clock rate will be initialized to 0.
So it looks that recalc_rate is expected to query hardware to get the
out_rate. So this implementation is OK.
>
> Regards,
> CK
>
> >
> > Regards,
> > CK
> >
> > > + hdmi_phy->pll_rate = out_rate;
I think you don't need to assign hdmi_phy->pll_rate in MT2701 because
it's useless in MT2701.
Regards,
CK
> > > +
> > > + return hdmi_phy->pll_rate;
> > > +}
> > >
> > > static const struct clk_ops mtk_hdmi_phy_pll_ops = {
> > > .prepare = mtk_hdmi_pll_prepare,
> > > diff --git a/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c b/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c
> > > index ed5916b27658..cb23c1e4692a 100644
> > > --- a/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c
> > > +++ b/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c
> > > @@ -285,6 +285,14 @@ static int mtk_hdmi_pll_set_rate(struct clk_hw *hw, unsigned long rate,
> > > return 0;
> > > }
> > >
> > > +static unsigned long mtk_hdmi_pll_recalc_rate(struct clk_hw *hw,
> > > + unsigned long parent_rate)
> > > +{
> > > + struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw);
> > > +
> > > + return hdmi_phy->pll_rate;
> > > +}
> > > +
> > > static const struct clk_ops mtk_hdmi_phy_pll_ops = {
> > > .prepare = mtk_hdmi_pll_prepare,
> > > .unprepare = mtk_hdmi_pll_unprepare,
> >
>