video: tegra: dc: Update t12x pll selection
[linux-3.10.git] / drivers / video / tegra / dc / sor.c
1 /*
2  * drivers/video/tegra/dc/sor.c
3  *
4  * Copyright (c) 2011, NVIDIA Corporation.
5  *
6  * This software is licensed under the terms of the GNU General Public
7  * License version 2, as published by the Free Software Foundation, and
8  * may be copied, distributed, and modified under those terms.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  */
16
17 #include <linux/clk.h>
18 #include <linux/err.h>
19 #include <linux/nvhost.h>
20 #include <linux/kernel.h>
21 #include <linux/fb.h>
22 #include <linux/delay.h>
23
24 #include <mach/clk.h>
25 #include <mach/dc.h>
26
27 #include "sor.h"
28 #include "sor_regs.h"
29 #include "dc_priv.h"
30
31
32 struct tegra_dc_sor_data *tegra_dc_sor_init(struct tegra_dc *dc,
33         const struct tegra_dc_dp_link_config *cfg)
34 {
35         struct tegra_dc_sor_data        *sor;
36         struct resource                 *res;
37         struct resource                 *base_res;
38         void __iomem                    *base;
39         struct clk                      *clk;
40         int                              err;
41
42         sor = kzalloc(sizeof(*sor), GFP_KERNEL);
43         if (!sor) {
44                 err = -ENOMEM;
45                 goto err_allocate;
46         }
47
48         res = nvhost_get_resource_byname(dc->ndev, IORESOURCE_MEM, "sor");
49         if (!res) {
50                 dev_err(&dc->ndev->dev, "sor: no mem resource\n");
51                 err = -ENOENT;
52                 goto err_free_sor;
53         }
54
55         base_res = request_mem_region(res->start, resource_size(res),
56                 dc->ndev->name);
57         if (!base_res) {
58                 dev_err(&dc->ndev->dev, "sor: request_mem_region failed\n");
59                 err = -EBUSY;
60                 goto err_free_sor;
61         }
62
63         base = ioremap(res->start, resource_size(res));
64         if (!base) {
65                 dev_err(&dc->ndev->dev, "sor: registers can't be mapped\n");
66                 err = -ENOENT;
67                 goto err_release_resource_reg;
68         }
69
70         clk = clk_get_sys("had2codec", "dpaux");
71         if (IS_ERR_OR_NULL(clk)) {
72                 dev_err(&dc->ndev->dev, "sor: can't get clock\n");
73                 err = -ENOENT;
74                 goto err_iounmap_reg;
75         }
76
77         sor->dc       = dc;
78         sor->base     = base;
79         sor->base_res = base_res;
80         sor->sor_clk  = clk;
81         sor->link_cfg = cfg;
82
83         return sor;
84
85
86 err_iounmap_reg:
87         iounmap(base);
88 err_release_resource_reg:
89         release_resource(base_res);
90 err_free_sor:
91         kfree(sor);
92 err_allocate:
93         return ERR_PTR(err);
94 }
95
96 static inline unsigned long tegra_sor_readl(struct tegra_dc_sor_data *sor,
97         unsigned long reg)
98 {
99         return readl(sor->base + reg * 4);
100 }
101
102 static inline void tegra_sor_writel(struct tegra_dc_sor_data *sor,
103         unsigned long reg, unsigned long val)
104 {
105         writel(val, sor->base + reg * 4);
106 }
107
108
109 static unsigned long tegra_dc_sor_poll_register(struct tegra_dc_sor_data *sor,
110         u32 reg, u32 mask, u32 exp_val, u32 poll_interval_us, u32 timeout_ms)
111 {
112         unsigned long timeout_jf = jiffies + msecs_to_jiffies(timeout_ms);
113         u32 reg_val = 0;
114
115         do {
116                 usleep_range(poll_interval_us, poll_interval_us << 1);
117                 reg_val = tegra_sor_readl(sor, reg);
118         } while (((reg_val & mask) != exp_val) &&
119                 time_after(timeout_jf, jiffies));
120
121         if ((reg_val & mask) == exp_val)
122                 return 0;       /* success */
123         dev_dbg(&sor->dc->ndev->dev,
124                 "sor_poll_register 0x%x: timeout\n", reg);
125         return jiffies - timeout_jf + 1;
126 }
127
128
129 static int tegra_dc_sor_set_power_state(struct tegra_dc_sor_data *sor,
130         int pu_pd)
131 {
132         unsigned long reg_val;
133         unsigned long orig_val;
134
135         if (tegra_dc_sor_poll_register(sor, NV_SOR_SEQ_CTL,
136                         NV_SOR_SEQ_CTL_STATUS_MASK,
137                         NV_SOR_SEQ_CTL_STATUS_STOPPED,
138                         100, TEGRA_SOR_TIMEOUT_MS)) {
139                 dev_err(&sor->dc->ndev->dev,
140                         "dc timeout waiting for SOR_SEQ_CT = STATUS_STOPPED\n");
141                 return -EFAULT;
142         }
143
144         orig_val = tegra_sor_readl(sor, NV_SOR_PWR);
145
146         reg_val = pu_pd ? NV_SOR_PWR_NORMAL_STATE_PU :
147                 NV_SOR_PWR_NORMAL_STATE_PD; /* normal state only */
148
149         if (reg_val == orig_val)
150                 return 0;       /* No update needed */
151
152         reg_val |= NV_SOR_PWR_SETTING_NEW_TRIGGER;
153         tegra_sor_writel(sor, NV_SOR_PWR, reg_val);
154         return 0;
155 }
156
157 void tegra_dc_sor_disable(struct tegra_dc_sor_data *sor)
158 {
159         /* Power down the SOR sequencer */
160         if ((tegra_dc_sor_set_power_state(sor, 0))) {
161                 dev_err(&sor->dc->ndev->dev,
162                         "Failed to power down SOR sequencer\n");
163                 return;
164         }
165
166         /* Power down DP lanes */
167         if (tegra_dc_sor_powerdown_dplanes(sor, 0)) {
168                 dev_err(&sor->dc->ndev->dev,
169                         "Failed to power down dp lanes\n");
170                 return;
171         }
172
173         clk_disable(sor->clk);
174 }
175 EXPORT_SYMBOL(tegra_dc_sor_disable);
176
177 void tegra_dc_sor_destroy(struct tegra_dc_sor_data *sor)
178 {
179         clk_put(sor->sor_clk);
180         iounmap(sor->base);
181         release_resource(sor->base_res);
182         kfree(sor);
183 }
184 EXPORT_SYMBOL(tegra_dc_sor_destroy);
185
186 void tegra_dc_sor_set_dp_linkctl(struct tegra_dc_sor_data *sor, bool ena,
187         u8 training_pattern, const struct tegra_dc_dp_link_config *cfg,
188         bool use_scramble)
189 {
190         unsigned long reg_val;
191
192         reg_val = tegra_sor_readl(sor, NV_SOR_DP_LINKCTL(sor->portnum));
193
194         if (ena)
195                 reg_val |= NV_SOR_DP_LINKCTL_ENABLE_YES;
196         else
197                 reg_val &= NV_SOR_DP_LINKCTL_ENABLE_NO;
198
199         reg_val |= (cfg->tu_size << NV_SOR_DP_LINKCTL_TUSIZE_SHIFT);
200
201         /* !!!TODO: fix the scrambler enabling */
202         if (use_scramble)
203                 reg_val |= cfg->scramble_ena <<
204                         NV_SOR_DP_LINKCTL_SCRAMBLEREN_SHIFT;
205
206         if (cfg->enhanced_framing)
207                 reg_val |= NV_SOR_DP_LINKCTL_ENHANCEDFRAME_ENABLE;
208         reg_val |= (training_pattern <<
209                 NV_SOR_DP_LINKCTL_TRAININGPTTRN_SHIFT);
210
211         tegra_sor_writel(sor, NV_SOR_DP_LINKCTL(sor->portnum),
212                 reg_val);
213 }
214 EXPORT_SYMBOL(tegra_dc_sor_set_dp_linkctl);
215
216 void tegra_dc_sor_set_dp_lanedata(struct tegra_dc_sor_data *sor,
217         u32 lane, u32 pre_emphasis, u32 drive_current, u32 tx_pu)
218 {
219         unsigned long d_cur;
220         unsigned long p_emp;
221         unsigned long p_ctl;
222
223
224         d_cur = tegra_sor_readl(sor, NV_SOR_DC(sor->portnum));
225         p_emp = tegra_sor_readl(sor, NV_SOR_PR(sor->portnum));
226         p_ctl = tegra_sor_readl(sor, NV_SOR_DP_PADCTL(sor->portnum));
227
228         switch (lane) {
229         case 0:
230                 p_emp &= ~NV_SOR_PR_LANE2_DP_LANE0_MASK;
231                 p_emp |= (pre_emphasis <<
232                         NV_SOR_PR_LANE2_DP_LANE0_SHIFT);
233                 d_cur &= ~NV_SOR_DC_LANE2_DP_LANE0_MASK;
234                 d_cur |= (drive_current <<
235                         NV_SOR_DC_LANE2_DP_LANE0_SHIFT);
236                 break;
237         case 1:
238                 p_emp &= ~NV_SOR_PR_LANE1_DP_LANE1_MASK;
239                 p_emp |= (pre_emphasis <<
240                         NV_SOR_PR_LANE1_DP_LANE1_SHIFT);
241                 d_cur &= ~NV_SOR_DC_LANE1_DP_LANE1_MASK;
242                 d_cur |= (drive_current <<
243                         NV_SOR_DC_LANE1_DP_LANE1_SHIFT);
244                 break;
245         case 2:
246                 p_emp &= ~NV_SOR_PR_LANE0_DP_LANE2_MASK;
247                 p_emp |= (pre_emphasis <<
248                         NV_SOR_PR_LANE0_DP_LANE2_SHIFT);
249                 d_cur &= ~NV_SOR_DC_LANE0_DP_LANE2_MASK;
250                 d_cur |= (drive_current <<
251                         NV_SOR_DC_LANE0_DP_LANE2_SHIFT);
252                 break;
253         case 3:
254                 p_emp &= ~NV_SOR_PR_LANE3_DP_LANE3_MASK;
255                 p_emp |= (pre_emphasis <<
256                         NV_SOR_PR_LANE3_DP_LANE3_SHIFT);
257                 d_cur &= ~NV_SOR_DC_LANE3_DP_LANE3_MASK;
258                 d_cur |= (drive_current <<
259                         NV_SOR_DC_LANE3_DP_LANE3_SHIFT);
260         default:
261                 dev_err(&sor->dc->ndev->dev,
262                         "dp: sor lane count %d is invalid\n", lane);
263         }
264
265         p_ctl &= ~NV_SOR_DP_PADCTL_TX_PU_VALUE_DEFAULT_MASK;
266         p_ctl |= (tx_pu << NV_SOR_DP_PADCTL_TX_PU_VALUE_SHIFT);
267
268         tegra_sor_writel(sor, NV_SOR_DP_LINKCTL(sor->portnum), d_cur);
269         tegra_sor_writel(sor, NV_SOR_PR(sor->portnum),
270                 p_emp);
271         tegra_sor_writel(sor, NV_SOR_DP_PADCTL(sor->portnum),
272                 p_ctl);
273 }
274 EXPORT_SYMBOL(tegra_dc_sor_set_dp_lanedata);
275
276
277 int tegra_dc_sor_powerdown_dplanes(struct tegra_dc_sor_data *sor,
278         u32 lane_count)
279 {
280         unsigned long reg_val;
281
282         reg_val = tegra_sor_readl(sor, NV_SOR_DP_PADCTL(sor->portnum));
283
284         if (lane_count < 4)
285                 reg_val &= (NV_SOR_DP_PADCTL_PD_TXD_3_YES |
286                         NV_SOR_DP_PADCTL_PD_TXD_2_YES);
287         if (lane_count < 2)
288                 reg_val &= NV_SOR_DP_PADCTL_PD_TXD_1_YES;
289         if (lane_count < 1)
290                 reg_val &= NV_SOR_DP_PADCTL_PD_TXD_0_YES;
291         tegra_sor_writel(sor, NV_SOR_DP_PADCTL(sor->portnum), reg_val);
292
293         /* SOR lane sequencer */
294         reg_val = tegra_sor_readl(sor, NV_SOR_LANE_SEQ_CTL);
295
296         reg_val |= NV_SOR_LANE_SEQ_CTL_SETTING_NEW_TRIGGER;
297         tegra_sor_writel(sor, NV_SOR_LANE_SEQ_CTL, reg_val);
298
299         if (tegra_dc_sor_poll_register(sor, NV_SOR_LANE_SEQ_CTL,
300                         NV_SOR_LANE_SEQ_CTL_SETTING_MASK, 0,
301                         100, TEGRA_SOR_TIMEOUT_MS)) {
302                 dev_dbg(&sor->dc->ndev->dev,
303                         "dp: timeout while waiting for SOR lane sequencer "
304                         "to power down langes\n");
305                 return -EFAULT;
306         }
307         return 0;
308 }
309 EXPORT_SYMBOL(tegra_dc_sor_powerdown_dplanes);
310
311
312 void tegra_dc_sor_set_panel_power(struct tegra_dc_sor_data *sor,
313         bool power_up)
314 {
315         unsigned long reg_val;
316
317         /* !!TODO: need to enable panel power through GPIO operations */
318         /* Check bug 790854 for HW progress */
319
320         reg_val = tegra_sor_readl(sor, NV_SOR_DP_PADCTL(sor->portnum));
321
322         if (power_up)
323                 reg_val |= NV_SOR_DP_PADCTL_PAD_CAL_PD_POWERUP;
324         else
325                 reg_val &= ~NV_SOR_DP_PADCTL_PAD_CAL_PD_POWERUP;
326
327         tegra_sor_writel(sor, NV_SOR_DP_PADCTL(sor->portnum), reg_val);
328 }
329 EXPORT_SYMBOL(tegra_dc_sor_set_panel_power);
330
331
332 void tegra_dc_sor_config_pwm(struct tegra_dc_sor_data *sor, u32 pwm_div,
333         u32 pwm_dutycycle, u32 pwm_clksrc)
334 {
335         unsigned long reg_val;
336
337         tegra_sor_writel(sor, NV_SOR_PWM_DIV, pwm_div);
338
339         reg_val = pwm_dutycycle & NV_SOR_PWM_CTL_DUTY_CYCLE_MASK;
340         reg_val |= (pwm_clksrc << NV_SOR_PWM_CTL_DUTY_CYCLE_SHIFT);
341         reg_val |= NV_SOR_PWM_CTL_SETTING_NEW_TRIGGER;
342         tegra_sor_writel(sor, NV_SOR_PWM_CTL, reg_val);
343
344         if (tegra_dc_sor_poll_register(sor, NV_SOR_PWM_CTL,
345                         NV_SOR_PWM_CTL_SETTING_NEW_SHIFT,
346                         NV_SOR_PWM_CTL_SETTING_NEW_DONE,
347                         100, TEGRA_SOR_TIMEOUT_MS)) {
348                 dev_dbg(&sor->dc->ndev->dev,
349                         "dp: timeout while waiting for SOR PWM setting\n");
350         }
351 }
352 EXPORT_SYMBOL(tegra_dc_sor_config_pwm);
353
354 static void tegra_dc_sor_set_dp_mode(struct tegra_dc_sor_data *sor,
355         const struct tegra_dc_dp_link_config *cfg)
356 {
357         unsigned long reg_val;
358
359         reg_val = NV_SOR_CLK_CNTRL_DP_CLK_SEL_DIFF_DPCLK;
360         reg_val |= (cfg->link_bw << NV_SOR_CLK_CNTRL_DP_LINK_SPEED_SHIFT);
361         tegra_sor_writel(sor, NV_SOR_CLK_CNTRL, reg_val);
362
363         /* TODO: SOR_NV_PDISP_SOR_REFCL */
364         /* tegra_dc_sor_set_dp_linkctl(sor, true,
365            trainingPattern_Disabled, true); */
366         reg_val = tegra_sor_readl(sor,
367                 NV_SOR_DP_CONFIG(sor->portnum));
368         reg_val &= NV_SOR_DP_CONFIG_WATERMARK_MASK;
369         reg_val |= cfg->watermark;
370         reg_val &= NV_SOR_DP_CONFIG_ACTIVESYM_COUNT_MASK;
371         reg_val |= (cfg->active_count <<
372                 NV_SOR_DP_CONFIG_ACTIVESYM_COUNT_SHIFT);
373         reg_val &= NV_SOR_DP_CONFIG_ACTIVESYM_FRAC_MASK;
374         reg_val |= (cfg->active_frac <<
375                 NV_SOR_DP_CONFIG_ACTIVESYM_FRAC_SHIFT);
376         if (cfg->activepolarity)
377                 reg_val |= NV_SOR_DP_CONFIG_ACTIVESYM_POLARITY_POSITIVE;
378         else
379                 reg_val &= ~NV_SOR_DP_CONFIG_ACTIVESYM_POLARITY_POSITIVE;
380         reg_val |= NV_SOR_DP_CONFIG_ACTIVESYM_CNTL_ENABLE;
381
382         tegra_sor_writel(sor, NV_SOR_DP_CONFIG(sor->portnum),
383                 reg_val);
384
385         /* program h/vblank sym */
386         reg_val = tegra_sor_readl(sor,
387                 NV_SOR_DP_LINKCTL(sor->portnum));
388
389         reg_val = cfg->hblank_sym & NV_SOR_DP_AUDIO_HBLANK_SYMBOLS_MASK;
390         tegra_sor_writel(sor, NV_SOR_DP_AUDIO_HBLANK_SYMBOLS,
391                 reg_val);
392
393         reg_val = cfg->vblank_sym & NV_SOR_DP_AUDIO_VBLANK_SYMBOLS_MASK;
394         tegra_sor_writel(sor, NV_SOR_DP_AUDIO_VBLANK_SYMBOLS,
395                 reg_val);
396 }
397
398 void tegra_dc_sor_enable(struct tegra_dc_sor_data *sor)
399 {
400         enable_clk(sor->clk);
401         tegra_dc_sor_set_dp_mode(sor, sor->link_cfg);
402 }
403 EXPORT_SYMBOL(tegra_dc_sor_enable);
404
405
406 int tegra_dc_sor_set_dp_packet(struct tegra_dc_sor_data *sor,
407         u8 *packet)
408 {
409         /* No need to set the infoframe yet as there is no audio or
410            stereo support. This is a placeholder for now */
411         return 0;
412 }
413
414
415 void tegra_dc_sor_set_internal_panel(struct tegra_dc_sor_data *sor, bool is_int)
416 {
417         unsigned long reg_val;
418
419         reg_val = tegra_sor_readl(sor, NV_SOR_DP_SPARE(sor->portnum));
420         if (is_int)
421                 reg_val |= NV_SOR_DP_SPARE_PANEL_INTERNAL;
422         else
423                 reg_val &= ~NV_SOR_DP_SPARE_PANEL_INTERNAL;
424         tegra_sor_writel(sor, NV_SOR_DP_SPARE(sor->portnum), reg_val);
425 }
426 EXPORT_SYMBOL(tegra_dc_sor_set_internal_panel);
427
428 void tegra_dc_sor_read_link_config(struct tegra_dc_sor_data *sor, u8 *link_bw,
429                                    u8 *lane_count)
430 {
431         unsigned long reg_val;
432
433         reg_val = tegra_sor_readl(sor, NV_SOR_CLK_CNTRL);
434         *link_bw = (reg_val & NV_SOR_CLK_CNTRL_DP_LINK_SPEED_MASK)
435                 >> NV_SOR_CLK_CNTRL_DP_LINK_SPEED_SHIFT;
436         reg_val = tegra_sor_readl(sor,
437                 NV_SOR_DP_LINKCTL(sor->portnum));
438
439         switch (reg_val & NV_SOR_DP_LINKCTL_LANECOUNT_MASK) {
440         case NV_SOR_DP_LINKCTL_LANECOUNT_ZERO:
441                 *lane_count = 0;
442                 break;
443         case NV_SOR_DP_LINKCTL_LANECOUNT_ONE:
444                 *lane_count = 1;
445                 break;
446         case NV_SOR_DP_LINKCTL_LANECOUNT_TWO:
447                 *lane_count = 2;
448                 break;
449         case NV_SOR_DP_LINKCTL_LANECOUNT_FOUR:
450                 *lane_count = 4;
451                 break;
452         default:
453                 dev_err(&sor->dc->ndev->dev, "Unknown lane count\n");
454         }
455 }
456 EXPORT_SYMBOL(tegra_dc_sor_read_link_config);
457
458 void tegra_dc_sor_set_link_bandwidth(struct tegra_dc_sor_data *sor, u8 link_bw)
459 {
460         unsigned long reg_val;
461
462         /* FIXME!!! make sure the clk (single/diff dpclk) is programmed */
463         reg_val = tegra_sor_readl(sor, NV_SOR_CLK_CNTRL);
464         reg_val &= ~NV_SOR_CLK_CNTRL_DP_LINK_SPEED_MASK;
465         reg_val |= link_bw << NV_SOR_CLK_CNTRL_DP_LINK_SPEED_SHIFT;
466         tegra_sor_writel(sor, NV_SOR_CLK_CNTRL, reg_val);
467 }
468 EXPORT_SYMBOL(tegra_dc_sor_set_link_bandwidth);
469
470 void tegra_dc_sor_set_lane_count(struct tegra_dc_sor_data *sor, u8 lane_count)
471 {
472         unsigned long reg_val;
473
474         reg_val = tegra_sor_readl(sor, NV_SOR_DP_LINKCTL(sor->portnum));
475         reg_val &= ~NV_SOR_DP_LINKCTL_LANECOUNT_MASK;
476         switch (lane_count) {
477         case 0:
478                 break;
479         case 1:
480                 reg_val |= NV_SOR_DP_LINKCTL_LANECOUNT_ONE;
481                 break;
482         case 2:
483                 reg_val |= NV_SOR_DP_LINKCTL_LANECOUNT_TWO;
484                 break;
485         case 4:
486                 reg_val |= NV_SOR_DP_LINKCTL_LANECOUNT_FOUR;
487                 break;
488         default:
489                 /* 0 should be handled earlier. */
490                 dev_err(&sor->dc->ndev->dev, "dp: Invalid lane count %d\n",
491                         lane_count);
492                 return;
493         }
494         reg_val |= (lane_count << NV_SOR_DP_LINKCTL_LANECOUNT_SHIFT);
495         tegra_sor_writel(sor, NV_SOR_DP_LINKCTL(sor->portnum),
496                 reg_val);
497 }
498 EXPORT_SYMBOL(tegra_dc_sor_set_lane_count);