Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

OMAPDSS: HDMI: PLL changes for OMAP5

Add a features struct to differentiate between the HDMI PLLs on OMAP4
and OMAP5. The OMAP5 PLL is more sensitive when it comes to locking. We
need to ensure that the DCO freq isn't too low for lower pixel clocks.

Modify the PLL computation slightly to ensure the HDMI PLL locks for lower
frequencies. This will be later replaced by a more complex computation
which makes sure all the PLL constraints are met.

Signed-off-by: Archit Taneja <archit@ti.com>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>

authored by

Archit Taneja and committed by
Tomi Valkeinen
2d64b1b3 19289fdc

+79 -2
+79 -2
drivers/video/fbdev/omap2/dss/hdmi_pll.c
··· 23 23 #define HDMI_DEFAULT_REGN 16 24 24 #define HDMI_DEFAULT_REGM2 1 25 25 26 + struct hdmi_pll_features { 27 + bool sys_reset; 28 + /* this is a hack, need to replace it with a better computation of M2 */ 29 + bool bound_dcofreq; 30 + unsigned long fint_min, fint_max; 31 + u16 regm_max; 32 + unsigned long dcofreq_low_min, dcofreq_low_max; 33 + unsigned long dcofreq_high_min, dcofreq_high_max; 34 + }; 35 + 36 + static const struct hdmi_pll_features *pll_feat; 37 + 26 38 void hdmi_pll_dump(struct hdmi_pll_data *pll, struct seq_file *s) 27 39 { 28 40 #define DUMPPLL(r) seq_printf(s, "%-35s %08x\n", #r,\ ··· 69 57 70 58 refclk = clkin / pi->regn; 71 59 72 - pi->regm2 = HDMI_DEFAULT_REGM2; 60 + /* temorary hack to make sure DCO freq isn't calculated too low */ 61 + if (pll_feat->bound_dcofreq && phy <= 65000) 62 + pi->regm2 = 3; 63 + else 64 + pi->regm2 = HDMI_DEFAULT_REGM2; 73 65 74 66 /* 75 67 * multiplier is pixel_clk/ref_clk ··· 170 154 static int hdmi_pll_reset(struct hdmi_pll_data *pll) 171 155 { 172 156 /* SYSRESET controlled by power FSM */ 173 - REG_FLD_MOD(pll->base, PLLCTRL_PLL_CONTROL, 0x0, 3, 3); 157 + REG_FLD_MOD(pll->base, PLLCTRL_PLL_CONTROL, pll_feat->sys_reset, 3, 3); 174 158 175 159 /* READ 0x0 reset is in progress */ 176 160 if (hdmi_wait_for_bit_change(pll->base, PLLCTRL_PLL_STATUS, 0, 0, 1) ··· 213 197 #define PLL_OFFSET 0x200 214 198 #define PLL_SIZE 0x100 215 199 200 + static const struct hdmi_pll_features omap44xx_pll_feats = { 201 + .sys_reset = false, 202 + .bound_dcofreq = false, 203 + .fint_min = 500000, 204 + .fint_max = 2500000, 205 + .regm_max = 4095, 206 + .dcofreq_low_min = 500000000, 207 + .dcofreq_low_max = 1000000000, 208 + .dcofreq_high_min = 1000000000, 209 + .dcofreq_high_max = 2000000000, 210 + }; 211 + 212 + static const struct hdmi_pll_features omap54xx_pll_feats = { 213 + .sys_reset = true, 214 + .bound_dcofreq = true, 215 + .fint_min = 620000, 216 + .fint_max = 2500000, 217 + .regm_max = 2046, 218 + .dcofreq_low_min = 750000000, 219 + .dcofreq_low_max = 1500000000, 220 + .dcofreq_high_min = 1250000000, 221 + .dcofreq_high_max = 2500000000UL, 222 + }; 223 + 224 + static int hdmi_pll_init_features(struct platform_device *pdev) 225 + { 226 + struct hdmi_pll_features *dst; 227 + const struct hdmi_pll_features *src; 228 + 229 + dst = devm_kzalloc(&pdev->dev, sizeof(*dst), GFP_KERNEL); 230 + if (!dst) { 231 + dev_err(&pdev->dev, "Failed to allocate HDMI PHY Features\n"); 232 + return -ENOMEM; 233 + } 234 + 235 + switch (omapdss_get_version()) { 236 + case OMAPDSS_VER_OMAP4430_ES1: 237 + case OMAPDSS_VER_OMAP4430_ES2: 238 + case OMAPDSS_VER_OMAP4: 239 + src = &omap44xx_pll_feats; 240 + break; 241 + 242 + case OMAPDSS_VER_OMAP5: 243 + src = &omap54xx_pll_feats; 244 + break; 245 + 246 + default: 247 + return -ENODEV; 248 + } 249 + 250 + memcpy(dst, src, sizeof(*dst)); 251 + pll_feat = dst; 252 + 253 + return 0; 254 + } 255 + 216 256 int hdmi_pll_init(struct platform_device *pdev, struct hdmi_pll_data *pll) 217 257 { 258 + int r; 218 259 struct resource *res; 219 260 struct resource temp_res; 261 + 262 + r = hdmi_pll_init_features(pdev); 263 + if (r) 264 + return r; 220 265 221 266 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pll"); 222 267 if (!res) {