0001
0002
0003
0004
0005
0006
0007
0008 #define DSS_SUBSYS_NAME "HDMIPLL"
0009
0010 #include <linux/kernel.h>
0011 #include <linux/module.h>
0012 #include <linux/err.h>
0013 #include <linux/io.h>
0014 #include <linux/platform_device.h>
0015 #include <linux/clk.h>
0016 #include <linux/seq_file.h>
0017 #include <linux/pm_runtime.h>
0018
0019 #include "omapdss.h"
0020 #include "dss.h"
0021 #include "hdmi.h"
0022
0023 void hdmi_pll_dump(struct hdmi_pll_data *pll, struct seq_file *s)
0024 {
0025 #define DUMPPLL(r) seq_printf(s, "%-35s %08x\n", #r,\
0026 hdmi_read_reg(pll->base, r))
0027
0028 DUMPPLL(PLLCTRL_PLL_CONTROL);
0029 DUMPPLL(PLLCTRL_PLL_STATUS);
0030 DUMPPLL(PLLCTRL_PLL_GO);
0031 DUMPPLL(PLLCTRL_CFG1);
0032 DUMPPLL(PLLCTRL_CFG2);
0033 DUMPPLL(PLLCTRL_CFG3);
0034 DUMPPLL(PLLCTRL_SSC_CFG1);
0035 DUMPPLL(PLLCTRL_SSC_CFG2);
0036 DUMPPLL(PLLCTRL_CFG4);
0037 }
0038
0039 static int hdmi_pll_enable(struct dss_pll *dsspll)
0040 {
0041 struct hdmi_pll_data *pll = container_of(dsspll, struct hdmi_pll_data, pll);
0042 struct hdmi_wp_data *wp = pll->wp;
0043 int r;
0044
0045 r = pm_runtime_get_sync(&pll->pdev->dev);
0046 WARN_ON(r < 0);
0047
0048 dss_ctrl_pll_enable(dsspll, true);
0049
0050 r = hdmi_wp_set_pll_pwr(wp, HDMI_PLLPWRCMD_BOTHON_ALLCLKS);
0051 if (r)
0052 return r;
0053
0054 return 0;
0055 }
0056
0057 static void hdmi_pll_disable(struct dss_pll *dsspll)
0058 {
0059 struct hdmi_pll_data *pll = container_of(dsspll, struct hdmi_pll_data, pll);
0060 struct hdmi_wp_data *wp = pll->wp;
0061 int r;
0062
0063 hdmi_wp_set_pll_pwr(wp, HDMI_PLLPWRCMD_ALLOFF);
0064
0065 dss_ctrl_pll_enable(dsspll, false);
0066
0067 r = pm_runtime_put_sync(&pll->pdev->dev);
0068 WARN_ON(r < 0 && r != -ENOSYS);
0069 }
0070
0071 static const struct dss_pll_ops hdmi_pll_ops = {
0072 .enable = hdmi_pll_enable,
0073 .disable = hdmi_pll_disable,
0074 .set_config = dss_pll_write_config_type_b,
0075 };
0076
0077 static const struct dss_pll_hw dss_omap4_hdmi_pll_hw = {
0078 .type = DSS_PLL_TYPE_B,
0079
0080 .n_max = 255,
0081 .m_min = 20,
0082 .m_max = 4095,
0083 .mX_max = 127,
0084 .fint_min = 500000,
0085 .fint_max = 2500000,
0086
0087 .clkdco_min = 500000000,
0088 .clkdco_low = 1000000000,
0089 .clkdco_max = 2000000000,
0090
0091 .n_msb = 8,
0092 .n_lsb = 1,
0093 .m_msb = 20,
0094 .m_lsb = 9,
0095
0096 .mX_msb[0] = 24,
0097 .mX_lsb[0] = 18,
0098
0099 .has_selfreqdco = true,
0100 };
0101
0102 static const struct dss_pll_hw dss_omap5_hdmi_pll_hw = {
0103 .type = DSS_PLL_TYPE_B,
0104
0105 .n_max = 255,
0106 .m_min = 20,
0107 .m_max = 2045,
0108 .mX_max = 127,
0109 .fint_min = 620000,
0110 .fint_max = 2500000,
0111
0112 .clkdco_min = 750000000,
0113 .clkdco_low = 1500000000,
0114 .clkdco_max = 2500000000UL,
0115
0116 .n_msb = 8,
0117 .n_lsb = 1,
0118 .m_msb = 20,
0119 .m_lsb = 9,
0120
0121 .mX_msb[0] = 24,
0122 .mX_lsb[0] = 18,
0123
0124 .has_selfreqdco = true,
0125 .has_refsel = true,
0126 };
0127
0128 static int hdmi_init_pll_data(struct dss_device *dss,
0129 struct platform_device *pdev,
0130 struct hdmi_pll_data *hpll)
0131 {
0132 struct dss_pll *pll = &hpll->pll;
0133 struct clk *clk;
0134 int r;
0135
0136 clk = devm_clk_get(&pdev->dev, "sys_clk");
0137 if (IS_ERR(clk)) {
0138 DSSERR("can't get sys_clk\n");
0139 return PTR_ERR(clk);
0140 }
0141
0142 pll->name = "hdmi";
0143 pll->id = DSS_PLL_HDMI;
0144 pll->base = hpll->base;
0145 pll->clkin = clk;
0146
0147 if (hpll->wp->version == 4)
0148 pll->hw = &dss_omap4_hdmi_pll_hw;
0149 else
0150 pll->hw = &dss_omap5_hdmi_pll_hw;
0151
0152 pll->ops = &hdmi_pll_ops;
0153
0154 r = dss_pll_register(dss, pll);
0155 if (r)
0156 return r;
0157
0158 return 0;
0159 }
0160
0161 int hdmi_pll_init(struct dss_device *dss, struct platform_device *pdev,
0162 struct hdmi_pll_data *pll, struct hdmi_wp_data *wp)
0163 {
0164 int r;
0165
0166 pll->pdev = pdev;
0167 pll->wp = wp;
0168
0169 pll->base = devm_platform_ioremap_resource_byname(pdev, "pll");
0170 if (IS_ERR(pll->base))
0171 return PTR_ERR(pll->base);
0172
0173 r = hdmi_init_pll_data(dss, pdev, pll);
0174 if (r) {
0175 DSSERR("failed to init HDMI PLL\n");
0176 return r;
0177 }
0178
0179 return 0;
0180 }
0181
0182 void hdmi_pll_uninit(struct hdmi_pll_data *hpll)
0183 {
0184 struct dss_pll *pll = &hpll->pll;
0185
0186 dss_pll_unregister(pll);
0187 }