openwrt/target/linux/d1/patches-6.1/0009-drm-sun4i-Copy-in-BSP-code-for-D1-HDMI-PHY.patch
Zoltan HERPAI 99545b4bb1 d1: add new target
This target adds support for the Allwinner D1 RISC-V based SoCs.

 - RISC-V single-core T-Head C906 (RV64GCV)
 - Tensilica HiFi4 DSP
 - DDR2/DDR3 support
 - 10/100/1000M ethernet
 - usual peripherals like USB2, SPI, I2C, PWM, etc.

Four boards are supported:
 - Dongshan Nezha STU
    - 512Mb RAM
    - ethernet

 - LicheePi RV Dock
    - 512Mb RAM
    - wireless-only (RTL8723DS)

 - MangoPi MQ-Pro
    - 512Mb RAM
    - there are pads available for an SPI flash
    - wireless-only (RTL8723DS)

 - Nezha D1
    - 512Mb/1Gb/2Gb RAM
    - 256Mb NAND flash
    - ethernet, wireless

Installation:
Standard SD-card installation via dd-ing the generated image to
an SD-card of at least 256Mb.

Signed-off-by: Zoltan HERPAI <wigyori@uid0.hu>
2024-02-29 16:50:22 +01:00

622 lines
22 KiB
Diff

