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

Configure Feed

Select the types of activity you want to include in your feed.

at v4.10 208 lines 4.1 kB view raw
1/* 2 * HDMI PLL 3 * 4 * Copyright (C) 2013 Texas Instruments Incorporated 5 * 6 * This program is free software; you can redistribute it and/or modify it 7 * under the terms of the GNU General Public License version 2 as published by 8 * the Free Software Foundation. 9 */ 10 11#define DSS_SUBSYS_NAME "HDMIPLL" 12 13#include <linux/kernel.h> 14#include <linux/module.h> 15#include <linux/err.h> 16#include <linux/io.h> 17#include <linux/platform_device.h> 18#include <linux/clk.h> 19#include <linux/seq_file.h> 20#include <linux/pm_runtime.h> 21 22#include "omapdss.h" 23#include "dss.h" 24#include "hdmi.h" 25 26void hdmi_pll_dump(struct hdmi_pll_data *pll, struct seq_file *s) 27{ 28#define DUMPPLL(r) seq_printf(s, "%-35s %08x\n", #r,\ 29 hdmi_read_reg(pll->base, r)) 30 31 DUMPPLL(PLLCTRL_PLL_CONTROL); 32 DUMPPLL(PLLCTRL_PLL_STATUS); 33 DUMPPLL(PLLCTRL_PLL_GO); 34 DUMPPLL(PLLCTRL_CFG1); 35 DUMPPLL(PLLCTRL_CFG2); 36 DUMPPLL(PLLCTRL_CFG3); 37 DUMPPLL(PLLCTRL_SSC_CFG1); 38 DUMPPLL(PLLCTRL_SSC_CFG2); 39 DUMPPLL(PLLCTRL_CFG4); 40} 41 42static int hdmi_pll_enable(struct dss_pll *dsspll) 43{ 44 struct hdmi_pll_data *pll = container_of(dsspll, struct hdmi_pll_data, pll); 45 struct hdmi_wp_data *wp = pll->wp; 46 int r; 47 48 r = pm_runtime_get_sync(&pll->pdev->dev); 49 WARN_ON(r < 0); 50 51 dss_ctrl_pll_enable(DSS_PLL_HDMI, true); 52 53 r = hdmi_wp_set_pll_pwr(wp, HDMI_PLLPWRCMD_BOTHON_ALLCLKS); 54 if (r) 55 return r; 56 57 return 0; 58} 59 60static void hdmi_pll_disable(struct dss_pll *dsspll) 61{ 62 struct hdmi_pll_data *pll = container_of(dsspll, struct hdmi_pll_data, pll); 63 struct hdmi_wp_data *wp = pll->wp; 64 int r; 65 66 hdmi_wp_set_pll_pwr(wp, HDMI_PLLPWRCMD_ALLOFF); 67 68 dss_ctrl_pll_enable(DSS_PLL_HDMI, false); 69 70 r = pm_runtime_put_sync(&pll->pdev->dev); 71 WARN_ON(r < 0 && r != -ENOSYS); 72} 73 74static const struct dss_pll_ops dsi_pll_ops = { 75 .enable = hdmi_pll_enable, 76 .disable = hdmi_pll_disable, 77 .set_config = dss_pll_write_config_type_b, 78}; 79 80static const struct dss_pll_hw dss_omap4_hdmi_pll_hw = { 81 .type = DSS_PLL_TYPE_B, 82 83 .n_max = 255, 84 .m_min = 20, 85 .m_max = 4095, 86 .mX_max = 127, 87 .fint_min = 500000, 88 .fint_max = 2500000, 89 90 .clkdco_min = 500000000, 91 .clkdco_low = 1000000000, 92 .clkdco_max = 2000000000, 93 94 .n_msb = 8, 95 .n_lsb = 1, 96 .m_msb = 20, 97 .m_lsb = 9, 98 99 .mX_msb[0] = 24, 100 .mX_lsb[0] = 18, 101 102 .has_selfreqdco = true, 103}; 104 105static const struct dss_pll_hw dss_omap5_hdmi_pll_hw = { 106 .type = DSS_PLL_TYPE_B, 107 108 .n_max = 255, 109 .m_min = 20, 110 .m_max = 2045, 111 .mX_max = 127, 112 .fint_min = 620000, 113 .fint_max = 2500000, 114 115 .clkdco_min = 750000000, 116 .clkdco_low = 1500000000, 117 .clkdco_max = 2500000000UL, 118 119 .n_msb = 8, 120 .n_lsb = 1, 121 .m_msb = 20, 122 .m_lsb = 9, 123 124 .mX_msb[0] = 24, 125 .mX_lsb[0] = 18, 126 127 .has_selfreqdco = true, 128 .has_refsel = true, 129}; 130 131static int dsi_init_pll_data(struct platform_device *pdev, struct hdmi_pll_data *hpll) 132{ 133 struct dss_pll *pll = &hpll->pll; 134 struct clk *clk; 135 int r; 136 137 clk = devm_clk_get(&pdev->dev, "sys_clk"); 138 if (IS_ERR(clk)) { 139 DSSERR("can't get sys_clk\n"); 140 return PTR_ERR(clk); 141 } 142 143 pll->name = "hdmi"; 144 pll->id = DSS_PLL_HDMI; 145 pll->base = hpll->base; 146 pll->clkin = clk; 147 148 switch (omapdss_get_version()) { 149 case OMAPDSS_VER_OMAP4430_ES1: 150 case OMAPDSS_VER_OMAP4430_ES2: 151 case OMAPDSS_VER_OMAP4: 152 pll->hw = &dss_omap4_hdmi_pll_hw; 153 break; 154 155 case OMAPDSS_VER_OMAP5: 156 case OMAPDSS_VER_DRA7xx: 157 pll->hw = &dss_omap5_hdmi_pll_hw; 158 break; 159 160 default: 161 return -ENODEV; 162 } 163 164 pll->ops = &dsi_pll_ops; 165 166 r = dss_pll_register(pll); 167 if (r) 168 return r; 169 170 return 0; 171} 172 173int hdmi_pll_init(struct platform_device *pdev, struct hdmi_pll_data *pll, 174 struct hdmi_wp_data *wp) 175{ 176 int r; 177 struct resource *res; 178 179 pll->pdev = pdev; 180 pll->wp = wp; 181 182 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pll"); 183 if (!res) { 184 DSSERR("can't get PLL mem resource\n"); 185 return -EINVAL; 186 } 187 188 pll->base = devm_ioremap_resource(&pdev->dev, res); 189 if (IS_ERR(pll->base)) { 190 DSSERR("can't ioremap PLLCTRL\n"); 191 return PTR_ERR(pll->base); 192 } 193 194 r = dsi_init_pll_data(pdev, pll); 195 if (r) { 196 DSSERR("failed to init HDMI PLL\n"); 197 return r; 198 } 199 200 return 0; 201} 202 203void hdmi_pll_uninit(struct hdmi_pll_data *hpll) 204{ 205 struct dss_pll *pll = &hpll->pll; 206 207 dss_pll_unregister(pll); 208}