mirror of https://gitee.com/openkylin/linux.git
Merge branch 'mediatek-drm-fixes-5.1' of https://github.com/ckhu-mediatek/linux.git-tags into drm-fixes
This include stable MT2701 HDMI, framebuffer device and some fixes for mediatek drm driver. Signed-off-by: Dave Airlie <airlied@redhat.com> From: CK Hu <ck.hu@mediatek.com> Link: https://patchwork.freedesktop.org/patch/msgid/1554860914.29842.4.camel@mtksdaap41
This commit is contained in:
commit
86dc6612ab
|
@ -662,13 +662,11 @@ static unsigned int mt8173_calculate_factor(int clock)
|
||||||
static unsigned int mt2701_calculate_factor(int clock)
|
static unsigned int mt2701_calculate_factor(int clock)
|
||||||
{
|
{
|
||||||
if (clock <= 64000)
|
if (clock <= 64000)
|
||||||
return 16;
|
|
||||||
else if (clock <= 128000)
|
|
||||||
return 8;
|
|
||||||
else if (clock <= 256000)
|
|
||||||
return 4;
|
return 4;
|
||||||
else
|
else if (clock <= 128000)
|
||||||
return 2;
|
return 2;
|
||||||
|
else
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct mtk_dpi_conf mt8173_conf = {
|
static const struct mtk_dpi_conf mt8173_conf = {
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#include <drm/drmP.h>
|
#include <drm/drmP.h>
|
||||||
#include <drm/drm_atomic.h>
|
#include <drm/drm_atomic.h>
|
||||||
#include <drm/drm_atomic_helper.h>
|
#include <drm/drm_atomic_helper.h>
|
||||||
|
#include <drm/drm_fb_helper.h>
|
||||||
#include <drm/drm_gem.h>
|
#include <drm/drm_gem.h>
|
||||||
#include <drm/drm_gem_cma_helper.h>
|
#include <drm/drm_gem_cma_helper.h>
|
||||||
#include <drm/drm_of.h>
|
#include <drm/drm_of.h>
|
||||||
|
@ -341,6 +342,8 @@ static struct drm_driver mtk_drm_driver = {
|
||||||
.gem_prime_get_sg_table = mtk_gem_prime_get_sg_table,
|
.gem_prime_get_sg_table = mtk_gem_prime_get_sg_table,
|
||||||
.gem_prime_import_sg_table = mtk_gem_prime_import_sg_table,
|
.gem_prime_import_sg_table = mtk_gem_prime_import_sg_table,
|
||||||
.gem_prime_mmap = mtk_drm_gem_mmap_buf,
|
.gem_prime_mmap = mtk_drm_gem_mmap_buf,
|
||||||
|
.gem_prime_vmap = mtk_drm_gem_prime_vmap,
|
||||||
|
.gem_prime_vunmap = mtk_drm_gem_prime_vunmap,
|
||||||
.fops = &mtk_drm_fops,
|
.fops = &mtk_drm_fops,
|
||||||
|
|
||||||
.name = DRIVER_NAME,
|
.name = DRIVER_NAME,
|
||||||
|
@ -376,6 +379,10 @@ static int mtk_drm_bind(struct device *dev)
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto err_deinit;
|
goto err_deinit;
|
||||||
|
|
||||||
|
ret = drm_fbdev_generic_setup(drm, 32);
|
||||||
|
if (ret)
|
||||||
|
DRM_ERROR("Failed to initialize fbdev: %d\n", ret);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err_deinit:
|
err_deinit:
|
||||||
|
|
|
@ -241,3 +241,49 @@ struct drm_gem_object *mtk_gem_prime_import_sg_table(struct drm_device *dev,
|
||||||
kfree(mtk_gem);
|
kfree(mtk_gem);
|
||||||
return ERR_PTR(ret);
|
return ERR_PTR(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void *mtk_drm_gem_prime_vmap(struct drm_gem_object *obj)
|
||||||
|
{
|
||||||
|
struct mtk_drm_gem_obj *mtk_gem = to_mtk_gem_obj(obj);
|
||||||
|
struct sg_table *sgt;
|
||||||
|
struct sg_page_iter iter;
|
||||||
|
unsigned int npages;
|
||||||
|
unsigned int i = 0;
|
||||||
|
|
||||||
|
if (mtk_gem->kvaddr)
|
||||||
|
return mtk_gem->kvaddr;
|
||||||
|
|
||||||
|
sgt = mtk_gem_prime_get_sg_table(obj);
|
||||||
|
if (IS_ERR(sgt))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
npages = obj->size >> PAGE_SHIFT;
|
||||||
|
mtk_gem->pages = kcalloc(npages, sizeof(*mtk_gem->pages), GFP_KERNEL);
|
||||||
|
if (!mtk_gem->pages)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
for_each_sg_page(sgt->sgl, &iter, sgt->orig_nents, 0) {
|
||||||
|
mtk_gem->pages[i++] = sg_page_iter_page(&iter);
|
||||||
|
if (i > npages)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
mtk_gem->kvaddr = vmap(mtk_gem->pages, npages, VM_MAP,
|
||||||
|
pgprot_writecombine(PAGE_KERNEL));
|
||||||
|
|
||||||
|
out:
|
||||||
|
kfree((void *)sgt);
|
||||||
|
|
||||||
|
return mtk_gem->kvaddr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mtk_drm_gem_prime_vunmap(struct drm_gem_object *obj, void *vaddr)
|
||||||
|
{
|
||||||
|
struct mtk_drm_gem_obj *mtk_gem = to_mtk_gem_obj(obj);
|
||||||
|
|
||||||
|
if (!mtk_gem->pages)
|
||||||
|
return;
|
||||||
|
|
||||||
|
vunmap(vaddr);
|
||||||
|
mtk_gem->kvaddr = 0;
|
||||||
|
kfree((void *)mtk_gem->pages);
|
||||||
|
}
|
||||||
|
|
|
@ -37,6 +37,7 @@ struct mtk_drm_gem_obj {
|
||||||
dma_addr_t dma_addr;
|
dma_addr_t dma_addr;
|
||||||
unsigned long dma_attrs;
|
unsigned long dma_attrs;
|
||||||
struct sg_table *sg;
|
struct sg_table *sg;
|
||||||
|
struct page **pages;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define to_mtk_gem_obj(x) container_of(x, struct mtk_drm_gem_obj, base)
|
#define to_mtk_gem_obj(x) container_of(x, struct mtk_drm_gem_obj, base)
|
||||||
|
@ -52,5 +53,7 @@ int mtk_drm_gem_mmap_buf(struct drm_gem_object *obj,
|
||||||
struct sg_table *mtk_gem_prime_get_sg_table(struct drm_gem_object *obj);
|
struct sg_table *mtk_gem_prime_get_sg_table(struct drm_gem_object *obj);
|
||||||
struct drm_gem_object *mtk_gem_prime_import_sg_table(struct drm_device *dev,
|
struct drm_gem_object *mtk_gem_prime_import_sg_table(struct drm_device *dev,
|
||||||
struct dma_buf_attachment *attach, struct sg_table *sg);
|
struct dma_buf_attachment *attach, struct sg_table *sg);
|
||||||
|
void *mtk_drm_gem_prime_vmap(struct drm_gem_object *obj);
|
||||||
|
void mtk_drm_gem_prime_vunmap(struct drm_gem_object *obj, void *vaddr);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1480,7 +1480,6 @@ static int mtk_hdmi_dt_parse_pdata(struct mtk_hdmi *hdmi,
|
||||||
if (IS_ERR(regmap))
|
if (IS_ERR(regmap))
|
||||||
ret = PTR_ERR(regmap);
|
ret = PTR_ERR(regmap);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
ret = PTR_ERR(regmap);
|
|
||||||
dev_err(dev,
|
dev_err(dev,
|
||||||
"Failed to get system configuration registers: %d\n",
|
"Failed to get system configuration registers: %d\n",
|
||||||
ret);
|
ret);
|
||||||
|
@ -1516,6 +1515,7 @@ static int mtk_hdmi_dt_parse_pdata(struct mtk_hdmi *hdmi,
|
||||||
of_node_put(remote);
|
of_node_put(remote);
|
||||||
|
|
||||||
hdmi->ddc_adpt = of_find_i2c_adapter_by_node(i2c_np);
|
hdmi->ddc_adpt = of_find_i2c_adapter_by_node(i2c_np);
|
||||||
|
of_node_put(i2c_np);
|
||||||
if (!hdmi->ddc_adpt) {
|
if (!hdmi->ddc_adpt) {
|
||||||
dev_err(dev, "Failed to get ddc i2c adapter by node\n");
|
dev_err(dev, "Failed to get ddc i2c adapter by node\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
|
@ -15,28 +15,6 @@ static const struct phy_ops mtk_hdmi_phy_dev_ops = {
|
||||||
.owner = THIS_MODULE,
|
.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;
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
void mtk_hdmi_phy_clear_bits(struct mtk_hdmi_phy *hdmi_phy, u32 offset,
|
void mtk_hdmi_phy_clear_bits(struct mtk_hdmi_phy *hdmi_phy, u32 offset,
|
||||||
u32 bits)
|
u32 bits)
|
||||||
{
|
{
|
||||||
|
@ -110,13 +88,11 @@ mtk_hdmi_phy_dev_get_ops(const struct mtk_hdmi_phy *hdmi_phy)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mtk_hdmi_phy_clk_get_ops(struct mtk_hdmi_phy *hdmi_phy,
|
static void mtk_hdmi_phy_clk_get_data(struct mtk_hdmi_phy *hdmi_phy,
|
||||||
const struct clk_ops **ops)
|
struct clk_init_data *clk_init)
|
||||||
{
|
{
|
||||||
if (hdmi_phy && hdmi_phy->conf && hdmi_phy->conf->hdmi_phy_clk_ops)
|
clk_init->flags = hdmi_phy->conf->flags;
|
||||||
*ops = hdmi_phy->conf->hdmi_phy_clk_ops;
|
clk_init->ops = hdmi_phy->conf->hdmi_phy_clk_ops;
|
||||||
else
|
|
||||||
dev_err(hdmi_phy->dev, "Failed to get clk ops of phy\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mtk_hdmi_phy_probe(struct platform_device *pdev)
|
static int mtk_hdmi_phy_probe(struct platform_device *pdev)
|
||||||
|
@ -129,7 +105,6 @@ static int mtk_hdmi_phy_probe(struct platform_device *pdev)
|
||||||
struct clk_init_data clk_init = {
|
struct clk_init_data clk_init = {
|
||||||
.num_parents = 1,
|
.num_parents = 1,
|
||||||
.parent_names = (const char * const *)&ref_clk_name,
|
.parent_names = (const char * const *)&ref_clk_name,
|
||||||
.flags = CLK_SET_RATE_PARENT | CLK_SET_RATE_GATE,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct phy *phy;
|
struct phy *phy;
|
||||||
|
@ -167,7 +142,7 @@ static int mtk_hdmi_phy_probe(struct platform_device *pdev)
|
||||||
hdmi_phy->dev = dev;
|
hdmi_phy->dev = dev;
|
||||||
hdmi_phy->conf =
|
hdmi_phy->conf =
|
||||||
(struct mtk_hdmi_phy_conf *)of_device_get_match_data(dev);
|
(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_hw.init = &clk_init;
|
||||||
hdmi_phy->pll = devm_clk_register(dev, &hdmi_phy->pll_hw);
|
hdmi_phy->pll = devm_clk_register(dev, &hdmi_phy->pll_hw);
|
||||||
if (IS_ERR(hdmi_phy->pll)) {
|
if (IS_ERR(hdmi_phy->pll)) {
|
||||||
|
|
|
@ -21,6 +21,7 @@ struct mtk_hdmi_phy;
|
||||||
|
|
||||||
struct mtk_hdmi_phy_conf {
|
struct mtk_hdmi_phy_conf {
|
||||||
bool tz_disabled;
|
bool tz_disabled;
|
||||||
|
unsigned long flags;
|
||||||
const struct clk_ops *hdmi_phy_clk_ops;
|
const struct clk_ops *hdmi_phy_clk_ops;
|
||||||
void (*hdmi_phy_enable_tmds)(struct mtk_hdmi_phy *hdmi_phy);
|
void (*hdmi_phy_enable_tmds)(struct mtk_hdmi_phy *hdmi_phy);
|
||||||
void (*hdmi_phy_disable_tmds)(struct mtk_hdmi_phy *hdmi_phy);
|
void (*hdmi_phy_disable_tmds)(struct mtk_hdmi_phy *hdmi_phy);
|
||||||
|
@ -48,10 +49,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,
|
void mtk_hdmi_phy_mask(struct mtk_hdmi_phy *hdmi_phy, u32 offset,
|
||||||
u32 val, u32 mask);
|
u32 val, u32 mask);
|
||||||
struct mtk_hdmi_phy *to_mtk_hdmi_phy(struct clk_hw *hw);
|
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 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_8173_conf;
|
||||||
|
|
|
@ -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);
|
mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_SLDO_MASK);
|
||||||
usleep_range(80, 100);
|
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_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_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_PRED_MASK);
|
||||||
mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_DRV_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_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_PRED_MASK);
|
||||||
mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_SER_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);
|
mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_MBIAS_LPF_EN);
|
||||||
usleep_range(80, 100);
|
usleep_range(80, 100);
|
||||||
mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_SLDO_MASK);
|
mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_SLDO_MASK);
|
||||||
|
@ -108,6 +106,12 @@ static void mtk_hdmi_pll_unprepare(struct clk_hw *hw)
|
||||||
usleep_range(80, 100);
|
usleep_range(80, 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static long mtk_hdmi_pll_round_rate(struct clk_hw *hw, unsigned long rate,
|
||||||
|
unsigned long *parent_rate)
|
||||||
|
{
|
||||||
|
return rate;
|
||||||
|
}
|
||||||
|
|
||||||
static int mtk_hdmi_pll_set_rate(struct clk_hw *hw, unsigned long rate,
|
static int mtk_hdmi_pll_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||||
unsigned long parent_rate)
|
unsigned long parent_rate)
|
||||||
{
|
{
|
||||||
|
@ -116,13 +120,14 @@ static int mtk_hdmi_pll_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||||
|
|
||||||
if (rate <= 64000000)
|
if (rate <= 64000000)
|
||||||
pos_div = 3;
|
pos_div = 3;
|
||||||
else if (rate <= 12800000)
|
else if (rate <= 128000000)
|
||||||
pos_div = 1;
|
pos_div = 2;
|
||||||
else
|
else
|
||||||
pos_div = 1;
|
pos_div = 1;
|
||||||
|
|
||||||
mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_PREDIV_MASK);
|
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_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),
|
mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON6, (0x1 << RG_HTPLL_IC),
|
||||||
RG_HTPLL_IC_MASK);
|
RG_HTPLL_IC_MASK);
|
||||||
mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON6, (0x1 << RG_HTPLL_IR),
|
mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON6, (0x1 << RG_HTPLL_IR),
|
||||||
|
@ -154,6 +159,39 @@ static int mtk_hdmi_pll_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||||
return 0;
|
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 = (readl(hdmi_phy->regs + 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 = (readl(hdmi_phy->regs + HDMI_CON6)
|
||||||
|
& RG_HTPLL_FBKDIV_MASK) >> RG_HTPLL_FBKDIV;
|
||||||
|
out_rate *= (val + 1) * 2;
|
||||||
|
val = (readl(hdmi_phy->regs + HDMI_CON2)
|
||||||
|
& RG_HDMITX_TX_POSDIV_MASK);
|
||||||
|
out_rate >>= (val >> RG_HDMITX_TX_POSDIV);
|
||||||
|
|
||||||
|
if (readl(hdmi_phy->regs + HDMI_CON2) & RG_HDMITX_EN_TX_POSDIV)
|
||||||
|
out_rate /= 5;
|
||||||
|
|
||||||
|
return out_rate;
|
||||||
|
}
|
||||||
|
|
||||||
static const struct clk_ops mtk_hdmi_phy_pll_ops = {
|
static const struct clk_ops mtk_hdmi_phy_pll_ops = {
|
||||||
.prepare = mtk_hdmi_pll_prepare,
|
.prepare = mtk_hdmi_pll_prepare,
|
||||||
.unprepare = mtk_hdmi_pll_unprepare,
|
.unprepare = mtk_hdmi_pll_unprepare,
|
||||||
|
@ -174,7 +212,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);
|
mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_SLDO_MASK);
|
||||||
usleep_range(80, 100);
|
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_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_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_PRED_MASK);
|
||||||
mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_DRV_MASK);
|
mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_DRV_MASK);
|
||||||
|
@ -186,7 +223,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_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_PRED_MASK);
|
||||||
mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_SER_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);
|
mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_MBIAS_LPF_EN);
|
||||||
usleep_range(80, 100);
|
usleep_range(80, 100);
|
||||||
mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_SLDO_MASK);
|
mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_SLDO_MASK);
|
||||||
|
@ -202,6 +238,7 @@ static void mtk_hdmi_phy_disable_tmds(struct mtk_hdmi_phy *hdmi_phy)
|
||||||
|
|
||||||
struct mtk_hdmi_phy_conf mtk_hdmi_phy_2701_conf = {
|
struct mtk_hdmi_phy_conf mtk_hdmi_phy_2701_conf = {
|
||||||
.tz_disabled = true,
|
.tz_disabled = true,
|
||||||
|
.flags = CLK_SET_RATE_GATE,
|
||||||
.hdmi_phy_clk_ops = &mtk_hdmi_phy_pll_ops,
|
.hdmi_phy_clk_ops = &mtk_hdmi_phy_pll_ops,
|
||||||
.hdmi_phy_enable_tmds = mtk_hdmi_phy_enable_tmds,
|
.hdmi_phy_enable_tmds = mtk_hdmi_phy_enable_tmds,
|
||||||
.hdmi_phy_disable_tmds = mtk_hdmi_phy_disable_tmds,
|
.hdmi_phy_disable_tmds = mtk_hdmi_phy_disable_tmds,
|
||||||
|
|
|
@ -199,6 +199,20 @@ static void mtk_hdmi_pll_unprepare(struct clk_hw *hw)
|
||||||
usleep_range(100, 150);
|
usleep_range(100, 150);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 int mtk_hdmi_pll_set_rate(struct clk_hw *hw, unsigned long rate,
|
static int mtk_hdmi_pll_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||||
unsigned long parent_rate)
|
unsigned long parent_rate)
|
||||||
{
|
{
|
||||||
|
@ -285,6 +299,14 @@ static int mtk_hdmi_pll_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||||
return 0;
|
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 = {
|
static const struct clk_ops mtk_hdmi_phy_pll_ops = {
|
||||||
.prepare = mtk_hdmi_pll_prepare,
|
.prepare = mtk_hdmi_pll_prepare,
|
||||||
.unprepare = mtk_hdmi_pll_unprepare,
|
.unprepare = mtk_hdmi_pll_unprepare,
|
||||||
|
@ -309,6 +331,7 @@ static void mtk_hdmi_phy_disable_tmds(struct mtk_hdmi_phy *hdmi_phy)
|
||||||
}
|
}
|
||||||
|
|
||||||
struct mtk_hdmi_phy_conf mtk_hdmi_phy_8173_conf = {
|
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_clk_ops = &mtk_hdmi_phy_pll_ops,
|
||||||
.hdmi_phy_enable_tmds = mtk_hdmi_phy_enable_tmds,
|
.hdmi_phy_enable_tmds = mtk_hdmi_phy_enable_tmds,
|
||||||
.hdmi_phy_disable_tmds = mtk_hdmi_phy_disable_tmds,
|
.hdmi_phy_disable_tmds = mtk_hdmi_phy_disable_tmds,
|
||||||
|
|
Loading…
Reference in New Issue