3636#define IS_DSI0 (dsi ) ((dsi)->id == 0)
3737#define IS_DSI1 (dsi ) ((dsi)->id == 1)
3838
39+ #define UPDATE (v , h , l ) (((v) << (l)) & GENMASK((h), (l)))
40+
3941#define DSI_VERSION 0x00
4042#define DSI_PWR_UP 0x04
4143#define RESET 0
203205
204206#define DSI_PHY_TST_CTRL0 0xb4
205207#define PHY_TESTCLK BIT(1)
206- #define PHY_UNTESTCLK 0
207208#define PHY_TESTCLR BIT(0)
208- #define PHY_UNTESTCLR 0
209-
210209#define DSI_PHY_TST_CTRL1 0xb8
211210#define PHY_TESTEN BIT(16)
212- #define PHY_UNTESTEN 0
213- #define PHY_TESTDOUT (n ) (((n) & 0xff) << 8)
214- #define PHY_TESTDIN (n ) (((n) & 0xff) << 0)
215-
211+ #define PHY_TESTDOUT_SHIFT 8
212+ #define PHY_TESTDIN_MASK GENMASK(7, 0)
213+ #define PHY_TESTDIN (v ) UPDATE(v, 7, 0)
216214#define DSI_INT_ST0 0xbc
217215#define DSI_INT_ST1 0xc0
218216#define DSI_INT_MSK0 0xc4
@@ -321,6 +319,7 @@ struct dw_mipi_dsi_plat_data {
321319
322320struct mipi_dphy {
323321 /* SNPS PHY */
322+ struct regmap * regmap ;
324323 struct clk * cfg_clk ;
325324 struct clk * ref_clk ;
326325 u16 input_div ;
@@ -481,24 +480,102 @@ static int genif_wait_write_fifo_empty(struct dw_mipi_dsi *dsi)
481480 return 0 ;
482481}
483482
484- static void dw_mipi_dsi_phy_write (struct dw_mipi_dsi * dsi , u8 test_code ,
485- u8 test_data )
483+ static inline void testif_testclk_assert (struct dw_mipi_dsi * dsi )
486484{
487- /*
488- * With the falling edge on TESTCLK, the TESTDIN[7:0] signal content
489- * is latched internally as the current test code. Test data is
490- * programmed internally by rising edge on TESTCLK.
491- */
492- regmap_write (dsi -> regmap , DSI_PHY_TST_CTRL0 ,
493- PHY_TESTCLK | PHY_UNTESTCLR );
494- regmap_write (dsi -> regmap , DSI_PHY_TST_CTRL1 ,
495- PHY_TESTEN | PHY_TESTDOUT (0 ) | PHY_TESTDIN (test_code ));
496- regmap_write (dsi -> regmap , DSI_PHY_TST_CTRL0 ,
497- PHY_UNTESTCLK | PHY_UNTESTCLR );
498- regmap_write (dsi -> regmap , DSI_PHY_TST_CTRL1 ,
499- PHY_UNTESTEN | PHY_TESTDOUT (0 ) | PHY_TESTDIN (test_data ));
500- regmap_write (dsi -> regmap , DSI_PHY_TST_CTRL0 ,
501- PHY_TESTCLK | PHY_UNTESTCLR );
485+ regmap_update_bits (dsi -> regmap , DSI_PHY_TST_CTRL0 ,
486+ PHY_TESTCLK , PHY_TESTCLK );
487+ udelay (1 );
488+ }
489+
490+ static inline void testif_testclk_deassert (struct dw_mipi_dsi * dsi )
491+ {
492+ regmap_update_bits (dsi -> regmap , DSI_PHY_TST_CTRL0 , PHY_TESTCLK , 0 );
493+ udelay (1 );
494+ }
495+
496+ static inline void testif_testclr_assert (struct dw_mipi_dsi * dsi )
497+ {
498+ regmap_update_bits (dsi -> regmap , DSI_PHY_TST_CTRL0 ,
499+ PHY_TESTCLR , PHY_TESTCLR );
500+ udelay (1 );
501+ }
502+
503+ static inline void testif_testclr_deassert (struct dw_mipi_dsi * dsi )
504+ {
505+ regmap_update_bits (dsi -> regmap , DSI_PHY_TST_CTRL0 , PHY_TESTCLR , 0 );
506+ udelay (1 );
507+ }
508+
509+ static inline void testif_testen_assert (struct dw_mipi_dsi * dsi )
510+ {
511+ regmap_update_bits (dsi -> regmap , DSI_PHY_TST_CTRL1 ,
512+ PHY_TESTEN , PHY_TESTEN );
513+ udelay (1 );
514+ }
515+
516+ static inline void testif_testen_deassert (struct dw_mipi_dsi * dsi )
517+ {
518+ regmap_update_bits (dsi -> regmap , DSI_PHY_TST_CTRL1 , PHY_TESTEN , 0 );
519+ udelay (1 );
520+ }
521+
522+ static inline void testif_set_data (struct dw_mipi_dsi * dsi , u8 data )
523+ {
524+ regmap_update_bits (dsi -> regmap , DSI_PHY_TST_CTRL1 ,
525+ PHY_TESTDIN_MASK , PHY_TESTDIN (data ));
526+ udelay (1 );
527+ }
528+
529+ static inline u8 testif_get_data (struct dw_mipi_dsi * dsi )
530+ {
531+ u32 data = 0 ;
532+
533+ regmap_read (dsi -> regmap , DSI_PHY_TST_CTRL1 , & data );
534+
535+ return data >> PHY_TESTDOUT_SHIFT ;
536+ }
537+
538+ static void testif_test_code_write (struct dw_mipi_dsi * dsi , u8 test_code )
539+ {
540+ testif_testclk_assert (dsi );
541+ testif_set_data (dsi , test_code );
542+ testif_testen_assert (dsi );
543+ testif_testclk_deassert (dsi );
544+ testif_testen_deassert (dsi );
545+ }
546+
547+ static void testif_test_data_write (struct dw_mipi_dsi * dsi , u8 test_data )
548+ {
549+ testif_testclk_deassert (dsi );
550+ testif_set_data (dsi , test_data );
551+ testif_testclk_assert (dsi );
552+ }
553+
554+ static int testif_write (void * context , unsigned int reg , unsigned int value )
555+ {
556+ struct dw_mipi_dsi * dsi = context ;
557+
558+ testif_testclr_deassert (dsi );
559+ testif_test_code_write (dsi , reg );
560+ testif_test_data_write (dsi , value );
561+
562+ dev_dbg (dsi -> dev ,
563+ "test_code=0x%02x, test_data=0x%02x, monitor_data=0x%02x\n" ,
564+ reg , value , testif_get_data (dsi ));
565+
566+ return 0 ;
567+ }
568+
569+ static int testif_read (void * context , unsigned int reg , unsigned int * value )
570+ {
571+ struct dw_mipi_dsi * dsi = context ;
572+
573+ testif_testclr_deassert (dsi );
574+ testif_test_code_write (dsi , reg );
575+ * value = testif_get_data (dsi );
576+ testif_test_data_write (dsi , * value );
577+
578+ return 0 ;
502579}
503580
504581static int mipi_dphy_power_on (struct dw_mipi_dsi * dsi )
@@ -554,19 +631,20 @@ static void dw_mipi_dsi_host_power_off(struct dw_mipi_dsi *dsi)
554631
555632static void dw_mipi_dsi_phy_pll_init (struct dw_mipi_dsi * dsi )
556633{
557- dw_mipi_dsi_phy_write ( dsi , 0x17 , INPUT_DIVIDER ( dsi -> dphy . input_div )) ;
558- dw_mipi_dsi_phy_write ( dsi , 0x18 ,
559- LOOP_DIV_LOW_SEL ( dsi -> dphy . feedback_div ) |
560- LOW_PROGRAM_EN );
561- dw_mipi_dsi_phy_write ( dsi , 0x19 , PLL_LOOP_DIV_EN | PLL_INPUT_DIV_EN );
562- dw_mipi_dsi_phy_write ( dsi , 0x18 ,
563- LOOP_DIV_HIGH_SEL ( dsi -> dphy . feedback_div ) |
564- HIGH_PROGRAM_EN );
565- dw_mipi_dsi_phy_write ( dsi , 0x19 , PLL_LOOP_DIV_EN | PLL_INPUT_DIV_EN );
634+ struct mipi_dphy * dphy = & dsi -> dphy ;
635+
636+ regmap_write ( dphy -> regmap , 0x17 , INPUT_DIVIDER ( dphy -> input_div ));
637+ regmap_write ( dphy -> regmap , 0x18 ,
638+ LOOP_DIV_LOW_SEL ( dphy -> feedback_div ) | LOW_PROGRAM_EN );
639+ regmap_write ( dphy -> regmap , 0x19 , PLL_LOOP_DIV_EN | PLL_INPUT_DIV_EN );
640+ regmap_write ( dphy -> regmap , 0x18 ,
641+ LOOP_DIV_HIGH_SEL ( dphy -> feedback_div ) | HIGH_PROGRAM_EN );
642+ regmap_write ( dphy -> regmap , 0x19 , PLL_LOOP_DIV_EN | PLL_INPUT_DIV_EN );
566643}
567644
568645static int dw_mipi_dsi_phy_init (struct dw_mipi_dsi * dsi )
569646{
647+ struct mipi_dphy * dphy = & dsi -> dphy ;
570648 int testdin , vco ;
571649
572650 vco = (dsi -> lane_mbps < 200 ) ? 0 : (dsi -> lane_mbps + 100 ) / 200 ;
@@ -579,37 +657,34 @@ static int dw_mipi_dsi_phy_init(struct dw_mipi_dsi *dsi)
579657 return testdin ;
580658 }
581659
582- dw_mipi_dsi_phy_write (dsi , 0x10 , BYPASS_VCO_RANGE |
583- VCO_RANGE_CON_SEL (vco ) |
584- VCO_IN_CAP_CON_LOW |
585- REF_BIAS_CUR_SEL );
660+ regmap_write (dphy -> regmap , 0x10 ,
661+ BYPASS_VCO_RANGE | VCO_RANGE_CON_SEL (vco ) |
662+ VCO_IN_CAP_CON_LOW | REF_BIAS_CUR_SEL );
663+ regmap_write (dphy -> regmap , 0x11 , CP_CURRENT_3MA );
664+ regmap_write (dphy -> regmap , 0x12 ,
665+ CP_PROGRAM_EN | LPF_PROGRAM_EN | LPF_RESISTORS_20_KOHM );
586666
587- dw_mipi_dsi_phy_write (dsi , 0x11 , CP_CURRENT_3MA );
588- dw_mipi_dsi_phy_write (dsi , 0x12 , CP_PROGRAM_EN | LPF_PROGRAM_EN |
589- LPF_RESISTORS_20_KOHM );
590-
591- dw_mipi_dsi_phy_write (dsi , 0x44 , HSFREQRANGE_SEL (testdin ));
667+ regmap_write (dphy -> regmap , 0x44 , HSFREQRANGE_SEL (testdin ));
592668
593669 if (IS_DSI0 (dsi ))
594670 dw_mipi_dsi_phy_pll_init (dsi );
595671
596- dw_mipi_dsi_phy_write (dsi , 0x20 , POWER_CONTROL | INTERNAL_REG_CURRENT |
597- BIAS_BLOCK_ON | BANDGAP_ON );
598-
599- dw_mipi_dsi_phy_write (dsi , 0x21 , TER_RESISTOR_LOW | TER_CAL_DONE |
600- SETRD_MAX | TER_RESISTORS_ON );
601- dw_mipi_dsi_phy_write (dsi , 0x21 , TER_RESISTOR_HIGH | LEVEL_SHIFTERS_ON |
602- SETRD_MAX | POWER_MANAGE |
603- TER_RESISTORS_ON );
604-
605- dw_mipi_dsi_phy_write (dsi , 0x22 , LOW_PROGRAM_EN |
606- BIASEXTR_SEL (BIASEXTR_127_7 ));
607- dw_mipi_dsi_phy_write (dsi , 0x22 , HIGH_PROGRAM_EN |
608- BANDGAP_SEL (BANDGAP_96_10 ));
609-
610- dw_mipi_dsi_phy_write (dsi , 0x70 , TLP_PROGRAM_EN | 0xf );
611- dw_mipi_dsi_phy_write (dsi , 0x71 , THS_PRE_PROGRAM_EN | 0x2d );
612- dw_mipi_dsi_phy_write (dsi , 0x72 , THS_ZERO_PROGRAM_EN | 0xa );
672+ regmap_write (dphy -> regmap , 0x20 ,
673+ POWER_CONTROL | INTERNAL_REG_CURRENT |
674+ BIAS_BLOCK_ON | BANDGAP_ON );
675+ regmap_write (dphy -> regmap , 0x21 ,
676+ TER_RESISTOR_LOW | TER_CAL_DONE | SETRD_MAX |
677+ TER_RESISTORS_ON );
678+ regmap_write (dphy -> regmap , 0x21 ,
679+ TER_RESISTOR_HIGH | LEVEL_SHIFTERS_ON |
680+ SETRD_MAX | POWER_MANAGE | TER_RESISTORS_ON );
681+ regmap_write (dphy -> regmap , 0x22 ,
682+ LOW_PROGRAM_EN | BIASEXTR_SEL (BIASEXTR_127_7 ));
683+ regmap_write (dphy -> regmap , 0x22 ,
684+ HIGH_PROGRAM_EN | BANDGAP_SEL (BANDGAP_96_10 ));
685+ regmap_write (dphy -> regmap , 0x70 , TLP_PROGRAM_EN | 0xf );
686+ regmap_write (dphy -> regmap , 0x71 , THS_PRE_PROGRAM_EN | 0x2d );
687+ regmap_write (dphy -> regmap , 0x72 , THS_ZERO_PROGRAM_EN | 0xa );
613688
614689 return 0 ;
615690}
@@ -1497,42 +1572,60 @@ static const struct component_ops dw_mipi_dsi_ops = {
14971572 .unbind = dw_mipi_dsi_unbind ,
14981573};
14991574
1575+ static const struct regmap_config testif_regmap_config = {
1576+ .name = "phy" ,
1577+ .reg_bits = 8 ,
1578+ .val_bits = 8 ,
1579+ .max_register = 0x97 ,
1580+ .fast_io = true,
1581+ .reg_write = testif_write ,
1582+ .reg_read = testif_read ,
1583+ };
1584+
15001585static int mipi_dphy_attach (struct dw_mipi_dsi * dsi )
15011586{
15021587 struct device * dev = dsi -> dev ;
1588+ struct mipi_dphy * dphy = & dsi -> dphy ;
15031589 int ret ;
15041590
1505- dsi -> dphy . phy = devm_phy_optional_get (dev , "mipi_dphy" );
1506- if (IS_ERR (dsi -> dphy . phy )) {
1507- ret = PTR_ERR (dsi -> dphy . phy );
1591+ dphy -> phy = devm_phy_optional_get (dev , "mipi_dphy" );
1592+ if (IS_ERR (dphy -> phy )) {
1593+ ret = PTR_ERR (dphy -> phy );
15081594 dev_err (dev , "failed to get mipi dphy: %d\n" , ret );
15091595 return ret ;
15101596 }
15111597
1512- if (dsi -> dphy . phy ) {
1598+ if (dphy -> phy ) {
15131599 dev_dbg (dev , "Use Non-SNPS PHY\n" );
15141600
1515- dsi -> dphy . hs_clk = devm_clk_get (dev , "hs_clk" );
1516- if (IS_ERR (dsi -> dphy . hs_clk )) {
1601+ dphy -> hs_clk = devm_clk_get (dev , "hs_clk" );
1602+ if (IS_ERR (dphy -> hs_clk )) {
15171603 dev_err (dev , "failed to get PHY high-speed clock\n" );
1518- return PTR_ERR (dsi -> dphy . hs_clk );
1604+ return PTR_ERR (dphy -> hs_clk );
15191605 }
15201606 } else {
15211607 dev_dbg (dev , "Use SNPS PHY\n" );
15221608
1523- dsi -> dphy . ref_clk = devm_clk_get (dev , "ref" );
1524- if (IS_ERR (dsi -> dphy . ref_clk )) {
1609+ dphy -> ref_clk = devm_clk_get (dev , "ref" );
1610+ if (IS_ERR (dphy -> ref_clk )) {
15251611 dev_err (dev , "failed to get PHY reference clock\n" );
1526- return PTR_ERR (dsi -> dphy . ref_clk );
1612+ return PTR_ERR (dphy -> ref_clk );
15271613 }
15281614
15291615 if (dsi -> pdata -> soc_type != RK3288 ) {
1530- dsi -> dphy . cfg_clk = devm_clk_get (dev , "phy_cfg" );
1531- if (IS_ERR (dsi -> dphy . cfg_clk )) {
1616+ dphy -> cfg_clk = devm_clk_get (dev , "phy_cfg" );
1617+ if (IS_ERR (dphy -> cfg_clk )) {
15321618 dev_err (dev , "failed to get PHY config clk\n" );
1533- return PTR_ERR (dsi -> dphy . cfg_clk );
1619+ return PTR_ERR (dphy -> cfg_clk );
15341620 }
15351621 }
1622+
1623+ dphy -> regmap = devm_regmap_init (dev , NULL , dsi ,
1624+ & testif_regmap_config );
1625+ if (IS_ERR (dphy -> regmap )) {
1626+ dev_err (dev , "failed to create mipi dphy regmap\n" );
1627+ return PTR_ERR (dphy -> regmap );
1628+ }
15361629 }
15371630
15381631 return 0 ;
@@ -1561,6 +1654,7 @@ static int dw_mipi_dsi_parse_dt(struct dw_mipi_dsi *dsi)
15611654}
15621655
15631656static const struct regmap_config dw_mipi_dsi_regmap_config = {
1657+ .name = "host" ,
15641658 .reg_bits = 32 ,
15651659 .val_bits = 32 ,
15661660 .reg_stride = 4 ,
0 commit comments