From 7ea7d4abfd537230da58533803a2d0257addace8 Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Wed, 30 Mar 2022 00:46:07 -0500
Subject: [PATCH 009/117] drm/sun4i: Copy in BSP code for D1 HDMI PHY
Signed-off-by: Samuel Holland <samuel@sholland.org>
---
drivers/gpu/drm/sun4i/aw_phy.h | 411 +++++++++++++++++++++++++
drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h | 1 +
drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c | 156 ++++++++++
3 files changed, 568 insertions(+)
create mode 100644 drivers/gpu/drm/sun4i/aw_phy.h
--- /dev/null
+++ b/drivers/gpu/drm/sun4i/aw_phy.h
@@ -0,0 +1,411 @@
+/*
+ * Allwinner SoCs hdmi2.0 driver.
+ *
+ * Copyright (C) 2016 Allwinner.
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef AW_PHY_H_
+#define AW_PHY_H_
+
+#define AW_PHY_TIMEOUT 1000
+#define LOCK_TIMEOUT 100
+
+/* allwinner phy register offset */
+#define HDMI_PHY_CTL0 0x40
+#define HDMI_PHY_CTL1 0x44
+#define HDMI_PHY_CTL2 0x48
+#define HDMI_PHY_CTL3 0x4C
+#define HDMI_PHY_CTL4 0x50
+#define HDMI_PHY_CTL5 0x54
+#define HDMI_PLL_CTL0 0x58
+#define HDMI_PLL_CTL1 0x5C
+#define HDMI_AFIFO_CFG 0x60
+#define HDMI_MODULATOR_CFG0 0x64
+#define HDMI_MODULATOR_CFG1 0x68
+#define HDMI_PHY_INDEB_CTRL 0x6C
+#define HDMI_PHY_INDBG_TXD0 0x70
+#define HDMI_PHY_INDBG_TXD1 0x74
+#define HDMI_PHY_INDBG_TXD2 0x78
+#define HDMI_PHY_INDBG_TXD3 0x7C
+#define HDMI_PHY_PLL_STS 0x80
+#define HDMI_PRBS_CTL 0x84
+#define HDMI_PRBS_SEED_GEN 0x88
+#define HDMI_PRBS_SEED_CHK 0x8C
+#define HDMI_PRBS_SEED_NUM 0x90
+#define HDMI_PRBS_CYCLE_NUM 0x94
+#define HDMI_PHY_PLL_ODLY_CFG 0x98
+#define HDMI_PHY_CTL6 0x9C
+#define HDMI_PHY_CTL7 0xA0
+
+typedef union {
+ u32 dwval;
+ struct {
+ u32 sda_en :1; // Default: 0;
+ u32 scl_en :1; // Default: 0;
+ u32 hpd_en :1; // Default: 0;
+ u32 res0 :1; // Default: 0;
+ u32 reg_ck_sel :1; // Default: 1;
+ u32 reg_ck_test_sel :1; // Default: 1;
+ u32 reg_csmps :2; // Default: 0;
+ u32 reg_den :4; // Default: F;
+ u32 reg_plr :4; // Default: 0;
+ u32 enck :1; // Default: 1;
+ u32 enldo_fs :1; // Default: 1;
+ u32 enldo :1; // Default: 1;
+ u32 res1 :1; // Default: 1;
+ u32 enbi :4; // Default: F;
+ u32 entx :4; // Default: F;
+ u32 async_fifo_autosync_disable :1; // Default: 0;
+ u32 async_fifo_workc_enable :1; // Default: 1;
+ u32 phy_pll_lock_mode :1; // Default: 1;
+ u32 phy_pll_lock_mode_man :1; // Default: 1;
+ } bits;
+} HDMI_PHY_CTL0_t; //=========================== 0x0040
+
+typedef union {
+ u32 dwval;
+ struct {
+ u32 reg_sp2_0 : 4 ; // Default: 0;
+ u32 reg_sp2_1 : 4 ; // Default: 0;
+ u32 reg_sp2_2 : 4 ; // Default: 0;
+ u32 reg_sp2_3 : 4 ; // Default: 0;
+ u32 reg_bst0 : 2 ; // Default: 3;
+ u32 reg_bst1 : 2 ; // Default: 3;
+ u32 reg_bst2 : 2 ; // Default: 3;
+ u32 res0 : 2 ; // Default: 0;
+ u32 reg_svr : 2 ; // Default: 2;
+ u32 reg_swi : 1 ; // Default: 0;
+ u32 res_scktmds : 1 ; // Default: 0;
+ u32 res_res_s : 2 ; // Default: 3;
+ u32 phy_rxsense_mode : 1 ; // Default: 0;
+ u32 res_rxsense_mode_man : 1 ; // Default: 0;
+ } bits;
+} HDMI_PHY_CTL1_t; //===================================================== 0x0044
+
+typedef union {
+ u32 dwval;
+ struct {
+ u32 reg_p2opt : 4 ; // Default: 0;
+ u32 reg_sp1_0 : 5 ; // Default: 0;
+ u32 reg_sp1_1 : 5 ; // Default: 0;
+ u32 reg_sp1_2 : 5 ; // Default: 0;
+ u32 reg_sp1_3 : 5 ; // Default: 0;
+ u32 reg_resdi : 6 ; // Default: 18;
+ u32 phy_hpdo_mode : 1 ; // Default: 0;
+ u32 phy_hpdo_mode_man : 1 ; // Default: 0;
+ } bits;
+} HDMI_PHY_CTL2_t; //===================================================== 0x0048
+
+
+
+typedef union {
+ u32 dwval;
+ struct {
+ u32 reg_mc0 : 4 ; // Default: F;
+ u32 reg_mc1 : 4 ; // Default: F;
+ u32 reg_mc2 : 4 ; // Default: F;
+ u32 reg_mc3 : 4 ; // Default: F;
+ u32 reg_p2_0 : 4 ; // Default: F;
+ u32 reg_p2_1 : 4 ; // Default: F;
+ u32 reg_p2_2 : 4 ; // Default: F;
+ u32 reg_p2_3 : 4 ; // Default: F;
+ } bits;
+} HDMI_PHY_CTL3_t; //===================================================== 0x004C
+
+
+
+typedef union {
+ u32 dwval;
+ struct {
+ u32 reg_p1_0 : 5 ; // Default: 0x10;
+ u32 res0 : 3 ; // Default: 0;
+ u32 reg_p1_1 : 5 ; // Default: 0x10;
+ u32 res1 : 3 ; // Default: 0;
+ u32 reg_p1_2 : 5 ; // Default: 0x10;
+ u32 res2 : 3 ; // Default: 0;
+ u32 reg_p1_3 : 5 ; // Default: 0x10;
+ u32 reg_slv : 3 ; // Default: 0;
+ } bits;
+} HDMI_PHY_CTL4_t; //===================================================== 0x0050
+
+typedef union {
+ u32 dwval;
+ struct {
+ u32 encalog : 1 ; // Default: 0x1;
+ u32 enib : 1 ; // Default: 0x1;
+ u32 res0 : 2 ; // Default: 0;
+ u32 enp2s : 4 ; // Default: 0xF;
+ u32 enrcal : 1 ; // Default: 0x1;
+ u32 enres : 1 ; // Default: 1;
+ u32 enresck : 1 ; // Default: 1;
+ u32 reg_calsw : 1 ; // Default: 0;
+ u32 reg_ckpdlyopt : 1 ; // Default: 0;
+ u32 res1 : 3 ; // Default: 0;
+ u32 reg_p1opt : 4 ; // Default: 0;
+ u32 res2 : 12 ; // Default: 0;
+ } bits;
+} HDMI_PHY_CTL5_t; //===================================================== 0x0054
+
+typedef union {
+ u32 dwval;
+ struct {
+ u32 prop_cntrl : 3 ; // Default: 0x7;
+ u32 res0 : 1 ; // Default: 0;
+ u32 gmp_cntrl : 2 ; // Default: 1;
+ u32 n_cntrl : 2 ; // Default: 0;
+ u32 vcorange : 1 ; // Default: 0;
+ u32 sdrven : 1 ; // Default: 0;
+ u32 divx1 : 1 ; // Default: 0;
+ u32 res1 : 1 ; // Default: 0;
+ u32 div_pre : 4 ; // Default: 0;
+ u32 div2_cktmds : 1 ; // Default: 1;
+ u32 div2_ckbit : 1 ; // Default: 1;
+ u32 cutfb : 1 ; // Default: 0;
+ u32 res2 : 1 ; // Default: 0;
+ u32 clr_dpth : 2 ; // Default: 0;
+ u32 bypass_clrdpth : 1 ; // Default: 0;
+ u32 bcr : 1 ; // Default: 0;
+ u32 slv : 3 ; // Default: 4;
+ u32 res3 : 1 ; // Default: 0;
+ u32 envbs : 1 ; // Default: 0;
+ u32 bypass_ppll : 1 ; // Default: 0;
+ u32 cko_sel : 2 ; // Default: 0;
+ } bits;
+} HDMI_PLL_CTL0_t; //===================================================== 0x0058
+
+
+
+typedef union {
+ u32 dwval;
+ struct {
+ u32 int_cntrl : 3 ; // Default: 0x0;
+ u32 res0 : 1 ; // Default: 0;
+ u32 ref_cntrl : 2 ; // Default: 3;
+ u32 gear_shift : 1 ; // Default: 0;
+ u32 fast_tech : 1 ; // Default: 0;
+ u32 drv_ana : 1 ; // Default: 1;
+ u32 sckfb : 1 ; // Default: 0;
+ u32 sckref : 1 ; // Default: 0;
+ u32 reset : 1 ; // Default: 0;
+ u32 pwron : 1 ; // Default: 0;
+ u32 res1 : 3 ; // Default: 0;
+ u32 pixel_rep : 2 ; // Default: 0;
+ u32 sdm_en : 1 ; // Default: 0;
+ u32 pcnt_en : 1 ; // Default: 0;
+ u32 pcnt_n : 8 ; // Default: 0xE;
+ u32 res2 : 3 ; // Default: 0;
+ u32 ctrl_modle_clksrc : 1 ; // Default: 0;
+ } bits;
+} HDMI_PLL_CTL1_t; //===================================================== 0x005C
+
+typedef union {
+ u32 dwval;
+ struct {
+ u32 hdmi_afifo_error : 1 ; // Default: 0x0;
+ u32 hdmi_afifo_error_det : 1 ; // Default: 0x0;
+ u32 res0 : 30 ; // Default: 0;
+ } bits;
+} HDMI_AFIFO_CFG_t; //===================================================== 0x0060
+
+typedef union {
+ u32 dwval;
+ struct {
+ u32 fnpll_mash_en : 1 ; // Default: 0x0;
+ u32 fnpll_mash_mod : 2 ; // Default: 0x0;
+ u32 fnpll_mash_stp : 9 ; // Default: 0x0;
+ u32 fnpll_mash_m12 : 1 ; // Default: 0x0;
+ u32 fnpll_mash_frq : 2 ; // Default: 0x0;
+ u32 fnpll_mash_bot : 17 ; // Default: 0x0;
+ } bits;
+} HDMI_MODULATOR_CFG0_t; //===================================================== 0x0064
+
+typedef union {
+ u32 dwval;
+ struct {
+ u32 fnpll_mash_dth : 1 ; // Default: 0x0;
+ u32 fnpll_mash_fen : 1 ; // Default: 0x0;
+ u32 fnpll_mash_frc : 17 ; // Default: 0x0;
+ u32 fnpll_mash_fnv : 8 ; // Default: 0x0;
+ u32 res0 : 5 ; // Default: 0x0;
+ } bits;
+} HDMI_MODULATOR_CFG1_t; //===================================================== 0x0068
+
+typedef union {
+ u32 dwval;
+ struct {
+ u32 txdata_debugmode : 2 ; // Default: 0x0;
+ u32 res0 : 14 ; // Default: 0x0;
+ u32 ceci_debug : 1 ; // Default: 0x0;
+ u32 ceci_debugmode : 1 ; // Default: 0x0;
+ u32 res1 : 2 ; // Default: 0x0;
+ u32 sdai_debug : 1 ; // Default: 0x0;
+ u32 sdai_debugmode : 1 ; // Default: 0x0;
+ u32 res2 : 2 ; // Default: 0x0;
+ u32 scli_debug : 1 ; // Default: 0x0;
+ u32 scli_debugmode : 1 ; // Default: 0x0;
+ u32 res3 : 2 ; // Default: 0x0;
+ u32 hpdi_debug : 1 ; // Default: 0x0;
+ u32 hpdi_debugmode : 1 ; // Default: 0x0;
+ u32 res4 : 2 ; // Default: 0x0;
+ } bits;
+} HDMI_PHY_INDBG_CTRL_t; //================================================== 0x006C
+
+typedef union {
+ u32 dwval;
+ struct {
+ u32 txdata0_debug_data : 32 ; // Default: 0x0;
+ } bits;
+} HDMI_PHY_INDBG_TXD0_t; //================================================== 0x0070
+
+typedef union {
+ u32 dwval;
+ struct {
+ u32 txdata1_debug_data : 32 ; // Default: 0x0;
+ } bits;
+} HDMI_PHY_INDBG_TXD1_t; //================================================== 0x0074
+
+typedef union {
+ u32 dwval;
+ struct {
+ u32 txdata2_debug_data : 32 ; // Default: 0x0;
+ } bits;
+} HDMI_PHY_INDBG_TXD2_t; //================================================== 0x0078
+
+typedef union {
+ u32 dwval;
+ struct {
+ u32 txdata3_debug_data : 32 ; // Default: 0x0;
+ } bits;
+} HDMI_PHY_INDBG_TXD3_t; //================================================== 0x007C
+
+typedef union {
+ u32 dwval;
+ struct {
+ u32 tx_ready_dly_status : 1 ; // Default: 0x0;
+ u32 rxsense_dly_status : 1 ; // Default: 0x0;
+ u32 res0 : 2 ; // Default: 0x0;
+ u32 pll_lock_status : 1 ; // Default: 0x0;
+ u32 res1 : 3 ; // Default: 0x0;
+ u32 phy_resdo2d_status : 6 ; // Default: 0x0;
+ u32 res2 : 2 ; // Default: 0x0;
+ u32 phy_rcalend2d_status : 1 ; // Default: 0x0;
+ u32 phy_cout2d_status : 1 ; // Default: 0x0;
+ u32 res3 : 2 ; // Default: 0x0;
+ u32 phy_ceco_status : 1 ; // Default: 0x0;
+ u32 phy_sdao_status : 1 ; // Default: 0x0;
+ u32 phy_sclo_status : 1 ; // Default: 0x0;
+ u32 phy_hpdo_status : 1 ; // Default: 0x0;
+ u32 phy_cdetn_status : 3 ; // Default: 0x0;
+ u32 phy_cdetnck_status : 1 ; // Default: 0x0;
+ u32 phy_cdetp_status : 3 ; // Default: 0x0;
+ u32 phy_cdetpck_status : 1 ; // Default: 0x0;
+ } bits;
+} HDMI_PHY_PLL_STS_t; //===================================================== 0x0080
+
+typedef union {
+ u32 dwval;
+ struct {
+ u32 prbs_en : 1 ; // Default: 0x0;
+ u32 prbs_start : 1 ; // Default: 0x0;
+ u32 prbs_seq_gen : 1 ; // Default: 0x0;
+ u32 prbs_seq_chk : 1 ; // Default: 0x0;
+ u32 prbs_mode : 4 ; // Default: 0x0;
+ u32 prbs_type : 2 ; // Default: 0x0;
+ u32 prbs_clk_pol : 1 ; // Default: 0x0;
+ u32 res0 : 21 ; // Default: 0x0;
+ } bits;
+} HDMI_PRBS_CTL_t; //===================================================== 0x0084
+
+typedef union {
+ u32 dwval;
+ struct {
+ u32 prbs_seed_gen : 32 ; // Default: 0x0;
+ } bits;
+} HDMI_PRBS_SEED_GEN_t; //================================================= 0x0088
+
+typedef union {
+ u32 dwval;
+ struct {
+ u32 prbs_seed_chk : 32 ; // Default: 0x0;
+ } bits;
+} HDMI_PRBS_SEED_CHK_t; //================================================= 0x008C
+
+typedef union {
+ u32 dwval;
+ struct {
+ u32 prbs_seed_num : 32 ; // Default: 0x0;
+ } bits;
+} HDMI_PRBS_SEED_NUM_t; //================================================= 0x0090
+
+typedef union {
+ u32 dwval;
+ struct {
+ u32 prbs_cycle_num : 32 ; // Default: 0x0;
+ } bits;
+} HDMI_PRBS_CYCLE_NUM_t; //================================================= 0x0094
+
+typedef union {
+ u32 dwval;
+ struct {
+ u32 tx_ready_dly_count : 15 ; // Default: 0x0;
+ u32 tx_ready_dly_reset : 1 ; // Default: 0x0;
+ u32 rxsense_dly_count : 15 ; // Default: 0x0;
+ u32 rxsense_dly_reset : 1 ; // Default: 0x0;
+ } bits;
+} HDMI_PHY_PLL_ODLY_CFG_t; //================================================= 0x0098
+
+typedef union {
+ u32 dwval;
+ struct {
+ u32 clk_greate0_340m : 10 ; // Default: 0x3FF;
+ u32 clk_greate1_340m : 10 ; // Default: 0x3FF;
+ u32 clk_greate2_340m : 10 ; // Default: 0x3FF;
+ u32 en_ckdat : 1 ; // Default: 0x3FF;
+ u32 switch_clkch_data_corresponding : 1 ; // Default: 0x3FF;
+ } bits;
+} HDMI_PHY_CTL6_t; //========================================================= 0x009C
+
+typedef union {
+ u32 dwval;
+ struct {
+ u32 clk_greate3_340m : 10 ; // Default: 0x0;
+ u32 res0 : 2 ; // Default: 0x3FF;
+ u32 clk_low_340m : 10 ; // Default: 0x3FF;
+ u32 res1 : 10 ; // Default: 0x3FF;
+ } bits;
+} HDMI_PHY_CTL7_t; //========================================================= 0x00A0
+
+struct __aw_phy_reg_t {
+ u32 res[16]; /* 0x0 ~ 0x3c */
+ HDMI_PHY_CTL0_t phy_ctl0; /* 0x0040 */
+ HDMI_PHY_CTL1_t phy_ctl1; /* 0x0044 */
+ HDMI_PHY_CTL2_t phy_ctl2; /* 0x0048 */
+ HDMI_PHY_CTL3_t phy_ctl3; /* 0x004c */
+ HDMI_PHY_CTL4_t phy_ctl4; /* 0x0050 */
+ HDMI_PHY_CTL5_t phy_ctl5; /* 0x0054 */
+ HDMI_PLL_CTL0_t pll_ctl0; /* 0x0058 */
+ HDMI_PLL_CTL1_t pll_ctl1; /* 0x005c */
+ HDMI_AFIFO_CFG_t afifo_cfg; /* 0x0060 */
+ HDMI_MODULATOR_CFG0_t modulator_cfg0; /* 0x0064 */
+ HDMI_MODULATOR_CFG1_t modulator_cfg1; /* 0x0068 */
+ HDMI_PHY_INDBG_CTRL_t phy_indbg_ctrl; /* 0x006c */
+ HDMI_PHY_INDBG_TXD0_t phy_indbg_txd0; /* 0x0070 */
+ HDMI_PHY_INDBG_TXD1_t phy_indbg_txd1; /* 0x0074 */
+ HDMI_PHY_INDBG_TXD2_t phy_indbg_txd2; /* 0x0078 */
+ HDMI_PHY_INDBG_TXD3_t phy_indbg_txd3; /* 0x007c */
+ HDMI_PHY_PLL_STS_t phy_pll_sts; /* 0x0080 */
+ HDMI_PRBS_CTL_t prbs_ctl; /* 0x0084 */
+ HDMI_PRBS_SEED_GEN_t prbs_seed_gen; /* 0x0088 */
+ HDMI_PRBS_SEED_CHK_t prbs_seed_chk; /* 0x008c */
+ HDMI_PRBS_SEED_NUM_t prbs_seed_num; /* 0x0090 */
+ HDMI_PRBS_CYCLE_NUM_t prbs_cycle_num; /* 0x0094 */
+ HDMI_PHY_PLL_ODLY_CFG_t phy_pll_odly_cfg; /* 0x0098 */
+ HDMI_PHY_CTL6_t phy_ctl6; /* 0x009c */
+ HDMI_PHY_CTL7_t phy_ctl7; /* 0x00A0 */
+};
+
+#endif /* AW_PHY_H_ */
--- a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h
+++ b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h
@@ -334,6 +334,7 @@ struct sun8i_hdmi_phy {
struct clk *clk_pll1;
struct device *dev;
unsigned int rcal;
+ void __iomem *base;
struct regmap *regs;
struct reset_control *rst_phy;
const struct sun8i_hdmi_phy_variant *variant;
--- a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
+++ b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
@@ -9,6 +9,8 @@
#include "sun8i_dw_hdmi.h"
+#include "aw_phy.h"
+
/*
* Address can be actually any value. Here is set to same value as
* it is set in BSP driver.
@@ -398,11 +400,164 @@ static const struct dw_hdmi_phy_ops sun8
.setup_hpd = dw_hdmi_phy_setup_hpd,
};
+static int sun20i_d1_hdmi_phy_enable(volatile struct __aw_phy_reg_t __iomem *phy_base)
+{
+ int i = 0, status = 0;
+
+ pr_info("enter %s\n", __func__);
+
+ //enib -> enldo -> enrcal -> encalog -> enbi[3:0] -> enck -> enp2s[3:0] -> enres -> enresck -> entx[3:0]
+ phy_base->phy_ctl4.bits.reg_slv = 4; //low power voltage 1.08V, default is 3, set 4 as well as pll_ctl0 bit [24:26]
+ phy_base->phy_ctl5.bits.enib = 1;
+ phy_base->phy_ctl0.bits.enldo = 1;
+ phy_base->phy_ctl0.bits.enldo_fs = 1;
+ phy_base->phy_ctl5.bits.enrcal = 1;
+
+ phy_base->phy_ctl5.bits.encalog = 1;
+
+ for (i = 0; i < AW_PHY_TIMEOUT; i++) {
+ udelay(5);
+ status = phy_base->phy_pll_sts.bits.phy_rcalend2d_status;
+ if (status & 0x1) {
+ pr_info("[%s]:phy_rcalend2d_status\n", __func__);
+ break;
+ }
+ }
+ if ((i == AW_PHY_TIMEOUT) && !status) {
+ pr_err("phy_rcalend2d_status Timeout !\n");
+ return -1;
+ }
+
+ phy_base->phy_ctl0.bits.enbi = 0xF;
+ for (i = 0; i < AW_PHY_TIMEOUT; i++) {
+ udelay(5);
+ status = phy_base->phy_pll_sts.bits.pll_lock_status;
+ if (status & 0x1) {
+ pr_info("[%s]:pll_lock_status\n", __func__);
+ break;
+ }
+ }
+ if ((i == AW_PHY_TIMEOUT) && !status) {
+ pr_err("pll_lock_status Timeout! status = 0x%x\n", status);
+ return -1;
+ }
+
+ phy_base->phy_ctl0.bits.enck = 1;
+ phy_base->phy_ctl5.bits.enp2s = 0xF;
+ phy_base->phy_ctl5.bits.enres = 1;
+ phy_base->phy_ctl5.bits.enresck = 1;
+ phy_base->phy_ctl0.bits.entx = 0xF;
+
+ for (i = 0; i < AW_PHY_TIMEOUT; i++) {
+ udelay(5);
+ status = phy_base->phy_pll_sts.bits.tx_ready_dly_status;
+ if (status & 0x1) {
+ pr_info("[%s]:tx_ready_status\n", __func__);
+ break;
+ }
+ }
+ if ((i == AW_PHY_TIMEOUT) && !status) {
+ pr_err("tx_ready_status Timeout ! status = 0x%x\n", status);
+ return -1;
+ }
+
+ return 0;
+}
+
static int sun20i_d1_hdmi_phy_config(struct dw_hdmi *hdmi, void *data,
const struct drm_display_info *display,
const struct drm_display_mode *mode)
{
struct sun8i_hdmi_phy *phy = data;
+ volatile struct __aw_phy_reg_t __iomem *phy_base = phy->base;
+ int ret;
+
+ pr_info("enter %s\n", __func__);
+
+ /* enable all channel */
+ phy_base->phy_ctl5.bits.reg_p1opt = 0xF;
+
+ // phy_reset
+ phy_base->phy_ctl0.bits.entx = 0;
+ phy_base->phy_ctl5.bits.enresck = 0;
+ phy_base->phy_ctl5.bits.enres = 0;
+ phy_base->phy_ctl5.bits.enp2s = 0;
+ phy_base->phy_ctl0.bits.enck = 0;
+ phy_base->phy_ctl0.bits.enbi = 0;
+ phy_base->phy_ctl5.bits.encalog = 0;
+ phy_base->phy_ctl5.bits.enrcal = 0;
+ phy_base->phy_ctl0.bits.enldo_fs = 0;
+ phy_base->phy_ctl0.bits.enldo = 0;
+ phy_base->phy_ctl5.bits.enib = 0;
+ phy_base->pll_ctl1.bits.reset = 1;
+ phy_base->pll_ctl1.bits.pwron = 0;
+ phy_base->pll_ctl0.bits.envbs = 0;
+
+ // phy_set_mpll
+ phy_base->pll_ctl0.bits.cko_sel = 0x3;
+ phy_base->pll_ctl0.bits.bypass_ppll = 0x1;
+ phy_base->pll_ctl1.bits.drv_ana = 1;
+ phy_base->pll_ctl1.bits.ctrl_modle_clksrc = 0x0; //0: PLL_video 1: MPLL
+ phy_base->pll_ctl1.bits.sdm_en = 0x0; //mpll sdm jitter is very large, not used for the time being
+ phy_base->pll_ctl1.bits.sckref = 0; //default value is 1
+ phy_base->pll_ctl0.bits.slv = 4;
+ phy_base->pll_ctl0.bits.prop_cntrl = 7; //default value 7
+ phy_base->pll_ctl0.bits.gmp_cntrl = 3; //default value 1
+ phy_base->pll_ctl1.bits.ref_cntrl = 0;
+ phy_base->pll_ctl0.bits.vcorange = 1;
+
+ // phy_set_div
+ phy_base->pll_ctl0.bits.div_pre = 0; //div7 = n+1
+ phy_base->pll_ctl1.bits.pcnt_en = 0;
+ phy_base->pll_ctl1.bits.pcnt_n = 1; //div6 = 1 (pcnt_en=0) [div6 = n (pcnt_en = 1) note that some multiples are problematic] 4-256
+ phy_base->pll_ctl1.bits.pixel_rep = 0; //div5 = n+1
+ phy_base->pll_ctl0.bits.bypass_clrdpth = 0;
+ phy_base->pll_ctl0.bits.clr_dpth = 0; //div4 = 1 (bypass_clrdpth = 0)
+ //00: 2 01: 2.5 10: 3 11: 4
+ phy_base->pll_ctl0.bits.n_cntrl = 1; //div
+ phy_base->pll_ctl0.bits.div2_ckbit = 0; //div1 = n+1
+ phy_base->pll_ctl0.bits.div2_cktmds = 0; //div2 = n+1
+ phy_base->pll_ctl0.bits.bcr = 0; //div3 0: [1:10] 1: [1:40]
+ phy_base->pll_ctl1.bits.pwron = 1;
+ phy_base->pll_ctl1.bits.reset = 0;
+
+ // configure phy
+ /* config values taken from table */
+ phy_base->phy_ctl1.dwval = ((phy_base->phy_ctl1.dwval & 0xFFC0FFFF) | /* config->phy_ctl1 */ 0x0);
+ phy_base->phy_ctl2.dwval = ((phy_base->phy_ctl2.dwval & 0xFF000000) | /* config->phy_ctl2 */ 0x0);
+ phy_base->phy_ctl3.dwval = ((phy_base->phy_ctl3.dwval & 0xFFFF0000) | /* config->phy_ctl3 */ 0xFFFF);
+ phy_base->phy_ctl4.dwval = ((phy_base->phy_ctl4.dwval & 0xE0000000) | /* config->phy_ctl4 */ 0xC0D0D0D);
+ //phy_base->pll_ctl0.dwval |= config->pll_ctl0;
+ //phy_base->pll_ctl1.dwval |= config->pll_ctl1;
+
+ // phy_set_clk
+ phy_base->phy_ctl6.bits.switch_clkch_data_corresponding = 0;
+ phy_base->phy_ctl6.bits.clk_greate0_340m = 0x3FF;
+ phy_base->phy_ctl6.bits.clk_greate1_340m = 0x3FF;
+ phy_base->phy_ctl6.bits.clk_greate2_340m = 0x0;
+ phy_base->phy_ctl7.bits.clk_greate3_340m = 0x0;
+ phy_base->phy_ctl7.bits.clk_low_340m = 0x3E0;
+ phy_base->phy_ctl6.bits.en_ckdat = 1; //default value is 0
+
+ // phy_base->phy_ctl2.bits.reg_resdi = 0x18;
+ // phy_base->phy_ctl4.bits.reg_slv = 3; //low power voltage 1.08V, default value is 3
+
+ phy_base->phy_ctl1.bits.res_scktmds = 0; //
+ phy_base->phy_ctl0.bits.reg_csmps = 2;
+ phy_base->phy_ctl0.bits.reg_ck_test_sel = 0; //?
+ phy_base->phy_ctl0.bits.reg_ck_sel = 1;
+ phy_base->phy_indbg_ctrl.bits.txdata_debugmode = 0;
+
+ // phy_enable
+ ret = sun20i_d1_hdmi_phy_enable(phy_base);
+ if (ret)
+ return ret;
+
+ phy_base->phy_ctl0.bits.sda_en = 1;
+ phy_base->phy_ctl0.bits.scl_en = 1;
+ phy_base->phy_ctl0.bits.hpd_en = 1;
+ phy_base->phy_ctl0.bits.reg_den = 0xF;
+ phy_base->pll_ctl0.bits.envbs = 1;
return 0;
}
@@ -720,6 +875,7 @@ static int sun8i_hdmi_phy_probe(struct p
return dev_err_probe(dev, PTR_ERR(regs),
"Couldn't map the HDMI PHY registers\n");
+ phy->base = regs;
phy->regs = devm_regmap_init_mmio(dev, regs,
&sun8i_hdmi_phy_regmap_config);
if (IS_ERR(phy->regs))