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)
|
||||
{
|
||||
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 = {
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include <drm/drmP.h>
|
||||
#include <drm/drm_atomic.h>
|
||||
#include <drm/drm_atomic_helper.h>
|
||||
#include <drm/drm_fb_helper.h>
|
||||
#include <drm/drm_gem.h>
|
||||
#include <drm/drm_gem_cma_helper.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_import_sg_table = mtk_gem_prime_import_sg_table,
|
||||
.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,
|
||||
|
||||
.name = DRIVER_NAME,
|
||||
|
@ -376,6 +379,10 @@ static int mtk_drm_bind(struct device *dev)
|
|||
if (ret < 0)
|
||||
goto err_deinit;
|
||||
|
||||
ret = drm_fbdev_generic_setup(drm, 32);
|
||||
if (ret)
|
||||
DRM_ERROR("Failed to initialize fbdev: %d\n", ret);
|
||||
|
||||
return 0;
|
||||
|
||||
err_deinit:
|
||||
|
|
|
@ -241,3 +241,49 @@ struct drm_gem_object *mtk_gem_prime_import_sg_table(struct drm_device *dev,
|
|||
kfree(mtk_gem);
|
||||
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;
|
||||
unsigned long dma_attrs;
|
||||
struct sg_table *sg;
|
||||
struct page **pages;
|
||||
};
|
||||
|
||||
#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 drm_gem_object *mtk_gem_prime_import_sg_table(struct drm_device *dev,
|
||||
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
|
||||
|
|
|
@ -1480,7 +1480,6 @@ static int mtk_hdmi_dt_parse_pdata(struct mtk_hdmi *hdmi,
|
|||
if (IS_ERR(regmap))
|
||||
ret = PTR_ERR(regmap);
|
||||
if (ret) {
|
||||
ret = PTR_ERR(regmap);
|
||||
dev_err(dev,
|
||||
"Failed to get system configuration registers: %d\n",
|
||||
ret);
|
||||
|
@ -1516,6 +1515,7 @@ static int mtk_hdmi_dt_parse_pdata(struct mtk_hdmi *hdmi,
|
|||
of_node_put(remote);
|
||||
|
||||
hdmi->ddc_adpt = of_find_i2c_adapter_by_node(i2c_np);
|
||||
of_node_put(i2c_np);
|
||||
if (!hdmi->ddc_adpt) {
|
||||
dev_err(dev, "Failed to get ddc i2c adapter by node\n");
|
||||
return -EINVAL;
|
||||
|
|
|
@ -15,28 +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;
|
||||
}
|
||||
|
||||
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,
|
||||
u32 bits)
|
||||
{
|
||||
|
@ -110,13 +88,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)
|
||||
|
@ -129,7 +105,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;
|
||||
|
@ -167,7 +142,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)) {
|
||||
|
|
|
@ -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);
|
||||
|
@ -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,
|
||||
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);
|
||||
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;
|
||||
|
|
|
@ -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);
|
||||
|
@ -108,6 +106,12 @@ static void mtk_hdmi_pll_unprepare(struct clk_hw *hw)
|
|||
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,
|
||||
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)
|
||||
pos_div = 3;
|
||||
else if (rate <= 12800000)
|
||||
pos_div = 1;
|
||||
else if (rate <= 128000000)
|
||||
pos_div = 2;
|
||||
else
|
||||
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_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),
|
||||
|
@ -154,6 +159,39 @@ 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);
|
||||
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 = {
|
||||
.prepare = mtk_hdmi_pll_prepare,
|
||||
.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);
|
||||
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);
|
||||
|
@ -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_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);
|
||||
|
@ -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 = {
|
||||
.tz_disabled = true,
|
||||
.flags = 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,
|
||||
|
|
|
@ -199,6 +199,20 @@ static void mtk_hdmi_pll_unprepare(struct clk_hw *hw)
|
|||
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,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
|
@ -285,6 +299,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,
|
||||
|
@ -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 = {
|
||||
.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,
|
||||
|
|
Loading…
Reference in New Issue