Skip to content

Commit 2c659c7

Browse files
bivvyrkhuangtao
authored andcommitted
drm/rockchip: dsi: export vendor-specific interface
Change-Id: I8156943179589b7edfeaa486322dfd057d470dea Signed-off-by: Wyon Bi <bivvy.bi@rock-chips.com>
1 parent 6d5ebad commit 2c659c7

1 file changed

Lines changed: 166 additions & 72 deletions

File tree

drivers/gpu/drm/rockchip/dw-mipi-dsi.c

Lines changed: 166 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@
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
@@ -203,16 +205,12 @@
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

322320
struct 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

504581
static 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

555632
static 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

568645
static 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+
15001585
static 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

15631656
static 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

Comments
 (0)