coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
dp.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 /*
4  * drivers/video/tegra/dc/dp.c
5  */
6 
7 #include <console/console.h>
8 #include <device/device.h>
9 #include <device/i2c_simple.h>
10 #include <edid.h>
11 #include <string.h>
12 #include <delay.h>
13 #include <soc/addressmap.h>
14 #include <soc/clock.h>
15 #include <soc/display.h>
16 #include <soc/nvidia/tegra/i2c.h>
17 #include <soc/nvidia/tegra/dc.h>
18 #include <soc/nvidia/tegra/types.h>
19 #include <soc/nvidia/tegra/pwm.h>
21 #include <soc/sor.h>
22 #include <types.h>
23 
24 #include "chip.h"
25 
26 #define DO_FAST_LINK_TRAINING 0
27 
28 struct tegra_dc dc_data;
29 
30 enum {
33 };
34 
36 
37 static inline u32 tegra_dpaux_readl(struct tegra_dc_dp_data *dp, u32 reg)
38 {
39  void *addr = dp->aux_base + (u32) (reg << 2);
40  u32 reg_val = READL(addr);
41  return reg_val;
42 }
43 
44 static inline void tegra_dpaux_writel(struct tegra_dc_dp_data *dp,
45  u32 reg, u32 val)
46 {
47  void *addr = dp->aux_base + (u32) (reg << 2);
48  WRITEL(val, addr);
49 }
50 
52  u32 reg, u32 mask, u32 exp_val,
53  u32 poll_interval_us,
54  u32 timeout_us)
55 {
56  u32 reg_val = 0;
57  u32 temp = timeout_us;
58 
59  do {
60  udelay(poll_interval_us);
61  reg_val = tegra_dpaux_readl(dp, reg);
62  if (timeout_us > poll_interval_us)
63  timeout_us -= poll_interval_us;
64  else
65  break;
66  } while ((reg_val & mask) != exp_val);
67 
68  if ((reg_val & mask) == exp_val)
69  return 0; /* success */
71  "dpaux_poll_register 0x%x: timeout: "
72  "(reg_val)0x%08x & (mask)0x%08x != (exp_val)0x%08x\n",
73  reg, reg_val, mask, exp_val);
74  return temp;
75 }
76 
77 static inline int tegra_dpaux_wait_transaction(struct tegra_dc_dp_data *dp)
78 {
79  /* According to DP spec, each aux transaction needs to finish
80  within 40ms. */
84  100, DP_AUX_TIMEOUT_MS * 1000) != 0) {
85  printk(BIOS_INFO, "dp: DPAUX transaction timeout\n");
86  return -1;
87  }
88  return 0;
89 }
90 
91 static int tegra_dc_dpaux_write_chunk(struct tegra_dc_dp_data *dp, u32 cmd,
92  u32 addr, u8 *data, u32 *size,
93  u32 *aux_stat)
94 {
95  int i;
96  u32 reg_val;
97  u32 timeout_retries = DP_AUX_TIMEOUT_MAX_TRIES;
98  u32 defer_retries = DP_AUX_DEFER_MAX_TRIES;
99  u32 temp_data;
100 
101  if (*size > DP_AUX_MAX_BYTES)
102  return -1; /* only write one chunk of data */
103 
104  /* Make sure the command is write command */
105  switch (cmd) {
109  break;
110  default:
111  printk(BIOS_ERR, "dp: aux write cmd 0x%x is invalid\n", cmd);
112  return -1;
113  }
114 
116  for (i = 0; i < DP_AUX_MAX_BYTES / 4; ++i) {
117  memcpy(&temp_data, data, 4);
118  tegra_dpaux_writel(dp, DPAUX_DP_AUXDATA_WRITE_W(i), temp_data);
119  data += 4;
120  }
121 
122  reg_val = tegra_dpaux_readl(dp, DPAUX_DP_AUXCTL);
123  reg_val &= ~DPAUX_DP_AUXCTL_CMD_MASK;
124  reg_val |= cmd;
125  reg_val &= ~DPAUX_DP_AUXCTL_CMDLEN_FIELD;
126  reg_val |= ((*size - 1) << DPAUX_DP_AUXCTL_CMDLEN_SHIFT);
127 
128  while ((timeout_retries > 0) && (defer_retries > 0)) {
129  if ((timeout_retries != DP_AUX_TIMEOUT_MAX_TRIES) ||
130  (defer_retries != DP_AUX_DEFER_MAX_TRIES))
131  udelay(1);
132 
134  tegra_dpaux_writel(dp, DPAUX_DP_AUXCTL, reg_val);
135 
137  printk(BIOS_ERR, "dp: aux write transaction timeout\n");
138 
139  *aux_stat = tegra_dpaux_readl(dp, DPAUX_DP_AUXSTAT);
140 
141  if ((*aux_stat & DPAUX_DP_AUXSTAT_TIMEOUT_ERROR_PENDING) ||
142  (*aux_stat & DPAUX_DP_AUXSTAT_RX_ERROR_PENDING) ||
145  if (timeout_retries-- > 0) {
146  printk(BIOS_INFO, "dp: aux write retry (0x%x)"
147  " -- %d\n",
148  *aux_stat, timeout_retries);
149  /* clear the error bits */
151  *aux_stat);
152  continue;
153  } else {
154  printk(BIOS_ERR, "dp: aux write got error"
155  " (0x%x)\n", *aux_stat);
156  return -1;
157  }
158  }
159 
160  if ((*aux_stat & DPAUX_DP_AUXSTAT_REPLYTYPE_I2CDEFER) ||
161  (*aux_stat & DPAUX_DP_AUXSTAT_REPLYTYPE_DEFER)) {
162  if (defer_retries-- > 0) {
163  printk(BIOS_INFO, "dp: aux write defer (0x%x)"
164  " -- %d\n", *aux_stat, defer_retries);
165  /* clear the error bits */
167  *aux_stat);
168  continue;
169  } else {
170  printk(BIOS_ERR, "dp: aux write defer exceeds"
171  " max retries (0x%x)\n", *aux_stat);
172  return -1;
173  }
174  }
175 
176  if ((*aux_stat & DPAUX_DP_AUXSTAT_REPLYTYPE_MASK) ==
178  *size = ((*aux_stat) & DPAUX_DP_AUXSTAT_REPLY_M_MASK);
179  return 0;
180  } else {
181  printk(BIOS_ERR, "dp: aux write failed (0x%x)\n",
182  *aux_stat);
183  return -1;
184  }
185  }
186  /* Should never come to here */
187  return -1;
188 }
189 
190 static int tegra_dc_dpaux_read_chunk(struct tegra_dc_dp_data *dp, u32 cmd,
191  u32 addr, u8 *data, u32 *size,
192  u32 *aux_stat)
193 {
194  u32 reg_val;
195  u32 timeout_retries = DP_AUX_TIMEOUT_MAX_TRIES;
196  u32 defer_retries = DP_AUX_DEFER_MAX_TRIES;
197 
198  if (*size > DP_AUX_MAX_BYTES)
199  return -1; /* only read one chunk */
200 
201  /* Check to make sure the command is read command */
202  switch (cmd) {
207  break;
208  default:
209  printk(BIOS_ERR, "dp: aux read cmd 0x%x is invalid\n", cmd);
210  return -1;
211  }
212 
213  *aux_stat = tegra_dpaux_readl(dp, DPAUX_DP_AUXSTAT);
214  if (!(*aux_stat & DPAUX_DP_AUXSTAT_HPD_STATUS_PLUGGED)) {
215  printk(BIOS_SPEW, "dp: HPD is not detected\n");
216  return -1;
217  }
218 
220 
221  reg_val = tegra_dpaux_readl(dp, DPAUX_DP_AUXCTL);
222  reg_val &= ~DPAUX_DP_AUXCTL_CMD_MASK;
223  reg_val |= cmd;
224  reg_val &= ~DPAUX_DP_AUXCTL_CMDLEN_FIELD;
225  reg_val |= ((*size - 1) << DPAUX_DP_AUXCTL_CMDLEN_SHIFT);
226  while ((timeout_retries > 0) && (defer_retries > 0)) {
227  if ((timeout_retries != DP_AUX_TIMEOUT_MAX_TRIES) ||
228  (defer_retries != DP_AUX_DEFER_MAX_TRIES))
230 
232  tegra_dpaux_writel(dp, DPAUX_DP_AUXCTL, reg_val);
233 
235  printk(BIOS_INFO, "dp: aux read transaction timeout\n");
236 
237  *aux_stat = tegra_dpaux_readl(dp, DPAUX_DP_AUXSTAT);
238 
239  if ((*aux_stat & DPAUX_DP_AUXSTAT_TIMEOUT_ERROR_PENDING) ||
240  (*aux_stat & DPAUX_DP_AUXSTAT_RX_ERROR_PENDING) ||
243  if (timeout_retries-- > 0) {
244  printk(BIOS_INFO, "dp: aux read retry (0x%x)"
245  " -- %d\n", *aux_stat,
246  timeout_retries);
247  /* clear the error bits */
249  *aux_stat);
250  continue; /* retry */
251  } else {
252  printk(BIOS_ERR, "dp: aux read got error"
253  " (0x%x)\n", *aux_stat);
254  return -1;
255  }
256  }
257 
258  if ((*aux_stat & DPAUX_DP_AUXSTAT_REPLYTYPE_I2CDEFER) ||
259  (*aux_stat & DPAUX_DP_AUXSTAT_REPLYTYPE_DEFER)) {
260  if (defer_retries-- > 0) {
261  printk(BIOS_INFO, "dp: aux read defer (0x%x)"
262  " -- %d\n", *aux_stat, defer_retries);
263  /* clear the error bits */
265  *aux_stat);
266  continue;
267  } else {
268  printk(BIOS_INFO, "dp: aux read defer exceeds"
269  " max retries (0x%x)\n", *aux_stat);
270  return -1;
271  }
272  }
273 
274  if ((*aux_stat & DPAUX_DP_AUXSTAT_REPLYTYPE_MASK) ==
276  int i;
277  u32 temp_data[4];
278 
279  for (i = 0; i < DP_AUX_MAX_BYTES / 4; ++i)
280  temp_data[i] = tegra_dpaux_readl(dp,
282 
283  *size = ((*aux_stat) & DPAUX_DP_AUXSTAT_REPLY_M_MASK);
284  memcpy(data, temp_data, *size);
285 
286  return 0;
287  } else {
288  printk(BIOS_ERR, "dp: aux read failed (0x%x\n",
289  *aux_stat);
290  return -1;
291  }
292  }
293  /* Should never come to here */
294  printk(BIOS_ERR, "%s: can't\n", __func__);
295  return -1;
296 }
297 
298 #if DO_FAST_LINK_TRAINING
299 static int tegra_dc_dpaux_read(struct tegra_dc_dp_data *dp, u32 cmd, u32 addr,
300  u8 *data, u32 *size, u32 *aux_stat)
301 {
302  u32 finished = 0;
303  u32 cur_size;
304  int ret = 0;
305 
306  do {
307  cur_size = *size - finished;
308  if (cur_size > DP_AUX_MAX_BYTES)
309  cur_size = DP_AUX_MAX_BYTES;
310 
311  ret = tegra_dc_dpaux_read_chunk(dp, cmd, addr,
312  data, &cur_size, aux_stat);
313  if (ret)
314  break;
315 
316  /* cur_size should be the real size returned */
317  addr += cur_size;
318  data += cur_size;
319  finished += cur_size;
320 
321  } while (*size > finished);
322 
323  *size = finished;
324  return ret;
325 }
326 #endif /* DO_FAST_LINK_TRAINING */
327 
328 static int tegra_dc_dp_dpcd_read(struct tegra_dc_dp_data *dp, u32 cmd,
329  u8 *data_ptr)
330 {
331  u32 size = 1;
332  u32 status = 0;
333  int ret;
334 
336  cmd, data_ptr, &size, &status);
337  if (ret)
339  "dp: Failed to read DPCD data. CMD 0x%x, Status 0x%x\n",
340  cmd, status);
341 
342  return ret;
343 }
344 
345 static int tegra_dc_dp_dpcd_write(struct tegra_dc_dp_data *dp, u32 cmd,
346  u8 data)
347 {
348  u32 size = 1;
349  u32 status = 0;
350  int ret;
351 
353  cmd, &data, &size, &status);
354  if (ret)
356  "dp: Failed to write DPCD data. CMD 0x%x, Status 0x%x\n",
357  cmd, status);
358  return ret;
359 }
360 
361 static int tegra_dc_i2c_aux_read(struct tegra_dc_dp_data *dp, u32 i2c_addr,
362  u8 addr, u8 *data, u32 *size, u32 *aux_stat)
363 {
364  u32 finished = 0;
365  int ret = 0;
366 
367  do {
368  u32 cur_size = MIN(DP_AUX_MAX_BYTES, *size - finished);
369 
370  u32 len = 1;
372  dp, DPAUX_DP_AUXCTL_CMD_MOTWR, i2c_addr,
373  &addr, &len, aux_stat);
374  if (ret) {
375  printk(BIOS_ERR, "%s: error sending address to read.\n",
376  __func__);
377  break;
378  }
379 
381  dp, DPAUX_DP_AUXCTL_CMD_I2CRD, i2c_addr,
382  data, &cur_size, aux_stat);
383  if (ret) {
384  printk(BIOS_ERR, "%s: error reading data.\n", __func__);
385  break;
386  }
387 
388  /* cur_size should be the real size returned */
389  addr += cur_size;
390  data += cur_size;
391  finished += cur_size;
392  } while (*size > finished);
393 
394  *size = finished;
395  return ret;
396 }
397 
399 {
400  /* clear interrupt */
401  tegra_dpaux_writel(dp, DPAUX_INTR_AUX, 0xffffffff);
402  /* do not enable interrupt for now. Enable them when Isr in place */
404 
410 
413 }
414 
416  const struct tegra_dc_dp_link_config *link_cfg)
417 {
418  printk(BIOS_INFO, "DP config: cfg_name "
419  "cfg_value\n");
420  printk(BIOS_INFO, " Lane Count %d\n",
422  printk(BIOS_INFO, " SupportEnhancedFraming %s\n",
423  link_cfg->support_enhanced_framing ? "Y" : "N");
424  printk(BIOS_INFO, " Bandwidth %d\n",
426  printk(BIOS_INFO, " bpp %d\n",
428  printk(BIOS_INFO, " EnhancedFraming %s\n",
429  link_cfg->enhanced_framing ? "Y" : "N");
430  printk(BIOS_INFO, " Scramble_enabled %s\n",
431  link_cfg->scramble_ena ? "Y" : "N");
432  printk(BIOS_INFO, " LinkBW %d\n",
433  link_cfg->link_bw);
434  printk(BIOS_INFO, " lane_count %d\n",
436  printk(BIOS_INFO, " activespolarity %d\n",
438  printk(BIOS_INFO, " active_count %d\n",
440  printk(BIOS_INFO, " tu_size %d\n",
441  link_cfg->tu_size);
442  printk(BIOS_INFO, " active_frac %d\n",
444  printk(BIOS_INFO, " watermark %d\n",
446  printk(BIOS_INFO, " hblank_sym %d\n",
448  printk(BIOS_INFO, " vblank_sym %d\n",
450 }
451 
454 {
455 
456  switch (link_cfg->link_bw) {
460  link_cfg->lane_count /= 2;
461  break;
462  case SOR_LINK_SPEED_G2_7:
464  break;
465  case SOR_LINK_SPEED_G5_4:
466  if (link_cfg->lane_count == 1) {
469  } else
470  link_cfg->lane_count /= 2;
471  break;
472  default:
473  printk(BIOS_ERR, "dp: Error link rate %d\n", link_cfg->link_bw);
474  return DP_LT_FAILED;
475  }
476 
477  return (link_cfg->lane_count > 0) ? DP_LT_SUCCESS : DP_LT_FAILED;
478 }
479 
480 /* Calculate if given cfg can meet the mode request. */
481 /* Return true if mode is possible, false otherwise. */
483  const struct soc_nvidia_tegra210_config *config,
485 {
486  const u32 link_rate = 27 * link_cfg->link_bw * 1000 * 1000;
487  const u64 f = 100000; /* precision factor */
488 
489  u32 num_linkclk_line; /* Number of link clocks per line */
490  u64 ratio_f; /* Ratio of incoming to outgoing data rate */
491 
492  u64 frac_f;
493  u64 activesym_f; /* Activesym per TU */
494  u64 activecount_f;
495  u32 activecount;
496  u32 activepolarity;
497  u64 approx_value_f;
498  u32 activefrac = 0;
499  u64 accumulated_error_f = 0;
500  u32 lowest_neg_activecount = 0;
501  u32 lowest_neg_activepolarity = 0;
502  u32 lowest_neg_tusize = 64;
503  u32 num_symbols_per_line;
504  u64 lowest_neg_activefrac = 0;
505  u64 lowest_neg_error_f = 64 * f;
506  u64 watermark_f;
507 
508  int i;
509  int neg;
510 
511  printk(BIOS_INFO, "dp: %s\n", __func__);
512 
513  if (!link_rate || !link_cfg->lane_count || !config->pixel_clock ||
515  return -1;
516 
517  if ((u64)config->pixel_clock * link_cfg->bits_per_pixel >=
519  return -1;
520 
521  num_linkclk_line = (u32)((u64)link_rate * (u64)config->xres /
522  config->pixel_clock);
523 
524  ratio_f = (u64)config->pixel_clock * link_cfg->bits_per_pixel * f;
525  ratio_f /= 8;
526  ratio_f = (u64)(ratio_f / (link_rate * link_cfg->lane_count));
527 
528  for (i = 64; i >= 32; --i) {
529  activesym_f = ratio_f * i;
530  activecount_f = (u64)(activesym_f / (u32)f) * f;
531  frac_f = activesym_f - activecount_f;
532  activecount = (u32)((u64)(activecount_f / (u32)f));
533 
534  if (frac_f < (f / 2)) /* fraction < 0.5 */
535  activepolarity = 0;
536  else {
537  activepolarity = 1;
538  frac_f = f - frac_f;
539  }
540 
541  if (frac_f != 0) {
542  frac_f = (u64)((f * f) / frac_f); /* 1/fraction */
543  if (frac_f > (15 * f))
544  activefrac = activepolarity ? 1 : 15;
545  else
546  activefrac = activepolarity ?
547  (u32)((u64)(frac_f / (u32)f)) + 1 :
548  (u32)((u64)(frac_f / (u32)f));
549  }
550 
551  if (activefrac == 1)
552  activepolarity = 0;
553 
554  if (activepolarity == 1)
555  approx_value_f = activefrac ? (u64)(
556  (activecount_f + (activefrac * f - f) * f) /
557  (activefrac * f)) :
558  activecount_f + f;
559  else
560  approx_value_f = activefrac ?
561  activecount_f + (u64)(f / activefrac) :
562  activecount_f;
563 
564  if (activesym_f < approx_value_f) {
565  accumulated_error_f = num_linkclk_line *
566  (u64)((approx_value_f - activesym_f) / i);
567  neg = 1;
568  } else {
569  accumulated_error_f = num_linkclk_line *
570  (u64)((activesym_f - approx_value_f) / i);
571  neg = 0;
572  }
573 
574  if ((neg && (lowest_neg_error_f > accumulated_error_f)) ||
575  (accumulated_error_f == 0)) {
576  lowest_neg_error_f = accumulated_error_f;
577  lowest_neg_tusize = i;
578  lowest_neg_activecount = activecount;
579  lowest_neg_activepolarity = activepolarity;
580  lowest_neg_activefrac = activefrac;
581 
582  if (accumulated_error_f == 0)
583  break;
584  }
585  }
586 
587  if (lowest_neg_activefrac == 0) {
589  link_cfg->active_count = lowest_neg_activepolarity ?
590  lowest_neg_activecount : lowest_neg_activecount - 1;
591  link_cfg->tu_size = lowest_neg_tusize;
592  link_cfg->active_frac = 1;
593  } else {
594  link_cfg->activepolarity = lowest_neg_activepolarity;
595  link_cfg->active_count = (u32)lowest_neg_activecount;
596  link_cfg->tu_size = lowest_neg_tusize;
597  link_cfg->active_frac = (u32)lowest_neg_activefrac;
598  }
599 
600  watermark_f = (u64)((ratio_f * link_cfg->tu_size * (f - ratio_f)) / f);
601  link_cfg->watermark = (u32)((u64)((watermark_f + lowest_neg_error_f) /
602  f)) + link_cfg->bits_per_pixel / 4 - 1;
603  num_symbols_per_line = (config->xres * link_cfg->bits_per_pixel) /
604  (8 * link_cfg->lane_count);
605 
606  if (link_cfg->watermark > 30) {
608  "dp: sor setting: unable to get a good tusize, "
609  "force watermark to 30.\n");
610  link_cfg->watermark = 30;
611  return -1;
612  } else if (link_cfg->watermark > num_symbols_per_line) {
614  "dp: sor setting: force watermark to the number "
615  "of symbols in the line.\n");
616  link_cfg->watermark = num_symbols_per_line;
617  return -1;
618  }
619 
620  /* Refer to dev_disp.ref for more information. */
621  /* # symbols/hblank = ((SetRasterBlankEnd.X + SetRasterSize.Width - */
622  /* SetRasterBlankStart.X - 7) * link_clk / pclk) */
623  /* - 3 * enhanced_framing - Y */
624  /* where Y = (# lanes == 4) 3 : (# lanes == 2) ? 6 : 12 */
625  link_cfg->hblank_sym = (int)((u64)(((u64)(config->hback_porch +
626  config->hfront_porch + config->hsync_width - 7) *
627  link_rate) / config->pixel_clock)) -
629  (12 / link_cfg->lane_count);
630 
631  if (link_cfg->hblank_sym < 0)
632  link_cfg->hblank_sym = 0;
633 
634  /* Refer to dev_disp.ref for more information. */
635  /* # symbols/vblank = ((SetRasterBlankStart.X - */
636  /* SetRasterBlankEen.X - 25) * link_clk / pclk) */
637  /* - Y - 1; */
638  /* where Y = (# lanes == 4) 12 : (# lanes == 2) ? 21 : 39 */
639  link_cfg->vblank_sym = (int)((u64)((u64)(config->xres - 25)
640  * link_rate / config->pixel_clock)) - (36 /
641  link_cfg->lane_count) - 4;
642 
643  if (link_cfg->vblank_sym < 0)
644  link_cfg->vblank_sym = 0;
645 
646  link_cfg->is_valid = 1;
648 
649  return 0;
650 }
651 
654  struct tegra_dc_dp_data *dp,
656 {
657  u8 dpcd_data;
658  int ret;
659 
660  printk(BIOS_INFO, "dp: %s\n", __func__);
661 
663  &dpcd_data));
665  link_cfg->tps3_supported = (dpcd_data &
667 
670  1 : 0;
671 
673  &dpcd_data));
675  ? 1 : 0;
676 
679 
681  &link_cfg->max_link_bw));
682 
683  link_cfg->bits_per_pixel = config->panel_bits_per_pixel;
684 
685  /*
686  * Set to a high value for link training and attach.
687  * Will be re-programmed when dp is enabled.
688  */
689  link_cfg->drive_current = config->dp.drive_current;
690  link_cfg->preemphasis = config->dp.preemphasis;
691  link_cfg->postcursor = config->dp.postcursor;
692 
694  &dpcd_data));
697  1 : 0;
700  1 : 0;
701 
705 
707  return 0;
708 }
709 
710 static int tegra_dc_dp_set_assr(struct tegra_dc_dp_data *dp, int ena)
711 {
712  int ret;
713 
714  u8 dpcd_data = ena ?
717 
719  dpcd_data));
720 
721  /* Also reset the scrambler to 0xfffe */
723  return 0;
724 }
725 
726 static int tegra_dp_set_link_bandwidth(struct tegra_dc_dp_data *dp, u8 link_bw)
727 {
728  tegra_dc_sor_set_link_bandwidth(&dp->sor, link_bw);
729 
730  /* Sink side */
732 }
733 
735  const struct tegra_dc_dp_link_config *link_cfg)
736 {
737  u8 dpcd_data;
738  int ret;
739 
740  /* check if panel support enhanched_framing */
741  dpcd_data = link_cfg->lane_count;
745  dpcd_data));
746 
748 
749  /* Also power down lanes that will not be used */
750  return 0;
751 }
752 
753 #if DO_FAST_LINK_TRAINING
754 static int tegra_dc_dp_link_trained(struct tegra_dc_dp_data *dp,
755  const struct tegra_dc_dp_link_config *link_cfg)
756 {
757  u32 lane;
758  u8 mask;
759  u8 data;
760  int ret;
761 
762  for (lane = 0; lane < link_cfg->lane_count; ++lane) {
763  CHECK_RET(tegra_dc_dp_dpcd_read(dp, (lane/2) ?
765  &data));
766  mask = (lane & 1) ?
773  if ((data & mask) != mask)
774  return -1;
775  }
776  return 0;
777 }
778 #endif /* DO_FAST_LINK_TRAINING */
779 
781 {
782  u32 cnt;
783  u32 n_lanes = dp->link_cfg.lane_count;
784  u8 data;
785  u8 ce_done = 1;
786 
787  for (cnt = 0; cnt < n_lanes / 2; cnt++) {
789  &data);
790 
791  if (n_lanes == 1) {
792  ce_done =
793  (data & (0x1 << NV_DPCD_STATUS_LANEX_CHN_EQ_DONE_SHIFT)) &&
795  break;
796  } else
797  if (!(data & (0x1 << NV_DPCD_STATUS_LANEX_CHN_EQ_DONE_SHIFT)) ||
798  !(data & (0x1 << NV_DPCD_STATUS_LANEX_SYMBOL_LOCKED_SHFIT)) ||
799  !(data & (0x1 << NV_DPCD_STATUS_LANEXPLUS1_CHN_EQ_DONE_SHIFT)) ||
801  return 0;
802  }
803 
804  if (ce_done) {
806  &data);
808  ce_done = 0;
809  }
810 
811  return ce_done;
812 }
813 
815 {
816  u32 cnt;
817  u32 n_lanes = dp->link_cfg.lane_count;
818  u8 data_ptr;
819 
820  for (cnt = 0; cnt < n_lanes / 2; cnt++) {
822  (NV_DPCD_LANE0_1_STATUS + cnt), &data_ptr);
823 
824  if (n_lanes == 1)
825  return (data_ptr & NV_DPCD_STATUS_LANEX_CR_DONE_YES) ? 1 : 0;
826  else if (!(data_ptr & NV_DPCD_STATUS_LANEX_CR_DONE_YES) ||
828  return 0;
829  }
830 
831  return 1;
832 }
833 
834 static void tegra_dp_lt_adjust(struct tegra_dc_dp_data *dp,
835  u32 pe[4], u32 vs[4], u32 pc[4],
836  u8 pc_supported)
837 {
838  size_t cnt;
839  u8 data_ptr;
840  u32 n_lanes = dp->link_cfg.lane_count;
841 
842  for (cnt = 0; cnt < n_lanes / 2; cnt++) {
844  (NV_DPCD_LANE0_1_ADJUST_REQ + cnt), &data_ptr);
845  pe[2 * cnt] = (data_ptr & NV_DPCD_ADJUST_REQ_LANEX_PE_MASK) >>
847  vs[2 * cnt] = (data_ptr & NV_DPCD_ADJUST_REQ_LANEX_DC_MASK) >>
849  pe[1 + 2 * cnt] =
852  vs[1 + 2 * cnt] =
855  }
856  if (pc_supported) {
859  for (cnt = 0; cnt < n_lanes; cnt++) {
860  pc[cnt] = (data_ptr >>
863  }
864  }
865 }
866 
868  u8 is_clk_recovery)
869 {
870  if (!dp->link_cfg.aux_rd_interval)
871  is_clk_recovery ? udelay(200) :
872  udelay(500);
873  else
875 
876  return dp->link_cfg.aux_rd_interval;
877 }
878 
879 static void tegra_dp_tpg(struct tegra_dc_dp_data *dp, u32 tp, u32 n_lanes)
880 {
881  u8 data = (tp == training_pattern_disabled)
884 
885  tegra_dc_sor_set_dp_linkctl(&dp->sor, 1, tp, &dp->link_cfg);
887 }
888 
890  const struct tegra_dc_dp_link_config *link_cfg)
891 {
892  u8 dpcd_data;
893  u32 retry;
894 
895  if (link_cfg->lane_count == 0) {
896  printk(BIOS_ERR, "dp: error: lane count is 0. "
897  "Can not set link config.\n");
898  return DP_LT_FAILED;
899  }
900 
901  /* Set power state if it is not in normal level */
902  if (tegra_dc_dp_dpcd_read(dp, NV_DPCD_SET_POWER, &dpcd_data))
903  return DP_LT_FAILED;
904 
905  if (dpcd_data == NV_DPCD_SET_POWER_VAL_D3_PWRDWN) {
907 
908  /* DP spec requires 3 retries */
909  for (retry = 3; retry > 0; --retry) {
911  dpcd_data))
912  break;
913  if (retry == 1) {
914  printk(BIOS_ERR, "dp: Failed to set DP panel"
915  " power\n");
916  return DP_LT_FAILED;
917  }
918  }
919  }
920 
921  /* Enable ASSR if possible */
923  if (tegra_dc_dp_set_assr(dp, 1))
924  return DP_LT_FAILED;
925 
927  printk(BIOS_ERR, "dp: Failed to set link bandwidth\n");
928  return DP_LT_FAILED;
929  }
931  printk(BIOS_ERR, "dp: Failed to set lane count\n");
932  return DP_LT_FAILED;
933  }
935  link_cfg);
936  return DP_LT_SUCCESS;
937 }
938 
940  struct tegra_dc_dp_link_config *cfg)
941 {
942  struct tegra_dc_dp_link_config tmp_cfg;
943 
944  tmp_cfg = dp->link_cfg;
945  cfg->is_valid = 0;
946 
947  if (_tegra_dp_lower_link_config(dp, cfg))
948  goto fail;
949 
950  if (tegra_dc_dp_calc_config(dp, dp->dc->config, cfg))
951  goto fail;
952  tegra_dp_link_config(dp, cfg);
953 
954  return DP_LT_SUCCESS;
955 fail:
956  dp->link_cfg = tmp_cfg;
957  tegra_dp_link_config(dp, &tmp_cfg);
958  return DP_LT_FAILED;
959 }
960 
961 static void tegra_dp_lt_config(struct tegra_dc_dp_data *dp,
962  u32 pe[4], u32 vs[4], u32 pc[4])
963 {
964  struct tegra_dc_sor_data *sor = &dp->sor;
965  u32 n_lanes = dp->link_cfg.lane_count;
966  u8 pc_supported = dp->link_cfg.tps3_supported;
967  u32 cnt;
968  u32 val;
969 
970  for (cnt = 0; cnt < n_lanes; cnt++) {
971  u32 mask = 0;
972  u32 pe_reg, vs_reg, pc_reg;
973  u32 shift = 0;
974 
975  switch (cnt) {
976  case 0:
979  break;
980  case 1:
983  break;
984  case 2:
987  break;
988  case 3:
991  break;
992  default:
994  "dp: incorrect lane cnt\n");
995  }
996 
997  pe_reg = tegra_dp_pe_regs[pc[cnt]][vs[cnt]][pe[cnt]];
998  vs_reg = tegra_dp_vs_regs[pc[cnt]][vs[cnt]][pe[cnt]];
999  pc_reg = tegra_dp_pc_regs[pc[cnt]][vs[cnt]][pe[cnt]];
1000 
1001  tegra_dp_set_pe_vs_pc(sor, mask, pe_reg << shift,
1002  vs_reg << shift, pc_reg << shift, pc_supported);
1003  }
1004 
1006  udelay(20);
1007 
1008  for (cnt = 0; cnt < n_lanes; cnt++) {
1009  u32 max_vs_flag = tegra_dp_is_max_vs(pe[cnt], vs[cnt]);
1010  u32 max_pe_flag = tegra_dp_is_max_pe(pe[cnt], vs[cnt]);
1011 
1012  val = (vs[cnt] << NV_DPCD_TRAINING_LANEX_SET_DC_SHIFT) |
1013  (max_vs_flag ?
1017  (max_pe_flag ?
1021  (NV_DPCD_TRAINING_LANE0_SET + cnt), val);
1022  }
1023 
1024  if (pc_supported) {
1025  for (cnt = 0; cnt < n_lanes / 2; cnt++) {
1026  u32 max_pc_flag0 = tegra_dp_is_max_pc(pc[cnt]);
1027  u32 max_pc_flag1 = tegra_dp_is_max_pc(pc[cnt + 1]);
1028  val = (pc[cnt] << NV_DPCD_LANEX_SET2_PC2_SHIFT) |
1029  (max_pc_flag0 ?
1032  (pc[cnt + 1] <<
1034  (max_pc_flag1 ?
1039  }
1040  }
1041 }
1042 
1043 static int _tegra_dp_channel_eq(struct tegra_dc_dp_data *dp, u32 pe[4],
1044  u32 vs[4], u32 pc[4], u8 pc_supported,
1045  u32 n_lanes)
1046 {
1047  u32 retry_cnt;
1048 
1049  for (retry_cnt = 0; retry_cnt < 4; retry_cnt++) {
1050  if (retry_cnt) {
1051  tegra_dp_lt_adjust(dp, pe, vs, pc, pc_supported);
1052  tegra_dp_lt_config(dp, pe, vs, pc);
1053  }
1054 
1056 
1057  if (!tegra_dp_clock_recovery_status(dp)) {
1058  printk(BIOS_ERR, "dp: CR failed in channel EQ"
1059  " sequence!\n");
1060  break;
1061  }
1062 
1064  return DP_LT_SUCCESS;
1065  }
1066 
1067  return DP_LT_FAILED;
1068 }
1069 
1071  u32 pe[4], u32 vs[4], u32 pc[4])
1072 {
1073  u32 n_lanes = dp->link_cfg.lane_count;
1074  u8 pc_supported = dp->link_cfg.tps3_supported;
1075  int err;
1076  u32 tp_src = training_pattern_2;
1077 
1078  if (pc_supported)
1079  tp_src = training_pattern_3;
1080 
1081  tegra_dp_tpg(dp, tp_src, n_lanes);
1082 
1083  err = _tegra_dp_channel_eq(dp, pe, vs, pc, pc_supported, n_lanes);
1084 
1086 
1087  return err;
1088 }
1089 
1090 static int _tegra_dp_clk_recovery(struct tegra_dc_dp_data *dp, u32 pe[4],
1091  u32 vs[4], u32 pc[4], u8 pc_supported,
1092  u32 n_lanes)
1093 {
1094  u32 vs_temp[4];
1095  u32 retry_cnt = 0;
1096 
1097  do {
1098  tegra_dp_lt_config(dp, pe, vs, pc);
1100 
1102  return DP_LT_SUCCESS;
1103 
1104  memcpy(vs_temp, vs, sizeof(vs_temp));
1105  tegra_dp_lt_adjust(dp, pe, vs, pc, pc_supported);
1106 
1107  if (memcmp(vs_temp, vs, sizeof(vs_temp)))
1108  retry_cnt = 0;
1109  else
1110  ++retry_cnt;
1111  } while (retry_cnt < 5);
1112 
1113  return DP_LT_FAILED;
1114 }
1115 
1117  u32 pe[4], u32 vs[4], u32 pc[4])
1118 {
1119  u32 n_lanes = dp->link_cfg.lane_count;
1120  u8 pc_supported = dp->link_cfg.tps3_supported;
1121  int err;
1122 
1123  tegra_dp_tpg(dp, training_pattern_1, n_lanes);
1124 
1125  err = _tegra_dp_clk_recovery(dp, pe, vs, pc, pc_supported, n_lanes);
1126  if (err < 0)
1128 
1129  return err;
1130 }
1131 
1133 {
1134  struct tegra_dc_sor_data *sor = &dp->sor;
1135  int err;
1136  u32 pe[4], vs[4], pc[4];
1137 
1138  printk(BIOS_INFO, "dp: %s\n", __func__);
1140 
1141 retry_cr:
1142  memset(pe, preEmphasis_Disabled, sizeof(pe));
1143  memset(vs, driveCurrent_Level0, sizeof(vs));
1144  memset(pc, postCursor2_Level0, sizeof(pc));
1145 
1146  err = tegra_dp_clk_recovery(dp, pe, vs, pc);
1147  if (err != DP_LT_SUCCESS) {
1148  if (!tegra_dp_lower_link_config(dp, &dp->link_cfg))
1149  goto retry_cr;
1150 
1151  printk(BIOS_ERR, "dp: clk recovery failed\n");
1152  goto fail;
1153  }
1154 
1155  err = tegra_dp_channel_eq(dp, pe, vs, pc);
1156  if (err != DP_LT_SUCCESS) {
1157  if (!tegra_dp_lower_link_config(dp, &dp->link_cfg))
1158  goto retry_cr;
1159 
1160  printk(BIOS_ERR,
1161  "dp: channel equalization failed\n");
1162  goto fail;
1163  }
1164 
1166 
1167  return 0;
1168 
1169 fail:
1170  return err;
1171 }
1172 
1173 /*
1174  * All link training functions are ported from kernel dc driver.
1175  * See more details at drivers/video/tegra/dc/dp.c
1176  */
1177 #if DO_FAST_LINK_TRAINING
1178 static int tegra_dc_dp_fast_link_training(struct tegra_dc_dp_data *dp,
1179  const struct tegra_dc_dp_link_config *link_cfg)
1180 {
1181  struct tegra_dc_sor_data *sor = &dp->sor;
1182  u8 link_bw;
1183  u8 lane_count;
1184  u16 data16;
1185  u32 data32;
1186  u32 size;
1187  u32 status;
1188  int j;
1189  u32 mask = 0xffff >> ((4 - link_cfg->lane_count) * 4);
1190 
1191  printk(BIOS_INFO, "dp: %s\n", __func__);
1192 
1196 
1197  /* Send TP1 */
1201 
1202  for (j = 0; j < link_cfg->lane_count; ++j)
1204  0x24);
1205  udelay(520);
1206 
1207  size = sizeof(data16);
1209  NV_DPCD_LANE0_1_STATUS, (u8 *)&data16, &size, &status);
1210  status = mask & 0x1111;
1211  if ((data16 & status) != status) {
1212  printk(BIOS_ERR,
1213  "dp: Link training error for TP1 (%#x)\n", data16);
1214  return -EFAULT;
1215  }
1216 
1217  /* enable ASSR */
1220 
1222  link_cfg->link_bw == 20 ? 0x23 : 0x22);
1223  for (j = 0; j < link_cfg->lane_count; ++j)
1225  0x24);
1226  udelay(520);
1227 
1228  size = sizeof(data32);
1230  NV_DPCD_LANE0_1_STATUS, (u8 *)&data32, &size, &status);
1231  if ((data32 & mask) != (0x7777 & mask)) {
1232  printk(BIOS_ERR,
1233  "dp: Link training error for TP2/3 (0x%x)\n", data32);
1234  return -EFAULT;
1235  }
1236 
1238  link_cfg);
1240 
1242  tegra_dc_sor_read_link_config(&dp->sor, &link_bw,
1243  &lane_count);
1244  printk(BIOS_ERR,
1245  "Fast link trainging failed, link bw %d, lane # %d\n",
1246  link_bw, lane_count);
1247  return -EFAULT;
1248  }
1249 
1250  printk(BIOS_INFO,
1251  "Fast link trainging succeeded, link bw %d, lane %d\n",
1253 
1254  return 0;
1255 }
1256 #endif /* DO_FAST_LINK_TRAINING */
1257 
1259  const struct tegra_dc_dp_link_config *link_cfg)
1260 {
1261  u8 link_bw;
1262  u8 lane_count;
1263 #if DO_FAST_LINK_TRAINING
1264  int ret;
1265 
1266  /* Now do the fast link training for eDP */
1268  if (ret) {
1269  printk(BIOS_ERR, "dp: fast link training failed\n");
1270 
1271  /* Try full link training then */
1273  printk(BIOS_ERR, "dp: full link training failed\n");
1274  return ret;
1275  }
1276  } else {
1277  /* set to a known-good drive setting if fast link succeeded */
1279  }
1280 #else
1282  printk(BIOS_ERR, "dp: full link training failed\n");
1283  return -EFAULT;
1284  }
1285 #endif
1286 
1287  /* Everything goes well, double check the link config */
1288  /* TODO: record edc/c2 data for debugging */
1289  tegra_dc_sor_read_link_config(&dp->sor, &link_bw, &lane_count);
1290 
1291  if ((link_cfg->link_bw == link_bw) &&
1292  (link_cfg->lane_count == lane_count))
1293  return 0;
1294  else
1295  return -EFAULT;
1296 }
1297 
1300  const struct soc_nvidia_tegra210_config *config)
1301 {
1302  struct tegra_dc_dp_link_config temp_cfg;
1303 
1304  if (!config->pixel_clock || !config->xres || !config->yres) {
1305  printk(BIOS_ERR,
1306  "dp: error mode configuration");
1307  return -EINVAL;
1308  }
1309  if (!link_cfg->max_link_bw || !link_cfg->max_lane_count) {
1310  printk(BIOS_ERR,
1311  "dp: error link configuration");
1312  return -EINVAL;
1313  }
1314 
1315  link_cfg->is_valid = 0;
1316 
1317  memcpy(&temp_cfg, link_cfg, sizeof(temp_cfg));
1318 
1319  temp_cfg.link_bw = temp_cfg.max_link_bw;
1320  temp_cfg.lane_count = temp_cfg.max_lane_count;
1321 
1322  /*
1323  * set to max link config
1324  */
1325  if ((!tegra_dc_dp_calc_config(dp, config, &temp_cfg)) &&
1326  (!tegra_dp_link_config(dp, &temp_cfg)) &&
1327  (!tegra_dp_do_link_training(dp, &temp_cfg)))
1328  /* the max link cfg is doable */
1329  memcpy(link_cfg, &temp_cfg, sizeof(temp_cfg));
1330 
1331  return link_cfg->is_valid ? 0 : -EFAULT;
1332 }
1333 
1336 {
1337  struct edid edid;
1338  u8 buf[128] = {0};
1339  u32 size = sizeof(buf), aux_stat = 0;
1340 
1341  printk(BIOS_ERR, "%s: enable r/w dump.\n",
1342  __func__);
1343 
1346  &aux_stat)) {
1347  printk(BIOS_ERR, "%s: Failed to read EDID. Use defaults.\n",
1348  __func__);
1349  return;
1350  }
1351 
1352  if (decode_edid(buf, sizeof(buf), &edid) != EDID_CONFORMANT) {
1353  printk(BIOS_ERR, "%s: Failed to decode EDID. Use defaults.\n",
1354  __func__);
1355  return;
1356  }
1357 
1358  config->xres = config->display_xres = edid.mode.ha;
1359  config->yres = config->display_yres = edid.mode.va;
1360 
1361  config->pixel_clock = edid.mode.pixel_clock * 1000;
1362 
1363  config->hfront_porch = edid.mode.hso;
1364  config->hsync_width = edid.mode.hspw;
1365  config->hback_porch = edid.mode.hbl - edid.mode.hso - edid.mode.hspw;
1366 
1367  config->vfront_porch = edid.mode.vso;
1368  config->vsync_width = edid.mode.vspw;
1369  config->vback_porch = edid.mode.vbl - edid.mode.vso - edid.mode.vspw;
1370 
1371  /**
1372  * Note edid->framebuffer_bits_per_pixel is currently hard-coded as 32,
1373  * so we should keep the default value in device config.
1374  *
1375  * EDID v1.3 panels may not have color depth info, so we need to check
1376  * if these values are zero before updating config.
1377  */
1379  config->panel_bits_per_pixel = edid.panel_bits_per_pixel;
1381  config->color_depth = edid.panel_bits_per_color;
1382  printk(BIOS_SPEW, "%s: configuration updated by EDID.\n", __func__);
1383 }
1384 
1385 void dp_init(void *_config)
1386 {
1387  struct soc_nvidia_tegra210_config *config = (void *)_config;
1388  struct tegra_dc *dc = config->dc_data;
1389  struct tegra_dc_dp_data *dp = &dp_data;
1390 
1391  /* set up links among config, dc, dp and sor */
1392  dp->dc = dc;
1393  dc->out = dp;
1394  dp->sor.dc = dc;
1395 
1396  dp->sor.power_is_up = 0;
1397  dp->sor.base = (void *)TEGRA_ARM_SOR;
1398  dp->sor.pmc_base = (void *)TEGRA_PMC_BASE;
1399  dp->sor.portnum = 0;
1400  dp->sor.link_cfg = &dp->link_cfg;
1401  dp->aux_base = (void *)TEGRA_ARM_DPAUX;
1402  dp->link_cfg.is_valid = 0;
1403  dp->enabled = 0;
1404 
1406 }
1407 
1408 static void tegra_dp_hpd_config(struct tegra_dc_dp_data *dp,
1410 {
1411  u32 val;
1412 
1413  val = config->dp.hpd_plug_min_us |
1414  (config->dp.hpd_unplug_min_us <<
1417 
1418  tegra_dpaux_writel(dp, DPAUX_HPD_IRQ_CONFIG, config->dp.hpd_irq_min_us);
1419 }
1420 
1421 static int tegra_dp_hpd_plug(struct tegra_dc_dp_data *dp, int timeout_ms)
1422 {
1423  u32 val;
1424  u32 timeout = timeout_ms * 1000;
1425  do {
1428  return 0;
1429  udelay(100);
1430  timeout -= 100;
1431  } while (timeout > 0);
1432  return -1;
1433 }
1434 
1436  u32 delay_ms)
1437 {
1438  u8 dpcd_data;
1439  int out_of_sync;
1440 
1441  mdelay(delay_ms);
1442  tegra_dc_dp_dpcd_read(dp, NV_DPCD_SINK_STATUS, &dpcd_data);
1443 
1444  out_of_sync = ((dpcd_data & NV_DPCD_SINK_STATUS_PORT0_IN_SYNC) !=
1446 
1447  if (out_of_sync)
1448  printk(BIOS_ERR,
1449  "SINK receive port 0 is out of synchronization\n");
1450  else
1451  printk(BIOS_INFO,
1452  "SINK is in synchronization\n");
1453 
1454  return out_of_sync;
1455 }
1456 
1459 {
1460 
1461  u8 max_retry = 3;
1462  int delay_frame;
1463 
1464  /* DP TCON may skip some main stream frames, thus we need to wait
1465  some delay before reading the DPCD SINK STATUS register, starting
1466  from 5 */
1467  delay_frame = 5;
1468 
1469  while (tegra_dc_dp_sink_out_of_sync(dp, FRAME_IN_MS * delay_frame) &&
1470  max_retry--) {
1471  tegra_dc_detach(&dp->sor);
1472  if (tegra_dc_dp_explore_link_cfg(dp, &dp->link_cfg, config)) {
1473  printk(BIOS_ERR, "dp: %s: error to configure link\n",
1474  __func__);
1475  continue;
1476  }
1477 
1479  tegra_dc_sor_attach(&dp->sor);
1480 
1481  /* Increase delay_frame for next try in case the sink is
1482  skipping more frames */
1483  delay_frame += 10;
1484  }
1485 }
1486 
1487 void dp_enable(void *_dp)
1488 {
1489  struct tegra_dc_dp_data *dp = _dp;
1490  struct tegra_dc *dc = dp->dc;
1492 
1493  u8 data;
1494  u32 retry;
1495  int ret;
1496 
1498 
1500  if (tegra_dp_hpd_plug(dp, config->dp.vdd_to_hpd_delay_ms) < 0) {
1501  printk(BIOS_ERR, "dp: hpd plug failed\n");
1502  goto error_enable;
1503  }
1504 
1505  if (tegra_dc_dp_init_max_link_cfg(config, dp, &dp->link_cfg)) {
1506  printk(BIOS_ERR, "dp: failed to init link configuration\n");
1507  goto error_enable;
1508  }
1509 
1510  tegra_dc_sor_enable_dp(&dp->sor);
1511 
1512  tegra_dc_sor_set_panel_power(&dp->sor, 1);
1513 
1514  /* Write power on to DPCD */
1516  retry = 0;
1517  do {
1518  ret = tegra_dc_dp_dpcd_write(dp,
1519  NV_DPCD_SET_POWER, data);
1520  } while ((retry++ < DP_POWER_ON_MAX_TRIES) && ret);
1521 
1522  if (ret || retry >= DP_POWER_ON_MAX_TRIES) {
1523  printk(BIOS_ERR,
1524  "dp: failed to power on panel (0x%x)\n", ret);
1525  goto error_enable;
1526  }
1527 
1528  /* Confirm DP is plugging status */
1531  printk(BIOS_ERR, "dp: could not detect HPD\n");
1532  goto error_enable;
1533  }
1534 
1535  /* Check DP version */
1536  if (tegra_dc_dp_dpcd_read(dp, NV_DPCD_REV, &dp->revision))
1537  printk(BIOS_ERR,
1538  "dp: failed to read the revision number from sink\n");
1539 
1540  if (tegra_dc_dp_explore_link_cfg(dp, &dp->link_cfg, config)) {
1541  printk(BIOS_ERR, "dp: error to configure link\n");
1542  goto error_enable;
1543  }
1544 
1545  tegra_dc_sor_set_power_state(&dp->sor, 1);
1546  tegra_dc_sor_attach(&dp->sor);
1547 
1549 
1550  /*
1551  * Power down the unused lanes to save power
1552  * (about hundreds milli-watts, varies from boards).
1553  */
1555 
1556  dp->enabled = 1;
1557 error_enable:
1558  return;
1559 }
1560 
1561 void dp_display_startup(struct device *dev)
1562 {
1564  struct display_controller *disp_ctrl =
1565  (void *)config->display_controller;
1566 
1567  u32 framebuffer_size_mb = config->framebuffer_size / MiB;
1568  u32 framebuffer_base_mb = config->framebuffer_base / MiB;
1569 
1570  struct pwm_controller *pwm = (void *)TEGRA_PWM_BASE;
1571  struct tegra_dc *dc = &dc_data;
1572  u32 plld_rate;
1573 
1574  printk(BIOS_INFO, "%s: entry: disp_ctrl: %p.\n",
1575  __func__, disp_ctrl);
1576 
1577  if (disp_ctrl == NULL) {
1578  printk(BIOS_ERR, "No dc is assigned by dt.\n");
1579  return;
1580  }
1581 
1582  dc->base = (void *)disp_ctrl;
1583  dc->config = config;
1584  config->dc_data = dc;
1585 
1586  /* Note dp_init may read EDID and change some config values. */
1587  dp_init(config);
1588 
1589  if (framebuffer_size_mb == 0) {
1590  framebuffer_size_mb = ALIGN_UP(config->display_xres *
1591  config->display_yres *
1592  (config->framebuffer_bits_per_pixel / 8), MiB)/MiB;
1593  }
1594 
1595  config->framebuffer_size = framebuffer_size_mb * MiB;
1596  config->framebuffer_base = framebuffer_base_mb * MiB;
1597 
1598  /* The plld is programmed with the assumption of the SHIFT_CLK_DIVIDER
1599  * and PIXEL_CLK_DIVIDER are zero (divide by 1). See the
1600  * update_display_mode() for detail.
1601  */
1602  plld_rate = clock_configure_plld(config->pixel_clock * 2);
1603  if (plld_rate == 0) {
1604  printk(BIOS_ERR, "dc: clock init failed\n");
1605  return;
1606  } else if (plld_rate != config->pixel_clock * 2) {
1607  printk(BIOS_WARNING, "dc: plld rounded to %u\n", plld_rate);
1608  config->pixel_clock = plld_rate / 2;
1609  }
1610 
1611  /* set disp1's clock source to PLLD_OUT0 */
1612  clock_configure_source(disp1, PLLD, (plld_rate/KHz)/2);
1613 
1614  /* Init dc */
1615  if (tegra_dc_init(disp_ctrl)) {
1616  printk(BIOS_ERR, "dc: init failed\n");
1617  return;
1618  }
1619 
1620  /* Configure dc mode */
1621  if (update_display_mode(disp_ctrl, config)) {
1622  printk(BIOS_ERR, "dc: failed to configure display mode.\n");
1623  return;
1624  }
1625 
1626  /* Enable dp */
1627  dp_enable(dc->out);
1628 
1629  /* Set up Tegra PWM n (where n is specified in config->dp.pwm) to drive the
1630  * panel backlight.
1631  */
1632  printk(BIOS_SPEW, "%s: enable panel backlight pwm\n", __func__);
1634  (220 << NV_PWM_CSR_PULSE_WIDTH_SHIFT) | /* 220/256 */
1635  0x02e), /* frequency divider */
1636  &pwm->pwm[config->dp.pwm].csr);
1637 
1638  /* Set up window */
1640  printk(BIOS_INFO, "%s: display init done.\n", __func__);
1641 
1642  /* Save panel mode to cb tables */
1644 
1645  /*
1646  * After this point, it is payload's responsibility to allocate
1647  * framebuffer and sets the base address to dc's
1648  * WINBUF_START_ADDR register and enables window by setting dc's
1649  * DISP_DISP_WIN_OPTIONS register.
1650  */
1651 }
void * memcpy(void *dest, const void *src, size_t n)
Definition: memcpy.c:7
void * memset(void *dstpp, int c, size_t len)
Definition: memset.c:12
#define MIN(a, b)
Definition: helpers.h:37
#define retry(attempts, condition,...)
Definition: helpers.h:126
#define MiB
Definition: helpers.h:76
#define KHz
Definition: helpers.h:79
#define ALIGN_UP(x, a)
Definition: helpers.h:17
static u32 addr
Definition: cirrus.c:14
#define printk(level,...)
Definition: stdlib.h:16
void pass_mode_info_to_payload(struct soc_nvidia_tegra210_config *config)
Definition: dc.c:212
unsigned long READL(void *p)
Definition: display.c:24
void WRITEL(unsigned long value, void *p)
Definition: display.c:41
void mdelay(unsigned int msecs)
Definition: delay.c:2
#define DPAUX_DP_AUXSTAT_REPLYTYPE_MASK
Definition: displayport.h:58
#define DPAUX_DP_AUXSTAT_TIMEOUT_ERROR_PENDING
Definition: displayport.h:75
#define NV_DPCD_TRAINING_LANEX_SET_DC_SHIFT
Definition: displayport.h:377
#define NV_DPCD_MAX_LANE_COUNT
Definition: displayport.h:342
#define NV_DPCD_LANE0_1_STATUS
Definition: displayport.h:407
#define DPAUX_DP_AUXSTAT_REPLYTYPE_DEFER
Definition: displayport.h:61
#define NV_DPCD_TRAINING_PATTERN_SET
Definition: displayport.h:365
#define NV_DPCD_SET_POWER_VAL_D3_PWRDWN
Definition: displayport.h:452
#define NV_DPCD_LINK_BANDWIDTH_SET
Definition: displayport.h:361
#define DP_POWER_ON_MAX_TRIES
Definition: displayport.h:124
#define NV_DPCD_ADJUST_REQ_LANEXPLUS1_DC_SHIFT
Definition: displayport.h:438
#define NV_DPCD_LANEX_SET2_PC2_MAX_REACHED_F
Definition: displayport.h:397
#define NV_DPCD_TRAINING_PATTERN_SET_TPS_TP1
Definition: displayport.h:368
#define NV_DPCD_MAIN_LINK_CHANNEL_CODING_SET_ANSI_8B10B
Definition: displayport.h:387
#define DPAUX_DP_AUXSTAT_HPD_STATUS_PLUGGED
Definition: displayport.h:41
#define DPAUX_DP_AUXSTAT_NO_STOP_ERROR_PENDING
Definition: displayport.h:66
#define DPAUX_DP_AUXCTL_TRANSACTREQ_PENDING
Definition: displayport.h:34
#define DPAUX_DP_AUXCTL_CMD_MOTWR
Definition: displayport.h:26
#define DPAUX_DP_AUXCTL_CMD_I2CREQWSTAT
Definition: displayport.h:25
#define DPAUX_INTR_AUX
Definition: displayport.h:14
#define DP_AUX_TIMEOUT_MAX_TRIES
Definition: displayport.h:123
#define NV_DPCD_ADJUST_REQ_LANEX_PE_SHIFT
Definition: displayport.h:436
#define DPAUX_HYBRID_PADCTL_AUX_DRVZ_OHM_50
Definition: displayport.h:100
#define DPAUX_HYBRID_SPARE
Definition: displayport.h:112
static const u32 tegra_dp_vs_regs[][4][4]
Definition: displayport.h:133
#define NV_DPCD_STATUS_LANEX_CHN_EQ_DONE_SHIFT
Definition: displayport.h:412
#define NV_DPCD_MAX_DOWNSPREAD_VAL_0_5_PCT
Definition: displayport.h:352
#define NV_DPCD_EDP_CONFIG_CAP_FRAMING_CHANGE_YES
Definition: displayport.h:359
#define NV_DPCD_STATUS_LANEXPLUS1_SYMBOL_LOCKED_YES
Definition: displayport.h:426
#define DP_AUX_TIMEOUT_MS
Definition: displayport.h:130
#define DPAUX_DP_AUXSTAT_RX_ERROR_PENDING
Definition: displayport.h:72
#define NV_DPCD_TRAINING_LANEX_SET_PE_MAX_REACHED_T
Definition: displayport.h:381
#define NV_DPCD_LANEX_SET2_PC2_SHIFT
Definition: displayport.h:395
#define NV_DPCD_ADJUST_REQ_POST_CURSOR2
Definition: displayport.h:442
#define NV_DPCD_LANE_COUNT_SET
Definition: displayport.h:362
#define DPAUX_HPD_CONFIG_UNPLUG_MIN_TIME_SHIFT
Definition: displayport.h:116
#define DPAUX_HYBRID_PADCTL
Definition: displayport.h:81
#define NV_DPCD_ADJUST_REQ_POST_CURSOR2_LANE_MASK
Definition: displayport.h:443
#define NV_DPCD_STATUS_LANEX_SYMBOL_LOCKED_SHFIT
Definition: displayport.h:415
#define NV_DPCD_ADJUST_REQ_LANEXPLUS1_PE_SHIFT
Definition: displayport.h:440
#define NV_DPCD_ADJUST_REQ_POST_CURSOR2_LANE_SHIFT(i)
Definition: displayport.h:444
#define NV_DPCD_ADJUST_REQ_LANEX_DC_MASK
Definition: displayport.h:435
#define DPAUX_DP_AUXADDR
Definition: displayport.h:17
#define NV_DPCD_STATUS_LANEXPLUS1_CR_DONE_YES
Definition: displayport.h:420
@ preEmphasis_Disabled
Definition: displayport.h:281
static int tegra_dp_is_max_pe(u32 pe, u32 vs)
Definition: displayport.h:300
#define DPAUX_DP_AUXCTL_CMD_MASK
Definition: displayport.h:22
#define DPAUX_DP_AUXSTAT_REPLYTYPE_ACK
Definition: displayport.h:59
#define NV_DPCD_TRAINING_AUX_RD_INTERVAL
Definition: displayport.h:360
#define DPAUX_DP_AUXCTL_CMD_I2CWR
Definition: displayport.h:23
static int tegra_dp_is_max_pc(u32 pc)
Definition: displayport.h:305
#define DP_DPCP_RETRY_SLEEP_NS
Definition: displayport.h:131
#define NV_DPCD_SET_POWER_VAL_D0_NORMAL
Definition: displayport.h:451
static const u32 tegra_dp_pe_regs[][4][4]
Definition: displayport.h:168
static int tegra_dp_is_max_vs(u32 pe, u32 vs)
Definition: displayport.h:295
#define DPAUX_DP_AUXDATA_WRITE_W(i)
Definition: displayport.h:15
#define DPAUX_DP_AUXCTL_CMDLEN_SHIFT
Definition: displayport.h:19
@ postCursor2_Level0
Definition: displayport.h:288
#define NV_DPCD_STATUS_LANEXPLUS1_CHN_EQ_DONE_SHIFT
Definition: displayport.h:421
#define NV_DPCD_LANEXPLUS1_SET2_PC2_MAX_REACHED_F
Definition: displayport.h:400
#define NV_DPCD_SET_POWER
Definition: displayport.h:449
#define NV_DPCD_ADJUST_REQ_LANEXPLUS1_PE_MASK
Definition: displayport.h:441
#define NV_DPCD_STATUS_LANEXPLUS1_CHN_EQ_DONE_YES
Definition: displayport.h:423
#define NV_DPCD_LANE_ALIGN_STATUS_UPDATED_DONE_YES
Definition: displayport.h:429
#define NV_DPCD_REV
Definition: displayport.h:333
#define NV_DPCD_LANE_ALIGN_STATUS_UPDATED
Definition: displayport.h:427
#define NV_DPCD_STATUS_LANEX_SYMBOL_LOCKED_YES
Definition: displayport.h:417
#define DPAUX_DP_AUXCTL_CMDLEN_FIELD
Definition: displayport.h:20
#define DPAUX_INTR_EN_AUX
Definition: displayport.h:13
#define NV_DPCD_TRAINING_LANE0_SET
Definition: displayport.h:373
#define NV_DPCD_MAIN_LINK_CHANNEL_CODING_SET
Definition: displayport.h:386
#define NV_DPCD_STATUS_LANEX_CHN_EQ_DONE_YES
Definition: displayport.h:414
#define DP_AUX_MAX_BYTES
Definition: displayport.h:128
#define NV_DPCD_TRAINING_LANEX_SET_PE_SHIFT
Definition: displayport.h:380
#define DPAUX_DP_AUXSTAT_REPLYTYPE_I2CDEFER
Definition: displayport.h:63
#define DPAUX_DP_AUXSTAT
Definition: displayport.h:38
#define NV_DPCD_LANEX_SET2_PC2_MAX_REACHED_T
Definition: displayport.h:396
#define NV_DPCD_TRAINING_LANE0_1_SET2
Definition: displayport.h:393
#define NV_DPCD_ADJUST_REQ_LANEX_DC_SHIFT
Definition: displayport.h:434
#define DPAUX_DP_AUXCTL_CMD_I2CRD
Definition: displayport.h:24
#define NV_DPCD_EDP_CONFIG_CAP
Definition: displayport.h:355
#define NV_DPCD_ADJUST_REQ_LANEXPLUS1_DC_MASK
Definition: displayport.h:439
static const u32 tegra_dp_pc_regs[][4][4]
Definition: displayport.h:203
#define NV_DPCD_TRAINING_LANEX_SET_DC_MAX_REACHED_T
Definition: displayport.h:378
#define NV_DPCD_EDP_CONFIG_CAP_ASC_RESET_YES
Definition: displayport.h:357
#define DP_AUX_DEFER_MAX_TRIES
Definition: displayport.h:122
#define DPAUX_HPD_CONFIG
Definition: displayport.h:78
#define NV_DPCD_MAX_LANE_COUNT_TPS3_SUPPORTED_YES
Definition: displayport.h:347
#define DPAUX_DP_AUXSTAT_REPLY_M_MASK
Definition: displayport.h:77
#define DPAUX_DP_AUXCTL
Definition: displayport.h:18
#define NV_DPCD_STATUS_LANEX_CR_DONE_YES
Definition: displayport.h:411
#define DPAUX_HYBRID_PADCTL_AUX_INPUT_RCV_ENABLE
Definition: displayport.h:108
#define NV_DPCD_TRAINING_PATTERN_SET_SC_DISABLED_F
Definition: displayport.h:371
#define NV_DPCD_LANE_COUNT_SET_ENHANCEDFRAMING_T
Definition: displayport.h:364
#define DPAUX_DP_AUXCTL_CMD_AUXWR
Definition: displayport.h:29
#define NV_DPCD_MAX_LANE_COUNT_MASK
Definition: displayport.h:343
#define DPAUX_HYBRID_PADCTL_AUX_CMH_V0_70
Definition: displayport.h:92
#define DPAUX_HYBRID_PADCTL_AUX_DRVI_SHIFT
Definition: displayport.h:104
#define NV_DPCD_EDP_CONFIG_SET_ASC_RESET_ENABLE
Definition: displayport.h:390
#define NV_DPCD_MAX_DOWNSPREAD
Definition: displayport.h:350
#define DPAUX_DP_AUXCTL_TRANSACTREQ_MASK
Definition: displayport.h:32
#define NV_DPCD_EDP_CONFIG_SET_ASC_RESET_DISABLE
Definition: displayport.h:389
#define DPAUX_DP_AUXCTL_TRANSACTREQ_DONE
Definition: displayport.h:33
#define NV_DPCD_LANEXPLUS1_SET2_PC2_SHIFT
Definition: displayport.h:398
#define NV_DPCD_ADJUST_REQ_LANEX_PE_MASK
Definition: displayport.h:437
#define NV_DPCD_STATUS_LANEXPLUS1_SYMBOL_LOCKED_SHIFT
Definition: displayport.h:424
#define NV_DPCD_TRAINING_LANEX_SET_DC_MAX_REACHED_F
Definition: displayport.h:379
#define NV_DPCD_TRAINING_LANEX_SET_PE_MAX_REACHED_F
Definition: displayport.h:382
#define NV_DPCD_SINK_STATUS_PORT0_IN_SYNC
Definition: displayport.h:431
#define DPAUX_DP_AUXCTL_CMD_MOTRD
Definition: displayport.h:27
#define DPAUX_DP_AUXSTAT_SINKSTAT_ERROR_PENDING
Definition: displayport.h:69
#define NV_DPCD_MAX_LANE_COUNT_ENHANCED_FRAMING_YES
Definition: displayport.h:349
@ driveCurrent_Level0
Definition: displayport.h:274
#define DPAUX_HYBRID_SPARE_PAD_PWR_POWERUP
Definition: displayport.h:113
#define NV_DPCD_LANE2_3_STATUS
Definition: displayport.h:408
#define NV_DPCD_TRAINING_PATTERN_SET_SC_DISABLED_T
Definition: displayport.h:372
#define NV_DPCD_EDP_CONFIG_SET
Definition: displayport.h:388
#define DPAUX_HPD_IRQ_CONFIG
Definition: displayport.h:79
#define NV_DPCD_SINK_STATUS
Definition: displayport.h:430
#define DPAUX_DP_AUXDATA_READ_W(i)
Definition: displayport.h:16
#define NV_DPCD_LANEXPLUS1_SET2_PC2_MAX_REACHED_T
Definition: displayport.h:399
#define DPAUX_DP_AUXCTL_CMD_AUXRD
Definition: displayport.h:30
#define NV_DPCD_MAX_LINK_BANDWIDTH
Definition: displayport.h:338
#define NV_DPCD_LANE0_1_ADJUST_REQ
Definition: displayport.h:432
link_rate
Definition: dp-core.h:15
#define EINVAL
Definition: errno.h:27
#define EFAULT
Definition: errno.h:19
@ EDID_CONFORMANT
Definition: edid.h:90
int decode_edid(unsigned char *edid, int size, struct edid *out)
Definition: edid.c:1104
#define BIOS_INFO
BIOS_INFO - Expected events.
Definition: loglevel.h:113
#define BIOS_ERR
BIOS_ERR - System in incomplete state.
Definition: loglevel.h:72
#define BIOS_SPEW
BIOS_SPEW - Excessively verbose output.
Definition: loglevel.h:142
#define BIOS_WARNING
BIOS_WARNING - Bad configuration.
Definition: loglevel.h:86
static uint8_t * buf
Definition: uart.c:7
enum board_config config
Definition: memory.c:448
void dp_init(void *_config)
Definition: dp.c:1344
@ DP_LT_SUCCESS
Definition: dp.c:23
@ DP_LT_FAILED
Definition: dp.c:24
static int tegra_dc_dpaux_read(struct tegra_dc_dp_data *dp, u32 cmd, u32 addr, u8 *data, u32 *size, u32 *aux_stat)
Definition: dp.c:288
static int tegra_dc_dp_link_trained(struct tegra_dc_dp_data *dp, const struct tegra_dc_dp_link_config *cfg)
Definition: dp.c:736
struct tegra_dc_dp_data dp_data
Definition: dp.c:27
void dp_enable(void *_dp)
Definition: dp.c:1394
static int tegra_dc_dp_fast_link_training(struct tegra_dc_dp_data *dp, const struct tegra_dc_dp_link_config *link_cfg)
Definition: dp.c:1151
static int tegra_dp_do_link_training(struct tegra_dc_dp_data *dp, const struct tegra_dc_dp_link_config *link_cfg)
Definition: dp.c:1258
static int tegra_dc_dp_explore_link_cfg(struct tegra_dc_dp_data *dp, struct tegra_dc_dp_link_config *link_cfg, const struct soc_nvidia_tegra210_config *config)
Definition: dp.c:1298
static u32 tegra_dpaux_readl(struct tegra_dc_dp_data *dp, u32 reg)
Definition: dp.c:37
static int _tegra_dp_channel_eq(struct tegra_dc_dp_data *dp, u32 pe[4], u32 vs[4], u32 pc[4], u8 pc_supported, u32 n_lanes)
Definition: dp.c:1043
static int tegra_dc_dp_dpcd_read(struct tegra_dc_dp_data *dp, u32 cmd, u8 *data_ptr)
Definition: dp.c:328
static void tegra_dc_dpaux_enable(struct tegra_dc_dp_data *dp)
Definition: dp.c:398
static int tegra_dc_dp_calc_config(struct tegra_dc_dp_data *dp, const struct soc_nvidia_tegra210_config *config, struct tegra_dc_dp_link_config *link_cfg)
Definition: dp.c:482
static int tegra_dp_clk_recovery(struct tegra_dc_dp_data *dp, u32 pe[4], u32 vs[4], u32 pc[4])
Definition: dp.c:1116
static int tegra_dc_dpaux_write_chunk(struct tegra_dc_dp_data *dp, u32 cmd, u32 addr, u8 *data, u32 *size, u32 *aux_stat)
Definition: dp.c:91
static int tegra_dc_dp_dpcd_write(struct tegra_dc_dp_data *dp, u32 cmd, u8 data)
Definition: dp.c:345
static int tegra_dc_i2c_aux_read(struct tegra_dc_dp_data *dp, u32 i2c_addr, u8 addr, u8 *data, u32 *size, u32 *aux_stat)
Definition: dp.c:361
static int tegra_dp_set_lane_count(struct tegra_dc_dp_data *dp, const struct tegra_dc_dp_link_config *link_cfg)
Definition: dp.c:734
static int tegra_dp_channel_eq_status(struct tegra_dc_dp_data *dp)
Definition: dp.c:780
static u32 tegra_dp_wait_aux_training(struct tegra_dc_dp_data *dp, u8 is_clk_recovery)
Definition: dp.c:867
struct tegra_dc dc_data
Definition: dp.c:28
static int tegra_dp_link_config(struct tegra_dc_dp_data *dp, const struct tegra_dc_dp_link_config *link_cfg)
Definition: dp.c:889
static int _tegra_dp_clk_recovery(struct tegra_dc_dp_data *dp, u32 pe[4], u32 vs[4], u32 pc[4], u8 pc_supported, u32 n_lanes)
Definition: dp.c:1090
static int tegra_dc_dp_sink_out_of_sync(struct tegra_dc_dp_data *dp, u32 delay_ms)
Definition: dp.c:1435
static int _tegra_dp_lower_link_config(struct tegra_dc_dp_data *dp, struct tegra_dc_dp_link_config *link_cfg)
Definition: dp.c:452
static int tegra_dp_channel_eq(struct tegra_dc_dp_data *dp, u32 pe[4], u32 vs[4], u32 pc[4])
Definition: dp.c:1070
static int tegra_dp_lower_link_config(struct tegra_dc_dp_data *dp, struct tegra_dc_dp_link_config *cfg)
Definition: dp.c:939
static u8 tegra_dp_clock_recovery_status(struct tegra_dc_dp_data *dp)
Definition: dp.c:814
static int tegra_dc_dp_set_assr(struct tegra_dc_dp_data *dp, int ena)
Definition: dp.c:710
static int tegra_dc_dp_init_max_link_cfg(struct soc_nvidia_tegra210_config *config, struct tegra_dc_dp_data *dp, struct tegra_dc_dp_link_config *link_cfg)
Definition: dp.c:652
static void tegra_dc_dp_dump_link_cfg(struct tegra_dc_dp_data *dp, const struct tegra_dc_dp_link_config *link_cfg)
Definition: dp.c:415
static void tegra_dp_tpg(struct tegra_dc_dp_data *dp, u32 tp, u32 n_lanes)
Definition: dp.c:879
static void tegra_dp_lt_adjust(struct tegra_dc_dp_data *dp, u32 pe[4], u32 vs[4], u32 pc[4], u8 pc_supported)
Definition: dp.c:834
static int tegra_dpaux_wait_transaction(struct tegra_dc_dp_data *dp)
Definition: dp.c:77
static u32 tegra_dc_dpaux_poll_register(struct tegra_dc_dp_data *dp, u32 reg, u32 mask, u32 exp_val, u32 poll_interval_us, u32 timeout_us)
Definition: dp.c:51
static void tegra_dp_lt_config(struct tegra_dc_dp_data *dp, u32 pe[4], u32 vs[4], u32 pc[4])
Definition: dp.c:961
static void tegra_dpaux_writel(struct tegra_dc_dp_data *dp, u32 reg, u32 val)
Definition: dp.c:44
void dp_display_startup(struct device *dev)
Definition: dp.c:1561
static int tegra_dp_hpd_plug(struct tegra_dc_dp_data *dp, int timeout_ms)
Definition: dp.c:1421
static int tegra_dp_set_link_bandwidth(struct tegra_dc_dp_data *dp, u8 link_bw)
Definition: dp.c:726
static void tegra_dc_dp_check_sink(struct tegra_dc_dp_data *dp, struct soc_nvidia_tegra210_config *config)
Definition: dp.c:1457
static void tegra_dp_update_config(struct tegra_dc_dp_data *dp, struct soc_nvidia_tegra210_config *config)
Definition: dp.c:1334
static int tegra_dc_dp_full_link_training(struct tegra_dc_dp_data *dp)
Definition: dp.c:1132
static int tegra_dc_dpaux_read_chunk(struct tegra_dc_dp_data *dp, u32 cmd, u32 addr, u8 *data, u32 *size, u32 *aux_stat)
Definition: dp.c:190
static void tegra_dp_hpd_config(struct tegra_dc_dp_data *dp, struct soc_nvidia_tegra210_config *config)
Definition: dp.c:1408
#define NV_PWM_CSR_PULSE_WIDTH_SHIFT
Definition: pwm.h:10
#define NV_PWM_CSR_ENABLE_SHIFT
Definition: pwm.h:9
static const int mask[4]
Definition: gpio.c:308
static void update_window(struct display_controller *disp_ctrl, struct soc_nvidia_tegra124_config *config)
Definition: display.c:121
static int update_display_mode(struct display_controller *disp_ctrl, struct soc_nvidia_tegra124_config *config)
Definition: display.c:78
static int tegra_dc_init(struct display_controller *disp_ctrl)
Definition: display.c:154
@ TEGRA_PWM_BASE
Definition: addressmap.h:36
@ TEGRA_ARM_DPAUX
Definition: addressmap.h:18
@ TEGRA_PMC_BASE
Definition: addressmap.h:51
@ TEGRA_ARM_SOR
Definition: addressmap.h:17
@ TEGRA_EDID_I2C_ADDRESS
Definition: addressmap.h:64
#define clock_configure_source(device, src, freq)
Definition: clock.h:229
#define PLLD(_n, _m, _p, _kcp, _kvco)
Definition: clock.c:105
u32 clock_configure_plld(u32 frequency)
Definition: clock.c:385
#define FRAME_IN_MS
Definition: display.h:29
#define NULL
Definition: stddef.h:19
uint64_t u64
Definition: stdint.h:54
uint32_t u32
Definition: stdint.h:51
uint16_t u16
Definition: stdint.h:48
uint8_t u8
Definition: stdint.h:45
int memcmp(const void *s1, const void *s2, size_t n)
Definition: memcmp.c:3
Definition: device.h:107
DEVTREE_CONST void * chip_info
Definition: device.h:164
unsigned int hbl
Definition: edid.h:26
unsigned int va
Definition: edid.h:30
unsigned int vspw
Definition: edid.h:33
unsigned int ha
Definition: edid.h:25
unsigned int vso
Definition: edid.h:32
unsigned int hso
Definition: edid.h:27
unsigned int pixel_clock
Definition: edid.h:22
unsigned int hspw
Definition: edid.h:28
unsigned int vbl
Definition: edid.h:31
Definition: edid.h:49
unsigned int panel_bits_per_pixel
Definition: edid.h:70
struct edid_mode mode
Definition: edid.h:72
unsigned int panel_bits_per_color
Definition: edid.h:63
struct soc_nvidia_tegra210_config::@1287 dp
struct tegra_dc_sor_data sor
Definition: displayport.h:322
struct tegra_dc * dc
Definition: displayport.h:321
struct tegra_dc_dp_link_config link_cfg
Definition: displayport.h:324
void * base
Definition: sor.h:881
struct tegra_dc * dc
Definition: sor.h:880
struct tegra_dc_dp_link_config * link_cfg
Definition: sor.h:884
int power_is_up
Definition: sor.h:885
void * pmc_base
Definition: sor.h:882
Definition: dc.h:475
void * base
Definition: dc.h:478
void * config
Definition: dc.h:476
void * out
Definition: dc.h:477
u8 val
Definition: sys.c:300
void tegra_dc_sor_set_lane_count(struct tegra_dc_sor_data *sor, u8 lane_count)
Definition: sor.c:418
void tegra_dc_sor_attach(struct tegra_dc_sor_data *sor)
Definition: sor.c:728
#define NV_SOR_PR_LANE0_DP_LANE2_SHIFT
Definition: sor.h:633
#define NV_SOR_PR_LANE2_DP_LANE0_MASK
Definition: sor.h:610
#define NV_SOR_PR_LANE0_DP_LANE2_MASK
Definition: sor.h:634
#define NV_SOR_PR_LANE2_DP_LANE0_SHIFT
Definition: sor.h:609
#define CHECK_RET(x)
Definition: sor.h:891
#define NV_SOR_PR_LANE1_DP_LANE1_SHIFT
Definition: sor.h:621
void tegra_dc_sor_read_link_config(struct tegra_dc_sor_data *sor, u8 *link_bw, u8 *lane_count)
Definition: sor.c:382
#define NV_SOR_PR_LANE1_DP_LANE1_MASK
Definition: sor.h:622
void tegra_dc_sor_set_dp_linkctl(struct tegra_dc_sor_data *sor, int ena, u8 training_pattern, const struct tegra_dc_dp_link_config *link_cfg)
Definition: sor.c:141
void tegra_dc_sor_set_voltage_swing(struct tegra_dc_sor_data *sor)
Definition: sor.c:818
@ training_pattern_2
Definition: sor.h:825
@ training_pattern_1
Definition: sor.h:824
@ training_pattern_none
Definition: sor.h:827
@ training_pattern_3
Definition: sor.h:826
@ training_pattern_disabled
Definition: sor.h:823
#define SOR_LINK_SPEED_G1_62
Definition: sor.h:835
void tegra_dc_sor_set_internal_panel(struct tegra_dc_sor_data *sor, int is_int)
Definition: sor.c:367
#define SOR_LINK_SPEED_G5_4
Definition: sor.h:837
void tegra_dp_disable_tx_pu(struct tegra_dc_sor_data *sor)
Definition: sor.c:66
void tegra_dc_sor_set_link_bandwidth(struct tegra_dc_sor_data *sor, u8 link_bw)
Definition: sor.c:411
int tegra_dc_sor_set_power_state(struct tegra_dc_sor_data *sor, int pu_pd)
Definition: sor.c:113
void tegra_dc_sor_set_lane_parm(struct tegra_dc_sor_data *sor, const struct tegra_dc_dp_link_config *link_cfg)
Definition: sor.c:789
#define SOR_LINK_SPEED_G2_7
Definition: sor.h:836
void tegra_sor_precharge_lanes(struct tegra_dc_sor_data *sor)
Definition: sor.c:885
#define NV_SOR_PR_LANE3_DP_LANE3_SHIFT
Definition: sor.h:597
void tegra_dc_sor_enable_dp(struct tegra_dc_sor_data *sor)
Definition: sor.c:672
#define NV_SOR_PR_LANE3_DP_LANE3_MASK
Definition: sor.h:598
void tegra_dc_sor_set_panel_power(struct tegra_dc_sor_data *sor, int power_up)
Definition: sor.c:242
void tegra_dc_sor_power_down_unused_lanes(struct tegra_dc_sor_data *sor)
Definition: sor.c:844
void tegra_dp_set_pe_vs_pc(struct tegra_dc_sor_data *sor, u32 mask, u32 pe_reg, u32 vs_reg, u32 pc_reg, u8 pc_supported)
Definition: sor.c:74
void tegra_dc_detach(struct tegra_dc_sor_data *sor)
Definition: sor.c:1039
void udelay(uint32_t us)
Definition: udelay.c:15