aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video
diff options
context:
space:
mode:
authorTomi Valkeinen <tomi.valkeinen@ti.com>2014-07-04 04:07:15 -0400
committerTomi Valkeinen <tomi.valkeinen@ti.com>2015-02-04 05:32:05 -0500
commitbe40eecf8dea217a3f3b9df5c2d7235e91e25fb0 (patch)
tree8628c8250df6f76c3cba5ba209ed7f85defb133b /drivers/video
parent6d817880cdfd0456ccf5f2b705d7078957ea09cb (diff)
OMAPDSS: Add functions for external control of PLL
Add functions which configure the control module register CTRL_CORE_DSS_PLL_CONTROL found in DRA7xx SoCs. This register configures whether the PLL registers are accessed internally by DSS, or externally using OCP2SCP interface. They also configure muxes which route the PLL output to a particular LCD overlay manager within DSS. Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/fbdev/omap2/dss/dss.c115
-rw-r--r--drivers/video/fbdev/omap2/dss/dss.h4
2 files changed, 119 insertions, 0 deletions
diff --git a/drivers/video/fbdev/omap2/dss/dss.c b/drivers/video/fbdev/omap2/dss/dss.c
index 8c79839fbe87..d75238f2c537 100644
--- a/drivers/video/fbdev/omap2/dss/dss.c
+++ b/drivers/video/fbdev/omap2/dss/dss.c
@@ -34,6 +34,8 @@
34#include <linux/pm_runtime.h> 34#include <linux/pm_runtime.h>
35#include <linux/gfp.h> 35#include <linux/gfp.h>
36#include <linux/sizes.h> 36#include <linux/sizes.h>
37#include <linux/mfd/syscon.h>
38#include <linux/regmap.h>
37#include <linux/of.h> 39#include <linux/of.h>
38 40
39#include <video/omapdss.h> 41#include <video/omapdss.h>
@@ -78,6 +80,8 @@ struct dss_features {
78static struct { 80static struct {
79 struct platform_device *pdev; 81 struct platform_device *pdev;
80 void __iomem *base; 82 void __iomem *base;
83 struct regmap *syscon_pll_ctrl;
84 u32 syscon_pll_ctrl_offset;
81 85
82 struct clk *parent_clk; 86 struct clk *parent_clk;
83 struct clk *dss_clk; 87 struct clk *dss_clk;
@@ -158,6 +162,99 @@ static void dss_restore_context(void)
158#undef SR 162#undef SR
159#undef RR 163#undef RR
160 164
165void dss_ctrl_pll_enable(enum dss_pll_id pll_id, bool enable)
166{
167 unsigned shift;
168 unsigned val;
169
170 if (!dss.syscon_pll_ctrl)
171 return;
172
173 val = !enable;
174
175 switch (pll_id) {
176 case DSS_PLL_VIDEO1:
177 shift = 0;
178 break;
179 case DSS_PLL_VIDEO2:
180 shift = 1;
181 break;
182 case DSS_PLL_HDMI:
183 shift = 2;
184 break;
185 default:
186 DSSERR("illegal DSS PLL ID %d\n", pll_id);
187 return;
188 }
189
190 regmap_update_bits(dss.syscon_pll_ctrl, dss.syscon_pll_ctrl_offset,
191 1 << shift, val << shift);
192}
193
194void dss_ctrl_pll_set_control_mux(enum dss_pll_id pll_id,
195 enum omap_channel channel)
196{
197 unsigned shift, val;
198
199 if (!dss.syscon_pll_ctrl)
200 return;
201
202 switch (channel) {
203 case OMAP_DSS_CHANNEL_LCD:
204 shift = 3;
205
206 switch (pll_id) {
207 case DSS_PLL_VIDEO1:
208 val = 0; break;
209 case DSS_PLL_HDMI:
210 val = 1; break;
211 default:
212 DSSERR("error in PLL mux config for LCD\n");
213 return;
214 }
215
216 break;
217 case OMAP_DSS_CHANNEL_LCD2:
218 shift = 5;
219
220 switch (pll_id) {
221 case DSS_PLL_VIDEO1:
222 val = 0; break;
223 case DSS_PLL_VIDEO2:
224 val = 1; break;
225 case DSS_PLL_HDMI:
226 val = 2; break;
227 default:
228 DSSERR("error in PLL mux config for LCD2\n");
229 return;
230 }
231
232 break;
233 case OMAP_DSS_CHANNEL_LCD3:
234 shift = 7;
235
236 switch (pll_id) {
237 case DSS_PLL_VIDEO1:
238 val = 1; break;
239 case DSS_PLL_VIDEO2:
240 val = 0; break;
241 case DSS_PLL_HDMI:
242 val = 2; break;
243 default:
244 DSSERR("error in PLL mux config for LCD3\n");
245 return;
246 }
247
248 break;
249 default:
250 DSSERR("error in PLL mux config\n");
251 return;
252 }
253
254 regmap_update_bits(dss.syscon_pll_ctrl, dss.syscon_pll_ctrl_offset,
255 0x3 << shift, val << shift);
256}
257
161void dss_sdi_init(int datapairs) 258void dss_sdi_init(int datapairs)
162{ 259{
163 u32 l; 260 u32 l;
@@ -923,6 +1020,7 @@ static void __exit dss_uninit_ports(struct platform_device *pdev)
923static int __init omap_dsshw_probe(struct platform_device *pdev) 1020static int __init omap_dsshw_probe(struct platform_device *pdev)
924{ 1021{
925 struct resource *dss_mem; 1022 struct resource *dss_mem;
1023 struct device_node *np = pdev->dev.of_node;
926 u32 rev; 1024 u32 rev;
927 int r; 1025 int r;
928 1026
@@ -979,6 +1077,23 @@ static int __init omap_dsshw_probe(struct platform_device *pdev)
979 1077
980 dss_init_ports(pdev); 1078 dss_init_ports(pdev);
981 1079
1080 if (np && of_property_read_bool(np, "syscon-pll-ctrl")) {
1081 dss.syscon_pll_ctrl = syscon_regmap_lookup_by_phandle(np,
1082 "syscon-pll-ctrl");
1083 if (IS_ERR(dss.syscon_pll_ctrl)) {
1084 dev_err(&pdev->dev,
1085 "failed to get syscon-pll-ctrl regmap\n");
1086 return PTR_ERR(dss.syscon_pll_ctrl);
1087 }
1088
1089 if (of_property_read_u32_index(np, "syscon-pll-ctrl", 1,
1090 &dss.syscon_pll_ctrl_offset)) {
1091 dev_err(&pdev->dev,
1092 "failed to get syscon-pll-ctrl offset\n");
1093 return -EINVAL;
1094 }
1095 }
1096
982 rev = dss_read_reg(DSS_REVISION); 1097 rev = dss_read_reg(DSS_REVISION);
983 printk(KERN_INFO "OMAP DSS rev %d.%d\n", 1098 printk(KERN_INFO "OMAP DSS rev %d.%d\n",
984 FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0)); 1099 FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0));
diff --git a/drivers/video/fbdev/omap2/dss/dss.h b/drivers/video/fbdev/omap2/dss/dss.h
index 4bca36a591ca..76a6eb1da090 100644
--- a/drivers/video/fbdev/omap2/dss/dss.h
+++ b/drivers/video/fbdev/omap2/dss/dss.h
@@ -274,6 +274,10 @@ u32 dss_of_port_get_port_number(struct device_node *port);
274void dss_debug_dump_clocks(struct seq_file *s); 274void dss_debug_dump_clocks(struct seq_file *s);
275#endif 275#endif
276 276
277void dss_ctrl_pll_enable(enum dss_pll_id pll_id, bool enable);
278void dss_ctrl_pll_set_control_mux(enum dss_pll_id pll_id,
279 enum omap_channel channel);
280
277void dss_sdi_init(int datapairs); 281void dss_sdi_init(int datapairs);
278int dss_sdi_enable(void); 282int dss_sdi_enable(void);
279void dss_sdi_disable(void); 283void dss_sdi_disable(void);