.. | .. |
---|
7 | 7 | |
---|
8 | 8 | #include <drm/drm_atomic_helper.h> |
---|
9 | 9 | #include <drm/drm_bridge.h> |
---|
10 | | -#include <drm/drm_crtc_helper.h> |
---|
| 10 | +#include <drm/drm_drv.h> |
---|
11 | 11 | #include <drm/drm_mipi_dsi.h> |
---|
12 | 12 | #include <drm/drm_panel.h> |
---|
| 13 | +#include <drm/drm_probe_helper.h> |
---|
13 | 14 | #include <video/mipi_display.h> |
---|
14 | 15 | |
---|
15 | 16 | #include <linux/clk.h> |
---|
| 17 | +#include <linux/interrupt.h> |
---|
16 | 18 | #include <linux/iopoll.h> |
---|
17 | 19 | #include <linux/module.h> |
---|
18 | 20 | #include <linux/of_address.h> |
---|
.. | .. |
---|
20 | 22 | #include <linux/platform_device.h> |
---|
21 | 23 | #include <linux/pm_runtime.h> |
---|
22 | 24 | #include <linux/reset.h> |
---|
| 25 | + |
---|
| 26 | +#include <linux/phy/phy.h> |
---|
| 27 | +#include <linux/phy/phy-mipi-dphy.h> |
---|
23 | 28 | |
---|
24 | 29 | #define IP_CONF 0x0 |
---|
25 | 30 | #define SP_HS_FIFO_DEPTH(x) (((x) & GENMASK(30, 26)) >> 26) |
---|
.. | .. |
---|
419 | 424 | #define DSI_NULL_FRAME_OVERHEAD 6 |
---|
420 | 425 | #define DSI_EOT_PKT_SIZE 4 |
---|
421 | 426 | |
---|
422 | | -#define REG_WAKEUP_TIME_NS 800 |
---|
423 | | -#define DPHY_PLL_RATE_HZ 108000000 |
---|
424 | | - |
---|
425 | | -/* DPHY registers */ |
---|
426 | | -#define DPHY_PMA_CMN(reg) (reg) |
---|
427 | | -#define DPHY_PMA_LCLK(reg) (0x100 + (reg)) |
---|
428 | | -#define DPHY_PMA_LDATA(lane, reg) (0x200 + ((lane) * 0x100) + (reg)) |
---|
429 | | -#define DPHY_PMA_RCLK(reg) (0x600 + (reg)) |
---|
430 | | -#define DPHY_PMA_RDATA(lane, reg) (0x700 + ((lane) * 0x100) + (reg)) |
---|
431 | | -#define DPHY_PCS(reg) (0xb00 + (reg)) |
---|
432 | | - |
---|
433 | | -#define DPHY_CMN_SSM DPHY_PMA_CMN(0x20) |
---|
434 | | -#define DPHY_CMN_SSM_EN BIT(0) |
---|
435 | | -#define DPHY_CMN_TX_MODE_EN BIT(9) |
---|
436 | | - |
---|
437 | | -#define DPHY_CMN_PWM DPHY_PMA_CMN(0x40) |
---|
438 | | -#define DPHY_CMN_PWM_DIV(x) ((x) << 20) |
---|
439 | | -#define DPHY_CMN_PWM_LOW(x) ((x) << 10) |
---|
440 | | -#define DPHY_CMN_PWM_HIGH(x) (x) |
---|
441 | | - |
---|
442 | | -#define DPHY_CMN_FBDIV DPHY_PMA_CMN(0x4c) |
---|
443 | | -#define DPHY_CMN_FBDIV_VAL(low, high) (((high) << 11) | ((low) << 22)) |
---|
444 | | -#define DPHY_CMN_FBDIV_FROM_REG (BIT(10) | BIT(21)) |
---|
445 | | - |
---|
446 | | -#define DPHY_CMN_OPIPDIV DPHY_PMA_CMN(0x50) |
---|
447 | | -#define DPHY_CMN_IPDIV_FROM_REG BIT(0) |
---|
448 | | -#define DPHY_CMN_IPDIV(x) ((x) << 1) |
---|
449 | | -#define DPHY_CMN_OPDIV_FROM_REG BIT(6) |
---|
450 | | -#define DPHY_CMN_OPDIV(x) ((x) << 7) |
---|
451 | | - |
---|
452 | | -#define DPHY_PSM_CFG DPHY_PCS(0x4) |
---|
453 | | -#define DPHY_PSM_CFG_FROM_REG BIT(0) |
---|
454 | | -#define DPHY_PSM_CLK_DIV(x) ((x) << 1) |
---|
455 | | - |
---|
456 | 427 | struct cdns_dsi_output { |
---|
457 | 428 | struct mipi_dsi_device *dev; |
---|
458 | 429 | struct drm_panel *panel; |
---|
459 | 430 | struct drm_bridge *bridge; |
---|
| 431 | + union phy_configure_opts phy_opts; |
---|
460 | 432 | }; |
---|
461 | 433 | |
---|
462 | 434 | enum cdns_dsi_input_id { |
---|
.. | .. |
---|
465 | 437 | CDNS_DSC_INPUT, |
---|
466 | 438 | }; |
---|
467 | 439 | |
---|
468 | | -struct cdns_dphy_cfg { |
---|
469 | | - u8 pll_ipdiv; |
---|
470 | | - u8 pll_opdiv; |
---|
471 | | - u16 pll_fbdiv; |
---|
472 | | - unsigned long lane_bps; |
---|
473 | | - unsigned int nlanes; |
---|
474 | | -}; |
---|
475 | | - |
---|
476 | 440 | struct cdns_dsi_cfg { |
---|
477 | 441 | unsigned int hfp; |
---|
478 | 442 | unsigned int hsa; |
---|
479 | 443 | unsigned int hbp; |
---|
480 | 444 | unsigned int hact; |
---|
481 | 445 | unsigned int htotal; |
---|
482 | | -}; |
---|
483 | | - |
---|
484 | | -struct cdns_dphy; |
---|
485 | | - |
---|
486 | | -enum cdns_dphy_clk_lane_cfg { |
---|
487 | | - DPHY_CLK_CFG_LEFT_DRIVES_ALL = 0, |
---|
488 | | - DPHY_CLK_CFG_LEFT_DRIVES_RIGHT = 1, |
---|
489 | | - DPHY_CLK_CFG_LEFT_DRIVES_LEFT = 2, |
---|
490 | | - DPHY_CLK_CFG_RIGHT_DRIVES_ALL = 3, |
---|
491 | | -}; |
---|
492 | | - |
---|
493 | | -struct cdns_dphy_ops { |
---|
494 | | - int (*probe)(struct cdns_dphy *dphy); |
---|
495 | | - void (*remove)(struct cdns_dphy *dphy); |
---|
496 | | - void (*set_psm_div)(struct cdns_dphy *dphy, u8 div); |
---|
497 | | - void (*set_clk_lane_cfg)(struct cdns_dphy *dphy, |
---|
498 | | - enum cdns_dphy_clk_lane_cfg cfg); |
---|
499 | | - void (*set_pll_cfg)(struct cdns_dphy *dphy, |
---|
500 | | - const struct cdns_dphy_cfg *cfg); |
---|
501 | | - unsigned long (*get_wakeup_time_ns)(struct cdns_dphy *dphy); |
---|
502 | | -}; |
---|
503 | | - |
---|
504 | | -struct cdns_dphy { |
---|
505 | | - struct cdns_dphy_cfg cfg; |
---|
506 | | - void __iomem *regs; |
---|
507 | | - struct clk *psm_clk; |
---|
508 | | - struct clk *pll_ref_clk; |
---|
509 | | - const struct cdns_dphy_ops *ops; |
---|
510 | 446 | }; |
---|
511 | 447 | |
---|
512 | 448 | struct cdns_dsi_input { |
---|
.. | .. |
---|
526 | 462 | struct reset_control *dsi_p_rst; |
---|
527 | 463 | struct clk *dsi_sys_clk; |
---|
528 | 464 | bool link_initialized; |
---|
529 | | - struct cdns_dphy *dphy; |
---|
| 465 | + struct phy *dphy; |
---|
530 | 466 | }; |
---|
531 | 467 | |
---|
532 | 468 | static inline struct cdns_dsi *input_to_dsi(struct cdns_dsi_input *input) |
---|
.. | .. |
---|
545 | 481 | return container_of(bridge, struct cdns_dsi_input, bridge); |
---|
546 | 482 | } |
---|
547 | 483 | |
---|
548 | | -static int cdns_dsi_get_dphy_pll_cfg(struct cdns_dphy *dphy, |
---|
549 | | - struct cdns_dphy_cfg *cfg, |
---|
550 | | - unsigned int dpi_htotal, |
---|
551 | | - unsigned int dpi_bpp, |
---|
552 | | - unsigned int dpi_hz, |
---|
553 | | - unsigned int dsi_htotal, |
---|
554 | | - unsigned int dsi_nlanes, |
---|
555 | | - unsigned int *dsi_hfp_ext) |
---|
| 484 | +static unsigned int mode_to_dpi_hfp(const struct drm_display_mode *mode, |
---|
| 485 | + bool mode_valid_check) |
---|
556 | 486 | { |
---|
557 | | - u64 dlane_bps, dlane_bps_max, fbdiv, fbdiv_max, adj_dsi_htotal; |
---|
558 | | - unsigned long pll_ref_hz = clk_get_rate(dphy->pll_ref_clk); |
---|
| 487 | + if (mode_valid_check) |
---|
| 488 | + return mode->hsync_start - mode->hdisplay; |
---|
559 | 489 | |
---|
560 | | - memset(cfg, 0, sizeof(*cfg)); |
---|
561 | | - |
---|
562 | | - cfg->nlanes = dsi_nlanes; |
---|
563 | | - |
---|
564 | | - if (pll_ref_hz < 9600000 || pll_ref_hz >= 150000000) |
---|
565 | | - return -EINVAL; |
---|
566 | | - else if (pll_ref_hz < 19200000) |
---|
567 | | - cfg->pll_ipdiv = 1; |
---|
568 | | - else if (pll_ref_hz < 38400000) |
---|
569 | | - cfg->pll_ipdiv = 2; |
---|
570 | | - else if (pll_ref_hz < 76800000) |
---|
571 | | - cfg->pll_ipdiv = 4; |
---|
572 | | - else |
---|
573 | | - cfg->pll_ipdiv = 8; |
---|
574 | | - |
---|
575 | | - /* |
---|
576 | | - * Make sure DSI htotal is aligned on a lane boundary when calculating |
---|
577 | | - * the expected data rate. This is done by extending HFP in case of |
---|
578 | | - * misalignment. |
---|
579 | | - */ |
---|
580 | | - adj_dsi_htotal = dsi_htotal; |
---|
581 | | - if (dsi_htotal % dsi_nlanes) |
---|
582 | | - adj_dsi_htotal += dsi_nlanes - (dsi_htotal % dsi_nlanes); |
---|
583 | | - |
---|
584 | | - dlane_bps = (u64)dpi_hz * adj_dsi_htotal; |
---|
585 | | - |
---|
586 | | - /* data rate in bytes/sec is not an integer, refuse the mode. */ |
---|
587 | | - if (do_div(dlane_bps, dsi_nlanes * dpi_htotal)) |
---|
588 | | - return -EINVAL; |
---|
589 | | - |
---|
590 | | - /* data rate was in bytes/sec, convert to bits/sec. */ |
---|
591 | | - dlane_bps *= 8; |
---|
592 | | - |
---|
593 | | - if (dlane_bps > 2500000000UL || dlane_bps < 160000000UL) |
---|
594 | | - return -EINVAL; |
---|
595 | | - else if (dlane_bps >= 1250000000) |
---|
596 | | - cfg->pll_opdiv = 1; |
---|
597 | | - else if (dlane_bps >= 630000000) |
---|
598 | | - cfg->pll_opdiv = 2; |
---|
599 | | - else if (dlane_bps >= 320000000) |
---|
600 | | - cfg->pll_opdiv = 4; |
---|
601 | | - else if (dlane_bps >= 160000000) |
---|
602 | | - cfg->pll_opdiv = 8; |
---|
603 | | - |
---|
604 | | - /* |
---|
605 | | - * Allow a deviation of 0.2% on the per-lane data rate to try to |
---|
606 | | - * recover a potential mismatch between DPI and PPI clks. |
---|
607 | | - */ |
---|
608 | | - dlane_bps_max = dlane_bps + DIV_ROUND_DOWN_ULL(dlane_bps, 500); |
---|
609 | | - fbdiv_max = DIV_ROUND_DOWN_ULL(dlane_bps_max * 2 * |
---|
610 | | - cfg->pll_opdiv * cfg->pll_ipdiv, |
---|
611 | | - pll_ref_hz); |
---|
612 | | - fbdiv = DIV_ROUND_UP_ULL(dlane_bps * 2 * cfg->pll_opdiv * |
---|
613 | | - cfg->pll_ipdiv, |
---|
614 | | - pll_ref_hz); |
---|
615 | | - |
---|
616 | | - /* |
---|
617 | | - * Iterate over all acceptable fbdiv and try to find an adjusted DSI |
---|
618 | | - * htotal length providing an exact match. |
---|
619 | | - * |
---|
620 | | - * Note that we could do something even trickier by relying on the fact |
---|
621 | | - * that a new line is not necessarily aligned on a lane boundary, so, |
---|
622 | | - * by making adj_dsi_htotal non aligned on a dsi_lanes we can improve a |
---|
623 | | - * bit the precision. With this, the step would be |
---|
624 | | - * |
---|
625 | | - * pll_ref_hz / (2 * opdiv * ipdiv * nlanes) |
---|
626 | | - * |
---|
627 | | - * instead of |
---|
628 | | - * |
---|
629 | | - * pll_ref_hz / (2 * opdiv * ipdiv) |
---|
630 | | - * |
---|
631 | | - * The drawback of this approach is that we would need to make sure the |
---|
632 | | - * number or lines is a multiple of the realignment periodicity which is |
---|
633 | | - * a function of the number of lanes and the original misalignment. For |
---|
634 | | - * example, for NLANES = 4 and HTOTAL % NLANES = 3, it takes 4 lines |
---|
635 | | - * to realign on a lane: |
---|
636 | | - * LINE 0: expected number of bytes, starts emitting first byte of |
---|
637 | | - * LINE 1 on LANE 3 |
---|
638 | | - * LINE 1: expected number of bytes, starts emitting first 2 bytes of |
---|
639 | | - * LINE 2 on LANES 2 and 3 |
---|
640 | | - * LINE 2: expected number of bytes, starts emitting first 3 bytes of |
---|
641 | | - * of LINE 3 on LANES 1, 2 and 3 |
---|
642 | | - * LINE 3: one byte less, now things are realigned on LANE 0 for LINE 4 |
---|
643 | | - * |
---|
644 | | - * I figured this extra complexity was not worth the benefit, but if |
---|
645 | | - * someone really has unfixable mismatch, that would be something to |
---|
646 | | - * investigate. |
---|
647 | | - */ |
---|
648 | | - for (; fbdiv <= fbdiv_max; fbdiv++) { |
---|
649 | | - u32 rem; |
---|
650 | | - |
---|
651 | | - adj_dsi_htotal = (u64)fbdiv * pll_ref_hz * dsi_nlanes * |
---|
652 | | - dpi_htotal; |
---|
653 | | - |
---|
654 | | - /* |
---|
655 | | - * Do the division in 2 steps to avoid an overflow on the |
---|
656 | | - * divider. |
---|
657 | | - */ |
---|
658 | | - rem = do_div(adj_dsi_htotal, dpi_hz); |
---|
659 | | - if (rem) |
---|
660 | | - continue; |
---|
661 | | - |
---|
662 | | - rem = do_div(adj_dsi_htotal, |
---|
663 | | - cfg->pll_opdiv * cfg->pll_ipdiv * 2 * 8); |
---|
664 | | - if (rem) |
---|
665 | | - continue; |
---|
666 | | - |
---|
667 | | - cfg->pll_fbdiv = fbdiv; |
---|
668 | | - *dsi_hfp_ext = adj_dsi_htotal - dsi_htotal; |
---|
669 | | - break; |
---|
670 | | - } |
---|
671 | | - |
---|
672 | | - /* No match, let's just reject the display mode. */ |
---|
673 | | - if (!cfg->pll_fbdiv) |
---|
674 | | - return -EINVAL; |
---|
675 | | - |
---|
676 | | - dlane_bps = DIV_ROUND_DOWN_ULL((u64)dpi_hz * adj_dsi_htotal * 8, |
---|
677 | | - dsi_nlanes * dpi_htotal); |
---|
678 | | - cfg->lane_bps = dlane_bps; |
---|
679 | | - |
---|
680 | | - return 0; |
---|
681 | | -} |
---|
682 | | - |
---|
683 | | -static int cdns_dphy_setup_psm(struct cdns_dphy *dphy) |
---|
684 | | -{ |
---|
685 | | - unsigned long psm_clk_hz = clk_get_rate(dphy->psm_clk); |
---|
686 | | - unsigned long psm_div; |
---|
687 | | - |
---|
688 | | - if (!psm_clk_hz || psm_clk_hz > 100000000) |
---|
689 | | - return -EINVAL; |
---|
690 | | - |
---|
691 | | - psm_div = DIV_ROUND_CLOSEST(psm_clk_hz, 1000000); |
---|
692 | | - if (dphy->ops->set_psm_div) |
---|
693 | | - dphy->ops->set_psm_div(dphy, psm_div); |
---|
694 | | - |
---|
695 | | - return 0; |
---|
696 | | -} |
---|
697 | | - |
---|
698 | | -static void cdns_dphy_set_clk_lane_cfg(struct cdns_dphy *dphy, |
---|
699 | | - enum cdns_dphy_clk_lane_cfg cfg) |
---|
700 | | -{ |
---|
701 | | - if (dphy->ops->set_clk_lane_cfg) |
---|
702 | | - dphy->ops->set_clk_lane_cfg(dphy, cfg); |
---|
703 | | -} |
---|
704 | | - |
---|
705 | | -static void cdns_dphy_set_pll_cfg(struct cdns_dphy *dphy, |
---|
706 | | - const struct cdns_dphy_cfg *cfg) |
---|
707 | | -{ |
---|
708 | | - if (dphy->ops->set_pll_cfg) |
---|
709 | | - dphy->ops->set_pll_cfg(dphy, cfg); |
---|
710 | | -} |
---|
711 | | - |
---|
712 | | -static unsigned long cdns_dphy_get_wakeup_time_ns(struct cdns_dphy *dphy) |
---|
713 | | -{ |
---|
714 | | - return dphy->ops->get_wakeup_time_ns(dphy); |
---|
| 490 | + return mode->crtc_hsync_start - mode->crtc_hdisplay; |
---|
715 | 491 | } |
---|
716 | 492 | |
---|
717 | 493 | static unsigned int dpi_to_dsi_timing(unsigned int dpi_timing, |
---|
.. | .. |
---|
731 | 507 | static int cdns_dsi_mode2cfg(struct cdns_dsi *dsi, |
---|
732 | 508 | const struct drm_display_mode *mode, |
---|
733 | 509 | struct cdns_dsi_cfg *dsi_cfg, |
---|
734 | | - struct cdns_dphy_cfg *dphy_cfg, |
---|
735 | 510 | bool mode_valid_check) |
---|
736 | 511 | { |
---|
737 | | - unsigned long dsi_htotal = 0, dsi_hss_hsa_hse_hbp = 0; |
---|
738 | 512 | struct cdns_dsi_output *output = &dsi->output; |
---|
739 | | - unsigned int dsi_hfp_ext = 0, dpi_hfp, tmp; |
---|
| 513 | + unsigned int tmp; |
---|
740 | 514 | bool sync_pulse = false; |
---|
741 | | - int bpp, nlanes, ret; |
---|
| 515 | + int bpp; |
---|
742 | 516 | |
---|
743 | 517 | memset(dsi_cfg, 0, sizeof(*dsi_cfg)); |
---|
744 | 518 | |
---|
.. | .. |
---|
746 | 520 | sync_pulse = true; |
---|
747 | 521 | |
---|
748 | 522 | bpp = mipi_dsi_pixel_format_to_bpp(output->dev->format); |
---|
749 | | - nlanes = output->dev->lanes; |
---|
750 | 523 | |
---|
751 | 524 | if (mode_valid_check) |
---|
752 | 525 | tmp = mode->htotal - |
---|
.. | .. |
---|
757 | 530 | mode->crtc_hsync_end : mode->crtc_hsync_start); |
---|
758 | 531 | |
---|
759 | 532 | dsi_cfg->hbp = dpi_to_dsi_timing(tmp, bpp, DSI_HBP_FRAME_OVERHEAD); |
---|
760 | | - dsi_htotal += dsi_cfg->hbp + DSI_HBP_FRAME_OVERHEAD; |
---|
761 | | - dsi_hss_hsa_hse_hbp += dsi_cfg->hbp + DSI_HBP_FRAME_OVERHEAD; |
---|
762 | 533 | |
---|
763 | 534 | if (sync_pulse) { |
---|
764 | 535 | if (mode_valid_check) |
---|
.. | .. |
---|
768 | 539 | |
---|
769 | 540 | dsi_cfg->hsa = dpi_to_dsi_timing(tmp, bpp, |
---|
770 | 541 | DSI_HSA_FRAME_OVERHEAD); |
---|
771 | | - dsi_htotal += dsi_cfg->hsa + DSI_HSA_FRAME_OVERHEAD; |
---|
772 | | - dsi_hss_hsa_hse_hbp += dsi_cfg->hsa + DSI_HSA_FRAME_OVERHEAD; |
---|
773 | 542 | } |
---|
774 | 543 | |
---|
775 | 544 | dsi_cfg->hact = dpi_to_dsi_timing(mode_valid_check ? |
---|
776 | 545 | mode->hdisplay : mode->crtc_hdisplay, |
---|
777 | 546 | bpp, 0); |
---|
| 547 | + dsi_cfg->hfp = dpi_to_dsi_timing(mode_to_dpi_hfp(mode, mode_valid_check), |
---|
| 548 | + bpp, DSI_HFP_FRAME_OVERHEAD); |
---|
| 549 | + |
---|
| 550 | + return 0; |
---|
| 551 | +} |
---|
| 552 | + |
---|
| 553 | +static int cdns_dsi_adjust_phy_config(struct cdns_dsi *dsi, |
---|
| 554 | + struct cdns_dsi_cfg *dsi_cfg, |
---|
| 555 | + struct phy_configure_opts_mipi_dphy *phy_cfg, |
---|
| 556 | + const struct drm_display_mode *mode, |
---|
| 557 | + bool mode_valid_check) |
---|
| 558 | +{ |
---|
| 559 | + struct cdns_dsi_output *output = &dsi->output; |
---|
| 560 | + unsigned long long dlane_bps; |
---|
| 561 | + unsigned long adj_dsi_htotal; |
---|
| 562 | + unsigned long dsi_htotal; |
---|
| 563 | + unsigned long dpi_htotal; |
---|
| 564 | + unsigned long dpi_hz; |
---|
| 565 | + unsigned int dsi_hfp_ext; |
---|
| 566 | + unsigned int lanes = output->dev->lanes; |
---|
| 567 | + |
---|
| 568 | + dsi_htotal = dsi_cfg->hbp + DSI_HBP_FRAME_OVERHEAD; |
---|
| 569 | + if (output->dev->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE) |
---|
| 570 | + dsi_htotal += dsi_cfg->hsa + DSI_HSA_FRAME_OVERHEAD; |
---|
| 571 | + |
---|
778 | 572 | dsi_htotal += dsi_cfg->hact; |
---|
779 | | - |
---|
780 | | - if (mode_valid_check) |
---|
781 | | - dpi_hfp = mode->hsync_start - mode->hdisplay; |
---|
782 | | - else |
---|
783 | | - dpi_hfp = mode->crtc_hsync_start - mode->crtc_hdisplay; |
---|
784 | | - |
---|
785 | | - dsi_cfg->hfp = dpi_to_dsi_timing(dpi_hfp, bpp, DSI_HFP_FRAME_OVERHEAD); |
---|
786 | 573 | dsi_htotal += dsi_cfg->hfp + DSI_HFP_FRAME_OVERHEAD; |
---|
787 | 574 | |
---|
788 | | - if (mode_valid_check) |
---|
789 | | - ret = cdns_dsi_get_dphy_pll_cfg(dsi->dphy, dphy_cfg, |
---|
790 | | - mode->htotal, bpp, |
---|
791 | | - mode->clock * 1000, |
---|
792 | | - dsi_htotal, nlanes, |
---|
793 | | - &dsi_hfp_ext); |
---|
794 | | - else |
---|
795 | | - ret = cdns_dsi_get_dphy_pll_cfg(dsi->dphy, dphy_cfg, |
---|
796 | | - mode->crtc_htotal, bpp, |
---|
797 | | - mode->crtc_clock * 1000, |
---|
798 | | - dsi_htotal, nlanes, |
---|
799 | | - &dsi_hfp_ext); |
---|
| 575 | + /* |
---|
| 576 | + * Make sure DSI htotal is aligned on a lane boundary when calculating |
---|
| 577 | + * the expected data rate. This is done by extending HFP in case of |
---|
| 578 | + * misalignment. |
---|
| 579 | + */ |
---|
| 580 | + adj_dsi_htotal = dsi_htotal; |
---|
| 581 | + if (dsi_htotal % lanes) |
---|
| 582 | + adj_dsi_htotal += lanes - (dsi_htotal % lanes); |
---|
800 | 583 | |
---|
| 584 | + dpi_hz = (mode_valid_check ? mode->clock : mode->crtc_clock) * 1000; |
---|
| 585 | + dlane_bps = (unsigned long long)dpi_hz * adj_dsi_htotal; |
---|
| 586 | + |
---|
| 587 | + /* data rate in bytes/sec is not an integer, refuse the mode. */ |
---|
| 588 | + dpi_htotal = mode_valid_check ? mode->htotal : mode->crtc_htotal; |
---|
| 589 | + if (do_div(dlane_bps, lanes * dpi_htotal)) |
---|
| 590 | + return -EINVAL; |
---|
| 591 | + |
---|
| 592 | + /* data rate was in bytes/sec, convert to bits/sec. */ |
---|
| 593 | + phy_cfg->hs_clk_rate = dlane_bps * 8; |
---|
| 594 | + |
---|
| 595 | + dsi_hfp_ext = adj_dsi_htotal - dsi_htotal; |
---|
| 596 | + dsi_cfg->hfp += dsi_hfp_ext; |
---|
| 597 | + dsi_cfg->htotal = dsi_htotal + dsi_hfp_ext; |
---|
| 598 | + |
---|
| 599 | + return 0; |
---|
| 600 | +} |
---|
| 601 | + |
---|
| 602 | +static int cdns_dsi_check_conf(struct cdns_dsi *dsi, |
---|
| 603 | + const struct drm_display_mode *mode, |
---|
| 604 | + struct cdns_dsi_cfg *dsi_cfg, |
---|
| 605 | + bool mode_valid_check) |
---|
| 606 | +{ |
---|
| 607 | + struct cdns_dsi_output *output = &dsi->output; |
---|
| 608 | + struct phy_configure_opts_mipi_dphy *phy_cfg = &output->phy_opts.mipi_dphy; |
---|
| 609 | + unsigned long dsi_hss_hsa_hse_hbp; |
---|
| 610 | + unsigned int nlanes = output->dev->lanes; |
---|
| 611 | + int ret; |
---|
| 612 | + |
---|
| 613 | + ret = cdns_dsi_mode2cfg(dsi, mode, dsi_cfg, mode_valid_check); |
---|
801 | 614 | if (ret) |
---|
802 | 615 | return ret; |
---|
803 | 616 | |
---|
804 | | - dsi_cfg->hfp += dsi_hfp_ext; |
---|
805 | | - dsi_htotal += dsi_hfp_ext; |
---|
806 | | - dsi_cfg->htotal = dsi_htotal; |
---|
| 617 | + phy_mipi_dphy_get_default_config(mode->crtc_clock * 1000, |
---|
| 618 | + mipi_dsi_pixel_format_to_bpp(output->dev->format), |
---|
| 619 | + nlanes, phy_cfg); |
---|
| 620 | + |
---|
| 621 | + ret = cdns_dsi_adjust_phy_config(dsi, dsi_cfg, phy_cfg, mode, mode_valid_check); |
---|
| 622 | + if (ret) |
---|
| 623 | + return ret; |
---|
| 624 | + |
---|
| 625 | + ret = phy_validate(dsi->dphy, PHY_MODE_MIPI_DPHY, 0, &output->phy_opts); |
---|
| 626 | + if (ret) |
---|
| 627 | + return ret; |
---|
| 628 | + |
---|
| 629 | + dsi_hss_hsa_hse_hbp = dsi_cfg->hbp + DSI_HBP_FRAME_OVERHEAD; |
---|
| 630 | + if (output->dev->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE) |
---|
| 631 | + dsi_hss_hsa_hse_hbp += dsi_cfg->hsa + DSI_HSA_FRAME_OVERHEAD; |
---|
807 | 632 | |
---|
808 | 633 | /* |
---|
809 | 634 | * Make sure DPI(HFP) > DSI(HSS+HSA+HSE+HBP) to guarantee that the FIFO |
---|
810 | 635 | * is empty before we start a receiving a new line on the DPI |
---|
811 | 636 | * interface. |
---|
812 | 637 | */ |
---|
813 | | - if ((u64)dphy_cfg->lane_bps * dpi_hfp * nlanes < |
---|
| 638 | + if ((u64)phy_cfg->hs_clk_rate * |
---|
| 639 | + mode_to_dpi_hfp(mode, mode_valid_check) * nlanes < |
---|
814 | 640 | (u64)dsi_hss_hsa_hse_hbp * |
---|
815 | 641 | (mode_valid_check ? mode->clock : mode->crtc_clock) * 1000) |
---|
816 | 642 | return -EINVAL; |
---|
.. | .. |
---|
818 | 644 | return 0; |
---|
819 | 645 | } |
---|
820 | 646 | |
---|
821 | | -static int cdns_dsi_bridge_attach(struct drm_bridge *bridge) |
---|
| 647 | +static int cdns_dsi_bridge_attach(struct drm_bridge *bridge, |
---|
| 648 | + enum drm_bridge_attach_flags flags) |
---|
822 | 649 | { |
---|
823 | 650 | struct cdns_dsi_input *input = bridge_to_cdns_dsi_input(bridge); |
---|
824 | 651 | struct cdns_dsi *dsi = input_to_dsi(input); |
---|
.. | .. |
---|
830 | 657 | return -ENOTSUPP; |
---|
831 | 658 | } |
---|
832 | 659 | |
---|
833 | | - return drm_bridge_attach(bridge->encoder, output->bridge, bridge); |
---|
| 660 | + return drm_bridge_attach(bridge->encoder, output->bridge, bridge, |
---|
| 661 | + flags); |
---|
834 | 662 | } |
---|
835 | 663 | |
---|
836 | 664 | static enum drm_mode_status |
---|
837 | 665 | cdns_dsi_bridge_mode_valid(struct drm_bridge *bridge, |
---|
| 666 | + const struct drm_display_info *info, |
---|
838 | 667 | const struct drm_display_mode *mode) |
---|
839 | 668 | { |
---|
840 | 669 | struct cdns_dsi_input *input = bridge_to_cdns_dsi_input(bridge); |
---|
841 | 670 | struct cdns_dsi *dsi = input_to_dsi(input); |
---|
842 | 671 | struct cdns_dsi_output *output = &dsi->output; |
---|
843 | | - struct cdns_dphy_cfg dphy_cfg; |
---|
844 | 672 | struct cdns_dsi_cfg dsi_cfg; |
---|
845 | | - int bpp, nlanes, ret; |
---|
| 673 | + int bpp, ret; |
---|
846 | 674 | |
---|
847 | 675 | /* |
---|
848 | 676 | * VFP_DSI should be less than VFP_DPI and VFP_DSI should be at |
---|
.. | .. |
---|
860 | 688 | if ((mode->hdisplay * bpp) % 32) |
---|
861 | 689 | return MODE_H_ILLEGAL; |
---|
862 | 690 | |
---|
863 | | - nlanes = output->dev->lanes; |
---|
864 | | - |
---|
865 | | - ret = cdns_dsi_mode2cfg(dsi, mode, &dsi_cfg, &dphy_cfg, true); |
---|
| 691 | + ret = cdns_dsi_check_conf(dsi, mode, &dsi_cfg, true); |
---|
866 | 692 | if (ret) |
---|
867 | | - return MODE_CLOCK_RANGE; |
---|
| 693 | + return MODE_BAD; |
---|
868 | 694 | |
---|
869 | 695 | return MODE_OK; |
---|
870 | 696 | } |
---|
.. | .. |
---|
885 | 711 | pm_runtime_put(dsi->base.dev); |
---|
886 | 712 | } |
---|
887 | 713 | |
---|
888 | | -static void cdns_dsi_hs_init(struct cdns_dsi *dsi, |
---|
889 | | - const struct cdns_dphy_cfg *dphy_cfg) |
---|
| 714 | +static void cdns_dsi_hs_init(struct cdns_dsi *dsi) |
---|
890 | 715 | { |
---|
| 716 | + struct cdns_dsi_output *output = &dsi->output; |
---|
891 | 717 | u32 status; |
---|
892 | 718 | |
---|
893 | 719 | /* |
---|
.. | .. |
---|
898 | 724 | DPHY_CMN_PDN | DPHY_PLL_PDN, |
---|
899 | 725 | dsi->regs + MCTL_DPHY_CFG0); |
---|
900 | 726 | |
---|
901 | | - /* |
---|
902 | | - * Configure the internal PSM clk divider so that the DPHY has a |
---|
903 | | - * 1MHz clk (or something close). |
---|
904 | | - */ |
---|
905 | | - WARN_ON_ONCE(cdns_dphy_setup_psm(dsi->dphy)); |
---|
906 | | - |
---|
907 | | - /* |
---|
908 | | - * Configure attach clk lanes to data lanes: the DPHY has 2 clk lanes |
---|
909 | | - * and 8 data lanes, each clk lane can be attache different set of |
---|
910 | | - * data lanes. The 2 groups are named 'left' and 'right', so here we |
---|
911 | | - * just say that we want the 'left' clk lane to drive the 'left' data |
---|
912 | | - * lanes. |
---|
913 | | - */ |
---|
914 | | - cdns_dphy_set_clk_lane_cfg(dsi->dphy, DPHY_CLK_CFG_LEFT_DRIVES_LEFT); |
---|
915 | | - |
---|
916 | | - /* |
---|
917 | | - * Configure the DPHY PLL that will be used to generate the TX byte |
---|
918 | | - * clk. |
---|
919 | | - */ |
---|
920 | | - cdns_dphy_set_pll_cfg(dsi->dphy, dphy_cfg); |
---|
921 | | - |
---|
922 | | - /* Start TX state machine. */ |
---|
923 | | - writel(DPHY_CMN_SSM_EN | DPHY_CMN_TX_MODE_EN, |
---|
924 | | - dsi->dphy->regs + DPHY_CMN_SSM); |
---|
| 727 | + phy_init(dsi->dphy); |
---|
| 728 | + phy_set_mode(dsi->dphy, PHY_MODE_MIPI_DPHY); |
---|
| 729 | + phy_configure(dsi->dphy, &output->phy_opts); |
---|
| 730 | + phy_power_on(dsi->dphy); |
---|
925 | 731 | |
---|
926 | 732 | /* Activate the PLL and wait until it's locked. */ |
---|
927 | 733 | writel(PLL_LOCKED, dsi->regs + MCTL_MAIN_STS_CLR); |
---|
.. | .. |
---|
931 | 737 | status & PLL_LOCKED, 100, 100)); |
---|
932 | 738 | /* De-assert data and clock reset lines. */ |
---|
933 | 739 | writel(DPHY_CMN_PSO | DPHY_ALL_D_PDN | DPHY_C_PDN | DPHY_CMN_PDN | |
---|
934 | | - DPHY_D_RSTB(dphy_cfg->nlanes) | DPHY_C_RSTB, |
---|
| 740 | + DPHY_D_RSTB(output->dev->lanes) | DPHY_C_RSTB, |
---|
935 | 741 | dsi->regs + MCTL_DPHY_CFG0); |
---|
936 | 742 | } |
---|
937 | 743 | |
---|
.. | .. |
---|
977 | 783 | struct cdns_dsi *dsi = input_to_dsi(input); |
---|
978 | 784 | struct cdns_dsi_output *output = &dsi->output; |
---|
979 | 785 | struct drm_display_mode *mode; |
---|
980 | | - struct cdns_dphy_cfg dphy_cfg; |
---|
| 786 | + struct phy_configure_opts_mipi_dphy *phy_cfg = &output->phy_opts.mipi_dphy; |
---|
981 | 787 | unsigned long tx_byte_period; |
---|
982 | 788 | struct cdns_dsi_cfg dsi_cfg; |
---|
983 | 789 | u32 tmp, reg_wakeup, div; |
---|
984 | | - int bpp, nlanes; |
---|
| 790 | + int nlanes; |
---|
985 | 791 | |
---|
986 | 792 | if (WARN_ON(pm_runtime_get_sync(dsi->base.dev) < 0)) |
---|
987 | 793 | return; |
---|
988 | 794 | |
---|
989 | 795 | mode = &bridge->encoder->crtc->state->adjusted_mode; |
---|
990 | | - bpp = mipi_dsi_pixel_format_to_bpp(output->dev->format); |
---|
991 | 796 | nlanes = output->dev->lanes; |
---|
992 | 797 | |
---|
993 | | - WARN_ON_ONCE(cdns_dsi_mode2cfg(dsi, mode, &dsi_cfg, &dphy_cfg, false)); |
---|
| 798 | + WARN_ON_ONCE(cdns_dsi_check_conf(dsi, mode, &dsi_cfg, false)); |
---|
994 | 799 | |
---|
995 | | - cdns_dsi_hs_init(dsi, &dphy_cfg); |
---|
| 800 | + cdns_dsi_hs_init(dsi); |
---|
996 | 801 | cdns_dsi_init_link(dsi); |
---|
997 | 802 | |
---|
998 | 803 | writel(HBP_LEN(dsi_cfg.hbp) | HSA_LEN(dsi_cfg.hsa), |
---|
.. | .. |
---|
1028 | 833 | tmp -= DIV_ROUND_UP(DSI_EOT_PKT_SIZE, nlanes); |
---|
1029 | 834 | |
---|
1030 | 835 | tx_byte_period = DIV_ROUND_DOWN_ULL((u64)NSEC_PER_SEC * 8, |
---|
1031 | | - dphy_cfg.lane_bps); |
---|
1032 | | - reg_wakeup = cdns_dphy_get_wakeup_time_ns(dsi->dphy) / |
---|
1033 | | - tx_byte_period; |
---|
| 836 | + phy_cfg->hs_clk_rate); |
---|
| 837 | + reg_wakeup = (phy_cfg->hs_prepare + phy_cfg->hs_zero) / tx_byte_period; |
---|
1034 | 838 | writel(REG_WAKEUP_TIME(reg_wakeup) | REG_LINE_DURATION(tmp), |
---|
1035 | 839 | dsi->regs + VID_DPHY_TIME); |
---|
1036 | 840 | |
---|
.. | .. |
---|
1153 | 957 | |
---|
1154 | 958 | panel = of_drm_find_panel(np); |
---|
1155 | 959 | if (!IS_ERR(panel)) { |
---|
1156 | | - bridge = drm_panel_bridge_add(panel, DRM_MODE_CONNECTOR_DSI); |
---|
| 960 | + bridge = drm_panel_bridge_add_typed(panel, |
---|
| 961 | + DRM_MODE_CONNECTOR_DSI); |
---|
1157 | 962 | } else { |
---|
1158 | 963 | bridge = of_drm_find_bridge(dev->dev.of_node); |
---|
1159 | 964 | if (!bridge) |
---|
.. | .. |
---|
1223 | 1028 | struct mipi_dsi_packet packet; |
---|
1224 | 1029 | int ret, i, tx_len, rx_len; |
---|
1225 | 1030 | |
---|
1226 | | - ret = pm_runtime_get_sync(host->dev); |
---|
| 1031 | + ret = pm_runtime_resume_and_get(host->dev); |
---|
1227 | 1032 | if (ret < 0) |
---|
1228 | 1033 | return ret; |
---|
1229 | 1034 | |
---|
.. | .. |
---|
1344 | 1149 | reset_control_deassert(dsi->dsi_p_rst); |
---|
1345 | 1150 | clk_prepare_enable(dsi->dsi_p_clk); |
---|
1346 | 1151 | clk_prepare_enable(dsi->dsi_sys_clk); |
---|
1347 | | - clk_prepare_enable(dsi->dphy->psm_clk); |
---|
1348 | | - clk_prepare_enable(dsi->dphy->pll_ref_clk); |
---|
1349 | 1152 | |
---|
1350 | 1153 | return 0; |
---|
1351 | 1154 | } |
---|
.. | .. |
---|
1354 | 1157 | { |
---|
1355 | 1158 | struct cdns_dsi *dsi = dev_get_drvdata(dev); |
---|
1356 | 1159 | |
---|
1357 | | - clk_disable_unprepare(dsi->dphy->pll_ref_clk); |
---|
1358 | | - clk_disable_unprepare(dsi->dphy->psm_clk); |
---|
1359 | 1160 | clk_disable_unprepare(dsi->dsi_sys_clk); |
---|
1360 | 1161 | clk_disable_unprepare(dsi->dsi_p_clk); |
---|
1361 | 1162 | reset_control_assert(dsi->dsi_p_rst); |
---|
.. | .. |
---|
1365 | 1166 | |
---|
1366 | 1167 | static UNIVERSAL_DEV_PM_OPS(cdns_dsi_pm_ops, cdns_dsi_suspend, cdns_dsi_resume, |
---|
1367 | 1168 | NULL); |
---|
1368 | | - |
---|
1369 | | -static unsigned long cdns_dphy_ref_get_wakeup_time_ns(struct cdns_dphy *dphy) |
---|
1370 | | -{ |
---|
1371 | | - /* Default wakeup time is 800 ns (in a simulated environment). */ |
---|
1372 | | - return 800; |
---|
1373 | | -} |
---|
1374 | | - |
---|
1375 | | -static void cdns_dphy_ref_set_pll_cfg(struct cdns_dphy *dphy, |
---|
1376 | | - const struct cdns_dphy_cfg *cfg) |
---|
1377 | | -{ |
---|
1378 | | - u32 fbdiv_low, fbdiv_high; |
---|
1379 | | - |
---|
1380 | | - fbdiv_low = (cfg->pll_fbdiv / 4) - 2; |
---|
1381 | | - fbdiv_high = cfg->pll_fbdiv - fbdiv_low - 2; |
---|
1382 | | - |
---|
1383 | | - writel(DPHY_CMN_IPDIV_FROM_REG | DPHY_CMN_OPDIV_FROM_REG | |
---|
1384 | | - DPHY_CMN_IPDIV(cfg->pll_ipdiv) | |
---|
1385 | | - DPHY_CMN_OPDIV(cfg->pll_opdiv), |
---|
1386 | | - dphy->regs + DPHY_CMN_OPIPDIV); |
---|
1387 | | - writel(DPHY_CMN_FBDIV_FROM_REG | |
---|
1388 | | - DPHY_CMN_FBDIV_VAL(fbdiv_low, fbdiv_high), |
---|
1389 | | - dphy->regs + DPHY_CMN_FBDIV); |
---|
1390 | | - writel(DPHY_CMN_PWM_HIGH(6) | DPHY_CMN_PWM_LOW(0x101) | |
---|
1391 | | - DPHY_CMN_PWM_DIV(0x8), |
---|
1392 | | - dphy->regs + DPHY_CMN_PWM); |
---|
1393 | | -} |
---|
1394 | | - |
---|
1395 | | -static void cdns_dphy_ref_set_psm_div(struct cdns_dphy *dphy, u8 div) |
---|
1396 | | -{ |
---|
1397 | | - writel(DPHY_PSM_CFG_FROM_REG | DPHY_PSM_CLK_DIV(div), |
---|
1398 | | - dphy->regs + DPHY_PSM_CFG); |
---|
1399 | | -} |
---|
1400 | | - |
---|
1401 | | -/* |
---|
1402 | | - * This is the reference implementation of DPHY hooks. Specific integration of |
---|
1403 | | - * this IP may have to re-implement some of them depending on how they decided |
---|
1404 | | - * to wire things in the SoC. |
---|
1405 | | - */ |
---|
1406 | | -static const struct cdns_dphy_ops ref_dphy_ops = { |
---|
1407 | | - .get_wakeup_time_ns = cdns_dphy_ref_get_wakeup_time_ns, |
---|
1408 | | - .set_pll_cfg = cdns_dphy_ref_set_pll_cfg, |
---|
1409 | | - .set_psm_div = cdns_dphy_ref_set_psm_div, |
---|
1410 | | -}; |
---|
1411 | | - |
---|
1412 | | -static const struct of_device_id cdns_dphy_of_match[] = { |
---|
1413 | | - { .compatible = "cdns,dphy", .data = &ref_dphy_ops }, |
---|
1414 | | - { /* sentinel */ }, |
---|
1415 | | -}; |
---|
1416 | | - |
---|
1417 | | -static struct cdns_dphy *cdns_dphy_probe(struct platform_device *pdev) |
---|
1418 | | -{ |
---|
1419 | | - const struct of_device_id *match; |
---|
1420 | | - struct cdns_dphy *dphy; |
---|
1421 | | - struct of_phandle_args args; |
---|
1422 | | - struct resource res; |
---|
1423 | | - int ret; |
---|
1424 | | - |
---|
1425 | | - ret = of_parse_phandle_with_args(pdev->dev.of_node, "phys", |
---|
1426 | | - "#phy-cells", 0, &args); |
---|
1427 | | - if (ret) |
---|
1428 | | - return ERR_PTR(-ENOENT); |
---|
1429 | | - |
---|
1430 | | - match = of_match_node(cdns_dphy_of_match, args.np); |
---|
1431 | | - if (!match || !match->data) |
---|
1432 | | - return ERR_PTR(-EINVAL); |
---|
1433 | | - |
---|
1434 | | - dphy = devm_kzalloc(&pdev->dev, sizeof(*dphy), GFP_KERNEL); |
---|
1435 | | - if (!dphy) |
---|
1436 | | - return ERR_PTR(-ENOMEM); |
---|
1437 | | - |
---|
1438 | | - dphy->ops = match->data; |
---|
1439 | | - |
---|
1440 | | - ret = of_address_to_resource(args.np, 0, &res); |
---|
1441 | | - if (ret) |
---|
1442 | | - return ERR_PTR(ret); |
---|
1443 | | - |
---|
1444 | | - dphy->regs = devm_ioremap_resource(&pdev->dev, &res); |
---|
1445 | | - if (IS_ERR(dphy->regs)) |
---|
1446 | | - return ERR_CAST(dphy->regs); |
---|
1447 | | - |
---|
1448 | | - dphy->psm_clk = of_clk_get_by_name(args.np, "psm"); |
---|
1449 | | - if (IS_ERR(dphy->psm_clk)) |
---|
1450 | | - return ERR_CAST(dphy->psm_clk); |
---|
1451 | | - |
---|
1452 | | - dphy->pll_ref_clk = of_clk_get_by_name(args.np, "pll_ref"); |
---|
1453 | | - if (IS_ERR(dphy->pll_ref_clk)) { |
---|
1454 | | - ret = PTR_ERR(dphy->pll_ref_clk); |
---|
1455 | | - goto err_put_psm_clk; |
---|
1456 | | - } |
---|
1457 | | - |
---|
1458 | | - if (dphy->ops->probe) { |
---|
1459 | | - ret = dphy->ops->probe(dphy); |
---|
1460 | | - if (ret) |
---|
1461 | | - goto err_put_pll_ref_clk; |
---|
1462 | | - } |
---|
1463 | | - |
---|
1464 | | - return dphy; |
---|
1465 | | - |
---|
1466 | | -err_put_pll_ref_clk: |
---|
1467 | | - clk_put(dphy->pll_ref_clk); |
---|
1468 | | - |
---|
1469 | | -err_put_psm_clk: |
---|
1470 | | - clk_put(dphy->psm_clk); |
---|
1471 | | - |
---|
1472 | | - return ERR_PTR(ret); |
---|
1473 | | -} |
---|
1474 | | - |
---|
1475 | | -static void cdns_dphy_remove(struct cdns_dphy *dphy) |
---|
1476 | | -{ |
---|
1477 | | - if (dphy->ops->remove) |
---|
1478 | | - dphy->ops->remove(dphy); |
---|
1479 | | - |
---|
1480 | | - clk_put(dphy->pll_ref_clk); |
---|
1481 | | - clk_put(dphy->psm_clk); |
---|
1482 | | -} |
---|
1483 | 1169 | |
---|
1484 | 1170 | static int cdns_dsi_drm_probe(struct platform_device *pdev) |
---|
1485 | 1171 | { |
---|
.. | .. |
---|
1519 | 1205 | if (irq < 0) |
---|
1520 | 1206 | return irq; |
---|
1521 | 1207 | |
---|
1522 | | - dsi->dphy = cdns_dphy_probe(pdev); |
---|
| 1208 | + dsi->dphy = devm_phy_get(&pdev->dev, "dphy"); |
---|
1523 | 1209 | if (IS_ERR(dsi->dphy)) |
---|
1524 | 1210 | return PTR_ERR(dsi->dphy); |
---|
1525 | 1211 | |
---|
1526 | 1212 | ret = clk_prepare_enable(dsi->dsi_p_clk); |
---|
1527 | 1213 | if (ret) |
---|
1528 | | - goto err_remove_dphy; |
---|
| 1214 | + return ret; |
---|
1529 | 1215 | |
---|
1530 | 1216 | val = readl(dsi->regs + ID_REG); |
---|
1531 | 1217 | if (REV_VENDOR_ID(val) != 0xcad) { |
---|
.. | .. |
---|
1583 | 1269 | err_disable_pclk: |
---|
1584 | 1270 | clk_disable_unprepare(dsi->dsi_p_clk); |
---|
1585 | 1271 | |
---|
1586 | | -err_remove_dphy: |
---|
1587 | | - cdns_dphy_remove(dsi->dphy); |
---|
1588 | | - |
---|
1589 | 1272 | return ret; |
---|
1590 | 1273 | } |
---|
1591 | 1274 | |
---|
.. | .. |
---|
1595 | 1278 | |
---|
1596 | 1279 | mipi_dsi_host_unregister(&dsi->base); |
---|
1597 | 1280 | pm_runtime_disable(&pdev->dev); |
---|
1598 | | - cdns_dphy_remove(dsi->dphy); |
---|
1599 | 1281 | |
---|
1600 | 1282 | return 0; |
---|
1601 | 1283 | } |
---|
.. | .. |
---|
1604 | 1286 | { .compatible = "cdns,dsi" }, |
---|
1605 | 1287 | { }, |
---|
1606 | 1288 | }; |
---|
| 1289 | +MODULE_DEVICE_TABLE(of, cdns_dsi_of_match); |
---|
1607 | 1290 | |
---|
1608 | 1291 | static struct platform_driver cdns_dsi_platform_driver = { |
---|
1609 | 1292 | .probe = cdns_dsi_drm_probe, |
---|