diff options
Diffstat (limited to 'drivers/gpu')
| -rw-r--r-- | drivers/gpu/drm/tegra/dsi.c | 269 |
1 files changed, 196 insertions, 73 deletions
diff --git a/drivers/gpu/drm/tegra/dsi.c b/drivers/gpu/drm/tegra/dsi.c index d98058dc4580..00b307120cdd 100644 --- a/drivers/gpu/drm/tegra/dsi.c +++ b/drivers/gpu/drm/tegra/dsi.c | |||
| @@ -28,6 +28,28 @@ | |||
| 28 | #include "dsi.h" | 28 | #include "dsi.h" |
| 29 | #include "mipi-phy.h" | 29 | #include "mipi-phy.h" |
| 30 | 30 | ||
| 31 | struct tegra_dsi_state { | ||
| 32 | struct drm_connector_state base; | ||
| 33 | |||
| 34 | struct mipi_dphy_timing timing; | ||
| 35 | unsigned long period; | ||
| 36 | |||
| 37 | unsigned int vrefresh; | ||
| 38 | unsigned int lanes; | ||
| 39 | unsigned long pclk; | ||
| 40 | unsigned long bclk; | ||
| 41 | |||
| 42 | enum tegra_dsi_format format; | ||
| 43 | unsigned int mul; | ||
| 44 | unsigned int div; | ||
| 45 | }; | ||
| 46 | |||
| 47 | static inline struct tegra_dsi_state * | ||
| 48 | to_dsi_state(struct drm_connector_state *state) | ||
| 49 | { | ||
| 50 | return container_of(state, struct tegra_dsi_state, base); | ||
| 51 | } | ||
| 52 | |||
| 31 | struct tegra_dsi { | 53 | struct tegra_dsi { |
| 32 | struct host1x_client client; | 54 | struct host1x_client client; |
| 33 | struct tegra_output output; | 55 | struct tegra_output output; |
| @@ -77,6 +99,11 @@ static inline struct tegra_dsi *to_dsi(struct tegra_output *output) | |||
| 77 | return container_of(output, struct tegra_dsi, output); | 99 | return container_of(output, struct tegra_dsi, output); |
| 78 | } | 100 | } |
| 79 | 101 | ||
| 102 | static struct tegra_dsi_state *tegra_dsi_get_state(struct tegra_dsi *dsi) | ||
| 103 | { | ||
| 104 | return to_dsi_state(dsi->output.connector.state); | ||
| 105 | } | ||
| 106 | |||
| 80 | static inline u32 tegra_dsi_readl(struct tegra_dsi *dsi, unsigned long reg) | 107 | static inline u32 tegra_dsi_readl(struct tegra_dsi *dsi, unsigned long reg) |
| 81 | { | 108 | { |
| 82 | return readl(dsi->regs + (reg << 2)); | 109 | return readl(dsi->regs + (reg << 2)); |
| @@ -335,62 +362,36 @@ static const u32 pkt_seq_command_mode[NUM_PKT_SEQ] = { | |||
| 335 | [11] = 0, | 362 | [11] = 0, |
| 336 | }; | 363 | }; |
| 337 | 364 | ||
| 338 | static int tegra_dsi_set_phy_timing(struct tegra_dsi *dsi) | 365 | static void tegra_dsi_set_phy_timing(struct tegra_dsi *dsi, |
| 366 | unsigned long period, | ||
| 367 | const struct mipi_dphy_timing *timing) | ||
| 339 | { | 368 | { |
| 340 | struct mipi_dphy_timing timing; | ||
| 341 | unsigned long period; | ||
| 342 | u32 value; | 369 | u32 value; |
| 343 | long rate; | ||
| 344 | int err; | ||
| 345 | |||
| 346 | rate = clk_get_rate(dsi->clk); | ||
| 347 | if (rate < 0) | ||
| 348 | return rate; | ||
| 349 | |||
| 350 | period = DIV_ROUND_CLOSEST(NSEC_PER_SEC, rate * 2); | ||
| 351 | 370 | ||
| 352 | err = mipi_dphy_timing_get_default(&timing, period); | 371 | value = DSI_TIMING_FIELD(timing->hsexit, period, 1) << 24 | |
| 353 | if (err < 0) | 372 | DSI_TIMING_FIELD(timing->hstrail, period, 0) << 16 | |
| 354 | return err; | 373 | DSI_TIMING_FIELD(timing->hszero, period, 3) << 8 | |
| 355 | 374 | DSI_TIMING_FIELD(timing->hsprepare, period, 1); | |
| 356 | err = mipi_dphy_timing_validate(&timing, period); | ||
| 357 | if (err < 0) { | ||
| 358 | dev_err(dsi->dev, "failed to validate D-PHY timing: %d\n", err); | ||
| 359 | return err; | ||
| 360 | } | ||
| 361 | |||
| 362 | /* | ||
| 363 | * The D-PHY timing fields below are expressed in byte-clock cycles, | ||
| 364 | * so multiply the period by 8. | ||
| 365 | */ | ||
| 366 | period *= 8; | ||
| 367 | |||
| 368 | value = DSI_TIMING_FIELD(timing.hsexit, period, 1) << 24 | | ||
| 369 | DSI_TIMING_FIELD(timing.hstrail, period, 0) << 16 | | ||
| 370 | DSI_TIMING_FIELD(timing.hszero, period, 3) << 8 | | ||
| 371 | DSI_TIMING_FIELD(timing.hsprepare, period, 1); | ||
| 372 | tegra_dsi_writel(dsi, value, DSI_PHY_TIMING_0); | 375 | tegra_dsi_writel(dsi, value, DSI_PHY_TIMING_0); |
| 373 | 376 | ||
| 374 | value = DSI_TIMING_FIELD(timing.clktrail, period, 1) << 24 | | 377 | value = DSI_TIMING_FIELD(timing->clktrail, period, 1) << 24 | |
| 375 | DSI_TIMING_FIELD(timing.clkpost, period, 1) << 16 | | 378 | DSI_TIMING_FIELD(timing->clkpost, period, 1) << 16 | |
| 376 | DSI_TIMING_FIELD(timing.clkzero, period, 1) << 8 | | 379 | DSI_TIMING_FIELD(timing->clkzero, period, 1) << 8 | |
| 377 | DSI_TIMING_FIELD(timing.lpx, period, 1); | 380 | DSI_TIMING_FIELD(timing->lpx, period, 1); |
| 378 | tegra_dsi_writel(dsi, value, DSI_PHY_TIMING_1); | 381 | tegra_dsi_writel(dsi, value, DSI_PHY_TIMING_1); |
| 379 | 382 | ||
| 380 | value = DSI_TIMING_FIELD(timing.clkprepare, period, 1) << 16 | | 383 | value = DSI_TIMING_FIELD(timing->clkprepare, period, 1) << 16 | |
| 381 | DSI_TIMING_FIELD(timing.clkpre, period, 1) << 8 | | 384 | DSI_TIMING_FIELD(timing->clkpre, period, 1) << 8 | |
| 382 | DSI_TIMING_FIELD(0xff * period, period, 0) << 0; | 385 | DSI_TIMING_FIELD(0xff * period, period, 0) << 0; |
| 383 | tegra_dsi_writel(dsi, value, DSI_PHY_TIMING_2); | 386 | tegra_dsi_writel(dsi, value, DSI_PHY_TIMING_2); |
| 384 | 387 | ||
| 385 | value = DSI_TIMING_FIELD(timing.taget, period, 1) << 16 | | 388 | value = DSI_TIMING_FIELD(timing->taget, period, 1) << 16 | |
| 386 | DSI_TIMING_FIELD(timing.tasure, period, 1) << 8 | | 389 | DSI_TIMING_FIELD(timing->tasure, period, 1) << 8 | |
| 387 | DSI_TIMING_FIELD(timing.tago, period, 1); | 390 | DSI_TIMING_FIELD(timing->tago, period, 1); |
| 388 | tegra_dsi_writel(dsi, value, DSI_BTA_TIMING); | 391 | tegra_dsi_writel(dsi, value, DSI_BTA_TIMING); |
| 389 | 392 | ||
| 390 | if (dsi->slave) | 393 | if (dsi->slave) |
| 391 | return tegra_dsi_set_phy_timing(dsi->slave); | 394 | tegra_dsi_set_phy_timing(dsi->slave, period, timing); |
| 392 | |||
| 393 | return 0; | ||
| 394 | } | 395 | } |
| 395 | 396 | ||
| 396 | static int tegra_dsi_get_muldiv(enum mipi_dsi_pixel_format format, | 397 | static int tegra_dsi_get_muldiv(enum mipi_dsi_pixel_format format, |
| @@ -482,14 +483,22 @@ static unsigned int tegra_dsi_get_lanes(struct tegra_dsi *dsi) | |||
| 482 | return dsi->lanes; | 483 | return dsi->lanes; |
| 483 | } | 484 | } |
| 484 | 485 | ||
| 485 | static int tegra_dsi_configure(struct tegra_dsi *dsi, unsigned int pipe, | 486 | static void tegra_dsi_configure(struct tegra_dsi *dsi, unsigned int pipe, |
| 486 | const struct drm_display_mode *mode) | 487 | const struct drm_display_mode *mode) |
| 487 | { | 488 | { |
| 488 | unsigned int hact, hsw, hbp, hfp, i, mul, div; | 489 | unsigned int hact, hsw, hbp, hfp, i, mul, div; |
| 489 | enum tegra_dsi_format format; | 490 | struct tegra_dsi_state *state; |
| 490 | const u32 *pkt_seq; | 491 | const u32 *pkt_seq; |
| 491 | u32 value; | 492 | u32 value; |
| 492 | int err; | 493 | |
| 494 | /* XXX: pass in state into this function? */ | ||
| 495 | if (dsi->master) | ||
| 496 | state = tegra_dsi_get_state(dsi->master); | ||
| 497 | else | ||
| 498 | state = tegra_dsi_get_state(dsi); | ||
| 499 | |||
| 500 | mul = state->mul; | ||
| 501 | div = state->div; | ||
| 493 | 502 | ||
| 494 | if (dsi->flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE) { | 503 | if (dsi->flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE) { |
| 495 | DRM_DEBUG_KMS("Non-burst video mode with sync pulses\n"); | 504 | DRM_DEBUG_KMS("Non-burst video mode with sync pulses\n"); |
| @@ -502,15 +511,8 @@ static int tegra_dsi_configure(struct tegra_dsi *dsi, unsigned int pipe, | |||
| 502 | pkt_seq = pkt_seq_command_mode; | 511 | pkt_seq = pkt_seq_command_mode; |
| 503 | } | 512 | } |
| 504 | 513 | ||
| 505 | err = tegra_dsi_get_muldiv(dsi->format, &mul, &div); | 514 | value = DSI_CONTROL_CHANNEL(0) | |
| 506 | if (err < 0) | 515 | DSI_CONTROL_FORMAT(state->format) | |
| 507 | return err; | ||
| 508 | |||
| 509 | err = tegra_dsi_get_format(dsi->format, &format); | ||
| 510 | if (err < 0) | ||
| 511 | return err; | ||
| 512 | |||
| 513 | value = DSI_CONTROL_CHANNEL(0) | DSI_CONTROL_FORMAT(format) | | ||
| 514 | DSI_CONTROL_LANES(dsi->lanes - 1) | | 516 | DSI_CONTROL_LANES(dsi->lanes - 1) | |
| 515 | DSI_CONTROL_SOURCE(pipe); | 517 | DSI_CONTROL_SOURCE(pipe); |
| 516 | tegra_dsi_writel(dsi, value, DSI_CONTROL); | 518 | tegra_dsi_writel(dsi, value, DSI_CONTROL); |
| @@ -589,8 +591,8 @@ static int tegra_dsi_configure(struct tegra_dsi *dsi, unsigned int pipe, | |||
| 589 | 591 | ||
| 590 | /* set SOL delay */ | 592 | /* set SOL delay */ |
| 591 | if (dsi->master || dsi->slave) { | 593 | if (dsi->master || dsi->slave) { |
| 592 | unsigned int lanes = tegra_dsi_get_lanes(dsi); | ||
| 593 | unsigned long delay, bclk, bclk_ganged; | 594 | unsigned long delay, bclk, bclk_ganged; |
| 595 | unsigned int lanes = state->lanes; | ||
| 594 | 596 | ||
| 595 | /* SOL to valid, valid to FIFO and FIFO write delay */ | 597 | /* SOL to valid, valid to FIFO and FIFO write delay */ |
| 596 | delay = 4 + 4 + 2; | 598 | delay = 4 + 4 + 2; |
| @@ -610,9 +612,7 @@ static int tegra_dsi_configure(struct tegra_dsi *dsi, unsigned int pipe, | |||
| 610 | } | 612 | } |
| 611 | 613 | ||
| 612 | if (dsi->slave) { | 614 | if (dsi->slave) { |
| 613 | err = tegra_dsi_configure(dsi->slave, pipe, mode); | 615 | tegra_dsi_configure(dsi->slave, pipe, mode); |
| 614 | if (err < 0) | ||
| 615 | return err; | ||
| 616 | 616 | ||
| 617 | /* | 617 | /* |
| 618 | * TODO: Support modes other than symmetrical left-right | 618 | * TODO: Support modes other than symmetrical left-right |
| @@ -622,8 +622,6 @@ static int tegra_dsi_configure(struct tegra_dsi *dsi, unsigned int pipe, | |||
| 622 | tegra_dsi_ganged_enable(dsi->slave, mode->hdisplay / 2, | 622 | tegra_dsi_ganged_enable(dsi->slave, mode->hdisplay / 2, |
| 623 | mode->hdisplay / 2); | 623 | mode->hdisplay / 2); |
| 624 | } | 624 | } |
| 625 | |||
| 626 | return 0; | ||
| 627 | } | 625 | } |
| 628 | 626 | ||
| 629 | static int tegra_dsi_wait_idle(struct tegra_dsi *dsi, unsigned long timeout) | 627 | static int tegra_dsi_wait_idle(struct tegra_dsi *dsi, unsigned long timeout) |
| @@ -732,13 +730,38 @@ static void tegra_dsi_connector_dpms(struct drm_connector *connector, int mode) | |||
| 732 | { | 730 | { |
| 733 | } | 731 | } |
| 734 | 732 | ||
| 733 | static void tegra_dsi_connector_reset(struct drm_connector *connector) | ||
| 734 | { | ||
| 735 | struct tegra_dsi_state *state; | ||
| 736 | |||
| 737 | kfree(connector->state); | ||
| 738 | connector->state = NULL; | ||
| 739 | |||
| 740 | state = kzalloc(sizeof(*state), GFP_KERNEL); | ||
| 741 | if (state) | ||
| 742 | connector->state = &state->base; | ||
| 743 | } | ||
| 744 | |||
| 745 | static struct drm_connector_state * | ||
| 746 | tegra_dsi_connector_duplicate_state(struct drm_connector *connector) | ||
| 747 | { | ||
| 748 | struct tegra_dsi_state *state = to_dsi_state(connector->state); | ||
| 749 | struct tegra_dsi_state *copy; | ||
| 750 | |||
| 751 | copy = kmemdup(state, sizeof(*state), GFP_KERNEL); | ||
| 752 | if (!copy) | ||
| 753 | return NULL; | ||
| 754 | |||
| 755 | return ©->base; | ||
| 756 | } | ||
| 757 | |||
| 735 | static const struct drm_connector_funcs tegra_dsi_connector_funcs = { | 758 | static const struct drm_connector_funcs tegra_dsi_connector_funcs = { |
| 736 | .dpms = tegra_dsi_connector_dpms, | 759 | .dpms = tegra_dsi_connector_dpms, |
| 737 | .reset = drm_atomic_helper_connector_reset, | 760 | .reset = tegra_dsi_connector_reset, |
| 738 | .detect = tegra_output_connector_detect, | 761 | .detect = tegra_output_connector_detect, |
| 739 | .fill_modes = drm_helper_probe_single_connector_modes, | 762 | .fill_modes = drm_helper_probe_single_connector_modes, |
| 740 | .destroy = tegra_output_connector_destroy, | 763 | .destroy = tegra_output_connector_destroy, |
| 741 | .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, | 764 | .atomic_duplicate_state = tegra_dsi_connector_duplicate_state, |
| 742 | .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, | 765 | .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, |
| 743 | }; | 766 | }; |
| 744 | 767 | ||
| @@ -771,7 +794,9 @@ static bool tegra_dsi_encoder_mode_fixup(struct drm_encoder *encoder, | |||
| 771 | struct tegra_dc *dc = to_tegra_dc(encoder->crtc); | 794 | struct tegra_dc *dc = to_tegra_dc(encoder->crtc); |
| 772 | unsigned int mul, div, scdiv, vrefresh, lanes; | 795 | unsigned int mul, div, scdiv, vrefresh, lanes; |
| 773 | struct tegra_dsi *dsi = to_dsi(output); | 796 | struct tegra_dsi *dsi = to_dsi(output); |
| 797 | struct mipi_dphy_timing timing; | ||
| 774 | unsigned long pclk, bclk, plld; | 798 | unsigned long pclk, bclk, plld; |
| 799 | unsigned long period; | ||
| 775 | int err; | 800 | int err; |
| 776 | 801 | ||
| 777 | lanes = tegra_dsi_get_lanes(dsi); | 802 | lanes = tegra_dsi_get_lanes(dsi); |
| @@ -792,6 +817,7 @@ static bool tegra_dsi_encoder_mode_fixup(struct drm_encoder *encoder, | |||
| 792 | * Compute bit clock and round up to the next MHz. | 817 | * Compute bit clock and round up to the next MHz. |
| 793 | */ | 818 | */ |
| 794 | plld = DIV_ROUND_UP(bclk * 8, USEC_PER_SEC) * USEC_PER_SEC; | 819 | plld = DIV_ROUND_UP(bclk * 8, USEC_PER_SEC) * USEC_PER_SEC; |
| 820 | period = DIV_ROUND_CLOSEST(NSEC_PER_SEC, plld); | ||
| 795 | 821 | ||
| 796 | /* | 822 | /* |
| 797 | * We divide the frequency by two here, but we make up for that by | 823 | * We divide the frequency by two here, but we make up for that by |
| @@ -827,12 +853,22 @@ static bool tegra_dsi_encoder_mode_fixup(struct drm_encoder *encoder, | |||
| 827 | 853 | ||
| 828 | tegra_dsi_set_timeout(dsi, bclk, vrefresh); | 854 | tegra_dsi_set_timeout(dsi, bclk, vrefresh); |
| 829 | 855 | ||
| 830 | err = tegra_dsi_set_phy_timing(dsi); | 856 | err = mipi_dphy_timing_get_default(&timing, period); |
| 857 | if (err < 0) | ||
| 858 | return err; | ||
| 859 | |||
| 860 | err = mipi_dphy_timing_validate(&timing, period); | ||
| 831 | if (err < 0) { | 861 | if (err < 0) { |
| 832 | dev_err(dsi->dev, "failed to setup D-PHY timing: %d\n", err); | 862 | dev_err(dsi->dev, "failed to validate D-PHY timing: %d\n", err); |
| 833 | return false; | 863 | return err; |
| 834 | } | 864 | } |
| 835 | 865 | ||
| 866 | /* | ||
| 867 | * The D-PHY timing fields are expressed in byte-clock cycles, so | ||
| 868 | * multiply the period by 8. | ||
| 869 | */ | ||
| 870 | tegra_dsi_set_phy_timing(dsi, period * 8, &timing); | ||
| 871 | |||
| 836 | return true; | 872 | return true; |
| 837 | } | 873 | } |
| 838 | 874 | ||
| @@ -851,19 +887,24 @@ static void tegra_dsi_encoder_mode_set(struct drm_encoder *encoder, | |||
| 851 | struct tegra_output *output = encoder_to_output(encoder); | 887 | struct tegra_output *output = encoder_to_output(encoder); |
| 852 | struct tegra_dc *dc = to_tegra_dc(encoder->crtc); | 888 | struct tegra_dc *dc = to_tegra_dc(encoder->crtc); |
| 853 | struct tegra_dsi *dsi = to_dsi(output); | 889 | struct tegra_dsi *dsi = to_dsi(output); |
| 890 | struct tegra_dsi_state *state; | ||
| 854 | u32 value; | 891 | u32 value; |
| 855 | int err; | ||
| 856 | 892 | ||
| 893 | state = tegra_dsi_get_state(dsi); | ||
| 857 | 894 | ||
| 858 | err = tegra_dsi_configure(dsi, dc->pipe, mode); | 895 | tegra_dsi_set_timeout(dsi, state->bclk, state->vrefresh); |
| 859 | if (err < 0) { | 896 | |
| 860 | dev_err(dsi->dev, "failed to configure DSI: %d\n", err); | 897 | /* |
| 861 | return; | 898 | * The D-PHY timing fields are expressed in byte-clock cycles, so |
| 862 | } | 899 | * multiply the period by 8. |
| 900 | */ | ||
| 901 | tegra_dsi_set_phy_timing(dsi, state->period * 8, &state->timing); | ||
| 863 | 902 | ||
| 864 | if (output->panel) | 903 | if (output->panel) |
| 865 | drm_panel_prepare(output->panel); | 904 | drm_panel_prepare(output->panel); |
| 866 | 905 | ||
| 906 | tegra_dsi_configure(dsi, dc->pipe, mode); | ||
| 907 | |||
| 867 | /* enable display controller */ | 908 | /* enable display controller */ |
| 868 | value = tegra_dc_readl(dc, DC_DISP_DISP_WIN_OPTIONS); | 909 | value = tegra_dc_readl(dc, DC_DISP_DISP_WIN_OPTIONS); |
| 869 | value |= DSI_ENABLE; | 910 | value |= DSI_ENABLE; |
| @@ -929,6 +970,87 @@ static void tegra_dsi_encoder_disable(struct drm_encoder *encoder) | |||
| 929 | return; | 970 | return; |
| 930 | } | 971 | } |
| 931 | 972 | ||
| 973 | static int | ||
| 974 | tegra_dsi_encoder_atomic_check(struct drm_encoder *encoder, | ||
| 975 | struct drm_crtc_state *crtc_state, | ||
| 976 | struct drm_connector_state *conn_state) | ||
| 977 | { | ||
| 978 | struct tegra_output *output = encoder_to_output(encoder); | ||
| 979 | struct tegra_dsi_state *state = to_dsi_state(conn_state); | ||
| 980 | struct tegra_dc *dc = to_tegra_dc(conn_state->crtc); | ||
| 981 | struct tegra_dsi *dsi = to_dsi(output); | ||
| 982 | unsigned int scdiv; | ||
| 983 | unsigned long plld; | ||
| 984 | int err; | ||
| 985 | |||
| 986 | state->pclk = crtc_state->mode.clock * 1000; | ||
| 987 | |||
| 988 | err = tegra_dsi_get_muldiv(dsi->format, &state->mul, &state->div); | ||
| 989 | if (err < 0) | ||
| 990 | return err; | ||
| 991 | |||
| 992 | state->lanes = tegra_dsi_get_lanes(dsi); | ||
| 993 | |||
| 994 | err = tegra_dsi_get_format(dsi->format, &state->format); | ||
| 995 | if (err < 0) | ||
| 996 | return err; | ||
| 997 | |||
| 998 | state->vrefresh = drm_mode_vrefresh(&crtc_state->mode); | ||
| 999 | |||
| 1000 | /* compute byte clock */ | ||
| 1001 | state->bclk = (state->pclk * state->mul) / (state->div * state->lanes); | ||
| 1002 | |||
| 1003 | DRM_DEBUG_KMS("mul: %u, div: %u, lanes: %u\n", state->mul, state->div, | ||
| 1004 | state->lanes); | ||
| 1005 | DRM_DEBUG_KMS("format: %u, vrefresh: %u\n", state->format, | ||
| 1006 | state->vrefresh); | ||
| 1007 | DRM_DEBUG_KMS("bclk: %lu\n", state->bclk); | ||
| 1008 | |||
| 1009 | /* | ||
| 1010 | * Compute bit clock and round up to the next MHz. | ||
| 1011 | */ | ||
| 1012 | plld = DIV_ROUND_UP(state->bclk * 8, USEC_PER_SEC) * USEC_PER_SEC; | ||
| 1013 | state->period = DIV_ROUND_CLOSEST(NSEC_PER_SEC, plld); | ||
| 1014 | |||
| 1015 | err = mipi_dphy_timing_get_default(&state->timing, state->period); | ||
| 1016 | if (err < 0) | ||
| 1017 | return err; | ||
| 1018 | |||
| 1019 | err = mipi_dphy_timing_validate(&state->timing, state->period); | ||
| 1020 | if (err < 0) { | ||
| 1021 | dev_err(dsi->dev, "failed to validate D-PHY timing: %d\n", err); | ||
| 1022 | return err; | ||
| 1023 | } | ||
| 1024 | |||
| 1025 | /* | ||
| 1026 | * We divide the frequency by two here, but we make up for that by | ||
| 1027 | * setting the shift clock divider (further below) to half of the | ||
| 1028 | * correct value. | ||
| 1029 | */ | ||
| 1030 | plld /= 2; | ||
| 1031 | |||
| 1032 | /* | ||
| 1033 | * Derive pixel clock from bit clock using the shift clock divider. | ||
| 1034 | * Note that this is only half of what we would expect, but we need | ||
| 1035 | * that to make up for the fact that we divided the bit clock by a | ||
| 1036 | * factor of two above. | ||
| 1037 | * | ||
| 1038 | * It's not clear exactly why this is necessary, but the display is | ||
| 1039 | * not working properly otherwise. Perhaps the PLLs cannot generate | ||
| 1040 | * frequencies sufficiently high. | ||
| 1041 | */ | ||
| 1042 | scdiv = ((8 * state->mul) / (state->div * state->lanes)) - 2; | ||
| 1043 | |||
| 1044 | err = tegra_dc_state_setup_clock(dc, crtc_state, dsi->clk_parent, | ||
| 1045 | plld, scdiv); | ||
| 1046 | if (err < 0) { | ||
| 1047 | dev_err(output->dev, "failed to setup CRTC state: %d\n", err); | ||
| 1048 | return err; | ||
| 1049 | } | ||
| 1050 | |||
| 1051 | return err; | ||
| 1052 | } | ||
| 1053 | |||
| 932 | static const struct drm_encoder_helper_funcs tegra_dsi_encoder_helper_funcs = { | 1054 | static const struct drm_encoder_helper_funcs tegra_dsi_encoder_helper_funcs = { |
| 933 | .dpms = tegra_dsi_encoder_dpms, | 1055 | .dpms = tegra_dsi_encoder_dpms, |
| 934 | .mode_fixup = tegra_dsi_encoder_mode_fixup, | 1056 | .mode_fixup = tegra_dsi_encoder_mode_fixup, |
| @@ -936,6 +1058,7 @@ static const struct drm_encoder_helper_funcs tegra_dsi_encoder_helper_funcs = { | |||
| 936 | .commit = tegra_dsi_encoder_commit, | 1058 | .commit = tegra_dsi_encoder_commit, |
| 937 | .mode_set = tegra_dsi_encoder_mode_set, | 1059 | .mode_set = tegra_dsi_encoder_mode_set, |
| 938 | .disable = tegra_dsi_encoder_disable, | 1060 | .disable = tegra_dsi_encoder_disable, |
| 1061 | .atomic_check = tegra_dsi_encoder_atomic_check, | ||
| 939 | }; | 1062 | }; |
| 940 | 1063 | ||
| 941 | static int tegra_dsi_pad_enable(struct tegra_dsi *dsi) | 1064 | static int tegra_dsi_pad_enable(struct tegra_dsi *dsi) |
