4045 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Copyright (C) 2013 NVIDIA Corporation4 */5 6#include <linux/clk.h>7#include <linux/clk-provider.h>8#include <linux/debugfs.h>9#include <linux/io.h>10#include <linux/module.h>11#include <linux/of.h>12#include <linux/platform_device.h>13#include <linux/pm_runtime.h>14#include <linux/regulator/consumer.h>15#include <linux/reset.h>16 17#include <soc/tegra/pmc.h>18 19#include <drm/display/drm_dp_helper.h>20#include <drm/display/drm_scdc_helper.h>21#include <drm/drm_atomic_helper.h>22#include <drm/drm_debugfs.h>23#include <drm/drm_edid.h>24#include <drm/drm_eld.h>25#include <drm/drm_file.h>26#include <drm/drm_panel.h>27#include <drm/drm_simple_kms_helper.h>28 29#include "dc.h"30#include "dp.h"31#include "drm.h"32#include "hda.h"33#include "sor.h"34#include "trace.h"35 36#define SOR_REKEY 0x3837 38struct tegra_sor_hdmi_settings {39 unsigned long frequency;40 41 u8 vcocap;42 u8 filter;43 u8 ichpmp;44 u8 loadadj;45 u8 tmds_termadj;46 u8 tx_pu_value;47 u8 bg_temp_coef;48 u8 bg_vref_level;49 u8 avdd10_level;50 u8 avdd14_level;51 u8 sparepll;52 53 u8 drive_current[4];54 u8 preemphasis[4];55};56 57#if 158static const struct tegra_sor_hdmi_settings tegra210_sor_hdmi_defaults[] = {59 {60 .frequency = 54000000,61 .vcocap = 0x0,62 .filter = 0x0,63 .ichpmp = 0x1,64 .loadadj = 0x3,65 .tmds_termadj = 0x9,66 .tx_pu_value = 0x10,67 .bg_temp_coef = 0x3,68 .bg_vref_level = 0x8,69 .avdd10_level = 0x4,70 .avdd14_level = 0x4,71 .sparepll = 0x0,72 .drive_current = { 0x33, 0x3a, 0x3a, 0x3a },73 .preemphasis = { 0x00, 0x00, 0x00, 0x00 },74 }, {75 .frequency = 75000000,76 .vcocap = 0x3,77 .filter = 0x0,78 .ichpmp = 0x1,79 .loadadj = 0x3,80 .tmds_termadj = 0x9,81 .tx_pu_value = 0x40,82 .bg_temp_coef = 0x3,83 .bg_vref_level = 0x8,84 .avdd10_level = 0x4,85 .avdd14_level = 0x4,86 .sparepll = 0x0,87 .drive_current = { 0x33, 0x3a, 0x3a, 0x3a },88 .preemphasis = { 0x00, 0x00, 0x00, 0x00 },89 }, {90 .frequency = 150000000,91 .vcocap = 0x3,92 .filter = 0x0,93 .ichpmp = 0x1,94 .loadadj = 0x3,95 .tmds_termadj = 0x9,96 .tx_pu_value = 0x66,97 .bg_temp_coef = 0x3,98 .bg_vref_level = 0x8,99 .avdd10_level = 0x4,100 .avdd14_level = 0x4,101 .sparepll = 0x0,102 .drive_current = { 0x33, 0x3a, 0x3a, 0x3a },103 .preemphasis = { 0x00, 0x00, 0x00, 0x00 },104 }, {105 .frequency = 300000000,106 .vcocap = 0x3,107 .filter = 0x0,108 .ichpmp = 0x1,109 .loadadj = 0x3,110 .tmds_termadj = 0x9,111 .tx_pu_value = 0x66,112 .bg_temp_coef = 0x3,113 .bg_vref_level = 0xa,114 .avdd10_level = 0x4,115 .avdd14_level = 0x4,116 .sparepll = 0x0,117 .drive_current = { 0x33, 0x3f, 0x3f, 0x3f },118 .preemphasis = { 0x00, 0x17, 0x17, 0x17 },119 }, {120 .frequency = 600000000,121 .vcocap = 0x3,122 .filter = 0x0,123 .ichpmp = 0x1,124 .loadadj = 0x3,125 .tmds_termadj = 0x9,126 .tx_pu_value = 0x66,127 .bg_temp_coef = 0x3,128 .bg_vref_level = 0x8,129 .avdd10_level = 0x4,130 .avdd14_level = 0x4,131 .sparepll = 0x0,132 .drive_current = { 0x33, 0x3f, 0x3f, 0x3f },133 .preemphasis = { 0x00, 0x00, 0x00, 0x00 },134 },135};136#else137static const struct tegra_sor_hdmi_settings tegra210_sor_hdmi_defaults[] = {138 {139 .frequency = 75000000,140 .vcocap = 0x3,141 .filter = 0x0,142 .ichpmp = 0x1,143 .loadadj = 0x3,144 .tmds_termadj = 0x9,145 .tx_pu_value = 0x40,146 .bg_temp_coef = 0x3,147 .bg_vref_level = 0x8,148 .avdd10_level = 0x4,149 .avdd14_level = 0x4,150 .sparepll = 0x0,151 .drive_current = { 0x29, 0x29, 0x29, 0x29 },152 .preemphasis = { 0x00, 0x00, 0x00, 0x00 },153 }, {154 .frequency = 150000000,155 .vcocap = 0x3,156 .filter = 0x0,157 .ichpmp = 0x1,158 .loadadj = 0x3,159 .tmds_termadj = 0x9,160 .tx_pu_value = 0x66,161 .bg_temp_coef = 0x3,162 .bg_vref_level = 0x8,163 .avdd10_level = 0x4,164 .avdd14_level = 0x4,165 .sparepll = 0x0,166 .drive_current = { 0x30, 0x37, 0x37, 0x37 },167 .preemphasis = { 0x01, 0x02, 0x02, 0x02 },168 }, {169 .frequency = 300000000,170 .vcocap = 0x3,171 .filter = 0x0,172 .ichpmp = 0x6,173 .loadadj = 0x3,174 .tmds_termadj = 0x9,175 .tx_pu_value = 0x66,176 .bg_temp_coef = 0x3,177 .bg_vref_level = 0xf,178 .avdd10_level = 0x4,179 .avdd14_level = 0x4,180 .sparepll = 0x0,181 .drive_current = { 0x30, 0x37, 0x37, 0x37 },182 .preemphasis = { 0x10, 0x3e, 0x3e, 0x3e },183 }, {184 .frequency = 600000000,185 .vcocap = 0x3,186 .filter = 0x0,187 .ichpmp = 0xa,188 .loadadj = 0x3,189 .tmds_termadj = 0xb,190 .tx_pu_value = 0x66,191 .bg_temp_coef = 0x3,192 .bg_vref_level = 0xe,193 .avdd10_level = 0x4,194 .avdd14_level = 0x4,195 .sparepll = 0x0,196 .drive_current = { 0x35, 0x3e, 0x3e, 0x3e },197 .preemphasis = { 0x02, 0x3f, 0x3f, 0x3f },198 },199};200#endif201 202static const struct tegra_sor_hdmi_settings tegra186_sor_hdmi_defaults[] = {203 {204 .frequency = 54000000,205 .vcocap = 0,206 .filter = 5,207 .ichpmp = 5,208 .loadadj = 3,209 .tmds_termadj = 0xf,210 .tx_pu_value = 0,211 .bg_temp_coef = 3,212 .bg_vref_level = 8,213 .avdd10_level = 4,214 .avdd14_level = 4,215 .sparepll = 0x54,216 .drive_current = { 0x3a, 0x3a, 0x3a, 0x33 },217 .preemphasis = { 0x00, 0x00, 0x00, 0x00 },218 }, {219 .frequency = 75000000,220 .vcocap = 1,221 .filter = 5,222 .ichpmp = 5,223 .loadadj = 3,224 .tmds_termadj = 0xf,225 .tx_pu_value = 0,226 .bg_temp_coef = 3,227 .bg_vref_level = 8,228 .avdd10_level = 4,229 .avdd14_level = 4,230 .sparepll = 0x44,231 .drive_current = { 0x3a, 0x3a, 0x3a, 0x33 },232 .preemphasis = { 0x00, 0x00, 0x00, 0x00 },233 }, {234 .frequency = 150000000,235 .vcocap = 3,236 .filter = 5,237 .ichpmp = 5,238 .loadadj = 3,239 .tmds_termadj = 15,240 .tx_pu_value = 0x66 /* 0 */,241 .bg_temp_coef = 3,242 .bg_vref_level = 8,243 .avdd10_level = 4,244 .avdd14_level = 4,245 .sparepll = 0x00, /* 0x34 */246 .drive_current = { 0x3a, 0x3a, 0x3a, 0x37 },247 .preemphasis = { 0x00, 0x00, 0x00, 0x00 },248 }, {249 .frequency = 300000000,250 .vcocap = 3,251 .filter = 5,252 .ichpmp = 5,253 .loadadj = 3,254 .tmds_termadj = 15,255 .tx_pu_value = 64,256 .bg_temp_coef = 3,257 .bg_vref_level = 8,258 .avdd10_level = 4,259 .avdd14_level = 4,260 .sparepll = 0x34,261 .drive_current = { 0x3d, 0x3d, 0x3d, 0x33 },262 .preemphasis = { 0x00, 0x00, 0x00, 0x00 },263 }, {264 .frequency = 600000000,265 .vcocap = 3,266 .filter = 5,267 .ichpmp = 5,268 .loadadj = 3,269 .tmds_termadj = 12,270 .tx_pu_value = 96,271 .bg_temp_coef = 3,272 .bg_vref_level = 8,273 .avdd10_level = 4,274 .avdd14_level = 4,275 .sparepll = 0x34,276 .drive_current = { 0x3d, 0x3d, 0x3d, 0x33 },277 .preemphasis = { 0x00, 0x00, 0x00, 0x00 },278 }279};280 281static const struct tegra_sor_hdmi_settings tegra194_sor_hdmi_defaults[] = {282 {283 .frequency = 54000000,284 .vcocap = 0,285 .filter = 5,286 .ichpmp = 5,287 .loadadj = 3,288 .tmds_termadj = 0xf,289 .tx_pu_value = 0,290 .bg_temp_coef = 3,291 .bg_vref_level = 8,292 .avdd10_level = 4,293 .avdd14_level = 4,294 .sparepll = 0x54,295 .drive_current = { 0x3a, 0x3a, 0x3a, 0x33 },296 .preemphasis = { 0x00, 0x00, 0x00, 0x00 },297 }, {298 .frequency = 75000000,299 .vcocap = 1,300 .filter = 5,301 .ichpmp = 5,302 .loadadj = 3,303 .tmds_termadj = 0xf,304 .tx_pu_value = 0,305 .bg_temp_coef = 3,306 .bg_vref_level = 8,307 .avdd10_level = 4,308 .avdd14_level = 4,309 .sparepll = 0x44,310 .drive_current = { 0x3a, 0x3a, 0x3a, 0x33 },311 .preemphasis = { 0x00, 0x00, 0x00, 0x00 },312 }, {313 .frequency = 150000000,314 .vcocap = 3,315 .filter = 5,316 .ichpmp = 5,317 .loadadj = 3,318 .tmds_termadj = 15,319 .tx_pu_value = 0x66 /* 0 */,320 .bg_temp_coef = 3,321 .bg_vref_level = 8,322 .avdd10_level = 4,323 .avdd14_level = 4,324 .sparepll = 0x00, /* 0x34 */325 .drive_current = { 0x3a, 0x3a, 0x3a, 0x37 },326 .preemphasis = { 0x00, 0x00, 0x00, 0x00 },327 }, {328 .frequency = 300000000,329 .vcocap = 3,330 .filter = 5,331 .ichpmp = 5,332 .loadadj = 3,333 .tmds_termadj = 15,334 .tx_pu_value = 64,335 .bg_temp_coef = 3,336 .bg_vref_level = 8,337 .avdd10_level = 4,338 .avdd14_level = 4,339 .sparepll = 0x34,340 .drive_current = { 0x3d, 0x3d, 0x3d, 0x33 },341 .preemphasis = { 0x00, 0x00, 0x00, 0x00 },342 }, {343 .frequency = 600000000,344 .vcocap = 3,345 .filter = 5,346 .ichpmp = 5,347 .loadadj = 3,348 .tmds_termadj = 12,349 .tx_pu_value = 96,350 .bg_temp_coef = 3,351 .bg_vref_level = 8,352 .avdd10_level = 4,353 .avdd14_level = 4,354 .sparepll = 0x34,355 .drive_current = { 0x3d, 0x3d, 0x3d, 0x33 },356 .preemphasis = { 0x00, 0x00, 0x00, 0x00 },357 }358};359 360struct tegra_sor_regs {361 unsigned int head_state0;362 unsigned int head_state1;363 unsigned int head_state2;364 unsigned int head_state3;365 unsigned int head_state4;366 unsigned int head_state5;367 unsigned int pll0;368 unsigned int pll1;369 unsigned int pll2;370 unsigned int pll3;371 unsigned int dp_padctl0;372 unsigned int dp_padctl2;373};374 375struct tegra_sor_soc {376 bool supports_lvds;377 bool supports_hdmi;378 bool supports_dp;379 bool supports_audio;380 bool supports_hdcp;381 382 const struct tegra_sor_regs *regs;383 bool has_nvdisplay;384 385 const struct tegra_sor_hdmi_settings *settings;386 unsigned int num_settings;387 388 const u8 *xbar_cfg;389 const u8 *lane_map;390 391 const u8 (*voltage_swing)[4][4];392 const u8 (*pre_emphasis)[4][4];393 const u8 (*post_cursor)[4][4];394 const u8 (*tx_pu)[4][4];395};396 397struct tegra_sor;398 399struct tegra_sor_ops {400 const char *name;401 int (*probe)(struct tegra_sor *sor);402 void (*audio_enable)(struct tegra_sor *sor);403 void (*audio_disable)(struct tegra_sor *sor);404};405 406struct tegra_sor {407 struct host1x_client client;408 struct tegra_output output;409 struct device *dev;410 411 const struct tegra_sor_soc *soc;412 void __iomem *regs;413 unsigned int index;414 unsigned int irq;415 416 struct reset_control *rst;417 struct clk *clk_parent;418 struct clk *clk_safe;419 struct clk *clk_out;420 struct clk *clk_pad;421 struct clk *clk_dp;422 struct clk *clk;423 424 u8 xbar_cfg[5];425 426 struct drm_dp_link link;427 struct drm_dp_aux *aux;428 429 struct drm_info_list *debugfs_files;430 431 const struct tegra_sor_ops *ops;432 enum tegra_io_pad pad;433 434 /* for HDMI 2.0 */435 struct tegra_sor_hdmi_settings *settings;436 unsigned int num_settings;437 438 struct regulator *avdd_io_supply;439 struct regulator *vdd_pll_supply;440 struct regulator *hdmi_supply;441 442 struct delayed_work scdc;443 bool scdc_enabled;444 445 struct tegra_hda_format format;446};447 448struct tegra_sor_state {449 struct drm_connector_state base;450 451 unsigned int link_speed;452 unsigned long pclk;453 unsigned int bpc;454};455 456static inline struct tegra_sor_state *457to_sor_state(struct drm_connector_state *state)458{459 return container_of(state, struct tegra_sor_state, base);460}461 462struct tegra_sor_config {463 u32 bits_per_pixel;464 465 u32 active_polarity;466 u32 active_count;467 u32 tu_size;468 u32 active_frac;469 u32 watermark;470 471 u32 hblank_symbols;472 u32 vblank_symbols;473};474 475static inline struct tegra_sor *476host1x_client_to_sor(struct host1x_client *client)477{478 return container_of(client, struct tegra_sor, client);479}480 481static inline struct tegra_sor *to_sor(struct tegra_output *output)482{483 return container_of(output, struct tegra_sor, output);484}485 486static inline u32 tegra_sor_readl(struct tegra_sor *sor, unsigned int offset)487{488 u32 value = readl(sor->regs + (offset << 2));489 490 trace_sor_readl(sor->dev, offset, value);491 492 return value;493}494 495static inline void tegra_sor_writel(struct tegra_sor *sor, u32 value,496 unsigned int offset)497{498 trace_sor_writel(sor->dev, offset, value);499 writel(value, sor->regs + (offset << 2));500}501 502static int tegra_sor_set_parent_clock(struct tegra_sor *sor, struct clk *parent)503{504 int err;505 506 clk_disable_unprepare(sor->clk);507 508 err = clk_set_parent(sor->clk_out, parent);509 if (err < 0)510 return err;511 512 err = clk_prepare_enable(sor->clk);513 if (err < 0)514 return err;515 516 return 0;517}518 519struct tegra_clk_sor_pad {520 struct clk_hw hw;521 struct tegra_sor *sor;522};523 524static inline struct tegra_clk_sor_pad *to_pad(struct clk_hw *hw)525{526 return container_of(hw, struct tegra_clk_sor_pad, hw);527}528 529static const char * const tegra_clk_sor_pad_parents[2][2] = {530 { "pll_d_out0", "pll_dp" },531 { "pll_d2_out0", "pll_dp" },532};533 534/*535 * Implementing ->set_parent() here isn't really required because the parent536 * will be explicitly selected in the driver code via the DP_CLK_SEL mux in537 * the SOR_CLK_CNTRL register. This is primarily for compatibility with the538 * Tegra186 and later SoC generations where the BPMP implements this clock539 * and doesn't expose the mux via the common clock framework.540 */541 542static int tegra_clk_sor_pad_set_parent(struct clk_hw *hw, u8 index)543{544 struct tegra_clk_sor_pad *pad = to_pad(hw);545 struct tegra_sor *sor = pad->sor;546 u32 value;547 548 value = tegra_sor_readl(sor, SOR_CLK_CNTRL);549 value &= ~SOR_CLK_CNTRL_DP_CLK_SEL_MASK;550 551 switch (index) {552 case 0:553 value |= SOR_CLK_CNTRL_DP_CLK_SEL_SINGLE_PCLK;554 break;555 556 case 1:557 value |= SOR_CLK_CNTRL_DP_CLK_SEL_SINGLE_DPCLK;558 break;559 }560 561 tegra_sor_writel(sor, value, SOR_CLK_CNTRL);562 563 return 0;564}565 566static u8 tegra_clk_sor_pad_get_parent(struct clk_hw *hw)567{568 struct tegra_clk_sor_pad *pad = to_pad(hw);569 struct tegra_sor *sor = pad->sor;570 u8 parent = U8_MAX;571 u32 value;572 573 value = tegra_sor_readl(sor, SOR_CLK_CNTRL);574 575 switch (value & SOR_CLK_CNTRL_DP_CLK_SEL_MASK) {576 case SOR_CLK_CNTRL_DP_CLK_SEL_SINGLE_PCLK:577 case SOR_CLK_CNTRL_DP_CLK_SEL_DIFF_PCLK:578 parent = 0;579 break;580 581 case SOR_CLK_CNTRL_DP_CLK_SEL_SINGLE_DPCLK:582 case SOR_CLK_CNTRL_DP_CLK_SEL_DIFF_DPCLK:583 parent = 1;584 break;585 }586 587 return parent;588}589 590static const struct clk_ops tegra_clk_sor_pad_ops = {591 .determine_rate = clk_hw_determine_rate_no_reparent,592 .set_parent = tegra_clk_sor_pad_set_parent,593 .get_parent = tegra_clk_sor_pad_get_parent,594};595 596static struct clk *tegra_clk_sor_pad_register(struct tegra_sor *sor,597 const char *name)598{599 struct tegra_clk_sor_pad *pad;600 struct clk_init_data init;601 struct clk *clk;602 603 pad = devm_kzalloc(sor->dev, sizeof(*pad), GFP_KERNEL);604 if (!pad)605 return ERR_PTR(-ENOMEM);606 607 pad->sor = sor;608 609 init.name = name;610 init.flags = 0;611 init.parent_names = tegra_clk_sor_pad_parents[sor->index];612 init.num_parents = ARRAY_SIZE(tegra_clk_sor_pad_parents[sor->index]);613 init.ops = &tegra_clk_sor_pad_ops;614 615 pad->hw.init = &init;616 617 clk = devm_clk_register(sor->dev, &pad->hw);618 619 return clk;620}621 622static void tegra_sor_filter_rates(struct tegra_sor *sor)623{624 struct drm_dp_link *link = &sor->link;625 unsigned int i;626 627 /* Tegra only supports RBR, HBR and HBR2 */628 for (i = 0; i < link->num_rates; i++) {629 switch (link->rates[i]) {630 case 1620000:631 case 2700000:632 case 5400000:633 break;634 635 default:636 DRM_DEBUG_KMS("link rate %lu kHz not supported\n",637 link->rates[i]);638 link->rates[i] = 0;639 break;640 }641 }642 643 drm_dp_link_update_rates(link);644}645 646static int tegra_sor_power_up_lanes(struct tegra_sor *sor, unsigned int lanes)647{648 unsigned long timeout;649 u32 value;650 651 /*652 * Clear or set the PD_TXD bit corresponding to each lane, depending653 * on whether it is used or not.654 */655 value = tegra_sor_readl(sor, sor->soc->regs->dp_padctl0);656 657 if (lanes <= 2)658 value &= ~(SOR_DP_PADCTL_PD_TXD(sor->soc->lane_map[3]) |659 SOR_DP_PADCTL_PD_TXD(sor->soc->lane_map[2]));660 else661 value |= SOR_DP_PADCTL_PD_TXD(sor->soc->lane_map[3]) |662 SOR_DP_PADCTL_PD_TXD(sor->soc->lane_map[2]);663 664 if (lanes <= 1)665 value &= ~SOR_DP_PADCTL_PD_TXD(sor->soc->lane_map[1]);666 else667 value |= SOR_DP_PADCTL_PD_TXD(sor->soc->lane_map[1]);668 669 if (lanes == 0)670 value &= ~SOR_DP_PADCTL_PD_TXD(sor->soc->lane_map[0]);671 else672 value |= SOR_DP_PADCTL_PD_TXD(sor->soc->lane_map[0]);673 674 tegra_sor_writel(sor, value, sor->soc->regs->dp_padctl0);675 676 /* start lane sequencer */677 value = SOR_LANE_SEQ_CTL_TRIGGER | SOR_LANE_SEQ_CTL_SEQUENCE_DOWN |678 SOR_LANE_SEQ_CTL_POWER_STATE_UP;679 tegra_sor_writel(sor, value, SOR_LANE_SEQ_CTL);680 681 timeout = jiffies + msecs_to_jiffies(250);682 683 while (time_before(jiffies, timeout)) {684 value = tegra_sor_readl(sor, SOR_LANE_SEQ_CTL);685 if ((value & SOR_LANE_SEQ_CTL_TRIGGER) == 0)686 break;687 688 usleep_range(250, 1000);689 }690 691 if ((value & SOR_LANE_SEQ_CTL_TRIGGER) != 0)692 return -ETIMEDOUT;693 694 return 0;695}696 697static int tegra_sor_power_down_lanes(struct tegra_sor *sor)698{699 unsigned long timeout;700 u32 value;701 702 /* power down all lanes */703 value = tegra_sor_readl(sor, sor->soc->regs->dp_padctl0);704 value &= ~(SOR_DP_PADCTL_PD_TXD_3 | SOR_DP_PADCTL_PD_TXD_0 |705 SOR_DP_PADCTL_PD_TXD_1 | SOR_DP_PADCTL_PD_TXD_2);706 tegra_sor_writel(sor, value, sor->soc->regs->dp_padctl0);707 708 /* start lane sequencer */709 value = SOR_LANE_SEQ_CTL_TRIGGER | SOR_LANE_SEQ_CTL_SEQUENCE_UP |710 SOR_LANE_SEQ_CTL_POWER_STATE_DOWN;711 tegra_sor_writel(sor, value, SOR_LANE_SEQ_CTL);712 713 timeout = jiffies + msecs_to_jiffies(250);714 715 while (time_before(jiffies, timeout)) {716 value = tegra_sor_readl(sor, SOR_LANE_SEQ_CTL);717 if ((value & SOR_LANE_SEQ_CTL_TRIGGER) == 0)718 break;719 720 usleep_range(25, 100);721 }722 723 if ((value & SOR_LANE_SEQ_CTL_TRIGGER) != 0)724 return -ETIMEDOUT;725 726 return 0;727}728 729static void tegra_sor_dp_precharge(struct tegra_sor *sor, unsigned int lanes)730{731 u32 value;732 733 /* pre-charge all used lanes */734 value = tegra_sor_readl(sor, sor->soc->regs->dp_padctl0);735 736 if (lanes <= 2)737 value &= ~(SOR_DP_PADCTL_CM_TXD(sor->soc->lane_map[3]) |738 SOR_DP_PADCTL_CM_TXD(sor->soc->lane_map[2]));739 else740 value |= SOR_DP_PADCTL_CM_TXD(sor->soc->lane_map[3]) |741 SOR_DP_PADCTL_CM_TXD(sor->soc->lane_map[2]);742 743 if (lanes <= 1)744 value &= ~SOR_DP_PADCTL_CM_TXD(sor->soc->lane_map[1]);745 else746 value |= SOR_DP_PADCTL_CM_TXD(sor->soc->lane_map[1]);747 748 if (lanes == 0)749 value &= ~SOR_DP_PADCTL_CM_TXD(sor->soc->lane_map[0]);750 else751 value |= SOR_DP_PADCTL_CM_TXD(sor->soc->lane_map[0]);752 753 tegra_sor_writel(sor, value, sor->soc->regs->dp_padctl0);754 755 usleep_range(15, 100);756 757 value = tegra_sor_readl(sor, sor->soc->regs->dp_padctl0);758 value &= ~(SOR_DP_PADCTL_CM_TXD_3 | SOR_DP_PADCTL_CM_TXD_2 |759 SOR_DP_PADCTL_CM_TXD_1 | SOR_DP_PADCTL_CM_TXD_0);760 tegra_sor_writel(sor, value, sor->soc->regs->dp_padctl0);761}762 763static void tegra_sor_dp_term_calibrate(struct tegra_sor *sor)764{765 u32 mask = 0x08, adj = 0, value;766 767 /* enable pad calibration logic */768 value = tegra_sor_readl(sor, sor->soc->regs->dp_padctl0);769 value &= ~SOR_DP_PADCTL_PAD_CAL_PD;770 tegra_sor_writel(sor, value, sor->soc->regs->dp_padctl0);771 772 value = tegra_sor_readl(sor, sor->soc->regs->pll1);773 value |= SOR_PLL1_TMDS_TERM;774 tegra_sor_writel(sor, value, sor->soc->regs->pll1);775 776 while (mask) {777 adj |= mask;778 779 value = tegra_sor_readl(sor, sor->soc->regs->pll1);780 value &= ~SOR_PLL1_TMDS_TERMADJ_MASK;781 value |= SOR_PLL1_TMDS_TERMADJ(adj);782 tegra_sor_writel(sor, value, sor->soc->regs->pll1);783 784 usleep_range(100, 200);785 786 value = tegra_sor_readl(sor, sor->soc->regs->pll1);787 if (value & SOR_PLL1_TERM_COMPOUT)788 adj &= ~mask;789 790 mask >>= 1;791 }792 793 value = tegra_sor_readl(sor, sor->soc->regs->pll1);794 value &= ~SOR_PLL1_TMDS_TERMADJ_MASK;795 value |= SOR_PLL1_TMDS_TERMADJ(adj);796 tegra_sor_writel(sor, value, sor->soc->regs->pll1);797 798 /* disable pad calibration logic */799 value = tegra_sor_readl(sor, sor->soc->regs->dp_padctl0);800 value |= SOR_DP_PADCTL_PAD_CAL_PD;801 tegra_sor_writel(sor, value, sor->soc->regs->dp_padctl0);802}803 804static int tegra_sor_dp_link_apply_training(struct drm_dp_link *link)805{806 struct tegra_sor *sor = container_of(link, struct tegra_sor, link);807 u32 voltage_swing = 0, pre_emphasis = 0, post_cursor = 0;808 const struct tegra_sor_soc *soc = sor->soc;809 u32 pattern = 0, tx_pu = 0, value;810 unsigned int i;811 812 for (value = 0, i = 0; i < link->lanes; i++) {813 u8 vs = link->train.request.voltage_swing[i];814 u8 pe = link->train.request.pre_emphasis[i];815 u8 pc = link->train.request.post_cursor[i];816 u8 shift = sor->soc->lane_map[i] << 3;817 818 voltage_swing |= soc->voltage_swing[pc][vs][pe] << shift;819 pre_emphasis |= soc->pre_emphasis[pc][vs][pe] << shift;820 post_cursor |= soc->post_cursor[pc][vs][pe] << shift;821 822 if (sor->soc->tx_pu[pc][vs][pe] > tx_pu)823 tx_pu = sor->soc->tx_pu[pc][vs][pe];824 825 switch (link->train.pattern) {826 case DP_TRAINING_PATTERN_DISABLE:827 value = SOR_DP_TPG_SCRAMBLER_GALIOS |828 SOR_DP_TPG_PATTERN_NONE;829 break;830 831 case DP_TRAINING_PATTERN_1:832 value = SOR_DP_TPG_SCRAMBLER_NONE |833 SOR_DP_TPG_PATTERN_TRAIN1;834 break;835 836 case DP_TRAINING_PATTERN_2:837 value = SOR_DP_TPG_SCRAMBLER_NONE |838 SOR_DP_TPG_PATTERN_TRAIN2;839 break;840 841 case DP_TRAINING_PATTERN_3:842 value = SOR_DP_TPG_SCRAMBLER_NONE |843 SOR_DP_TPG_PATTERN_TRAIN3;844 break;845 846 default:847 return -EINVAL;848 }849 850 if (link->caps.channel_coding)851 value |= SOR_DP_TPG_CHANNEL_CODING;852 853 pattern = pattern << 8 | value;854 }855 856 tegra_sor_writel(sor, voltage_swing, SOR_LANE_DRIVE_CURRENT0);857 tegra_sor_writel(sor, pre_emphasis, SOR_LANE_PREEMPHASIS0);858 859 if (link->caps.tps3_supported)860 tegra_sor_writel(sor, post_cursor, SOR_LANE_POSTCURSOR0);861 862 tegra_sor_writel(sor, pattern, SOR_DP_TPG);863 864 value = tegra_sor_readl(sor, sor->soc->regs->dp_padctl0);865 value &= ~SOR_DP_PADCTL_TX_PU_MASK;866 value |= SOR_DP_PADCTL_TX_PU_ENABLE;867 value |= SOR_DP_PADCTL_TX_PU(tx_pu);868 tegra_sor_writel(sor, value, sor->soc->regs->dp_padctl0);869 870 usleep_range(20, 100);871 872 return 0;873}874 875static int tegra_sor_dp_link_configure(struct drm_dp_link *link)876{877 struct tegra_sor *sor = container_of(link, struct tegra_sor, link);878 unsigned int rate, lanes;879 u32 value;880 int err;881 882 rate = drm_dp_link_rate_to_bw_code(link->rate);883 lanes = link->lanes;884 885 /* configure link speed and lane count */886 value = tegra_sor_readl(sor, SOR_CLK_CNTRL);887 value &= ~SOR_CLK_CNTRL_DP_LINK_SPEED_MASK;888 value |= SOR_CLK_CNTRL_DP_LINK_SPEED(rate);889 tegra_sor_writel(sor, value, SOR_CLK_CNTRL);890 891 value = tegra_sor_readl(sor, SOR_DP_LINKCTL0);892 value &= ~SOR_DP_LINKCTL_LANE_COUNT_MASK;893 value |= SOR_DP_LINKCTL_LANE_COUNT(lanes);894 895 if (link->caps.enhanced_framing)896 value |= SOR_DP_LINKCTL_ENHANCED_FRAME;897 898 tegra_sor_writel(sor, value, SOR_DP_LINKCTL0);899 900 usleep_range(400, 1000);901 902 /* configure load pulse position adjustment */903 value = tegra_sor_readl(sor, sor->soc->regs->pll1);904 value &= ~SOR_PLL1_LOADADJ_MASK;905 906 switch (rate) {907 case DP_LINK_BW_1_62:908 value |= SOR_PLL1_LOADADJ(0x3);909 break;910 911 case DP_LINK_BW_2_7:912 value |= SOR_PLL1_LOADADJ(0x4);913 break;914 915 case DP_LINK_BW_5_4:916 value |= SOR_PLL1_LOADADJ(0x6);917 break;918 }919 920 tegra_sor_writel(sor, value, sor->soc->regs->pll1);921 922 /* use alternate scrambler reset for eDP */923 value = tegra_sor_readl(sor, SOR_DP_SPARE0);924 925 if (link->edp == 0)926 value &= ~SOR_DP_SPARE_PANEL_INTERNAL;927 else928 value |= SOR_DP_SPARE_PANEL_INTERNAL;929 930 tegra_sor_writel(sor, value, SOR_DP_SPARE0);931 932 err = tegra_sor_power_down_lanes(sor);933 if (err < 0) {934 dev_err(sor->dev, "failed to power down lanes: %d\n", err);935 return err;936 }937 938 /* power up and pre-charge lanes */939 err = tegra_sor_power_up_lanes(sor, lanes);940 if (err < 0) {941 dev_err(sor->dev, "failed to power up %u lane%s: %d\n",942 lanes, (lanes != 1) ? "s" : "", err);943 return err;944 }945 946 tegra_sor_dp_precharge(sor, lanes);947 948 return 0;949}950 951static const struct drm_dp_link_ops tegra_sor_dp_link_ops = {952 .apply_training = tegra_sor_dp_link_apply_training,953 .configure = tegra_sor_dp_link_configure,954};955 956static void tegra_sor_super_update(struct tegra_sor *sor)957{958 tegra_sor_writel(sor, 0, SOR_SUPER_STATE0);959 tegra_sor_writel(sor, 1, SOR_SUPER_STATE0);960 tegra_sor_writel(sor, 0, SOR_SUPER_STATE0);961}962 963static void tegra_sor_update(struct tegra_sor *sor)964{965 tegra_sor_writel(sor, 0, SOR_STATE0);966 tegra_sor_writel(sor, 1, SOR_STATE0);967 tegra_sor_writel(sor, 0, SOR_STATE0);968}969 970static int tegra_sor_setup_pwm(struct tegra_sor *sor, unsigned long timeout)971{972 u32 value;973 974 value = tegra_sor_readl(sor, SOR_PWM_DIV);975 value &= ~SOR_PWM_DIV_MASK;976 value |= 0x400; /* period */977 tegra_sor_writel(sor, value, SOR_PWM_DIV);978 979 value = tegra_sor_readl(sor, SOR_PWM_CTL);980 value &= ~SOR_PWM_CTL_DUTY_CYCLE_MASK;981 value |= 0x400; /* duty cycle */982 value &= ~SOR_PWM_CTL_CLK_SEL; /* clock source: PCLK */983 value |= SOR_PWM_CTL_TRIGGER;984 tegra_sor_writel(sor, value, SOR_PWM_CTL);985 986 timeout = jiffies + msecs_to_jiffies(timeout);987 988 while (time_before(jiffies, timeout)) {989 value = tegra_sor_readl(sor, SOR_PWM_CTL);990 if ((value & SOR_PWM_CTL_TRIGGER) == 0)991 return 0;992 993 usleep_range(25, 100);994 }995 996 return -ETIMEDOUT;997}998 999static int tegra_sor_attach(struct tegra_sor *sor)1000{1001 unsigned long value, timeout;1002 1003 /* wake up in normal mode */1004 value = tegra_sor_readl(sor, SOR_SUPER_STATE1);1005 value |= SOR_SUPER_STATE_HEAD_MODE_AWAKE;1006 value |= SOR_SUPER_STATE_MODE_NORMAL;1007 tegra_sor_writel(sor, value, SOR_SUPER_STATE1);1008 tegra_sor_super_update(sor);1009 1010 /* attach */1011 value = tegra_sor_readl(sor, SOR_SUPER_STATE1);1012 value |= SOR_SUPER_STATE_ATTACHED;1013 tegra_sor_writel(sor, value, SOR_SUPER_STATE1);1014 tegra_sor_super_update(sor);1015 1016 timeout = jiffies + msecs_to_jiffies(250);1017 1018 while (time_before(jiffies, timeout)) {1019 value = tegra_sor_readl(sor, SOR_TEST);1020 if ((value & SOR_TEST_ATTACHED) != 0)1021 return 0;1022 1023 usleep_range(25, 100);1024 }1025 1026 return -ETIMEDOUT;1027}1028 1029static int tegra_sor_wakeup(struct tegra_sor *sor)1030{1031 unsigned long value, timeout;1032 1033 timeout = jiffies + msecs_to_jiffies(250);1034 1035 /* wait for head to wake up */1036 while (time_before(jiffies, timeout)) {1037 value = tegra_sor_readl(sor, SOR_TEST);1038 value &= SOR_TEST_HEAD_MODE_MASK;1039 1040 if (value == SOR_TEST_HEAD_MODE_AWAKE)1041 return 0;1042 1043 usleep_range(25, 100);1044 }1045 1046 return -ETIMEDOUT;1047}1048 1049static int tegra_sor_power_up(struct tegra_sor *sor, unsigned long timeout)1050{1051 u32 value;1052 1053 value = tegra_sor_readl(sor, SOR_PWR);1054 value |= SOR_PWR_TRIGGER | SOR_PWR_NORMAL_STATE_PU;1055 tegra_sor_writel(sor, value, SOR_PWR);1056 1057 timeout = jiffies + msecs_to_jiffies(timeout);1058 1059 while (time_before(jiffies, timeout)) {1060 value = tegra_sor_readl(sor, SOR_PWR);1061 if ((value & SOR_PWR_TRIGGER) == 0)1062 return 0;1063 1064 usleep_range(25, 100);1065 }1066 1067 return -ETIMEDOUT;1068}1069 1070struct tegra_sor_params {1071 /* number of link clocks per line */1072 unsigned int num_clocks;1073 /* ratio between input and output */1074 u64 ratio;1075 /* precision factor */1076 u64 precision;1077 1078 unsigned int active_polarity;1079 unsigned int active_count;1080 unsigned int active_frac;1081 unsigned int tu_size;1082 unsigned int error;1083};1084 1085static int tegra_sor_compute_params(struct tegra_sor *sor,1086 struct tegra_sor_params *params,1087 unsigned int tu_size)1088{1089 u64 active_sym, active_count, frac, approx;1090 u32 active_polarity, active_frac = 0;1091 const u64 f = params->precision;1092 s64 error;1093 1094 active_sym = params->ratio * tu_size;1095 active_count = div_u64(active_sym, f) * f;1096 frac = active_sym - active_count;1097 1098 /* fraction < 0.5 */1099 if (frac >= (f / 2)) {1100 active_polarity = 1;1101 frac = f - frac;1102 } else {1103 active_polarity = 0;1104 }1105 1106 if (frac != 0) {1107 frac = div_u64(f * f, frac); /* 1/fraction */1108 if (frac <= (15 * f)) {1109 active_frac = div_u64(frac, f);1110 1111 /* round up */1112 if (active_polarity)1113 active_frac++;1114 } else {1115 active_frac = active_polarity ? 1 : 15;1116 }1117 }1118 1119 if (active_frac == 1)1120 active_polarity = 0;1121 1122 if (active_polarity == 1) {1123 if (active_frac) {1124 approx = active_count + (active_frac * (f - 1)) * f;1125 approx = div_u64(approx, active_frac * f);1126 } else {1127 approx = active_count + f;1128 }1129 } else {1130 if (active_frac)1131 approx = active_count + div_u64(f, active_frac);1132 else1133 approx = active_count;1134 }1135 1136 error = div_s64(active_sym - approx, tu_size);1137 error *= params->num_clocks;1138 1139 if (error <= 0 && abs(error) < params->error) {1140 params->active_count = div_u64(active_count, f);1141 params->active_polarity = active_polarity;1142 params->active_frac = active_frac;1143 params->error = abs(error);1144 params->tu_size = tu_size;1145 1146 if (error == 0)1147 return true;1148 }1149 1150 return false;1151}1152 1153static int tegra_sor_compute_config(struct tegra_sor *sor,1154 const struct drm_display_mode *mode,1155 struct tegra_sor_config *config,1156 struct drm_dp_link *link)1157{1158 const u64 f = 100000, link_rate = link->rate * 1000;1159 const u64 pclk = (u64)mode->clock * 1000;1160 u64 input, output, watermark, num;1161 struct tegra_sor_params params;1162 u32 num_syms_per_line;1163 unsigned int i;1164 1165 if (!link_rate || !link->lanes || !pclk || !config->bits_per_pixel)1166 return -EINVAL;1167 1168 input = pclk * config->bits_per_pixel;1169 output = link_rate * 8 * link->lanes;1170 1171 if (input >= output)1172 return -ERANGE;1173 1174 memset(¶ms, 0, sizeof(params));1175 params.ratio = div64_u64(input * f, output);1176 params.num_clocks = div_u64(link_rate * mode->hdisplay, pclk);1177 params.precision = f;1178 params.error = 64 * f;1179 params.tu_size = 64;1180 1181 for (i = params.tu_size; i >= 32; i--)1182 if (tegra_sor_compute_params(sor, ¶ms, i))1183 break;1184 1185 if (params.active_frac == 0) {1186 config->active_polarity = 0;1187 config->active_count = params.active_count;1188 1189 if (!params.active_polarity)1190 config->active_count--;1191 1192 config->tu_size = params.tu_size;1193 config->active_frac = 1;1194 } else {1195 config->active_polarity = params.active_polarity;1196 config->active_count = params.active_count;1197 config->active_frac = params.active_frac;1198 config->tu_size = params.tu_size;1199 }1200 1201 dev_dbg(sor->dev,1202 "polarity: %d active count: %d tu size: %d active frac: %d\n",1203 config->active_polarity, config->active_count,1204 config->tu_size, config->active_frac);1205 1206 watermark = params.ratio * config->tu_size * (f - params.ratio);1207 watermark = div_u64(watermark, f);1208 1209 watermark = div_u64(watermark + params.error, f);1210 config->watermark = watermark + (config->bits_per_pixel / 8) + 2;1211 num_syms_per_line = (mode->hdisplay * config->bits_per_pixel) *1212 (link->lanes * 8);1213 1214 if (config->watermark > 30) {1215 config->watermark = 30;1216 dev_err(sor->dev,1217 "unable to compute TU size, forcing watermark to %u\n",1218 config->watermark);1219 } else if (config->watermark > num_syms_per_line) {1220 config->watermark = num_syms_per_line;1221 dev_err(sor->dev, "watermark too high, forcing to %u\n",1222 config->watermark);1223 }1224 1225 /* compute the number of symbols per horizontal blanking interval */1226 num = ((mode->htotal - mode->hdisplay) - 7) * link_rate;1227 config->hblank_symbols = div_u64(num, pclk);1228 1229 if (link->caps.enhanced_framing)1230 config->hblank_symbols -= 3;1231 1232 config->hblank_symbols -= 12 / link->lanes;1233 1234 /* compute the number of symbols per vertical blanking interval */1235 num = (mode->hdisplay - 25) * link_rate;1236 config->vblank_symbols = div_u64(num, pclk);1237 config->vblank_symbols -= 36 / link->lanes + 4;1238 1239 dev_dbg(sor->dev, "blank symbols: H:%u V:%u\n", config->hblank_symbols,1240 config->vblank_symbols);1241 1242 return 0;1243}1244 1245static void tegra_sor_apply_config(struct tegra_sor *sor,1246 const struct tegra_sor_config *config)1247{1248 u32 value;1249 1250 value = tegra_sor_readl(sor, SOR_DP_LINKCTL0);1251 value &= ~SOR_DP_LINKCTL_TU_SIZE_MASK;1252 value |= SOR_DP_LINKCTL_TU_SIZE(config->tu_size);1253 tegra_sor_writel(sor, value, SOR_DP_LINKCTL0);1254 1255 value = tegra_sor_readl(sor, SOR_DP_CONFIG0);1256 value &= ~SOR_DP_CONFIG_WATERMARK_MASK;1257 value |= SOR_DP_CONFIG_WATERMARK(config->watermark);1258 1259 value &= ~SOR_DP_CONFIG_ACTIVE_SYM_COUNT_MASK;1260 value |= SOR_DP_CONFIG_ACTIVE_SYM_COUNT(config->active_count);1261 1262 value &= ~SOR_DP_CONFIG_ACTIVE_SYM_FRAC_MASK;1263 value |= SOR_DP_CONFIG_ACTIVE_SYM_FRAC(config->active_frac);1264 1265 if (config->active_polarity)1266 value |= SOR_DP_CONFIG_ACTIVE_SYM_POLARITY;1267 else1268 value &= ~SOR_DP_CONFIG_ACTIVE_SYM_POLARITY;1269 1270 value |= SOR_DP_CONFIG_ACTIVE_SYM_ENABLE;1271 value |= SOR_DP_CONFIG_DISPARITY_NEGATIVE;1272 tegra_sor_writel(sor, value, SOR_DP_CONFIG0);1273 1274 value = tegra_sor_readl(sor, SOR_DP_AUDIO_HBLANK_SYMBOLS);1275 value &= ~SOR_DP_AUDIO_HBLANK_SYMBOLS_MASK;1276 value |= config->hblank_symbols & 0xffff;1277 tegra_sor_writel(sor, value, SOR_DP_AUDIO_HBLANK_SYMBOLS);1278 1279 value = tegra_sor_readl(sor, SOR_DP_AUDIO_VBLANK_SYMBOLS);1280 value &= ~SOR_DP_AUDIO_VBLANK_SYMBOLS_MASK;1281 value |= config->vblank_symbols & 0xffff;1282 tegra_sor_writel(sor, value, SOR_DP_AUDIO_VBLANK_SYMBOLS);1283}1284 1285static void tegra_sor_mode_set(struct tegra_sor *sor,1286 const struct drm_display_mode *mode,1287 struct tegra_sor_state *state)1288{1289 struct tegra_dc *dc = to_tegra_dc(sor->output.encoder.crtc);1290 unsigned int vbe, vse, hbe, hse, vbs, hbs;1291 u32 value;1292 1293 value = tegra_sor_readl(sor, SOR_STATE1);1294 value &= ~SOR_STATE_ASY_PIXELDEPTH_MASK;1295 value &= ~SOR_STATE_ASY_CRC_MODE_MASK;1296 value &= ~SOR_STATE_ASY_OWNER_MASK;1297 1298 value |= SOR_STATE_ASY_CRC_MODE_COMPLETE |1299 SOR_STATE_ASY_OWNER(dc->pipe + 1);1300 1301 if (mode->flags & DRM_MODE_FLAG_PHSYNC)1302 value &= ~SOR_STATE_ASY_HSYNCPOL;1303 1304 if (mode->flags & DRM_MODE_FLAG_NHSYNC)1305 value |= SOR_STATE_ASY_HSYNCPOL;1306 1307 if (mode->flags & DRM_MODE_FLAG_PVSYNC)1308 value &= ~SOR_STATE_ASY_VSYNCPOL;1309 1310 if (mode->flags & DRM_MODE_FLAG_NVSYNC)1311 value |= SOR_STATE_ASY_VSYNCPOL;1312 1313 switch (state->bpc) {1314 case 16:1315 value |= SOR_STATE_ASY_PIXELDEPTH_BPP_48_444;1316 break;1317 1318 case 12:1319 value |= SOR_STATE_ASY_PIXELDEPTH_BPP_36_444;1320 break;1321 1322 case 10:1323 value |= SOR_STATE_ASY_PIXELDEPTH_BPP_30_444;1324 break;1325 1326 case 8:1327 value |= SOR_STATE_ASY_PIXELDEPTH_BPP_24_444;1328 break;1329 1330 case 6:1331 value |= SOR_STATE_ASY_PIXELDEPTH_BPP_18_444;1332 break;1333 1334 default:1335 value |= SOR_STATE_ASY_PIXELDEPTH_BPP_24_444;1336 break;1337 }1338 1339 tegra_sor_writel(sor, value, SOR_STATE1);1340 1341 /*1342 * TODO: The video timing programming below doesn't seem to match the1343 * register definitions.1344 */1345 1346 value = ((mode->vtotal & 0x7fff) << 16) | (mode->htotal & 0x7fff);1347 tegra_sor_writel(sor, value, sor->soc->regs->head_state1 + dc->pipe);1348 1349 /* sync end = sync width - 1 */1350 vse = mode->vsync_end - mode->vsync_start - 1;1351 hse = mode->hsync_end - mode->hsync_start - 1;1352 1353 value = ((vse & 0x7fff) << 16) | (hse & 0x7fff);1354 tegra_sor_writel(sor, value, sor->soc->regs->head_state2 + dc->pipe);1355 1356 /* blank end = sync end + back porch */1357 vbe = vse + (mode->vtotal - mode->vsync_end);1358 hbe = hse + (mode->htotal - mode->hsync_end);1359 1360 value = ((vbe & 0x7fff) << 16) | (hbe & 0x7fff);1361 tegra_sor_writel(sor, value, sor->soc->regs->head_state3 + dc->pipe);1362 1363 /* blank start = blank end + active */1364 vbs = vbe + mode->vdisplay;1365 hbs = hbe + mode->hdisplay;1366 1367 value = ((vbs & 0x7fff) << 16) | (hbs & 0x7fff);1368 tegra_sor_writel(sor, value, sor->soc->regs->head_state4 + dc->pipe);1369 1370 /* XXX interlacing support */1371 tegra_sor_writel(sor, 0x001, sor->soc->regs->head_state5 + dc->pipe);1372}1373 1374static int tegra_sor_detach(struct tegra_sor *sor)1375{1376 unsigned long value, timeout;1377 1378 /* switch to safe mode */1379 value = tegra_sor_readl(sor, SOR_SUPER_STATE1);1380 value &= ~SOR_SUPER_STATE_MODE_NORMAL;1381 tegra_sor_writel(sor, value, SOR_SUPER_STATE1);1382 tegra_sor_super_update(sor);1383 1384 timeout = jiffies + msecs_to_jiffies(250);1385 1386 while (time_before(jiffies, timeout)) {1387 value = tegra_sor_readl(sor, SOR_PWR);1388 if (value & SOR_PWR_MODE_SAFE)1389 break;1390 }1391 1392 if ((value & SOR_PWR_MODE_SAFE) == 0)1393 return -ETIMEDOUT;1394 1395 /* go to sleep */1396 value = tegra_sor_readl(sor, SOR_SUPER_STATE1);1397 value &= ~SOR_SUPER_STATE_HEAD_MODE_MASK;1398 tegra_sor_writel(sor, value, SOR_SUPER_STATE1);1399 tegra_sor_super_update(sor);1400 1401 /* detach */1402 value = tegra_sor_readl(sor, SOR_SUPER_STATE1);1403 value &= ~SOR_SUPER_STATE_ATTACHED;1404 tegra_sor_writel(sor, value, SOR_SUPER_STATE1);1405 tegra_sor_super_update(sor);1406 1407 timeout = jiffies + msecs_to_jiffies(250);1408 1409 while (time_before(jiffies, timeout)) {1410 value = tegra_sor_readl(sor, SOR_TEST);1411 if ((value & SOR_TEST_ATTACHED) == 0)1412 break;1413 1414 usleep_range(25, 100);1415 }1416 1417 if ((value & SOR_TEST_ATTACHED) != 0)1418 return -ETIMEDOUT;1419 1420 return 0;1421}1422 1423static int tegra_sor_power_down(struct tegra_sor *sor)1424{1425 unsigned long value, timeout;1426 int err;1427 1428 value = tegra_sor_readl(sor, SOR_PWR);1429 value &= ~SOR_PWR_NORMAL_STATE_PU;1430 value |= SOR_PWR_TRIGGER;1431 tegra_sor_writel(sor, value, SOR_PWR);1432 1433 timeout = jiffies + msecs_to_jiffies(250);1434 1435 while (time_before(jiffies, timeout)) {1436 value = tegra_sor_readl(sor, SOR_PWR);1437 if ((value & SOR_PWR_TRIGGER) == 0)1438 return 0;1439 1440 usleep_range(25, 100);1441 }1442 1443 if ((value & SOR_PWR_TRIGGER) != 0)1444 return -ETIMEDOUT;1445 1446 /* switch to safe parent clock */1447 err = tegra_sor_set_parent_clock(sor, sor->clk_safe);1448 if (err < 0) {1449 dev_err(sor->dev, "failed to set safe parent clock: %d\n", err);1450 return err;1451 }1452 1453 value = tegra_sor_readl(sor, sor->soc->regs->pll2);1454 value |= SOR_PLL2_PORT_POWERDOWN;1455 tegra_sor_writel(sor, value, sor->soc->regs->pll2);1456 1457 usleep_range(20, 100);1458 1459 value = tegra_sor_readl(sor, sor->soc->regs->pll0);1460 value |= SOR_PLL0_VCOPD | SOR_PLL0_PWR;1461 tegra_sor_writel(sor, value, sor->soc->regs->pll0);1462 1463 value = tegra_sor_readl(sor, sor->soc->regs->pll2);1464 value |= SOR_PLL2_SEQ_PLLCAPPD;1465 value |= SOR_PLL2_SEQ_PLLCAPPD_ENFORCE;1466 tegra_sor_writel(sor, value, sor->soc->regs->pll2);1467 1468 usleep_range(20, 100);1469 1470 return 0;1471}1472 1473static int tegra_sor_crc_wait(struct tegra_sor *sor, unsigned long timeout)1474{1475 u32 value;1476 1477 timeout = jiffies + msecs_to_jiffies(timeout);1478 1479 while (time_before(jiffies, timeout)) {1480 value = tegra_sor_readl(sor, SOR_CRCA);1481 if (value & SOR_CRCA_VALID)1482 return 0;1483 1484 usleep_range(100, 200);1485 }1486 1487 return -ETIMEDOUT;1488}1489 1490static int tegra_sor_show_crc(struct seq_file *s, void *data)1491{1492 struct drm_info_node *node = s->private;1493 struct tegra_sor *sor = node->info_ent->data;1494 struct drm_crtc *crtc = sor->output.encoder.crtc;1495 struct drm_device *drm = node->minor->dev;1496 int err = 0;1497 u32 value;1498 1499 drm_modeset_lock_all(drm);1500 1501 if (!crtc || !crtc->state->active) {1502 err = -EBUSY;1503 goto unlock;1504 }1505 1506 value = tegra_sor_readl(sor, SOR_STATE1);1507 value &= ~SOR_STATE_ASY_CRC_MODE_MASK;1508 tegra_sor_writel(sor, value, SOR_STATE1);1509 1510 value = tegra_sor_readl(sor, SOR_CRC_CNTRL);1511 value |= SOR_CRC_CNTRL_ENABLE;1512 tegra_sor_writel(sor, value, SOR_CRC_CNTRL);1513 1514 value = tegra_sor_readl(sor, SOR_TEST);1515 value &= ~SOR_TEST_CRC_POST_SERIALIZE;1516 tegra_sor_writel(sor, value, SOR_TEST);1517 1518 err = tegra_sor_crc_wait(sor, 100);1519 if (err < 0)1520 goto unlock;1521 1522 tegra_sor_writel(sor, SOR_CRCA_RESET, SOR_CRCA);1523 value = tegra_sor_readl(sor, SOR_CRCB);1524 1525 seq_printf(s, "%08x\n", value);1526 1527unlock:1528 drm_modeset_unlock_all(drm);1529 return err;1530}1531 1532#define DEBUGFS_REG32(_name) { .name = #_name, .offset = _name }1533 1534static const struct debugfs_reg32 tegra_sor_regs[] = {1535 DEBUGFS_REG32(SOR_CTXSW),1536 DEBUGFS_REG32(SOR_SUPER_STATE0),1537 DEBUGFS_REG32(SOR_SUPER_STATE1),1538 DEBUGFS_REG32(SOR_STATE0),1539 DEBUGFS_REG32(SOR_STATE1),1540 DEBUGFS_REG32(SOR_HEAD_STATE0(0)),1541 DEBUGFS_REG32(SOR_HEAD_STATE0(1)),1542 DEBUGFS_REG32(SOR_HEAD_STATE1(0)),1543 DEBUGFS_REG32(SOR_HEAD_STATE1(1)),1544 DEBUGFS_REG32(SOR_HEAD_STATE2(0)),1545 DEBUGFS_REG32(SOR_HEAD_STATE2(1)),1546 DEBUGFS_REG32(SOR_HEAD_STATE3(0)),1547 DEBUGFS_REG32(SOR_HEAD_STATE3(1)),1548 DEBUGFS_REG32(SOR_HEAD_STATE4(0)),1549 DEBUGFS_REG32(SOR_HEAD_STATE4(1)),1550 DEBUGFS_REG32(SOR_HEAD_STATE5(0)),1551 DEBUGFS_REG32(SOR_HEAD_STATE5(1)),1552 DEBUGFS_REG32(SOR_CRC_CNTRL),1553 DEBUGFS_REG32(SOR_DP_DEBUG_MVID),1554 DEBUGFS_REG32(SOR_CLK_CNTRL),1555 DEBUGFS_REG32(SOR_CAP),1556 DEBUGFS_REG32(SOR_PWR),1557 DEBUGFS_REG32(SOR_TEST),1558 DEBUGFS_REG32(SOR_PLL0),1559 DEBUGFS_REG32(SOR_PLL1),1560 DEBUGFS_REG32(SOR_PLL2),1561 DEBUGFS_REG32(SOR_PLL3),1562 DEBUGFS_REG32(SOR_CSTM),1563 DEBUGFS_REG32(SOR_LVDS),1564 DEBUGFS_REG32(SOR_CRCA),1565 DEBUGFS_REG32(SOR_CRCB),1566 DEBUGFS_REG32(SOR_BLANK),1567 DEBUGFS_REG32(SOR_SEQ_CTL),1568 DEBUGFS_REG32(SOR_LANE_SEQ_CTL),1569 DEBUGFS_REG32(SOR_SEQ_INST(0)),1570 DEBUGFS_REG32(SOR_SEQ_INST(1)),1571 DEBUGFS_REG32(SOR_SEQ_INST(2)),1572 DEBUGFS_REG32(SOR_SEQ_INST(3)),1573 DEBUGFS_REG32(SOR_SEQ_INST(4)),1574 DEBUGFS_REG32(SOR_SEQ_INST(5)),1575 DEBUGFS_REG32(SOR_SEQ_INST(6)),1576 DEBUGFS_REG32(SOR_SEQ_INST(7)),1577 DEBUGFS_REG32(SOR_SEQ_INST(8)),1578 DEBUGFS_REG32(SOR_SEQ_INST(9)),1579 DEBUGFS_REG32(SOR_SEQ_INST(10)),1580 DEBUGFS_REG32(SOR_SEQ_INST(11)),1581 DEBUGFS_REG32(SOR_SEQ_INST(12)),1582 DEBUGFS_REG32(SOR_SEQ_INST(13)),1583 DEBUGFS_REG32(SOR_SEQ_INST(14)),1584 DEBUGFS_REG32(SOR_SEQ_INST(15)),1585 DEBUGFS_REG32(SOR_PWM_DIV),1586 DEBUGFS_REG32(SOR_PWM_CTL),1587 DEBUGFS_REG32(SOR_VCRC_A0),1588 DEBUGFS_REG32(SOR_VCRC_A1),1589 DEBUGFS_REG32(SOR_VCRC_B0),1590 DEBUGFS_REG32(SOR_VCRC_B1),1591 DEBUGFS_REG32(SOR_CCRC_A0),1592 DEBUGFS_REG32(SOR_CCRC_A1),1593 DEBUGFS_REG32(SOR_CCRC_B0),1594 DEBUGFS_REG32(SOR_CCRC_B1),1595 DEBUGFS_REG32(SOR_EDATA_A0),1596 DEBUGFS_REG32(SOR_EDATA_A1),1597 DEBUGFS_REG32(SOR_EDATA_B0),1598 DEBUGFS_REG32(SOR_EDATA_B1),1599 DEBUGFS_REG32(SOR_COUNT_A0),1600 DEBUGFS_REG32(SOR_COUNT_A1),1601 DEBUGFS_REG32(SOR_COUNT_B0),1602 DEBUGFS_REG32(SOR_COUNT_B1),1603 DEBUGFS_REG32(SOR_DEBUG_A0),1604 DEBUGFS_REG32(SOR_DEBUG_A1),1605 DEBUGFS_REG32(SOR_DEBUG_B0),1606 DEBUGFS_REG32(SOR_DEBUG_B1),1607 DEBUGFS_REG32(SOR_TRIG),1608 DEBUGFS_REG32(SOR_MSCHECK),1609 DEBUGFS_REG32(SOR_XBAR_CTRL),1610 DEBUGFS_REG32(SOR_XBAR_POL),1611 DEBUGFS_REG32(SOR_DP_LINKCTL0),1612 DEBUGFS_REG32(SOR_DP_LINKCTL1),1613 DEBUGFS_REG32(SOR_LANE_DRIVE_CURRENT0),1614 DEBUGFS_REG32(SOR_LANE_DRIVE_CURRENT1),1615 DEBUGFS_REG32(SOR_LANE4_DRIVE_CURRENT0),1616 DEBUGFS_REG32(SOR_LANE4_DRIVE_CURRENT1),1617 DEBUGFS_REG32(SOR_LANE_PREEMPHASIS0),1618 DEBUGFS_REG32(SOR_LANE_PREEMPHASIS1),1619 DEBUGFS_REG32(SOR_LANE4_PREEMPHASIS0),1620 DEBUGFS_REG32(SOR_LANE4_PREEMPHASIS1),1621 DEBUGFS_REG32(SOR_LANE_POSTCURSOR0),1622 DEBUGFS_REG32(SOR_LANE_POSTCURSOR1),1623 DEBUGFS_REG32(SOR_DP_CONFIG0),1624 DEBUGFS_REG32(SOR_DP_CONFIG1),1625 DEBUGFS_REG32(SOR_DP_MN0),1626 DEBUGFS_REG32(SOR_DP_MN1),1627 DEBUGFS_REG32(SOR_DP_PADCTL0),1628 DEBUGFS_REG32(SOR_DP_PADCTL1),1629 DEBUGFS_REG32(SOR_DP_PADCTL2),1630 DEBUGFS_REG32(SOR_DP_DEBUG0),1631 DEBUGFS_REG32(SOR_DP_DEBUG1),1632 DEBUGFS_REG32(SOR_DP_SPARE0),1633 DEBUGFS_REG32(SOR_DP_SPARE1),1634 DEBUGFS_REG32(SOR_DP_AUDIO_CTRL),1635 DEBUGFS_REG32(SOR_DP_AUDIO_HBLANK_SYMBOLS),1636 DEBUGFS_REG32(SOR_DP_AUDIO_VBLANK_SYMBOLS),1637 DEBUGFS_REG32(SOR_DP_GENERIC_INFOFRAME_HEADER),1638 DEBUGFS_REG32(SOR_DP_GENERIC_INFOFRAME_SUBPACK0),1639 DEBUGFS_REG32(SOR_DP_GENERIC_INFOFRAME_SUBPACK1),1640 DEBUGFS_REG32(SOR_DP_GENERIC_INFOFRAME_SUBPACK2),1641 DEBUGFS_REG32(SOR_DP_GENERIC_INFOFRAME_SUBPACK3),1642 DEBUGFS_REG32(SOR_DP_GENERIC_INFOFRAME_SUBPACK4),1643 DEBUGFS_REG32(SOR_DP_GENERIC_INFOFRAME_SUBPACK5),1644 DEBUGFS_REG32(SOR_DP_GENERIC_INFOFRAME_SUBPACK6),1645 DEBUGFS_REG32(SOR_DP_TPG),1646 DEBUGFS_REG32(SOR_DP_TPG_CONFIG),1647 DEBUGFS_REG32(SOR_DP_LQ_CSTM0),1648 DEBUGFS_REG32(SOR_DP_LQ_CSTM1),1649 DEBUGFS_REG32(SOR_DP_LQ_CSTM2),1650};1651 1652static int tegra_sor_show_regs(struct seq_file *s, void *data)1653{1654 struct drm_info_node *node = s->private;1655 struct tegra_sor *sor = node->info_ent->data;1656 struct drm_crtc *crtc = sor->output.encoder.crtc;1657 struct drm_device *drm = node->minor->dev;1658 unsigned int i;1659 int err = 0;1660 1661 drm_modeset_lock_all(drm);1662 1663 if (!crtc || !crtc->state->active) {1664 err = -EBUSY;1665 goto unlock;1666 }1667 1668 for (i = 0; i < ARRAY_SIZE(tegra_sor_regs); i++) {1669 unsigned int offset = tegra_sor_regs[i].offset;1670 1671 seq_printf(s, "%-38s %#05x %08x\n", tegra_sor_regs[i].name,1672 offset, tegra_sor_readl(sor, offset));1673 }1674 1675unlock:1676 drm_modeset_unlock_all(drm);1677 return err;1678}1679 1680static const struct drm_info_list debugfs_files[] = {1681 { "crc", tegra_sor_show_crc, 0, NULL },1682 { "regs", tegra_sor_show_regs, 0, NULL },1683};1684 1685static int tegra_sor_late_register(struct drm_connector *connector)1686{1687 struct tegra_output *output = connector_to_output(connector);1688 unsigned int i, count = ARRAY_SIZE(debugfs_files);1689 struct drm_minor *minor = connector->dev->primary;1690 struct dentry *root = connector->debugfs_entry;1691 struct tegra_sor *sor = to_sor(output);1692 1693 sor->debugfs_files = kmemdup(debugfs_files, sizeof(debugfs_files),1694 GFP_KERNEL);1695 if (!sor->debugfs_files)1696 return -ENOMEM;1697 1698 for (i = 0; i < count; i++)1699 sor->debugfs_files[i].data = sor;1700 1701 drm_debugfs_create_files(sor->debugfs_files, count, root, minor);1702 1703 return 0;1704}1705 1706static void tegra_sor_early_unregister(struct drm_connector *connector)1707{1708 struct tegra_output *output = connector_to_output(connector);1709 unsigned int count = ARRAY_SIZE(debugfs_files);1710 struct tegra_sor *sor = to_sor(output);1711 1712 drm_debugfs_remove_files(sor->debugfs_files, count,1713 connector->debugfs_entry,1714 connector->dev->primary);1715 kfree(sor->debugfs_files);1716 sor->debugfs_files = NULL;1717}1718 1719static void tegra_sor_connector_reset(struct drm_connector *connector)1720{1721 struct tegra_sor_state *state;1722 1723 state = kzalloc(sizeof(*state), GFP_KERNEL);1724 if (!state)1725 return;1726 1727 if (connector->state) {1728 __drm_atomic_helper_connector_destroy_state(connector->state);1729 kfree(connector->state);1730 }1731 1732 __drm_atomic_helper_connector_reset(connector, &state->base);1733}1734 1735static enum drm_connector_status1736tegra_sor_connector_detect(struct drm_connector *connector, bool force)1737{1738 struct tegra_output *output = connector_to_output(connector);1739 struct tegra_sor *sor = to_sor(output);1740 1741 if (sor->aux)1742 return drm_dp_aux_detect(sor->aux);1743 1744 return tegra_output_connector_detect(connector, force);1745}1746 1747static struct drm_connector_state *1748tegra_sor_connector_duplicate_state(struct drm_connector *connector)1749{1750 struct tegra_sor_state *state = to_sor_state(connector->state);1751 struct tegra_sor_state *copy;1752 1753 copy = kmemdup(state, sizeof(*state), GFP_KERNEL);1754 if (!copy)1755 return NULL;1756 1757 __drm_atomic_helper_connector_duplicate_state(connector, ©->base);1758 1759 return ©->base;1760}1761 1762static const struct drm_connector_funcs tegra_sor_connector_funcs = {1763 .reset = tegra_sor_connector_reset,1764 .detect = tegra_sor_connector_detect,1765 .fill_modes = drm_helper_probe_single_connector_modes,1766 .destroy = tegra_output_connector_destroy,1767 .atomic_duplicate_state = tegra_sor_connector_duplicate_state,1768 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,1769 .late_register = tegra_sor_late_register,1770 .early_unregister = tegra_sor_early_unregister,1771};1772 1773static int tegra_sor_connector_get_modes(struct drm_connector *connector)1774{1775 struct tegra_output *output = connector_to_output(connector);1776 struct tegra_sor *sor = to_sor(output);1777 int err;1778 1779 if (sor->aux)1780 drm_dp_aux_enable(sor->aux);1781 1782 err = tegra_output_connector_get_modes(connector);1783 1784 if (sor->aux)1785 drm_dp_aux_disable(sor->aux);1786 1787 return err;1788}1789 1790static enum drm_mode_status1791tegra_sor_connector_mode_valid(struct drm_connector *connector,1792 struct drm_display_mode *mode)1793{1794 return MODE_OK;1795}1796 1797static const struct drm_connector_helper_funcs tegra_sor_connector_helper_funcs = {1798 .get_modes = tegra_sor_connector_get_modes,1799 .mode_valid = tegra_sor_connector_mode_valid,1800};1801 1802static int1803tegra_sor_encoder_atomic_check(struct drm_encoder *encoder,1804 struct drm_crtc_state *crtc_state,1805 struct drm_connector_state *conn_state)1806{1807 struct tegra_output *output = encoder_to_output(encoder);1808 struct tegra_sor_state *state = to_sor_state(conn_state);1809 struct tegra_dc *dc = to_tegra_dc(conn_state->crtc);1810 unsigned long pclk = crtc_state->mode.clock * 1000;1811 struct tegra_sor *sor = to_sor(output);1812 struct drm_display_info *info;1813 int err;1814 1815 info = &output->connector.display_info;1816 1817 /*1818 * For HBR2 modes, the SOR brick needs to use the x20 multiplier, so1819 * the pixel clock must be corrected accordingly.1820 */1821 if (pclk >= 340000000) {1822 state->link_speed = 20;1823 state->pclk = pclk / 2;1824 } else {1825 state->link_speed = 10;1826 state->pclk = pclk;1827 }1828 1829 err = tegra_dc_state_setup_clock(dc, crtc_state, sor->clk_parent,1830 pclk, 0);1831 if (err < 0) {1832 dev_err(output->dev, "failed to setup CRTC state: %d\n", err);1833 return err;1834 }1835 1836 switch (info->bpc) {1837 case 8:1838 case 6:1839 state->bpc = info->bpc;1840 break;1841 1842 default:1843 DRM_DEBUG_KMS("%u bits-per-color not supported\n", info->bpc);1844 state->bpc = 8;1845 break;1846 }1847 1848 return 0;1849}1850 1851static inline u32 tegra_sor_hdmi_subpack(const u8 *ptr, size_t size)1852{1853 u32 value = 0;1854 size_t i;1855 1856 for (i = size; i > 0; i--)1857 value = (value << 8) | ptr[i - 1];1858 1859 return value;1860}1861 1862static void tegra_sor_hdmi_write_infopack(struct tegra_sor *sor,1863 const void *data, size_t size)1864{1865 const u8 *ptr = data;1866 unsigned long offset;1867 size_t i, j;1868 u32 value;1869 1870 switch (ptr[0]) {1871 case HDMI_INFOFRAME_TYPE_AVI:1872 offset = SOR_HDMI_AVI_INFOFRAME_HEADER;1873 break;1874 1875 case HDMI_INFOFRAME_TYPE_AUDIO:1876 offset = SOR_HDMI_AUDIO_INFOFRAME_HEADER;1877 break;1878 1879 case HDMI_INFOFRAME_TYPE_VENDOR:1880 offset = SOR_HDMI_VSI_INFOFRAME_HEADER;1881 break;1882 1883 default:1884 dev_err(sor->dev, "unsupported infoframe type: %02x\n",1885 ptr[0]);1886 return;1887 }1888 1889 value = INFOFRAME_HEADER_TYPE(ptr[0]) |1890 INFOFRAME_HEADER_VERSION(ptr[1]) |1891 INFOFRAME_HEADER_LEN(ptr[2]);1892 tegra_sor_writel(sor, value, offset);1893 offset++;1894 1895 /*1896 * Each subpack contains 7 bytes, divided into:1897 * - subpack_low: bytes 0 - 31898 * - subpack_high: bytes 4 - 6 (with byte 7 padded to 0x00)1899 */1900 for (i = 3, j = 0; i < size; i += 7, j += 8) {1901 size_t rem = size - i, num = min_t(size_t, rem, 4);1902 1903 value = tegra_sor_hdmi_subpack(&ptr[i], num);1904 tegra_sor_writel(sor, value, offset++);1905 1906 num = min_t(size_t, rem - num, 3);1907 1908 value = tegra_sor_hdmi_subpack(&ptr[i + 4], num);1909 tegra_sor_writel(sor, value, offset++);1910 }1911}1912 1913static int1914tegra_sor_hdmi_setup_avi_infoframe(struct tegra_sor *sor,1915 const struct drm_display_mode *mode)1916{1917 u8 buffer[HDMI_INFOFRAME_SIZE(AVI)];1918 struct hdmi_avi_infoframe frame;1919 u32 value;1920 int err;1921 1922 /* disable AVI infoframe */1923 value = tegra_sor_readl(sor, SOR_HDMI_AVI_INFOFRAME_CTRL);1924 value &= ~INFOFRAME_CTRL_SINGLE;1925 value &= ~INFOFRAME_CTRL_OTHER;1926 value &= ~INFOFRAME_CTRL_ENABLE;1927 tegra_sor_writel(sor, value, SOR_HDMI_AVI_INFOFRAME_CTRL);1928 1929 err = drm_hdmi_avi_infoframe_from_display_mode(&frame,1930 &sor->output.connector, mode);1931 if (err < 0) {1932 dev_err(sor->dev, "failed to setup AVI infoframe: %d\n", err);1933 return err;1934 }1935 1936 err = hdmi_avi_infoframe_pack(&frame, buffer, sizeof(buffer));1937 if (err < 0) {1938 dev_err(sor->dev, "failed to pack AVI infoframe: %d\n", err);1939 return err;1940 }1941 1942 tegra_sor_hdmi_write_infopack(sor, buffer, err);1943 1944 /* enable AVI infoframe */1945 value = tegra_sor_readl(sor, SOR_HDMI_AVI_INFOFRAME_CTRL);1946 value |= INFOFRAME_CTRL_CHECKSUM_ENABLE;1947 value |= INFOFRAME_CTRL_ENABLE;1948 tegra_sor_writel(sor, value, SOR_HDMI_AVI_INFOFRAME_CTRL);1949 1950 return 0;1951}1952 1953static void tegra_sor_write_eld(struct tegra_sor *sor)1954{1955 size_t length = drm_eld_size(sor->output.connector.eld), i;1956 1957 for (i = 0; i < length; i++)1958 tegra_sor_writel(sor, i << 8 | sor->output.connector.eld[i],1959 SOR_AUDIO_HDA_ELD_BUFWR);1960 1961 /*1962 * The HDA codec will always report an ELD buffer size of 96 bytes and1963 * the HDA codec driver will check that each byte read from the buffer1964 * is valid. Therefore every byte must be written, even if no 96 bytes1965 * were parsed from EDID.1966 */1967 for (i = length; i < 96; i++)1968 tegra_sor_writel(sor, i << 8 | 0, SOR_AUDIO_HDA_ELD_BUFWR);1969}1970 1971static void tegra_sor_audio_prepare(struct tegra_sor *sor)1972{1973 u32 value;1974 1975 /*1976 * Enable and unmask the HDA codec SCRATCH0 register interrupt. This1977 * is used for interoperability between the HDA codec driver and the1978 * HDMI/DP driver.1979 */1980 value = SOR_INT_CODEC_SCRATCH1 | SOR_INT_CODEC_SCRATCH0;1981 tegra_sor_writel(sor, value, SOR_INT_ENABLE);1982 tegra_sor_writel(sor, value, SOR_INT_MASK);1983 1984 tegra_sor_write_eld(sor);1985 1986 value = SOR_AUDIO_HDA_PRESENSE_ELDV | SOR_AUDIO_HDA_PRESENSE_PD;1987 tegra_sor_writel(sor, value, SOR_AUDIO_HDA_PRESENSE);1988}1989 1990static void tegra_sor_audio_unprepare(struct tegra_sor *sor)1991{1992 tegra_sor_writel(sor, 0, SOR_AUDIO_HDA_PRESENSE);1993 tegra_sor_writel(sor, 0, SOR_INT_MASK);1994 tegra_sor_writel(sor, 0, SOR_INT_ENABLE);1995}1996 1997static void tegra_sor_audio_enable(struct tegra_sor *sor)1998{1999 u32 value;2000 2001 value = tegra_sor_readl(sor, SOR_AUDIO_CNTRL);2002 2003 /* select HDA audio input */2004 value &= ~SOR_AUDIO_CNTRL_SOURCE_SELECT(SOURCE_SELECT_MASK);2005 value |= SOR_AUDIO_CNTRL_SOURCE_SELECT(SOURCE_SELECT_HDA);2006 2007 /* inject null samples */2008 if (sor->format.channels != 2)2009 value &= ~SOR_AUDIO_CNTRL_INJECT_NULLSMPL;2010 else2011 value |= SOR_AUDIO_CNTRL_INJECT_NULLSMPL;2012 2013 value |= SOR_AUDIO_CNTRL_AFIFO_FLUSH;2014 2015 tegra_sor_writel(sor, value, SOR_AUDIO_CNTRL);2016 2017 /* enable advertising HBR capability */2018 tegra_sor_writel(sor, SOR_AUDIO_SPARE_HBR_ENABLE, SOR_AUDIO_SPARE);2019}2020 2021static int tegra_sor_hdmi_enable_audio_infoframe(struct tegra_sor *sor)2022{2023 u8 buffer[HDMI_INFOFRAME_SIZE(AUDIO)];2024 struct hdmi_audio_infoframe frame;2025 u32 value;2026 int err;2027 2028 err = hdmi_audio_infoframe_init(&frame);2029 if (err < 0) {2030 dev_err(sor->dev, "failed to setup audio infoframe: %d\n", err);2031 return err;2032 }2033 2034 frame.channels = sor->format.channels;2035 2036 err = hdmi_audio_infoframe_pack(&frame, buffer, sizeof(buffer));2037 if (err < 0) {2038 dev_err(sor->dev, "failed to pack audio infoframe: %d\n", err);2039 return err;2040 }2041 2042 tegra_sor_hdmi_write_infopack(sor, buffer, err);2043 2044 value = tegra_sor_readl(sor, SOR_HDMI_AUDIO_INFOFRAME_CTRL);2045 value |= INFOFRAME_CTRL_CHECKSUM_ENABLE;2046 value |= INFOFRAME_CTRL_ENABLE;2047 tegra_sor_writel(sor, value, SOR_HDMI_AUDIO_INFOFRAME_CTRL);2048 2049 return 0;2050}2051 2052static void tegra_sor_hdmi_audio_enable(struct tegra_sor *sor)2053{2054 u32 value;2055 2056 tegra_sor_audio_enable(sor);2057 2058 tegra_sor_writel(sor, 0, SOR_HDMI_ACR_CTRL);2059 2060 value = SOR_HDMI_SPARE_ACR_PRIORITY_HIGH |2061 SOR_HDMI_SPARE_CTS_RESET(1) |2062 SOR_HDMI_SPARE_HW_CTS_ENABLE;2063 tegra_sor_writel(sor, value, SOR_HDMI_SPARE);2064 2065 /* enable HW CTS */2066 value = SOR_HDMI_ACR_SUBPACK_LOW_SB1(0);2067 tegra_sor_writel(sor, value, SOR_HDMI_ACR_0441_SUBPACK_LOW);2068 2069 /* allow packet to be sent */2070 value = SOR_HDMI_ACR_SUBPACK_HIGH_ENABLE;2071 tegra_sor_writel(sor, value, SOR_HDMI_ACR_0441_SUBPACK_HIGH);2072 2073 /* reset N counter and enable lookup */2074 value = SOR_HDMI_AUDIO_N_RESET | SOR_HDMI_AUDIO_N_LOOKUP;2075 tegra_sor_writel(sor, value, SOR_HDMI_AUDIO_N);2076 2077 value = (24000 * 4096) / (128 * sor->format.sample_rate / 1000);2078 tegra_sor_writel(sor, value, SOR_AUDIO_AVAL_0320);2079 tegra_sor_writel(sor, 4096, SOR_AUDIO_NVAL_0320);2080 2081 tegra_sor_writel(sor, 20000, SOR_AUDIO_AVAL_0441);2082 tegra_sor_writel(sor, 4704, SOR_AUDIO_NVAL_0441);2083 2084 tegra_sor_writel(sor, 20000, SOR_AUDIO_AVAL_0882);2085 tegra_sor_writel(sor, 9408, SOR_AUDIO_NVAL_0882);2086 2087 tegra_sor_writel(sor, 20000, SOR_AUDIO_AVAL_1764);2088 tegra_sor_writel(sor, 18816, SOR_AUDIO_NVAL_1764);2089 2090 value = (24000 * 6144) / (128 * sor->format.sample_rate / 1000);2091 tegra_sor_writel(sor, value, SOR_AUDIO_AVAL_0480);2092 tegra_sor_writel(sor, 6144, SOR_AUDIO_NVAL_0480);2093 2094 value = (24000 * 12288) / (128 * sor->format.sample_rate / 1000);2095 tegra_sor_writel(sor, value, SOR_AUDIO_AVAL_0960);2096 tegra_sor_writel(sor, 12288, SOR_AUDIO_NVAL_0960);2097 2098 value = (24000 * 24576) / (128 * sor->format.sample_rate / 1000);2099 tegra_sor_writel(sor, value, SOR_AUDIO_AVAL_1920);2100 tegra_sor_writel(sor, 24576, SOR_AUDIO_NVAL_1920);2101 2102 value = tegra_sor_readl(sor, SOR_HDMI_AUDIO_N);2103 value &= ~SOR_HDMI_AUDIO_N_RESET;2104 tegra_sor_writel(sor, value, SOR_HDMI_AUDIO_N);2105 2106 tegra_sor_hdmi_enable_audio_infoframe(sor);2107}2108 2109static void tegra_sor_hdmi_disable_audio_infoframe(struct tegra_sor *sor)2110{2111 u32 value;2112 2113 value = tegra_sor_readl(sor, SOR_HDMI_AUDIO_INFOFRAME_CTRL);2114 value &= ~INFOFRAME_CTRL_ENABLE;2115 tegra_sor_writel(sor, value, SOR_HDMI_AUDIO_INFOFRAME_CTRL);2116}2117 2118static void tegra_sor_hdmi_audio_disable(struct tegra_sor *sor)2119{2120 tegra_sor_hdmi_disable_audio_infoframe(sor);2121}2122 2123static struct tegra_sor_hdmi_settings *2124tegra_sor_hdmi_find_settings(struct tegra_sor *sor, unsigned long frequency)2125{2126 unsigned int i;2127 2128 for (i = 0; i < sor->num_settings; i++)2129 if (frequency <= sor->settings[i].frequency)2130 return &sor->settings[i];2131 2132 return NULL;2133}2134 2135static void tegra_sor_hdmi_disable_scrambling(struct tegra_sor *sor)2136{2137 u32 value;2138 2139 value = tegra_sor_readl(sor, SOR_HDMI2_CTRL);2140 value &= ~SOR_HDMI2_CTRL_CLOCK_MODE_DIV_BY_4;2141 value &= ~SOR_HDMI2_CTRL_SCRAMBLE;2142 tegra_sor_writel(sor, value, SOR_HDMI2_CTRL);2143}2144 2145static void tegra_sor_hdmi_scdc_disable(struct tegra_sor *sor)2146{2147 drm_scdc_set_high_tmds_clock_ratio(&sor->output.connector, false);2148 drm_scdc_set_scrambling(&sor->output.connector, false);2149 2150 tegra_sor_hdmi_disable_scrambling(sor);2151}2152 2153static void tegra_sor_hdmi_scdc_stop(struct tegra_sor *sor)2154{2155 if (sor->scdc_enabled) {2156 cancel_delayed_work_sync(&sor->scdc);2157 tegra_sor_hdmi_scdc_disable(sor);2158 }2159}2160 2161static void tegra_sor_hdmi_enable_scrambling(struct tegra_sor *sor)2162{2163 u32 value;2164 2165 value = tegra_sor_readl(sor, SOR_HDMI2_CTRL);2166 value |= SOR_HDMI2_CTRL_CLOCK_MODE_DIV_BY_4;2167 value |= SOR_HDMI2_CTRL_SCRAMBLE;2168 tegra_sor_writel(sor, value, SOR_HDMI2_CTRL);2169}2170 2171static void tegra_sor_hdmi_scdc_enable(struct tegra_sor *sor)2172{2173 drm_scdc_set_high_tmds_clock_ratio(&sor->output.connector, true);2174 drm_scdc_set_scrambling(&sor->output.connector, true);2175 2176 tegra_sor_hdmi_enable_scrambling(sor);2177}2178 2179static void tegra_sor_hdmi_scdc_work(struct work_struct *work)2180{2181 struct tegra_sor *sor = container_of(work, struct tegra_sor, scdc.work);2182 2183 if (!drm_scdc_get_scrambling_status(&sor->output.connector)) {2184 DRM_DEBUG_KMS("SCDC not scrambled\n");2185 tegra_sor_hdmi_scdc_enable(sor);2186 }2187 2188 schedule_delayed_work(&sor->scdc, msecs_to_jiffies(5000));2189}2190 2191static void tegra_sor_hdmi_scdc_start(struct tegra_sor *sor)2192{2193 struct drm_scdc *scdc = &sor->output.connector.display_info.hdmi.scdc;2194 struct drm_display_mode *mode;2195 2196 mode = &sor->output.encoder.crtc->state->adjusted_mode;2197 2198 if (mode->clock >= 340000 && scdc->supported) {2199 schedule_delayed_work(&sor->scdc, msecs_to_jiffies(5000));2200 tegra_sor_hdmi_scdc_enable(sor);2201 sor->scdc_enabled = true;2202 }2203}2204 2205static void tegra_sor_hdmi_disable(struct drm_encoder *encoder)2206{2207 struct tegra_output *output = encoder_to_output(encoder);2208 struct tegra_dc *dc = to_tegra_dc(encoder->crtc);2209 struct tegra_sor *sor = to_sor(output);2210 u32 value;2211 int err;2212 2213 tegra_sor_audio_unprepare(sor);2214 tegra_sor_hdmi_scdc_stop(sor);2215 2216 err = tegra_sor_detach(sor);2217 if (err < 0)2218 dev_err(sor->dev, "failed to detach SOR: %d\n", err);2219 2220 tegra_sor_writel(sor, 0, SOR_STATE1);2221 tegra_sor_update(sor);2222 2223 /* disable display to SOR clock */2224 value = tegra_dc_readl(dc, DC_DISP_DISP_WIN_OPTIONS);2225 2226 if (!sor->soc->has_nvdisplay)2227 value &= ~SOR1_TIMING_CYA;2228 2229 value &= ~SOR_ENABLE(sor->index);2230 2231 tegra_dc_writel(dc, value, DC_DISP_DISP_WIN_OPTIONS);2232 2233 tegra_dc_commit(dc);2234 2235 err = tegra_sor_power_down(sor);2236 if (err < 0)2237 dev_err(sor->dev, "failed to power down SOR: %d\n", err);2238 2239 err = tegra_io_pad_power_disable(sor->pad);2240 if (err < 0)2241 dev_err(sor->dev, "failed to power off I/O pad: %d\n", err);2242 2243 host1x_client_suspend(&sor->client);2244}2245 2246static void tegra_sor_hdmi_enable(struct drm_encoder *encoder)2247{2248 struct tegra_output *output = encoder_to_output(encoder);2249 unsigned int h_ref_to_sync = 1, pulse_start, max_ac;2250 struct tegra_dc *dc = to_tegra_dc(encoder->crtc);2251 struct tegra_sor_hdmi_settings *settings;2252 struct tegra_sor *sor = to_sor(output);2253 struct tegra_sor_state *state;2254 struct drm_display_mode *mode;2255 unsigned long rate, pclk;2256 unsigned int div, i;2257 u32 value;2258 int err;2259 2260 state = to_sor_state(output->connector.state);2261 mode = &encoder->crtc->state->adjusted_mode;2262 pclk = mode->clock * 1000;2263 2264 err = host1x_client_resume(&sor->client);2265 if (err < 0) {2266 dev_err(sor->dev, "failed to resume: %d\n", err);2267 return;2268 }2269 2270 /* switch to safe parent clock */2271 err = tegra_sor_set_parent_clock(sor, sor->clk_safe);2272 if (err < 0) {2273 dev_err(sor->dev, "failed to set safe parent clock: %d\n", err);2274 return;2275 }2276 2277 div = clk_get_rate(sor->clk) / 1000000 * 4;2278 2279 err = tegra_io_pad_power_enable(sor->pad);2280 if (err < 0)2281 dev_err(sor->dev, "failed to power on I/O pad: %d\n", err);2282 2283 usleep_range(20, 100);2284 2285 value = tegra_sor_readl(sor, sor->soc->regs->pll2);2286 value &= ~SOR_PLL2_BANDGAP_POWERDOWN;2287 tegra_sor_writel(sor, value, sor->soc->regs->pll2);2288 2289 usleep_range(20, 100);2290 2291 value = tegra_sor_readl(sor, sor->soc->regs->pll3);2292 value &= ~SOR_PLL3_PLL_VDD_MODE_3V3;2293 tegra_sor_writel(sor, value, sor->soc->regs->pll3);2294 2295 value = tegra_sor_readl(sor, sor->soc->regs->pll0);2296 value &= ~SOR_PLL0_VCOPD;2297 value &= ~SOR_PLL0_PWR;2298 tegra_sor_writel(sor, value, sor->soc->regs->pll0);2299 2300 value = tegra_sor_readl(sor, sor->soc->regs->pll2);2301 value &= ~SOR_PLL2_SEQ_PLLCAPPD_ENFORCE;2302 tegra_sor_writel(sor, value, sor->soc->regs->pll2);2303 2304 usleep_range(200, 400);2305 2306 value = tegra_sor_readl(sor, sor->soc->regs->pll2);2307 value &= ~SOR_PLL2_POWERDOWN_OVERRIDE;2308 value &= ~SOR_PLL2_PORT_POWERDOWN;2309 tegra_sor_writel(sor, value, sor->soc->regs->pll2);2310 2311 usleep_range(20, 100);2312 2313 value = tegra_sor_readl(sor, sor->soc->regs->dp_padctl0);2314 value |= SOR_DP_PADCTL_PD_TXD_3 | SOR_DP_PADCTL_PD_TXD_0 |2315 SOR_DP_PADCTL_PD_TXD_1 | SOR_DP_PADCTL_PD_TXD_2;2316 tegra_sor_writel(sor, value, sor->soc->regs->dp_padctl0);2317 2318 while (true) {2319 value = tegra_sor_readl(sor, SOR_LANE_SEQ_CTL);2320 if ((value & SOR_LANE_SEQ_CTL_STATE_BUSY) == 0)2321 break;2322 2323 usleep_range(250, 1000);2324 }2325 2326 value = SOR_LANE_SEQ_CTL_TRIGGER | SOR_LANE_SEQ_CTL_SEQUENCE_DOWN |2327 SOR_LANE_SEQ_CTL_POWER_STATE_UP | SOR_LANE_SEQ_CTL_DELAY(5);2328 tegra_sor_writel(sor, value, SOR_LANE_SEQ_CTL);2329 2330 while (true) {2331 value = tegra_sor_readl(sor, SOR_LANE_SEQ_CTL);2332 if ((value & SOR_LANE_SEQ_CTL_TRIGGER) == 0)2333 break;2334 2335 usleep_range(250, 1000);2336 }2337 2338 value = tegra_sor_readl(sor, SOR_CLK_CNTRL);2339 value &= ~SOR_CLK_CNTRL_DP_LINK_SPEED_MASK;2340 value &= ~SOR_CLK_CNTRL_DP_CLK_SEL_MASK;2341 2342 if (mode->clock < 340000) {2343 DRM_DEBUG_KMS("setting 2.7 GHz link speed\n");2344 value |= SOR_CLK_CNTRL_DP_LINK_SPEED_G2_70;2345 } else {2346 DRM_DEBUG_KMS("setting 5.4 GHz link speed\n");2347 value |= SOR_CLK_CNTRL_DP_LINK_SPEED_G5_40;2348 }2349 2350 value |= SOR_CLK_CNTRL_DP_CLK_SEL_SINGLE_PCLK;2351 tegra_sor_writel(sor, value, SOR_CLK_CNTRL);2352 2353 /* SOR pad PLL stabilization time */2354 usleep_range(250, 1000);2355 2356 value = tegra_sor_readl(sor, SOR_DP_LINKCTL0);2357 value &= ~SOR_DP_LINKCTL_LANE_COUNT_MASK;2358 value |= SOR_DP_LINKCTL_LANE_COUNT(4);2359 tegra_sor_writel(sor, value, SOR_DP_LINKCTL0);2360 2361 value = tegra_sor_readl(sor, SOR_DP_SPARE0);2362 value &= ~SOR_DP_SPARE_DISP_VIDEO_PREAMBLE;2363 value &= ~SOR_DP_SPARE_PANEL_INTERNAL;2364 value &= ~SOR_DP_SPARE_SEQ_ENABLE;2365 value &= ~SOR_DP_SPARE_MACRO_SOR_CLK;2366 tegra_sor_writel(sor, value, SOR_DP_SPARE0);2367 2368 value = SOR_SEQ_CTL_PU_PC(0) | SOR_SEQ_CTL_PU_PC_ALT(0) |2369 SOR_SEQ_CTL_PD_PC(8) | SOR_SEQ_CTL_PD_PC_ALT(8);2370 tegra_sor_writel(sor, value, SOR_SEQ_CTL);2371 2372 value = SOR_SEQ_INST_DRIVE_PWM_OUT_LO | SOR_SEQ_INST_HALT |2373 SOR_SEQ_INST_WAIT_VSYNC | SOR_SEQ_INST_WAIT(1);2374 tegra_sor_writel(sor, value, SOR_SEQ_INST(0));2375 tegra_sor_writel(sor, value, SOR_SEQ_INST(8));2376 2377 if (!sor->soc->has_nvdisplay) {2378 /* program the reference clock */2379 value = SOR_REFCLK_DIV_INT(div) | SOR_REFCLK_DIV_FRAC(div);2380 tegra_sor_writel(sor, value, SOR_REFCLK);2381 }2382 2383 /* XXX not in TRM */2384 for (value = 0, i = 0; i < 5; i++)2385 value |= SOR_XBAR_CTRL_LINK0_XSEL(i, sor->xbar_cfg[i]) |2386 SOR_XBAR_CTRL_LINK1_XSEL(i, i);2387 2388 tegra_sor_writel(sor, 0x00000000, SOR_XBAR_POL);2389 tegra_sor_writel(sor, value, SOR_XBAR_CTRL);2390 2391 /*2392 * Switch the pad clock to the DP clock. Note that we cannot actually2393 * do this because Tegra186 and later don't support clk_set_parent()2394 * on the sorX_pad_clkout clocks. We already do the equivalent above2395 * using the DP_CLK_SEL mux of the SOR_CLK_CNTRL register.2396 */2397#if 02398 err = clk_set_parent(sor->clk_pad, sor->clk_dp);2399 if (err < 0) {2400 dev_err(sor->dev, "failed to select pad parent clock: %d\n",2401 err);2402 return;2403 }2404#endif2405 2406 /* switch the SOR clock to the pad clock */2407 err = tegra_sor_set_parent_clock(sor, sor->clk_pad);2408 if (err < 0) {2409 dev_err(sor->dev, "failed to select SOR parent clock: %d\n",2410 err);2411 return;2412 }2413 2414 /* switch the output clock to the parent pixel clock */2415 err = clk_set_parent(sor->clk, sor->clk_parent);2416 if (err < 0) {2417 dev_err(sor->dev, "failed to select output parent clock: %d\n",2418 err);2419 return;2420 }2421 2422 /* adjust clock rate for HDMI 2.0 modes */2423 rate = clk_get_rate(sor->clk_parent);2424 2425 if (mode->clock >= 340000)2426 rate /= 2;2427 2428 DRM_DEBUG_KMS("setting clock to %lu Hz, mode: %lu Hz\n", rate, pclk);2429 2430 clk_set_rate(sor->clk, rate);2431 2432 if (!sor->soc->has_nvdisplay) {2433 value = SOR_INPUT_CONTROL_HDMI_SRC_SELECT(dc->pipe);2434 2435 /* XXX is this the proper check? */2436 if (mode->clock < 75000)2437 value |= SOR_INPUT_CONTROL_ARM_VIDEO_RANGE_LIMITED;2438 2439 tegra_sor_writel(sor, value, SOR_INPUT_CONTROL);2440 }2441 2442 max_ac = ((mode->htotal - mode->hdisplay) - SOR_REKEY - 18) / 32;2443 2444 value = SOR_HDMI_CTRL_ENABLE | SOR_HDMI_CTRL_MAX_AC_PACKET(max_ac) |2445 SOR_HDMI_CTRL_AUDIO_LAYOUT | SOR_HDMI_CTRL_REKEY(SOR_REKEY);2446 tegra_sor_writel(sor, value, SOR_HDMI_CTRL);2447 2448 if (!dc->soc->has_nvdisplay) {2449 /* H_PULSE2 setup */2450 pulse_start = h_ref_to_sync +2451 (mode->hsync_end - mode->hsync_start) +2452 (mode->htotal - mode->hsync_end) - 10;2453 2454 value = PULSE_LAST_END_A | PULSE_QUAL_VACTIVE |2455 PULSE_POLARITY_HIGH | PULSE_MODE_NORMAL;2456 tegra_dc_writel(dc, value, DC_DISP_H_PULSE2_CONTROL);2457 2458 value = PULSE_END(pulse_start + 8) | PULSE_START(pulse_start);2459 tegra_dc_writel(dc, value, DC_DISP_H_PULSE2_POSITION_A);2460 2461 value = tegra_dc_readl(dc, DC_DISP_DISP_SIGNAL_OPTIONS0);2462 value |= H_PULSE2_ENABLE;2463 tegra_dc_writel(dc, value, DC_DISP_DISP_SIGNAL_OPTIONS0);2464 }2465 2466 /* infoframe setup */2467 err = tegra_sor_hdmi_setup_avi_infoframe(sor, mode);2468 if (err < 0)2469 dev_err(sor->dev, "failed to setup AVI infoframe: %d\n", err);2470 2471 /* XXX HDMI audio support not implemented yet */2472 tegra_sor_hdmi_disable_audio_infoframe(sor);2473 2474 /* use single TMDS protocol */2475 value = tegra_sor_readl(sor, SOR_STATE1);2476 value &= ~SOR_STATE_ASY_PROTOCOL_MASK;2477 value |= SOR_STATE_ASY_PROTOCOL_SINGLE_TMDS_A;2478 tegra_sor_writel(sor, value, SOR_STATE1);2479 2480 /* power up pad calibration */2481 value = tegra_sor_readl(sor, sor->soc->regs->dp_padctl0);2482 value &= ~SOR_DP_PADCTL_PAD_CAL_PD;2483 tegra_sor_writel(sor, value, sor->soc->regs->dp_padctl0);2484 2485 /* production settings */2486 settings = tegra_sor_hdmi_find_settings(sor, mode->clock * 1000);2487 if (!settings) {2488 dev_err(sor->dev, "no settings for pixel clock %d Hz\n",2489 mode->clock * 1000);2490 return;2491 }2492 2493 value = tegra_sor_readl(sor, sor->soc->regs->pll0);2494 value &= ~SOR_PLL0_ICHPMP_MASK;2495 value &= ~SOR_PLL0_FILTER_MASK;2496 value &= ~SOR_PLL0_VCOCAP_MASK;2497 value |= SOR_PLL0_ICHPMP(settings->ichpmp);2498 value |= SOR_PLL0_FILTER(settings->filter);2499 value |= SOR_PLL0_VCOCAP(settings->vcocap);2500 tegra_sor_writel(sor, value, sor->soc->regs->pll0);2501 2502 /* XXX not in TRM */2503 value = tegra_sor_readl(sor, sor->soc->regs->pll1);2504 value &= ~SOR_PLL1_LOADADJ_MASK;2505 value &= ~SOR_PLL1_TMDS_TERMADJ_MASK;2506 value |= SOR_PLL1_LOADADJ(settings->loadadj);2507 value |= SOR_PLL1_TMDS_TERMADJ(settings->tmds_termadj);2508 value |= SOR_PLL1_TMDS_TERM;2509 tegra_sor_writel(sor, value, sor->soc->regs->pll1);2510 2511 value = tegra_sor_readl(sor, sor->soc->regs->pll3);2512 value &= ~SOR_PLL3_BG_TEMP_COEF_MASK;2513 value &= ~SOR_PLL3_BG_VREF_LEVEL_MASK;2514 value &= ~SOR_PLL3_AVDD10_LEVEL_MASK;2515 value &= ~SOR_PLL3_AVDD14_LEVEL_MASK;2516 value |= SOR_PLL3_BG_TEMP_COEF(settings->bg_temp_coef);2517 value |= SOR_PLL3_BG_VREF_LEVEL(settings->bg_vref_level);2518 value |= SOR_PLL3_AVDD10_LEVEL(settings->avdd10_level);2519 value |= SOR_PLL3_AVDD14_LEVEL(settings->avdd14_level);2520 tegra_sor_writel(sor, value, sor->soc->regs->pll3);2521 2522 value = settings->drive_current[3] << 24 |2523 settings->drive_current[2] << 16 |2524 settings->drive_current[1] << 8 |2525 settings->drive_current[0] << 0;2526 tegra_sor_writel(sor, value, SOR_LANE_DRIVE_CURRENT0);2527 2528 value = settings->preemphasis[3] << 24 |2529 settings->preemphasis[2] << 16 |2530 settings->preemphasis[1] << 8 |2531 settings->preemphasis[0] << 0;2532 tegra_sor_writel(sor, value, SOR_LANE_PREEMPHASIS0);2533 2534 value = tegra_sor_readl(sor, sor->soc->regs->dp_padctl0);2535 value &= ~SOR_DP_PADCTL_TX_PU_MASK;2536 value |= SOR_DP_PADCTL_TX_PU_ENABLE;2537 value |= SOR_DP_PADCTL_TX_PU(settings->tx_pu_value);2538 tegra_sor_writel(sor, value, sor->soc->regs->dp_padctl0);2539 2540 value = tegra_sor_readl(sor, sor->soc->regs->dp_padctl2);2541 value &= ~SOR_DP_PADCTL_SPAREPLL_MASK;2542 value |= SOR_DP_PADCTL_SPAREPLL(settings->sparepll);2543 tegra_sor_writel(sor, value, sor->soc->regs->dp_padctl2);2544 2545 /* power down pad calibration */2546 value = tegra_sor_readl(sor, sor->soc->regs->dp_padctl0);2547 value |= SOR_DP_PADCTL_PAD_CAL_PD;2548 tegra_sor_writel(sor, value, sor->soc->regs->dp_padctl0);2549 2550 if (!dc->soc->has_nvdisplay) {2551 /* miscellaneous display controller settings */2552 value = VSYNC_H_POSITION(1);2553 tegra_dc_writel(dc, value, DC_DISP_DISP_TIMING_OPTIONS);2554 }2555 2556 value = tegra_dc_readl(dc, DC_DISP_DISP_COLOR_CONTROL);2557 value &= ~DITHER_CONTROL_MASK;2558 value &= ~BASE_COLOR_SIZE_MASK;2559 2560 switch (state->bpc) {2561 case 6:2562 value |= BASE_COLOR_SIZE_666;2563 break;2564 2565 case 8:2566 value |= BASE_COLOR_SIZE_888;2567 break;2568 2569 case 10:2570 value |= BASE_COLOR_SIZE_101010;2571 break;2572 2573 case 12:2574 value |= BASE_COLOR_SIZE_121212;2575 break;2576 2577 default:2578 WARN(1, "%u bits-per-color not supported\n", state->bpc);2579 value |= BASE_COLOR_SIZE_888;2580 break;2581 }2582 2583 tegra_dc_writel(dc, value, DC_DISP_DISP_COLOR_CONTROL);2584 2585 /* XXX set display head owner */2586 value = tegra_sor_readl(sor, SOR_STATE1);2587 value &= ~SOR_STATE_ASY_OWNER_MASK;2588 value |= SOR_STATE_ASY_OWNER(1 + dc->pipe);2589 tegra_sor_writel(sor, value, SOR_STATE1);2590 2591 err = tegra_sor_power_up(sor, 250);2592 if (err < 0)2593 dev_err(sor->dev, "failed to power up SOR: %d\n", err);2594 2595 /* configure dynamic range of output */2596 value = tegra_sor_readl(sor, sor->soc->regs->head_state0 + dc->pipe);2597 value &= ~SOR_HEAD_STATE_RANGECOMPRESS_MASK;2598 value &= ~SOR_HEAD_STATE_DYNRANGE_MASK;2599 tegra_sor_writel(sor, value, sor->soc->regs->head_state0 + dc->pipe);2600 2601 /* configure colorspace */2602 value = tegra_sor_readl(sor, sor->soc->regs->head_state0 + dc->pipe);2603 value &= ~SOR_HEAD_STATE_COLORSPACE_MASK;2604 value |= SOR_HEAD_STATE_COLORSPACE_RGB;2605 tegra_sor_writel(sor, value, sor->soc->regs->head_state0 + dc->pipe);2606 2607 tegra_sor_mode_set(sor, mode, state);2608 2609 tegra_sor_update(sor);2610 2611 /* program preamble timing in SOR (XXX) */2612 value = tegra_sor_readl(sor, SOR_DP_SPARE0);2613 value &= ~SOR_DP_SPARE_DISP_VIDEO_PREAMBLE;2614 tegra_sor_writel(sor, value, SOR_DP_SPARE0);2615 2616 err = tegra_sor_attach(sor);2617 if (err < 0)2618 dev_err(sor->dev, "failed to attach SOR: %d\n", err);2619 2620 /* enable display to SOR clock and generate HDMI preamble */2621 value = tegra_dc_readl(dc, DC_DISP_DISP_WIN_OPTIONS);2622 2623 if (!sor->soc->has_nvdisplay)2624 value |= SOR1_TIMING_CYA;2625 2626 value |= SOR_ENABLE(sor->index);2627 2628 tegra_dc_writel(dc, value, DC_DISP_DISP_WIN_OPTIONS);2629 2630 if (dc->soc->has_nvdisplay) {2631 value = tegra_dc_readl(dc, DC_DISP_CORE_SOR_SET_CONTROL(sor->index));2632 value &= ~PROTOCOL_MASK;2633 value |= PROTOCOL_SINGLE_TMDS_A;2634 tegra_dc_writel(dc, value, DC_DISP_CORE_SOR_SET_CONTROL(sor->index));2635 }2636 2637 tegra_dc_commit(dc);2638 2639 err = tegra_sor_wakeup(sor);2640 if (err < 0)2641 dev_err(sor->dev, "failed to wakeup SOR: %d\n", err);2642 2643 tegra_sor_hdmi_scdc_start(sor);2644 tegra_sor_audio_prepare(sor);2645}2646 2647static const struct drm_encoder_helper_funcs tegra_sor_hdmi_helpers = {2648 .disable = tegra_sor_hdmi_disable,2649 .enable = tegra_sor_hdmi_enable,2650 .atomic_check = tegra_sor_encoder_atomic_check,2651};2652 2653static void tegra_sor_dp_disable(struct drm_encoder *encoder)2654{2655 struct tegra_output *output = encoder_to_output(encoder);2656 struct tegra_dc *dc = to_tegra_dc(encoder->crtc);2657 struct tegra_sor *sor = to_sor(output);2658 u32 value;2659 int err;2660 2661 if (output->panel)2662 drm_panel_disable(output->panel);2663 2664 /*2665 * Do not attempt to power down a DP link if we're not connected since2666 * the AUX transactions would just be timing out.2667 */2668 if (output->connector.status != connector_status_disconnected) {2669 err = drm_dp_link_power_down(sor->aux, &sor->link);2670 if (err < 0)2671 dev_err(sor->dev, "failed to power down link: %d\n",2672 err);2673 }2674 2675 err = tegra_sor_detach(sor);2676 if (err < 0)2677 dev_err(sor->dev, "failed to detach SOR: %d\n", err);2678 2679 tegra_sor_writel(sor, 0, SOR_STATE1);2680 tegra_sor_update(sor);2681 2682 value = tegra_dc_readl(dc, DC_DISP_DISP_WIN_OPTIONS);2683 value &= ~SOR_ENABLE(sor->index);2684 tegra_dc_writel(dc, value, DC_DISP_DISP_WIN_OPTIONS);2685 tegra_dc_commit(dc);2686 2687 value = tegra_sor_readl(sor, SOR_STATE1);2688 value &= ~SOR_STATE_ASY_PROTOCOL_MASK;2689 value &= ~SOR_STATE_ASY_SUBOWNER_MASK;2690 value &= ~SOR_STATE_ASY_OWNER_MASK;2691 tegra_sor_writel(sor, value, SOR_STATE1);2692 tegra_sor_update(sor);2693 2694 /* switch to safe parent clock */2695 err = tegra_sor_set_parent_clock(sor, sor->clk_safe);2696 if (err < 0)2697 dev_err(sor->dev, "failed to set safe clock: %d\n", err);2698 2699 err = tegra_sor_power_down(sor);2700 if (err < 0)2701 dev_err(sor->dev, "failed to power down SOR: %d\n", err);2702 2703 err = tegra_io_pad_power_disable(sor->pad);2704 if (err < 0)2705 dev_err(sor->dev, "failed to power off I/O pad: %d\n", err);2706 2707 err = drm_dp_aux_disable(sor->aux);2708 if (err < 0)2709 dev_err(sor->dev, "failed disable DPAUX: %d\n", err);2710 2711 if (output->panel)2712 drm_panel_unprepare(output->panel);2713 2714 host1x_client_suspend(&sor->client);2715}2716 2717static void tegra_sor_dp_enable(struct drm_encoder *encoder)2718{2719 struct tegra_output *output = encoder_to_output(encoder);2720 struct tegra_dc *dc = to_tegra_dc(encoder->crtc);2721 struct tegra_sor *sor = to_sor(output);2722 struct tegra_sor_config config;2723 struct tegra_sor_state *state;2724 struct drm_display_mode *mode;2725 struct drm_display_info *info;2726 unsigned int i;2727 u32 value;2728 int err;2729 2730 state = to_sor_state(output->connector.state);2731 mode = &encoder->crtc->state->adjusted_mode;2732 info = &output->connector.display_info;2733 2734 err = host1x_client_resume(&sor->client);2735 if (err < 0) {2736 dev_err(sor->dev, "failed to resume: %d\n", err);2737 return;2738 }2739 2740 /* switch to safe parent clock */2741 err = tegra_sor_set_parent_clock(sor, sor->clk_safe);2742 if (err < 0)2743 dev_err(sor->dev, "failed to set safe parent clock: %d\n", err);2744 2745 err = tegra_io_pad_power_enable(sor->pad);2746 if (err < 0)2747 dev_err(sor->dev, "failed to power on LVDS rail: %d\n", err);2748 2749 usleep_range(20, 100);2750 2751 err = drm_dp_aux_enable(sor->aux);2752 if (err < 0)2753 dev_err(sor->dev, "failed to enable DPAUX: %d\n", err);2754 2755 err = drm_dp_link_probe(sor->aux, &sor->link);2756 if (err < 0)2757 dev_err(sor->dev, "failed to probe DP link: %d\n", err);2758 2759 tegra_sor_filter_rates(sor);2760 2761 err = drm_dp_link_choose(&sor->link, mode, info);2762 if (err < 0)2763 dev_err(sor->dev, "failed to choose link: %d\n", err);2764 2765 if (output->panel)2766 drm_panel_prepare(output->panel);2767 2768 value = tegra_sor_readl(sor, sor->soc->regs->pll2);2769 value &= ~SOR_PLL2_BANDGAP_POWERDOWN;2770 tegra_sor_writel(sor, value, sor->soc->regs->pll2);2771 2772 usleep_range(20, 40);2773 2774 value = tegra_sor_readl(sor, sor->soc->regs->pll3);2775 value |= SOR_PLL3_PLL_VDD_MODE_3V3;2776 tegra_sor_writel(sor, value, sor->soc->regs->pll3);2777 2778 value = tegra_sor_readl(sor, sor->soc->regs->pll0);2779 value &= ~(SOR_PLL0_VCOPD | SOR_PLL0_PWR);2780 tegra_sor_writel(sor, value, sor->soc->regs->pll0);2781 2782 value = tegra_sor_readl(sor, sor->soc->regs->pll2);2783 value &= ~SOR_PLL2_SEQ_PLLCAPPD_ENFORCE;2784 value |= SOR_PLL2_SEQ_PLLCAPPD;2785 tegra_sor_writel(sor, value, sor->soc->regs->pll2);2786 2787 usleep_range(200, 400);2788 2789 value = tegra_sor_readl(sor, sor->soc->regs->pll2);2790 value &= ~SOR_PLL2_POWERDOWN_OVERRIDE;2791 value &= ~SOR_PLL2_PORT_POWERDOWN;2792 tegra_sor_writel(sor, value, sor->soc->regs->pll2);2793 2794 value = tegra_sor_readl(sor, SOR_CLK_CNTRL);2795 value &= ~SOR_CLK_CNTRL_DP_CLK_SEL_MASK;2796 2797 if (output->panel)2798 value |= SOR_CLK_CNTRL_DP_CLK_SEL_SINGLE_DPCLK;2799 else2800 value |= SOR_CLK_CNTRL_DP_CLK_SEL_DIFF_DPCLK;2801 2802 tegra_sor_writel(sor, value, SOR_CLK_CNTRL);2803 2804 usleep_range(200, 400);2805 2806 value = tegra_sor_readl(sor, SOR_DP_SPARE0);2807 /* XXX not in TRM */2808 if (output->panel)2809 value |= SOR_DP_SPARE_PANEL_INTERNAL;2810 else2811 value &= ~SOR_DP_SPARE_PANEL_INTERNAL;2812 2813 value |= SOR_DP_SPARE_SEQ_ENABLE;2814 tegra_sor_writel(sor, value, SOR_DP_SPARE0);2815 2816 /* XXX not in TRM */2817 tegra_sor_writel(sor, 0, SOR_LVDS);2818 2819 value = tegra_sor_readl(sor, sor->soc->regs->pll0);2820 value &= ~SOR_PLL0_ICHPMP_MASK;2821 value &= ~SOR_PLL0_VCOCAP_MASK;2822 value |= SOR_PLL0_ICHPMP(0x1);2823 value |= SOR_PLL0_VCOCAP(0x3);2824 value |= SOR_PLL0_RESISTOR_EXT;2825 tegra_sor_writel(sor, value, sor->soc->regs->pll0);2826 2827 /* XXX not in TRM */2828 for (value = 0, i = 0; i < 5; i++)2829 value |= SOR_XBAR_CTRL_LINK0_XSEL(i, sor->soc->xbar_cfg[i]) |2830 SOR_XBAR_CTRL_LINK1_XSEL(i, i);2831 2832 tegra_sor_writel(sor, 0x00000000, SOR_XBAR_POL);2833 tegra_sor_writel(sor, value, SOR_XBAR_CTRL);2834 2835 /*2836 * Switch the pad clock to the DP clock. Note that we cannot actually2837 * do this because Tegra186 and later don't support clk_set_parent()2838 * on the sorX_pad_clkout clocks. We already do the equivalent above2839 * using the DP_CLK_SEL mux of the SOR_CLK_CNTRL register.2840 */2841#if 02842 err = clk_set_parent(sor->clk_pad, sor->clk_parent);2843 if (err < 0) {2844 dev_err(sor->dev, "failed to select pad parent clock: %d\n",2845 err);2846 return;2847 }2848#endif2849 2850 /* switch the SOR clock to the pad clock */2851 err = tegra_sor_set_parent_clock(sor, sor->clk_pad);2852 if (err < 0) {2853 dev_err(sor->dev, "failed to select SOR parent clock: %d\n",2854 err);2855 return;2856 }2857 2858 /* switch the output clock to the parent pixel clock */2859 err = clk_set_parent(sor->clk, sor->clk_parent);2860 if (err < 0) {2861 dev_err(sor->dev, "failed to select output parent clock: %d\n",2862 err);2863 return;2864 }2865 2866 /* use DP-A protocol */2867 value = tegra_sor_readl(sor, SOR_STATE1);2868 value &= ~SOR_STATE_ASY_PROTOCOL_MASK;2869 value |= SOR_STATE_ASY_PROTOCOL_DP_A;2870 tegra_sor_writel(sor, value, SOR_STATE1);2871 2872 /* enable port */2873 value = tegra_sor_readl(sor, SOR_DP_LINKCTL0);2874 value |= SOR_DP_LINKCTL_ENABLE;2875 tegra_sor_writel(sor, value, SOR_DP_LINKCTL0);2876 2877 tegra_sor_dp_term_calibrate(sor);2878 2879 err = drm_dp_link_train(&sor->link);2880 if (err < 0)2881 dev_err(sor->dev, "link training failed: %d\n", err);2882 else2883 dev_dbg(sor->dev, "link training succeeded\n");2884 2885 err = drm_dp_link_power_up(sor->aux, &sor->link);2886 if (err < 0)2887 dev_err(sor->dev, "failed to power up DP link: %d\n", err);2888 2889 /* compute configuration */2890 memset(&config, 0, sizeof(config));2891 config.bits_per_pixel = state->bpc * 3;2892 2893 err = tegra_sor_compute_config(sor, mode, &config, &sor->link);2894 if (err < 0)2895 dev_err(sor->dev, "failed to compute configuration: %d\n", err);2896 2897 tegra_sor_apply_config(sor, &config);2898 tegra_sor_mode_set(sor, mode, state);2899 2900 if (output->panel) {2901 /* CSTM (LVDS, link A/B, upper) */2902 value = SOR_CSTM_LVDS | SOR_CSTM_LINK_ACT_A | SOR_CSTM_LINK_ACT_B |2903 SOR_CSTM_UPPER;2904 tegra_sor_writel(sor, value, SOR_CSTM);2905 2906 /* PWM setup */2907 err = tegra_sor_setup_pwm(sor, 250);2908 if (err < 0)2909 dev_err(sor->dev, "failed to setup PWM: %d\n", err);2910 }2911 2912 tegra_sor_update(sor);2913 2914 err = tegra_sor_power_up(sor, 250);2915 if (err < 0)2916 dev_err(sor->dev, "failed to power up SOR: %d\n", err);2917 2918 /* attach and wake up */2919 err = tegra_sor_attach(sor);2920 if (err < 0)2921 dev_err(sor->dev, "failed to attach SOR: %d\n", err);2922 2923 value = tegra_dc_readl(dc, DC_DISP_DISP_WIN_OPTIONS);2924 value |= SOR_ENABLE(sor->index);2925 tegra_dc_writel(dc, value, DC_DISP_DISP_WIN_OPTIONS);2926 2927 tegra_dc_commit(dc);2928 2929 err = tegra_sor_wakeup(sor);2930 if (err < 0)2931 dev_err(sor->dev, "failed to wakeup SOR: %d\n", err);2932 2933 if (output->panel)2934 drm_panel_enable(output->panel);2935}2936 2937static const struct drm_encoder_helper_funcs tegra_sor_dp_helpers = {2938 .disable = tegra_sor_dp_disable,2939 .enable = tegra_sor_dp_enable,2940 .atomic_check = tegra_sor_encoder_atomic_check,2941};2942 2943static void tegra_sor_disable_regulator(void *data)2944{2945 struct regulator *reg = data;2946 2947 regulator_disable(reg);2948}2949 2950static int tegra_sor_enable_regulator(struct tegra_sor *sor, struct regulator *reg)2951{2952 int err;2953 2954 err = regulator_enable(reg);2955 if (err)2956 return err;2957 2958 return devm_add_action_or_reset(sor->dev, tegra_sor_disable_regulator, reg);2959}2960 2961static int tegra_sor_hdmi_probe(struct tegra_sor *sor)2962{2963 int err;2964 2965 sor->avdd_io_supply = devm_regulator_get(sor->dev, "avdd-io-hdmi-dp");2966 if (IS_ERR(sor->avdd_io_supply))2967 return dev_err_probe(sor->dev, PTR_ERR(sor->avdd_io_supply),2968 "cannot get AVDD I/O supply\n");2969 2970 err = tegra_sor_enable_regulator(sor, sor->avdd_io_supply);2971 if (err < 0) {2972 dev_err(sor->dev, "failed to enable AVDD I/O supply: %d\n",2973 err);2974 return err;2975 }2976 2977 sor->vdd_pll_supply = devm_regulator_get(sor->dev, "vdd-hdmi-dp-pll");2978 if (IS_ERR(sor->vdd_pll_supply))2979 return dev_err_probe(sor->dev, PTR_ERR(sor->vdd_pll_supply),2980 "cannot get VDD PLL supply\n");2981 2982 err = tegra_sor_enable_regulator(sor, sor->vdd_pll_supply);2983 if (err < 0) {2984 dev_err(sor->dev, "failed to enable VDD PLL supply: %d\n",2985 err);2986 return err;2987 }2988 2989 sor->hdmi_supply = devm_regulator_get(sor->dev, "hdmi");2990 if (IS_ERR(sor->hdmi_supply))2991 return dev_err_probe(sor->dev, PTR_ERR(sor->hdmi_supply),2992 "cannot get HDMI supply\n");2993 2994 err = tegra_sor_enable_regulator(sor, sor->hdmi_supply);2995 if (err < 0) {2996 dev_err(sor->dev, "failed to enable HDMI supply: %d\n", err);2997 return err;2998 }2999 3000 INIT_DELAYED_WORK(&sor->scdc, tegra_sor_hdmi_scdc_work);3001 3002 return 0;3003}3004 3005static const struct tegra_sor_ops tegra_sor_hdmi_ops = {3006 .name = "HDMI",3007 .probe = tegra_sor_hdmi_probe,3008 .audio_enable = tegra_sor_hdmi_audio_enable,3009 .audio_disable = tegra_sor_hdmi_audio_disable,3010};3011 3012static int tegra_sor_dp_probe(struct tegra_sor *sor)3013{3014 int err;3015 3016 sor->avdd_io_supply = devm_regulator_get(sor->dev, "avdd-io-hdmi-dp");3017 if (IS_ERR(sor->avdd_io_supply))3018 return PTR_ERR(sor->avdd_io_supply);3019 3020 err = tegra_sor_enable_regulator(sor, sor->avdd_io_supply);3021 if (err < 0)3022 return err;3023 3024 sor->vdd_pll_supply = devm_regulator_get(sor->dev, "vdd-hdmi-dp-pll");3025 if (IS_ERR(sor->vdd_pll_supply))3026 return PTR_ERR(sor->vdd_pll_supply);3027 3028 err = tegra_sor_enable_regulator(sor, sor->vdd_pll_supply);3029 if (err < 0)3030 return err;3031 3032 return 0;3033}3034 3035static const struct tegra_sor_ops tegra_sor_dp_ops = {3036 .name = "DP",3037 .probe = tegra_sor_dp_probe,3038};3039 3040static int tegra_sor_init(struct host1x_client *client)3041{3042 struct drm_device *drm = dev_get_drvdata(client->host);3043 const struct drm_encoder_helper_funcs *helpers = NULL;3044 struct tegra_sor *sor = host1x_client_to_sor(client);3045 int connector = DRM_MODE_CONNECTOR_Unknown;3046 int encoder = DRM_MODE_ENCODER_NONE;3047 int err;3048 3049 if (!sor->aux) {3050 if (sor->ops == &tegra_sor_hdmi_ops) {3051 connector = DRM_MODE_CONNECTOR_HDMIA;3052 encoder = DRM_MODE_ENCODER_TMDS;3053 helpers = &tegra_sor_hdmi_helpers;3054 } else if (sor->soc->supports_lvds) {3055 connector = DRM_MODE_CONNECTOR_LVDS;3056 encoder = DRM_MODE_ENCODER_LVDS;3057 }3058 } else {3059 if (sor->output.panel) {3060 connector = DRM_MODE_CONNECTOR_eDP;3061 encoder = DRM_MODE_ENCODER_TMDS;3062 helpers = &tegra_sor_dp_helpers;3063 } else {3064 connector = DRM_MODE_CONNECTOR_DisplayPort;3065 encoder = DRM_MODE_ENCODER_TMDS;3066 helpers = &tegra_sor_dp_helpers;3067 }3068 3069 sor->link.ops = &tegra_sor_dp_link_ops;3070 sor->link.aux = sor->aux;3071 }3072 3073 sor->output.dev = sor->dev;3074 3075 drm_connector_init_with_ddc(drm, &sor->output.connector,3076 &tegra_sor_connector_funcs,3077 connector,3078 sor->output.ddc);3079 drm_connector_helper_add(&sor->output.connector,3080 &tegra_sor_connector_helper_funcs);3081 sor->output.connector.dpms = DRM_MODE_DPMS_OFF;3082 3083 drm_simple_encoder_init(drm, &sor->output.encoder, encoder);3084 drm_encoder_helper_add(&sor->output.encoder, helpers);3085 3086 drm_connector_attach_encoder(&sor->output.connector,3087 &sor->output.encoder);3088 drm_connector_register(&sor->output.connector);3089 3090 err = tegra_output_init(drm, &sor->output);3091 if (err < 0) {3092 dev_err(client->dev, "failed to initialize output: %d\n", err);3093 return err;3094 }3095 3096 tegra_output_find_possible_crtcs(&sor->output, drm);3097 3098 if (sor->aux) {3099 err = drm_dp_aux_attach(sor->aux, &sor->output);3100 if (err < 0) {3101 dev_err(sor->dev, "failed to attach DP: %d\n", err);3102 return err;3103 }3104 }3105 3106 /*3107 * XXX: Remove this reset once proper hand-over from firmware to3108 * kernel is possible.3109 */3110 if (sor->rst) {3111 err = pm_runtime_resume_and_get(sor->dev);3112 if (err < 0) {3113 dev_err(sor->dev, "failed to get runtime PM: %d\n", err);3114 return err;3115 }3116 3117 err = reset_control_acquire(sor->rst);3118 if (err < 0) {3119 dev_err(sor->dev, "failed to acquire SOR reset: %d\n",3120 err);3121 goto rpm_put;3122 }3123 3124 err = reset_control_assert(sor->rst);3125 if (err < 0) {3126 dev_err(sor->dev, "failed to assert SOR reset: %d\n",3127 err);3128 goto rpm_put;3129 }3130 }3131 3132 err = clk_prepare_enable(sor->clk);3133 if (err < 0) {3134 dev_err(sor->dev, "failed to enable clock: %d\n", err);3135 goto rpm_put;3136 }3137 3138 usleep_range(1000, 3000);3139 3140 if (sor->rst) {3141 err = reset_control_deassert(sor->rst);3142 if (err < 0) {3143 dev_err(sor->dev, "failed to deassert SOR reset: %d\n",3144 err);3145 clk_disable_unprepare(sor->clk);3146 goto rpm_put;3147 }3148 3149 reset_control_release(sor->rst);3150 pm_runtime_put(sor->dev);3151 }3152 3153 err = clk_prepare_enable(sor->clk_safe);3154 if (err < 0) {3155 clk_disable_unprepare(sor->clk);3156 return err;3157 }3158 3159 err = clk_prepare_enable(sor->clk_dp);3160 if (err < 0) {3161 clk_disable_unprepare(sor->clk_safe);3162 clk_disable_unprepare(sor->clk);3163 return err;3164 }3165 3166 return 0;3167 3168rpm_put:3169 if (sor->rst)3170 pm_runtime_put(sor->dev);3171 3172 return err;3173}3174 3175static int tegra_sor_exit(struct host1x_client *client)3176{3177 struct tegra_sor *sor = host1x_client_to_sor(client);3178 int err;3179 3180 tegra_output_exit(&sor->output);3181 3182 if (sor->aux) {3183 err = drm_dp_aux_detach(sor->aux);3184 if (err < 0) {3185 dev_err(sor->dev, "failed to detach DP: %d\n", err);3186 return err;3187 }3188 }3189 3190 clk_disable_unprepare(sor->clk_safe);3191 clk_disable_unprepare(sor->clk_dp);3192 clk_disable_unprepare(sor->clk);3193 3194 return 0;3195}3196 3197static int tegra_sor_runtime_suspend(struct host1x_client *client)3198{3199 struct tegra_sor *sor = host1x_client_to_sor(client);3200 struct device *dev = client->dev;3201 int err;3202 3203 if (sor->rst) {3204 err = reset_control_assert(sor->rst);3205 if (err < 0) {3206 dev_err(dev, "failed to assert reset: %d\n", err);3207 return err;3208 }3209 3210 reset_control_release(sor->rst);3211 }3212 3213 usleep_range(1000, 2000);3214 3215 clk_disable_unprepare(sor->clk);3216 pm_runtime_put_sync(dev);3217 3218 return 0;3219}3220 3221static int tegra_sor_runtime_resume(struct host1x_client *client)3222{3223 struct tegra_sor *sor = host1x_client_to_sor(client);3224 struct device *dev = client->dev;3225 int err;3226 3227 err = pm_runtime_resume_and_get(dev);3228 if (err < 0) {3229 dev_err(dev, "failed to get runtime PM: %d\n", err);3230 return err;3231 }3232 3233 err = clk_prepare_enable(sor->clk);3234 if (err < 0) {3235 dev_err(dev, "failed to enable clock: %d\n", err);3236 goto put_rpm;3237 }3238 3239 usleep_range(1000, 2000);3240 3241 if (sor->rst) {3242 err = reset_control_acquire(sor->rst);3243 if (err < 0) {3244 dev_err(dev, "failed to acquire reset: %d\n", err);3245 goto disable_clk;3246 }3247 3248 err = reset_control_deassert(sor->rst);3249 if (err < 0) {3250 dev_err(dev, "failed to deassert reset: %d\n", err);3251 goto release_reset;3252 }3253 }3254 3255 return 0;3256 3257release_reset:3258 reset_control_release(sor->rst);3259disable_clk:3260 clk_disable_unprepare(sor->clk);3261put_rpm:3262 pm_runtime_put_sync(dev);3263 return err;3264}3265 3266static const struct host1x_client_ops sor_client_ops = {3267 .init = tegra_sor_init,3268 .exit = tegra_sor_exit,3269 .suspend = tegra_sor_runtime_suspend,3270 .resume = tegra_sor_runtime_resume,3271};3272 3273static const u8 tegra124_sor_xbar_cfg[5] = {3274 0, 1, 2, 3, 43275};3276 3277static const struct tegra_sor_regs tegra124_sor_regs = {3278 .head_state0 = 0x05,3279 .head_state1 = 0x07,3280 .head_state2 = 0x09,3281 .head_state3 = 0x0b,3282 .head_state4 = 0x0d,3283 .head_state5 = 0x0f,3284 .pll0 = 0x17,3285 .pll1 = 0x18,3286 .pll2 = 0x19,3287 .pll3 = 0x1a,3288 .dp_padctl0 = 0x5c,3289 .dp_padctl2 = 0x73,3290};3291 3292/* Tegra124 and Tegra132 have lanes 0 and 2 swapped. */3293static const u8 tegra124_sor_lane_map[4] = {3294 2, 1, 0, 3,3295};3296 3297static const u8 tegra124_sor_voltage_swing[4][4][4] = {3298 {3299 { 0x13, 0x19, 0x1e, 0x28 },3300 { 0x1e, 0x25, 0x2d, },3301 { 0x28, 0x32, },3302 { 0x3c, },3303 }, {3304 { 0x12, 0x17, 0x1b, 0x25 },3305 { 0x1c, 0x23, 0x2a, },3306 { 0x25, 0x2f, },3307 { 0x39, }3308 }, {3309 { 0x12, 0x16, 0x1a, 0x22 },3310 { 0x1b, 0x20, 0x27, },3311 { 0x24, 0x2d, },3312 { 0x36, },3313 }, {3314 { 0x11, 0x14, 0x17, 0x1f },3315 { 0x19, 0x1e, 0x24, },3316 { 0x22, 0x2a, },3317 { 0x32, },3318 },3319};3320 3321static const u8 tegra124_sor_pre_emphasis[4][4][4] = {3322 {3323 { 0x00, 0x09, 0x13, 0x25 },3324 { 0x00, 0x0f, 0x1e, },3325 { 0x00, 0x14, },3326 { 0x00, },3327 }, {3328 { 0x00, 0x0a, 0x14, 0x28 },3329 { 0x00, 0x0f, 0x1e, },3330 { 0x00, 0x14, },3331 { 0x00 },3332 }, {3333 { 0x00, 0x0a, 0x14, 0x28 },3334 { 0x00, 0x0f, 0x1e, },3335 { 0x00, 0x14, },3336 { 0x00, },3337 }, {3338 { 0x00, 0x0a, 0x14, 0x28 },3339 { 0x00, 0x0f, 0x1e, },3340 { 0x00, 0x14, },3341 { 0x00, },3342 },3343};3344 3345static const u8 tegra124_sor_post_cursor[4][4][4] = {3346 {3347 { 0x00, 0x00, 0x00, 0x00 },3348 { 0x00, 0x00, 0x00, },3349 { 0x00, 0x00, },3350 { 0x00, },3351 }, {3352 { 0x02, 0x02, 0x04, 0x05 },3353 { 0x02, 0x04, 0x05, },3354 { 0x04, 0x05, },3355 { 0x05, },3356 }, {3357 { 0x04, 0x05, 0x08, 0x0b },3358 { 0x05, 0x09, 0x0b, },3359 { 0x08, 0x0a, },3360 { 0x0b, },3361 }, {3362 { 0x05, 0x09, 0x0b, 0x12 },3363 { 0x09, 0x0d, 0x12, },3364 { 0x0b, 0x0f, },3365 { 0x12, },3366 },3367};3368 3369static const u8 tegra124_sor_tx_pu[4][4][4] = {3370 {3371 { 0x20, 0x30, 0x40, 0x60 },3372 { 0x30, 0x40, 0x60, },3373 { 0x40, 0x60, },3374 { 0x60, },3375 }, {3376 { 0x20, 0x20, 0x30, 0x50 },3377 { 0x30, 0x40, 0x50, },3378 { 0x40, 0x50, },3379 { 0x60, },3380 }, {3381 { 0x20, 0x20, 0x30, 0x40, },3382 { 0x30, 0x30, 0x40, },3383 { 0x40, 0x50, },3384 { 0x60, },3385 }, {3386 { 0x20, 0x20, 0x20, 0x40, },3387 { 0x30, 0x30, 0x40, },3388 { 0x40, 0x40, },3389 { 0x60, },3390 },3391};3392 3393static const struct tegra_sor_soc tegra124_sor = {3394 .supports_lvds = true,3395 .supports_hdmi = false,3396 .supports_dp = true,3397 .supports_audio = false,3398 .supports_hdcp = false,3399 .regs = &tegra124_sor_regs,3400 .has_nvdisplay = false,3401 .xbar_cfg = tegra124_sor_xbar_cfg,3402 .lane_map = tegra124_sor_lane_map,3403 .voltage_swing = tegra124_sor_voltage_swing,3404 .pre_emphasis = tegra124_sor_pre_emphasis,3405 .post_cursor = tegra124_sor_post_cursor,3406 .tx_pu = tegra124_sor_tx_pu,3407};3408 3409static const u8 tegra132_sor_pre_emphasis[4][4][4] = {3410 {3411 { 0x00, 0x08, 0x12, 0x24 },3412 { 0x01, 0x0e, 0x1d, },3413 { 0x01, 0x13, },3414 { 0x00, },3415 }, {3416 { 0x00, 0x08, 0x12, 0x24 },3417 { 0x00, 0x0e, 0x1d, },3418 { 0x00, 0x13, },3419 { 0x00 },3420 }, {3421 { 0x00, 0x08, 0x12, 0x24 },3422 { 0x00, 0x0e, 0x1d, },3423 { 0x00, 0x13, },3424 { 0x00, },3425 }, {3426 { 0x00, 0x08, 0x12, 0x24 },3427 { 0x00, 0x0e, 0x1d, },3428 { 0x00, 0x13, },3429 { 0x00, },3430 },3431};3432 3433static const struct tegra_sor_soc tegra132_sor = {3434 .supports_lvds = true,3435 .supports_hdmi = false,3436 .supports_dp = true,3437 .supports_audio = false,3438 .supports_hdcp = false,3439 .regs = &tegra124_sor_regs,3440 .has_nvdisplay = false,3441 .xbar_cfg = tegra124_sor_xbar_cfg,3442 .lane_map = tegra124_sor_lane_map,3443 .voltage_swing = tegra124_sor_voltage_swing,3444 .pre_emphasis = tegra132_sor_pre_emphasis,3445 .post_cursor = tegra124_sor_post_cursor,3446 .tx_pu = tegra124_sor_tx_pu,3447};3448 3449static const struct tegra_sor_regs tegra210_sor_regs = {3450 .head_state0 = 0x05,3451 .head_state1 = 0x07,3452 .head_state2 = 0x09,3453 .head_state3 = 0x0b,3454 .head_state4 = 0x0d,3455 .head_state5 = 0x0f,3456 .pll0 = 0x17,3457 .pll1 = 0x18,3458 .pll2 = 0x19,3459 .pll3 = 0x1a,3460 .dp_padctl0 = 0x5c,3461 .dp_padctl2 = 0x73,3462};3463 3464static const u8 tegra210_sor_xbar_cfg[5] = {3465 2, 1, 0, 3, 43466};3467 3468static const u8 tegra210_sor_lane_map[4] = {3469 0, 1, 2, 3,3470};3471 3472static const struct tegra_sor_soc tegra210_sor = {3473 .supports_lvds = false,3474 .supports_hdmi = false,3475 .supports_dp = true,3476 .supports_audio = false,3477 .supports_hdcp = false,3478 3479 .regs = &tegra210_sor_regs,3480 .has_nvdisplay = false,3481 3482 .xbar_cfg = tegra210_sor_xbar_cfg,3483 .lane_map = tegra210_sor_lane_map,3484 .voltage_swing = tegra124_sor_voltage_swing,3485 .pre_emphasis = tegra124_sor_pre_emphasis,3486 .post_cursor = tegra124_sor_post_cursor,3487 .tx_pu = tegra124_sor_tx_pu,3488};3489 3490static const struct tegra_sor_soc tegra210_sor1 = {3491 .supports_lvds = false,3492 .supports_hdmi = true,3493 .supports_dp = true,3494 .supports_audio = true,3495 .supports_hdcp = true,3496 3497 .regs = &tegra210_sor_regs,3498 .has_nvdisplay = false,3499 3500 .num_settings = ARRAY_SIZE(tegra210_sor_hdmi_defaults),3501 .settings = tegra210_sor_hdmi_defaults,3502 .xbar_cfg = tegra210_sor_xbar_cfg,3503 .lane_map = tegra210_sor_lane_map,3504 .voltage_swing = tegra124_sor_voltage_swing,3505 .pre_emphasis = tegra124_sor_pre_emphasis,3506 .post_cursor = tegra124_sor_post_cursor,3507 .tx_pu = tegra124_sor_tx_pu,3508};3509 3510static const struct tegra_sor_regs tegra186_sor_regs = {3511 .head_state0 = 0x151,3512 .head_state1 = 0x154,3513 .head_state2 = 0x157,3514 .head_state3 = 0x15a,3515 .head_state4 = 0x15d,3516 .head_state5 = 0x160,3517 .pll0 = 0x163,3518 .pll1 = 0x164,3519 .pll2 = 0x165,3520 .pll3 = 0x166,3521 .dp_padctl0 = 0x168,3522 .dp_padctl2 = 0x16a,3523};3524 3525static const u8 tegra186_sor_voltage_swing[4][4][4] = {3526 {3527 { 0x13, 0x19, 0x1e, 0x28 },3528 { 0x1e, 0x25, 0x2d, },3529 { 0x28, 0x32, },3530 { 0x39, },3531 }, {3532 { 0x12, 0x16, 0x1b, 0x25 },3533 { 0x1c, 0x23, 0x2a, },3534 { 0x25, 0x2f, },3535 { 0x37, }3536 }, {3537 { 0x12, 0x16, 0x1a, 0x22 },3538 { 0x1b, 0x20, 0x27, },3539 { 0x24, 0x2d, },3540 { 0x35, },3541 }, {3542 { 0x11, 0x14, 0x17, 0x1f },3543 { 0x19, 0x1e, 0x24, },3544 { 0x22, 0x2a, },3545 { 0x32, },3546 },3547};3548 3549static const u8 tegra186_sor_pre_emphasis[4][4][4] = {3550 {3551 { 0x00, 0x08, 0x12, 0x24 },3552 { 0x01, 0x0e, 0x1d, },3553 { 0x01, 0x13, },3554 { 0x00, },3555 }, {3556 { 0x00, 0x08, 0x12, 0x24 },3557 { 0x00, 0x0e, 0x1d, },3558 { 0x00, 0x13, },3559 { 0x00 },3560 }, {3561 { 0x00, 0x08, 0x14, 0x24 },3562 { 0x00, 0x0e, 0x1d, },3563 { 0x00, 0x13, },3564 { 0x00, },3565 }, {3566 { 0x00, 0x08, 0x12, 0x24 },3567 { 0x00, 0x0e, 0x1d, },3568 { 0x00, 0x13, },3569 { 0x00, },3570 },3571};3572 3573static const struct tegra_sor_soc tegra186_sor = {3574 .supports_lvds = false,3575 .supports_hdmi = true,3576 .supports_dp = true,3577 .supports_audio = true,3578 .supports_hdcp = true,3579 3580 .regs = &tegra186_sor_regs,3581 .has_nvdisplay = true,3582 3583 .num_settings = ARRAY_SIZE(tegra186_sor_hdmi_defaults),3584 .settings = tegra186_sor_hdmi_defaults,3585 .xbar_cfg = tegra124_sor_xbar_cfg,3586 .lane_map = tegra124_sor_lane_map,3587 .voltage_swing = tegra186_sor_voltage_swing,3588 .pre_emphasis = tegra186_sor_pre_emphasis,3589 .post_cursor = tegra124_sor_post_cursor,3590 .tx_pu = tegra124_sor_tx_pu,3591};3592 3593static const struct tegra_sor_regs tegra194_sor_regs = {3594 .head_state0 = 0x151,3595 .head_state1 = 0x155,3596 .head_state2 = 0x159,3597 .head_state3 = 0x15d,3598 .head_state4 = 0x161,3599 .head_state5 = 0x165,3600 .pll0 = 0x169,3601 .pll1 = 0x16a,3602 .pll2 = 0x16b,3603 .pll3 = 0x16c,3604 .dp_padctl0 = 0x16e,3605 .dp_padctl2 = 0x16f,3606};3607 3608static const struct tegra_sor_soc tegra194_sor = {3609 .supports_lvds = false,3610 .supports_hdmi = true,3611 .supports_dp = true,3612 .supports_audio = true,3613 .supports_hdcp = true,3614 3615 .regs = &tegra194_sor_regs,3616 .has_nvdisplay = true,3617 3618 .num_settings = ARRAY_SIZE(tegra194_sor_hdmi_defaults),3619 .settings = tegra194_sor_hdmi_defaults,3620 3621 .xbar_cfg = tegra210_sor_xbar_cfg,3622 .lane_map = tegra124_sor_lane_map,3623 .voltage_swing = tegra186_sor_voltage_swing,3624 .pre_emphasis = tegra186_sor_pre_emphasis,3625 .post_cursor = tegra124_sor_post_cursor,3626 .tx_pu = tegra124_sor_tx_pu,3627};3628 3629static const struct of_device_id tegra_sor_of_match[] = {3630 { .compatible = "nvidia,tegra194-sor", .data = &tegra194_sor },3631 { .compatible = "nvidia,tegra186-sor", .data = &tegra186_sor },3632 { .compatible = "nvidia,tegra210-sor1", .data = &tegra210_sor1 },3633 { .compatible = "nvidia,tegra210-sor", .data = &tegra210_sor },3634 { .compatible = "nvidia,tegra132-sor", .data = &tegra132_sor },3635 { .compatible = "nvidia,tegra124-sor", .data = &tegra124_sor },3636 { },3637};3638MODULE_DEVICE_TABLE(of, tegra_sor_of_match);3639 3640static int tegra_sor_parse_dt(struct tegra_sor *sor)3641{3642 struct device_node *np = sor->dev->of_node;3643 u32 xbar_cfg[5];3644 unsigned int i;3645 u32 value;3646 int err;3647 3648 if (sor->soc->has_nvdisplay) {3649 err = of_property_read_u32(np, "nvidia,interface", &value);3650 if (err < 0)3651 return err;3652 3653 sor->index = value;3654 3655 /*3656 * override the default that we already set for Tegra210 and3657 * earlier3658 */3659 sor->pad = TEGRA_IO_PAD_HDMI_DP0 + sor->index;3660 } else {3661 if (!sor->soc->supports_audio)3662 sor->index = 0;3663 else3664 sor->index = 1;3665 }3666 3667 err = of_property_read_u32_array(np, "nvidia,xbar-cfg", xbar_cfg, 5);3668 if (err < 0) {3669 /* fall back to default per-SoC XBAR configuration */3670 for (i = 0; i < 5; i++)3671 sor->xbar_cfg[i] = sor->soc->xbar_cfg[i];3672 } else {3673 /* copy cells to SOR XBAR configuration */3674 for (i = 0; i < 5; i++)3675 sor->xbar_cfg[i] = xbar_cfg[i];3676 }3677 3678 return 0;3679}3680 3681static irqreturn_t tegra_sor_irq(int irq, void *data)3682{3683 struct tegra_sor *sor = data;3684 u32 value;3685 3686 value = tegra_sor_readl(sor, SOR_INT_STATUS);3687 tegra_sor_writel(sor, value, SOR_INT_STATUS);3688 3689 if (value & SOR_INT_CODEC_SCRATCH0) {3690 value = tegra_sor_readl(sor, SOR_AUDIO_HDA_CODEC_SCRATCH0);3691 3692 if (value & SOR_AUDIO_HDA_CODEC_SCRATCH0_VALID) {3693 unsigned int format;3694 3695 format = value & SOR_AUDIO_HDA_CODEC_SCRATCH0_FMT_MASK;3696 3697 tegra_hda_parse_format(format, &sor->format);3698 3699 if (sor->ops->audio_enable)3700 sor->ops->audio_enable(sor);3701 } else {3702 if (sor->ops->audio_disable)3703 sor->ops->audio_disable(sor);3704 }3705 }3706 3707 return IRQ_HANDLED;3708}3709 3710static int tegra_sor_probe(struct platform_device *pdev)3711{3712 struct device_node *np;3713 struct tegra_sor *sor;3714 int err;3715 3716 sor = devm_kzalloc(&pdev->dev, sizeof(*sor), GFP_KERNEL);3717 if (!sor)3718 return -ENOMEM;3719 3720 sor->soc = of_device_get_match_data(&pdev->dev);3721 sor->output.dev = sor->dev = &pdev->dev;3722 3723 sor->settings = devm_kmemdup(&pdev->dev, sor->soc->settings,3724 sor->soc->num_settings *3725 sizeof(*sor->settings),3726 GFP_KERNEL);3727 if (!sor->settings)3728 return -ENOMEM;3729 3730 sor->num_settings = sor->soc->num_settings;3731 3732 np = of_parse_phandle(pdev->dev.of_node, "nvidia,dpaux", 0);3733 if (np) {3734 sor->aux = drm_dp_aux_find_by_of_node(np);3735 of_node_put(np);3736 3737 if (!sor->aux)3738 return -EPROBE_DEFER;3739 3740 if (get_device(sor->aux->dev))3741 sor->output.ddc = &sor->aux->ddc;3742 }3743 3744 if (!sor->aux) {3745 if (sor->soc->supports_hdmi) {3746 sor->ops = &tegra_sor_hdmi_ops;3747 sor->pad = TEGRA_IO_PAD_HDMI;3748 } else if (sor->soc->supports_lvds) {3749 dev_err(&pdev->dev, "LVDS not supported yet\n");3750 return -ENODEV;3751 } else {3752 dev_err(&pdev->dev, "unknown (non-DP) support\n");3753 return -ENODEV;3754 }3755 } else {3756 np = of_parse_phandle(pdev->dev.of_node, "nvidia,panel", 0);3757 /*3758 * No need to keep this around since we only use it as a check3759 * to see if a panel is connected (eDP) or not (DP).3760 */3761 of_node_put(np);3762 3763 sor->ops = &tegra_sor_dp_ops;3764 sor->pad = TEGRA_IO_PAD_LVDS;3765 }3766 3767 err = tegra_sor_parse_dt(sor);3768 if (err < 0)3769 goto put_aux;3770 3771 err = tegra_output_probe(&sor->output);3772 if (err < 0) {3773 dev_err_probe(&pdev->dev, err, "failed to probe output\n");3774 goto put_aux;3775 }3776 3777 if (sor->ops && sor->ops->probe) {3778 err = sor->ops->probe(sor);3779 if (err < 0) {3780 dev_err(&pdev->dev, "failed to probe %s: %d\n",3781 sor->ops->name, err);3782 goto remove;3783 }3784 }3785 3786 sor->regs = devm_platform_ioremap_resource(pdev, 0);3787 if (IS_ERR(sor->regs)) {3788 err = PTR_ERR(sor->regs);3789 goto remove;3790 }3791 3792 err = platform_get_irq(pdev, 0);3793 if (err < 0)3794 goto remove;3795 3796 sor->irq = err;3797 3798 err = devm_request_irq(sor->dev, sor->irq, tegra_sor_irq, 0,3799 dev_name(sor->dev), sor);3800 if (err < 0) {3801 dev_err(&pdev->dev, "failed to request IRQ: %d\n", err);3802 goto remove;3803 }3804 3805 sor->rst = devm_reset_control_get_exclusive_released(&pdev->dev, "sor");3806 if (IS_ERR(sor->rst)) {3807 err = PTR_ERR(sor->rst);3808 3809 if (err != -EBUSY || WARN_ON(!pdev->dev.pm_domain)) {3810 dev_err(&pdev->dev, "failed to get reset control: %d\n",3811 err);3812 goto remove;3813 }3814 3815 /*3816 * At this point, the reset control is most likely being used3817 * by the generic power domain implementation. With any luck3818 * the power domain will have taken care of resetting the SOR3819 * and we don't have to do anything.3820 */3821 sor->rst = NULL;3822 }3823 3824 sor->clk = devm_clk_get(&pdev->dev, NULL);3825 if (IS_ERR(sor->clk)) {3826 err = PTR_ERR(sor->clk);3827 dev_err(&pdev->dev, "failed to get module clock: %d\n", err);3828 goto remove;3829 }3830 3831 if (sor->soc->supports_hdmi || sor->soc->supports_dp) {3832 struct device_node *np = pdev->dev.of_node;3833 const char *name;3834 3835 /*3836 * For backwards compatibility with Tegra210 device trees,3837 * fall back to the old clock name "source" if the new "out"3838 * clock is not available.3839 */3840 if (of_property_match_string(np, "clock-names", "out") < 0)3841 name = "source";3842 else3843 name = "out";3844 3845 sor->clk_out = devm_clk_get(&pdev->dev, name);3846 if (IS_ERR(sor->clk_out)) {3847 err = PTR_ERR(sor->clk_out);3848 dev_err(sor->dev, "failed to get %s clock: %d\n",3849 name, err);3850 goto remove;3851 }3852 } else {3853 /* fall back to the module clock on SOR0 (eDP/LVDS only) */3854 sor->clk_out = sor->clk;3855 }3856 3857 sor->clk_parent = devm_clk_get(&pdev->dev, "parent");3858 if (IS_ERR(sor->clk_parent)) {3859 err = PTR_ERR(sor->clk_parent);3860 dev_err(&pdev->dev, "failed to get parent clock: %d\n", err);3861 goto remove;3862 }3863 3864 sor->clk_safe = devm_clk_get(&pdev->dev, "safe");3865 if (IS_ERR(sor->clk_safe)) {3866 err = PTR_ERR(sor->clk_safe);3867 dev_err(&pdev->dev, "failed to get safe clock: %d\n", err);3868 goto remove;3869 }3870 3871 sor->clk_dp = devm_clk_get(&pdev->dev, "dp");3872 if (IS_ERR(sor->clk_dp)) {3873 err = PTR_ERR(sor->clk_dp);3874 dev_err(&pdev->dev, "failed to get DP clock: %d\n", err);3875 goto remove;3876 }3877 3878 /*3879 * Starting with Tegra186, the BPMP provides an implementation for3880 * the pad output clock, so we have to look it up from device tree.3881 */3882 sor->clk_pad = devm_clk_get(&pdev->dev, "pad");3883 if (IS_ERR(sor->clk_pad)) {3884 if (sor->clk_pad != ERR_PTR(-ENOENT)) {3885 err = PTR_ERR(sor->clk_pad);3886 goto remove;3887 }3888 3889 /*3890 * If the pad output clock is not available, then we assume3891 * we're on Tegra210 or earlier and have to provide our own3892 * implementation.3893 */3894 sor->clk_pad = NULL;3895 }3896 3897 /*3898 * The bootloader may have set up the SOR such that it's module clock3899 * is sourced by one of the display PLLs. However, that doesn't work3900 * without properly having set up other bits of the SOR.3901 */3902 err = clk_set_parent(sor->clk_out, sor->clk_safe);3903 if (err < 0) {3904 dev_err(&pdev->dev, "failed to use safe clock: %d\n", err);3905 goto remove;3906 }3907 3908 platform_set_drvdata(pdev, sor);3909 pm_runtime_enable(&pdev->dev);3910 3911 host1x_client_init(&sor->client);3912 sor->client.ops = &sor_client_ops;3913 sor->client.dev = &pdev->dev;3914 3915 /*3916 * On Tegra210 and earlier, provide our own implementation for the3917 * pad output clock.3918 */3919 if (!sor->clk_pad) {3920 char *name;3921 3922 name = devm_kasprintf(sor->dev, GFP_KERNEL, "sor%u_pad_clkout",3923 sor->index);3924 if (!name) {3925 err = -ENOMEM;3926 goto uninit;3927 }3928 3929 err = host1x_client_resume(&sor->client);3930 if (err < 0) {3931 dev_err(sor->dev, "failed to resume: %d\n", err);3932 goto uninit;3933 }3934 3935 sor->clk_pad = tegra_clk_sor_pad_register(sor, name);3936 host1x_client_suspend(&sor->client);3937 }3938 3939 if (IS_ERR(sor->clk_pad)) {3940 err = PTR_ERR(sor->clk_pad);3941 dev_err(sor->dev, "failed to register SOR pad clock: %d\n",3942 err);3943 goto uninit;3944 }3945 3946 err = __host1x_client_register(&sor->client);3947 if (err < 0) {3948 dev_err(&pdev->dev, "failed to register host1x client: %d\n",3949 err);3950 goto uninit;3951 }3952 3953 return 0;3954 3955uninit:3956 host1x_client_exit(&sor->client);3957 pm_runtime_disable(&pdev->dev);3958remove:3959 if (sor->aux)3960 sor->output.ddc = NULL;3961 3962 tegra_output_remove(&sor->output);3963put_aux:3964 if (sor->aux)3965 put_device(sor->aux->dev);3966 3967 return err;3968}3969 3970static void tegra_sor_remove(struct platform_device *pdev)3971{3972 struct tegra_sor *sor = platform_get_drvdata(pdev);3973 3974 host1x_client_unregister(&sor->client);3975 3976 pm_runtime_disable(&pdev->dev);3977 3978 if (sor->aux) {3979 put_device(sor->aux->dev);3980 sor->output.ddc = NULL;3981 }3982 3983 tegra_output_remove(&sor->output);3984}3985 3986static int __maybe_unused tegra_sor_suspend(struct device *dev)3987{3988 struct tegra_sor *sor = dev_get_drvdata(dev);3989 int err;3990 3991 err = tegra_output_suspend(&sor->output);3992 if (err < 0) {3993 dev_err(dev, "failed to suspend output: %d\n", err);3994 return err;3995 }3996 3997 if (sor->hdmi_supply) {3998 err = regulator_disable(sor->hdmi_supply);3999 if (err < 0) {4000 tegra_output_resume(&sor->output);4001 return err;4002 }4003 }4004 4005 return 0;4006}4007 4008static int __maybe_unused tegra_sor_resume(struct device *dev)4009{4010 struct tegra_sor *sor = dev_get_drvdata(dev);4011 int err;4012 4013 if (sor->hdmi_supply) {4014 err = regulator_enable(sor->hdmi_supply);4015 if (err < 0)4016 return err;4017 }4018 4019 err = tegra_output_resume(&sor->output);4020 if (err < 0) {4021 dev_err(dev, "failed to resume output: %d\n", err);4022 4023 if (sor->hdmi_supply)4024 regulator_disable(sor->hdmi_supply);4025 4026 return err;4027 }4028 4029 return 0;4030}4031 4032static const struct dev_pm_ops tegra_sor_pm_ops = {4033 SET_SYSTEM_SLEEP_PM_OPS(tegra_sor_suspend, tegra_sor_resume)4034};4035 4036struct platform_driver tegra_sor_driver = {4037 .driver = {4038 .name = "tegra-sor",4039 .of_match_table = tegra_sor_of_match,4040 .pm = &tegra_sor_pm_ops,4041 },4042 .probe = tegra_sor_probe,4043 .remove_new = tegra_sor_remove,4044};4045