// SPDX-License-Identifier: GPL-2.0-only
/*
* HDMI PLL
*
* Copyright ( C ) 2013 Texas Instruments Incorporated - https : //www.ti.com/
*/
#define DSS_SUBSYS_NAME "HDMIPLL"
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/err.h>
#include <linux/io.h>
#include <linux/platform_device.h>
#include <linux/clk.h>
#include <linux/seq_file.h>
#include <linux/pm_runtime.h>
#include "omapdss.h"
#include "dss.h"
#include "hdmi.h"
void hdmi_pll_dump(struct hdmi_pll_data *pll, struct seq_file *s)
{
#define DUMPPLL(r) seq_printf(s, "%-35s %08x\n" , #r ,\
hdmi_read_reg(pll->base, r))
DUMPPLL(PLLCTRL_PLL_CONTROL);
DUMPPLL(PLLCTRL_PLL_STATUS);
DUMPPLL(PLLCTRL_PLL_GO);
DUMPPLL(PLLCTRL_CFG1);
DUMPPLL(PLLCTRL_CFG2);
DUMPPLL(PLLCTRL_CFG3);
DUMPPLL(PLLCTRL_SSC_CFG1);
DUMPPLL(PLLCTRL_SSC_CFG2);
DUMPPLL(PLLCTRL_CFG4);
}
static int hdmi_pll_enable(struct dss_pll *dsspll)
{
struct hdmi_pll_data *pll = container_of(dsspll, struct hdmi_pll_data, pll);
struct hdmi_wp_data *wp = pll->wp;
int r;
r = pm_runtime_get_sync(&pll->pdev->dev);
WARN_ON(r < 0 );
dss_ctrl_pll_enable(dsspll, true );
r = hdmi_wp_set_pll_pwr(wp, HDMI_PLLPWRCMD_BOTHON_ALLCLKS);
if (r)
return r;
return 0 ;
}
static void hdmi_pll_disable(struct dss_pll *dsspll)
{
struct hdmi_pll_data *pll = container_of(dsspll, struct hdmi_pll_data, pll);
struct hdmi_wp_data *wp = pll->wp;
int r;
hdmi_wp_set_pll_pwr(wp, HDMI_PLLPWRCMD_ALLOFF);
dss_ctrl_pll_enable(dsspll, false );
r = pm_runtime_put_sync(&pll->pdev->dev);
WARN_ON(r < 0 && r != -ENOSYS);
}
static const struct dss_pll_ops hdmi_pll_ops = {
.enable = hdmi_pll_enable,
.disable = hdmi_pll_disable,
.set_config = dss_pll_write_config_type_b,
};
static const struct dss_pll_hw dss_omap4_hdmi_pll_hw = {
.type = DSS_PLL_TYPE_B,
.n_max = 255 ,
.m_min = 20 ,
.m_max = 4095 ,
.mX_max = 127 ,
.fint_min = 500000 ,
.fint_max = 2500000 ,
.clkdco_min = 500000000 ,
.clkdco_low = 1000000000 ,
.clkdco_max = 2000000000 ,
.n_msb = 8 ,
.n_lsb = 1 ,
.m_msb = 20 ,
.m_lsb = 9 ,
.mX_msb[0 ] = 24 ,
.mX_lsb[0 ] = 18 ,
.has_selfreqdco = true ,
};
static const struct dss_pll_hw dss_omap5_hdmi_pll_hw = {
.type = DSS_PLL_TYPE_B,
.n_max = 255 ,
.m_min = 20 ,
.m_max = 2045 ,
.mX_max = 127 ,
.fint_min = 620000 ,
.fint_max = 2500000 ,
.clkdco_min = 750000000 ,
.clkdco_low = 1500000000 ,
.clkdco_max = 2500000000 UL,
.n_msb = 8 ,
.n_lsb = 1 ,
.m_msb = 20 ,
.m_lsb = 9 ,
.mX_msb[0 ] = 24 ,
.mX_lsb[0 ] = 18 ,
.has_selfreqdco = true ,
.has_refsel = true ,
};
static int hdmi_init_pll_data(struct dss_device *dss,
struct platform_device *pdev,
struct hdmi_pll_data *hpll)
{
struct dss_pll *pll = &hpll->pll;
struct clk *clk;
int r;
clk = devm_clk_get(&pdev->dev, "sys_clk" );
if (IS_ERR(clk)) {
DSSERR("can't get sys_clk\n" );
return PTR_ERR(clk);
}
pll->name = "hdmi" ;
pll->id = DSS_PLL_HDMI;
pll->base = hpll->base;
pll->clkin = clk;
if (hpll->wp->version == 4 )
pll->hw = &dss_omap4_hdmi_pll_hw;
else
pll->hw = &dss_omap5_hdmi_pll_hw;
pll->ops = &hdmi_pll_ops;
r = dss_pll_register(dss, pll);
if (r)
return r;
return 0 ;
}
int hdmi_pll_init(struct dss_device *dss, struct platform_device *pdev,
struct hdmi_pll_data *pll, struct hdmi_wp_data *wp)
{
int r;
pll->pdev = pdev;
pll->wp = wp;
pll->base = devm_platform_ioremap_resource_byname(pdev, "pll" );
if (IS_ERR(pll->base))
return PTR_ERR(pll->base);
r = hdmi_init_pll_data(dss, pdev, pll);
if (r) {
DSSERR("failed to init HDMI PLL\n" );
return r;
}
return 0 ;
}
void hdmi_pll_uninit(struct hdmi_pll_data *hpll)
{
struct dss_pll *pll = &hpll->pll;
dss_pll_unregister(pll);
}
Messung V0.5 in Prozent C=99 H=100 G=99
¤ Dauer der Verarbeitung: 0.17 Sekunden
(vorverarbeitet am 2026-10-03)
¤
*© Formatika GbR, Deutschland