Release develop 260104

This commit is contained in:
hongyi
2026-01-04 12:22:11 +08:00
parent 52d25821d3
commit 8cf766e6cf
11 changed files with 314 additions and 125 deletions

View File

@@ -353,7 +353,7 @@
};
sata_p1_pins: sata_p1-0 {
sata_p1-pins {
pins = "GPIO0_14", "GPIO0_15", "GPIO0_16", "GPIO0_17", "GPIO0_18";
pins = "GPIO0_14", "GPIO0_15", "GPIO0_16", "GPIO0_17", "GPIO1_5"; // DEVSLP, MP_SWITCH, CP_DET, CP_POD, ACT_LED
function = "sata_p1";
bias-disable;
drive-strength = <7>;
@@ -396,7 +396,7 @@
};
sata_p0_pins: sata_p0-0 {
sata_p0-pins {
pins = "GPIO0_19", "GPIO0_20", "GPIO0_21", "GPIO0_22", "GPIO0_23";
pins = "GPIO0_19", "GPIO0_20", "GPIO0_21", "GPIO0_22", "GPIO0_23"; // DEVSLP, MP_SWITCH, CP_DET, CP_POD, ACT_LED
function = "sata_p0";
bias-disable;
drive-strength = <7>;
@@ -493,7 +493,7 @@
};
pcie_x1_pins: pcie_x1-1 {
pcie_x1-pins {
pins = "GPIO0_24", "GPIO0_25", "GPIO0_26", "GPIO0_27";
pins = "GPIO0_24", "GPIO0_25", "GPIO0_26", "GPIO0_27"; // BTN_RSTN, LKREQN, PERSTN, WAKEN
function = "pcie_x1";
bias-disable;
drive-strength = <7>;

View File

@@ -3,33 +3,33 @@
// status = "disabled";
};
// &c908_1 {
// status = "disabled";
// };
&c908_1 {
status = "disabled";
};
// &c908_2 {
// status = "disabled";
// };
&c908_2 {
status = "disabled";
};
// &c908_3 {
// status = "disabled";
// };
&c908_3 {
status = "disabled";
};
// &c920_4 {
// status = "disabled";
// };
&c920_4 {
status = "disabled";
};
// &c920_5 {
// status = "disabled";
// };
&c920_5 {
status = "disabled";
};
// &c920_6 {
// status = "disabled";
// };
&c920_6 {
status = "disabled";
};
// &c920_7 {
// status = "disabled";
// };
&c920_7 {
status = "disabled";
};
&uart0 {
status = "disabled";
@@ -79,6 +79,10 @@
status = "disabled";
};
&i2c0 {
status = "disabled";
};
&i2c1 {
status = "disabled";
};
@@ -181,7 +185,7 @@
};
&dm3x4 {
status = "okay";
status = "disabled";
};
&rp3x1 {

View File

@@ -741,11 +741,10 @@
power-domains = <&power_top>;
#power-domain-cells = <0>;
id = <A210_PD_PCIE0>;
clocks = <&clk_pcie E16PHY_PCLK_EN>, <&clk_pcie PCIE_DM_GEN3X4_AUX_CLK_EN>,
clocks = <&clk_pcie PCIE_DM_GEN3X4_AUX_CLK_EN>,
<&clk_pcie PCIE_DM_GEN3X4_SLV_ACLK_EN>, <&clk_pcie PCIE_DM_GEN3X4_MST_ACLK_EN>,
<&clk_pcie PCIE_DM_GEN3X4_PCLK_EN>;
resets = <&rst PCIE_E16PHY_PHY_RST>, <&rst PCIE_E16PHY_APBS_PRST>,
<&rst PCIE_DM_GEN3X4_APBS_PRST>, <&rst PCIE_DM_GEN3X4_POWER_UP_RST>;
resets = <&rst PCIE_DM_GEN3X4_APBS_PRST>, <&rst PCIE_DM_GEN3X4_POWER_UP_RST>;
iopmps = <&device_pcie_0_iopmp>;
};
power_pcie1:power_pcie1 {
@@ -754,11 +753,10 @@
power-domains = <&power_top>;
#power-domain-cells = <0>;
id = <A210_PD_PCIE1>;
clocks = <&clk_pcie E16PHY_PCLK_EN>, <&clk_pcie PCIE_RP_GEN3X1_AUX_CLK_EN>,
clocks = <&clk_pcie PCIE_RP_GEN3X1_AUX_CLK_EN>,
<&clk_pcie PCIE_RP_GEN3X1_SLV_ACLK_EN>, <&clk_pcie PCIE_RP_GEN3X1_MST_ACLK_EN>,
<&clk_pcie PCIE_RP_GEN3X1_PCLK_EN>;
resets = <&rst PCIE_E16PHY_PHY_RST>, <&rst PCIE_E16PHY_APBS_PRST>,
<&rst PCIE_RP_GEN3X1_APBS_PRST>, <&rst PCIE_RP_GEN3X1_POWER_UP_RST>;
resets = <&rst PCIE_RP_GEN3X1_APBS_PRST>, <&rst PCIE_RP_GEN3X1_POWER_UP_RST>;
iopmps = <&device_pcie_1_iopmp>;
};
power_sata:power_sata {
@@ -767,9 +765,9 @@
power-domains = <&power_top>;
#power-domain-cells = <0>;
id = <A210_PD_SATA>;
clocks = <&clk_pcie E16PHY_PCLK_EN>, <&clk_pcie SATA_GEN3X2_ACLK_EN>, <&clk_pcie SATA_PMALIVE_CLK_EN>,
clocks = <&clk_pcie SATA_GEN3X2_ACLK_EN>, <&clk_pcie SATA_PMALIVE_CLK_EN>,
<&clk_pcie SATA_RXOOB0_CLK_EN>, <&clk_pcie SATA_RXOOB1_CLK_EN>;
resets = <&rst PCIE_E16PHY_PHY_RST>, <&rst PCIE_E16PHY_APBS_PRST>, <&rst PCIE_SATA_ARESET>,
resets = <&rst PCIE_SATA_ARESET>,
<&rst PCIE_SATA_RST_PMALIVE>, <&rst PCIE_SATA_RST_ASIC0>, <&rst PCIE_SATA_RST_ASIC1>,
<&rst PCIE_SATA_RST_RXOOB0>, <&rst PCIE_SATA_RST_RXOOB1>;
iopmps = <&device_sata_0_iopmp>;

View File

@@ -1678,21 +1678,22 @@
status = "okay";
};
pcie_phy: pcie-phy@32f00000 {
compatible = "fsl,imx8mp-pcie-phy";
reg = <0x00 0x0A180000 0x0 0x001000>;
power-domains = <&power_pcie0>;
pcie_phy: pcie-phy@a1800000 {
compatible = "zhihe,a210-pcie-phy";
reg = <0x00 0xa180000 0x0 0x001000>;
#phy-cells = <0>;
status = "disabled";
clocks = <&clk_pcie E16PHY_PCLK_EN>;
clock-names = "e16phy_clk";
resets = <&rst PCIE_E16PHY_PHY_RST>,<&rst PCIE_E16PHY_APBS_PRST>;
reset-names = "apb", "phy";
};
dm3x4: pcie@b000000 {
compatible = "zh,p100-pcie";
reg = <0x00 0x0b000000 0x0 0x800000>,
<0x18 0x00000000 0x0 0x200000>,
<0x00 0x0A004000 0x0 0x001000>,
<0x00 0x0A180000 0x0 0x001000>;
reg-names = "dbi","config","pcie_sysreg","phy_sysreg";
<0x00 0x0A004000 0x0 0x001000>;
reg-names = "dbi","config","pcie_sysreg";
#address-cells = <3>;
#size-cells = <2>;
#interrupt-cells = <1>;
@@ -1711,16 +1712,12 @@
<0x0 0x0 0x0 0x3 &intc 142>,
<0x0 0x0 0x0 0x4 &intc 143>;
zh,max-link-speed = <3>;
clocks = <&clk_pcie E16PHY_PCLK_EN>,
<&clk_pcie PCIE_DM_GEN3X4_AUX_CLK_EN>,
clocks = <&clk_pcie PCIE_DM_GEN3X4_AUX_CLK_EN>,
<&clk_pcie PCIE_DM_GEN3X4_SLV_ACLK_EN>,
<&clk_pcie PCIE_DM_GEN3X4_MST_ACLK_EN>,
<&clk_pcie PCIE_DM_GEN3X4_PCLK_EN>;
clock-names = "e16phy_clk","gen3x4_aux_clk","gen3x4_slv_clk","gen3x4_mst_clk","gen3x4_pclk";
clock-names = "gen3x4_aux_clk","gen3x4_slv_clk","gen3x4_mst_clk","gen3x4_pclk";
power-domains = <&power_pcie0>;
resets = <&rst PCIE_E16PHY_PHY_RST>,
<&rst PCIE_E16PHY_APBS_PRST>;
reset-names = "pcie-rst", "pcie-prst";
//iommus = <&pcie_dfmu_iommu DEVID_DIE0_PCIE_0>;
phys = <&pcie_phy>;
phy-names = "pcie-phy";
@@ -1805,10 +1802,10 @@
clocks = <&clk_pcie SATA_PMALIVE_CLK_EN>,
<&clk_pcie SATA_RXOOB0_CLK_EN>,
<&clk_pcie SATA_GEN3X2_ACLK_EN>;
clock-names = "pmalive", "rxoob", "aclk";
clock-names = "pmalive", "rxoob", "aclk"; // sata_pmalive_clk, sata_rxoob0_clk, sata_gen3x2_aclk
power-domains = <&power_sata>;
//iommus = <&iommu DEVID_DIE0_SATA_0>;
ports-implemented = <3>;
ports-implemented = <1>;
status = "okay";
sata0: sata-port@0 {
@@ -1816,6 +1813,8 @@
hba-port-cap = <HBA_PORT_FBSCP>;
snps,tx-ts-max = <16>;
snps,rx-ts-max = <16>;
phys = <&pcie_phy>;
phy-names = "sata-phy";
};
sata1: sata-port@1 {
@@ -1823,6 +1822,8 @@
hba-port-cap = <HBA_PORT_FBSCP>;
snps,tx-ts-max = <16>;
snps,rx-ts-max = <16>;
phys = <&pcie_phy>;
phy-names = "sata-phy";
};
};

View File

@@ -131,6 +131,8 @@ CONFIG_TH1520_DSMART_CARD=y
CONFIG_IO_EVENT_WRAPER=y
CONFIG_EEPROM_AT24=y
CONFIG_BLK_DEV_SD=m
CONFIG_SCSI_CONSTANTS=y
CONFIG_SCSI_LOGGING=y
CONFIG_ATA=m
CONFIG_AHCI_DWC=m
CONFIG_MD=y
@@ -339,26 +341,13 @@ CONFIG_V4L_MEM2MEM_DRIVERS=y
# CONFIG_MEDIA_TUNER_XC4000 is not set
# CONFIG_MEDIA_TUNER_XC5000 is not set
CONFIG_DRM=y
CONFIG_DRM_MIPI_DSI=y
CONFIG_DRM_KMS_HELPER=y
CONFIG_DRM_FBDEV_EMULATION=y
CONFIG_DRM_FBDEV_OVERALLOC=100
CONFIG_DRM_LOAD_EDID_FIRMWARE=y
CONFIG_DRM_DISPLAY_HELPER=m
CONFIG_DRM_DISPLAY_DP_HELPER=y
CONFIG_DRM_DISPLAY_HDCP_HELPER=y
CONFIG_DRM_DISPLAY_HDMI_HELPER=y
CONFIG_DRM_DP_AUX_CHARDEV=y
CONFIG_DRM_PANEL=y
CONFIG_DRM_PANEL_SIMPLE=m
CONFIG_DRM_PANEL_ILITEK_ILI9881C=m
CONFIG_DRM_PANEL_JADARD_JD9365DA_H3=y
CONFIG_DRM_PANEL_LT8911=y
CONFIG_DRM_BRIDGE=y
CONFIG_DRM_PANEL_BRIDGE=y
CONFIG_DRM_DW_HDMI=m
CONFIG_DRM_VERISILICON=m
CONFIG_DRM_PANEL_ORIENTATION_QUIRKS=y
CONFIG_VERISILICON_DW_DP_P100=y
CONFIG_ZHIHE_AUXDISP=y
CONFIG_FB=y
@@ -462,6 +451,7 @@ CONFIG_IIO_SW_DEVICE=y
CONFIG_PWM=y
CONFIG_PWM_THEAD=y
CONFIG_PHY_DW_DPHY=y
CONFIG_PHY_ZHIHE_SNPS_PCIE3=m
CONFIG_NVMEM_XUANTIE_TH1520_EFUSE=y
CONFIG_NVMEM_ZH_EFUSE=y
CONFIG_TEE=m

View File

@@ -659,7 +659,10 @@ static int ahci_scr_read(struct ata_link *link, unsigned int sc_reg, u32 *val)
int offset = ahci_scr_offset(link->ap, sc_reg);
if (offset) {
// dma_mb();
*val = readl(port_mmio + offset);
// dev_info(link->ap->dev, "------------------------------------ahci_scr_read: offset 0x%x, val=0x%08x\n", offset, *val);
// dma_mb();
return 0;
}
return -EINVAL;
@@ -671,7 +674,10 @@ static int ahci_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val)
int offset = ahci_scr_offset(link->ap, sc_reg);
if (offset) {
// dev_info(link->ap->dev, "------------------------------------ahci_scr_write: offset 0x%x, val 0x%08x\n", offset, val);
// dma_mb();
writel(val, port_mmio + offset);
// dma_mb();
return 0;
}
return -EINVAL;
@@ -683,10 +689,14 @@ void ahci_start_engine(struct ata_port *ap)
u32 tmp;
/* start DMA */
dma_mb();
tmp = readl(port_mmio + PORT_CMD);
tmp |= PORT_CMD_START;
writel(tmp, port_mmio + PORT_CMD);
// dma_mb();
readl(port_mmio + PORT_CMD); /* flush */
// dma_mb();
// dev_info(ap->dev, "------------------------------------ahci_start_engine\n");
}
EXPORT_SYMBOL_GPL(ahci_start_engine);
@@ -709,6 +719,7 @@ int ahci_stop_engine(struct ata_port *ap)
return -EIO;
}
// dma_mb();
tmp = readl(port_mmio + PORT_CMD);
/* check if the HBA is idle */
@@ -728,6 +739,7 @@ int ahci_stop_engine(struct ata_port *ap)
/* setting HBA to idle */
tmp &= ~PORT_CMD_START;
writel(tmp, port_mmio + PORT_CMD);
// dma_mb();
/* wait for engine to stop. This could be as long as 500 msec */
tmp = ata_wait_register(ap, port_mmio + PORT_CMD,

View File

@@ -4790,6 +4790,7 @@ static void fill_result_tf(struct ata_queued_cmd *qc)
qc->result_tf.flags = qc->tf.flags;
ap->ops->qc_fill_rtf(qc);
// dma_mb();
}
static void ata_verify_xfer(struct ata_queued_cmd *qc)

View File

@@ -30,11 +30,6 @@
#define PCIE_GEN3X4_CTRL_REG 0x00000000
#define PCIE_GEN3X4_DBG_INFO_REG0 0x00000430
#define E16PHY_GLB_CTRL_REG 0x00000000
#define E16PHY_SRC_SEL_REG 0x00000004
#define E16PHY_PROTLCOL_REG 0x00000008
#define E16PHY_RES_RTURN_REG 0x00000048
#define PCIE_EXTENDED_REG0 0x00000154
#define PCIE_EXTENDED_REG1 0x00000158
#define PCIE_EXTENDED_REG2 0x0000015c
@@ -59,9 +54,6 @@ struct zhihe_pcie {
enum dw_pcie_device_mode mode;
unsigned int ip_type;
void __iomem *cfg_base;
void __iomem *phy_base;
struct reset_control *pcie_rst;
struct reset_control *pcie_prst;
struct gpio_desc *pcie_bat_en;
struct gpio_desc *pcie_3v3_en;
struct gpio_desc *pcie_12v_en;
@@ -91,18 +83,6 @@ static inline void zhihe_pcie_cfg_writel(struct zhihe_pcie *pcie,
writel(val, pcie->cfg_base + reg);
}
static inline int zhihe_pcie_readl_phy(struct zhihe_pcie *pcie,
u32 reg)
{
return readl(pcie->phy_base + reg);
}
static inline void zhihe_pcie_writel_phy(struct zhihe_pcie *pcie,
u32 reg, u32 val)
{
writel(val, pcie->phy_base + reg);
}
static void __maybe_unused zhihe_pcie_ltssm_enable(struct dw_pcie *pci)
{
struct zhihe_pcie *pcie = to_zhihe_pcie(pci);
@@ -144,7 +124,6 @@ static int zhihe_pcie_get_resources(struct platform_device *pdev,
struct zhihe_pcie *pcie)
{
struct resource *res;
static void __iomem *ep16phy_base;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
@@ -163,29 +142,6 @@ static int zhihe_pcie_get_resources(struct platform_device *pdev,
return dev_err_probe(&pdev->dev, PTR_ERR(pcie->cfg_base),
"Failed to get pcie_sysreg resource");
if (pcie->ip_type == PCIE_X4_TYPE) {
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "phy_sysreg");
pcie->phy_base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(pcie->phy_base))
return dev_err_probe(&pdev->dev, PTR_ERR(pcie->phy_base),
"Failed to get phy_sysreg resource");
ep16phy_base = pcie->phy_base;
}
if (pcie->ip_type == PCIE_X1_TYPE)
pcie->phy_base = ep16phy_base;
if (pcie->ip_type == PCIE_X4_TYPE) {
pcie->pcie_rst = devm_reset_control_get_shared(&pdev->dev, "pcie-rst");
if(IS_ERR(pcie->pcie_rst))
return dev_err_probe(&pdev->dev, PTR_ERR(pcie->pcie_rst),
"Failed to get pcie-rst reset");
pcie->pcie_prst = devm_reset_control_get_shared(&pdev->dev, "pcie-prst");
if(IS_ERR(pcie->pcie_prst))
return dev_err_probe(&pdev->dev, PTR_ERR(pcie->pcie_prst),
"Failed to get pcie-prst reset");
}
/* Get GPIO descriptors for PCIe power control */
pcie->pcie_bat_en = devm_gpiod_get_optional(&pdev->dev,
"pcie-bat-en", GPIOD_OUT_LOW);
@@ -251,6 +207,7 @@ static int __maybe_unused zhihe_pcie_phy_init(struct zhihe_pcie *pcie)
ret = phy_init(pcie->phy);
if (ret < 0)
return ret;
dev_info(dev, "phy_init======================================================\n");
ret = phy_power_on(pcie->phy);
if (ret)
@@ -267,8 +224,6 @@ static void __maybe_unused zhihe_pcie_phy_deinit(struct zhihe_pcie *pcie)
static void zhihe_pcie_stop_link(struct dw_pcie *pci)
{
struct zhihe_pcie *zhihe_pcie = dev_get_drvdata(pci->dev);
zhihe_pcie_ltssm_disable(pci);
}
@@ -285,18 +240,7 @@ static int zhihe_pcie_ipctrl_init(struct dw_pcie_rp *pp)
/*disable ltssm*/
zhihe_pcie_ltssm_disable(pci);
/*enable rp && sata*/
if (pcie->ip_type == PCIE_X1_TYPE) {
zhihe_pcie_writel_phy(pcie, E16PHY_GLB_CTRL_REG, 0x110101);
zhihe_pcie_writel_phy(pcie, E16PHY_SRC_SEL_REG, 0x1100);
zhihe_pcie_writel_phy(pcie, E16PHY_PROTLCOL_REG, 0x2200);
}
/*phy deassert*/
if (pcie->ip_type == PCIE_X4_TYPE) {
reset_control_deassert(pcie->pcie_rst);
reset_control_deassert(pcie->pcie_prst);
}
/*resistor tune request && res_ack_in*/
zhihe_pcie_writel_phy(pcie, E16PHY_RES_RTURN_REG, 0x10001);
if (pcie->ip_type == PCIE_X4_TYPE) {
/*cfg x4 lane*/
dw_pcie_writel_dbi(pci, PCIE_PORT_LINK_CONTROL, 0x70120);
@@ -428,9 +372,9 @@ static int zhihe_pcie_probe(struct platform_device *pdev)
if (ret)
return ret;
// ret = zhihe_pcie_phy_init(pcie);
// if (ret)
// return ret;
ret = zhihe_pcie_phy_init(pcie);
if (ret)
return ret;
switch (pcie->mode) {
case DW_PCIE_RC_TYPE:
@@ -455,8 +399,6 @@ static int zhihe_pcie_remove(struct platform_device *pdev)
dw_pcie_host_deinit(&pcie->pci.pp);
reset_control_assert(pcie->pcie_rst);
reset_control_assert(pcie->pcie_prst);
return 0;
}

View File

@@ -8,3 +8,12 @@ config PHY_DW_DPHY
help
Choose this option if you have DesignWare D-PHY in your system.
If M is selected, the module will be called dw-dphy.
config PHY_ZHIHE_SNPS_PCIE3
tristate "Zhihe Snps PCIe3 PHY Driver"
depends on (ARCH_ZHIHE && OF) || COMPILE_TEST
depends on HAS_IOMEM
select GENERIC_PHY
select MFD_SYSCON
help
Enable this to support the ZHIHE snps PCIe3 PHY.

View File

@@ -1,3 +1,4 @@
# SPDX-License-Identifier: GPL-2.0-only
obj-$(CONFIG_PHY_DW_DPHY) += phy-dw-mipi-dphy.o
obj-$(CONFIG_PHY_ZHIHE_SNPS_PCIE3) += phy-dw-e16.o

View File

@@ -0,0 +1,231 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Rockchip PCIE3.0 phy driver
*
* Copyright (C) 2022 Rockchip Electronics Co., Ltd.
*/
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/iopoll.h>
#include <linux/kernel.h>
#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/phy/pcie.h>
#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/reset.h>
/* Register for A210 */
#define E16PHY_GLB_CTRL_REG 0x00000000
#define E16PHY_SRC_SEL_REG 0x00000004
#define E16PHY_PROTLCOL_REG 0x00000008
#define E16PHY_RES_RTURN_REG 0x00000048
/* Register for RK3568 */
#define GRF_PCIE30PHY_CON1 0x4
#define GRF_PCIE30PHY_CON6 0x18
#define GRF_PCIE30PHY_CON9 0x24
#define GRF_PCIE30PHY_DA_OCM (BIT(15) | BIT(31))
#define GRF_PCIE30PHY_STATUS0 0x80
#define GRF_PCIE30PHY_WR_EN (0xf << 16)
#define SRAM_INIT_DONE(reg) (reg & BIT(14))
#define RK3568_BIFURCATION_LANE_0_1 BIT(0)
/* Register for RK3588 */
#define PHP_GRF_PCIESEL_CON 0x100
#define RK3588_PCIE3PHY_GRF_CMN_CON0 0x0
#define RK3588_PCIE3PHY_GRF_PHY0_STATUS1 0x904
#define RK3588_PCIE3PHY_GRF_PHY1_STATUS1 0xa04
#define RK3588_SRAM_INIT_DONE(reg) (reg & BIT(0))
#define RK3588_BIFURCATION_LANE_0_1 BIT(0)
#define RK3588_BIFURCATION_LANE_2_3 BIT(1)
#define RK3588_LANE_AGGREGATION BIT(2)
struct zhihe_p3phy_ops;
struct zhihe_p3phy_priv {
const struct zhihe_p3phy_ops *ops;
void __iomem *mmio;
/* mode: RC, EP */
int mode;
/* pcie30_phymode: Aggregation, Bifurcation */
int pcie30_phymode;
struct reset_control *apb_rst;
struct reset_control *phy_rst;
struct phy *phy;
struct clk_bulk_data *clks;
int num_clks;
int num_lanes;
u32 lanes[4];
};
struct zhihe_p3phy_ops {
int (*phy_init)(struct zhihe_p3phy_priv *priv);
};
static int zhihe_p3phy_set_mode(struct phy *phy, enum phy_mode mode, int submode)
{
struct zhihe_p3phy_priv *priv = phy_get_drvdata(phy);
/* Actually We don't care EP/RC mode, but just record it */
switch (mode) {
case PHY_MODE_SATA:
priv->mode = PHY_MODE_SATA;
break;
default:
dev_err(&phy->dev, "%s, invalid mode, submode %d\n", __func__, submode);
return -EINVAL;
}
return 0;
}
static int zhihe_p3phy_a210_init(struct zhihe_p3phy_priv *priv)
{
int ret = 0;
// dev_info(&priv->phy->dev, "%s mmio=%px\n", __func__, priv->mmio);
writel(0x00110101, priv->mmio + 0);
writel(0x00001100, priv->mmio + 4);
writel(0x00002200, priv->mmio + 8);
writel(0x00000011, priv->mmio + 108);
writel(0x00010001, priv->mmio + 48);
// dma_mb();
return ret;
}
static const struct zhihe_p3phy_ops a210_ops = {
.phy_init = zhihe_p3phy_a210_init,
};
static int rochchip_p3phy_init(struct phy *phy)
{
struct zhihe_p3phy_priv *priv = phy_get_drvdata(phy);
int ret;
ret = clk_bulk_prepare_enable(priv->num_clks, priv->clks);
if (ret) {
dev_err(&priv->phy->dev, "failed to enable PCIe bulk clks %d\n", ret);
return ret;
}
udelay(10);
reset_control_assert(priv->apb_rst);
reset_control_assert(priv->phy_rst);
if (priv->ops->phy_init) {
ret = priv->ops->phy_init(priv);
if (ret) {
clk_bulk_disable_unprepare(priv->num_clks, priv->clks);
reset_control_assert(priv->apb_rst);
return ret;
}
}
// reset_control_deassert(priv->apb_rst);
udelay(1);
reset_control_deassert(priv->phy_rst);
return ret;
}
static int rochchip_p3phy_exit(struct phy *phy)
{
struct zhihe_p3phy_priv *priv = phy_get_drvdata(phy);
clk_bulk_disable_unprepare(priv->num_clks, priv->clks);
reset_control_assert(priv->phy_rst);
reset_control_assert(priv->apb_rst);
return 0;
}
static const struct phy_ops rochchip_p3phy_ops = {
.init = rochchip_p3phy_init,
.exit = rochchip_p3phy_exit,
.set_mode = zhihe_p3phy_set_mode,
.owner = THIS_MODULE,
};
static int zhihe_p3phy_probe(struct platform_device *pdev)
{
struct phy_provider *phy_provider;
struct device *dev = &pdev->dev;
struct zhihe_p3phy_priv *priv;
struct resource *res;
int ret;
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
priv->mmio = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
if (IS_ERR(priv->mmio)) {
ret = PTR_ERR(priv->mmio);
return ret;
}
dev_info(&pdev->dev,
"E16PHY mapped: phys=%pa, virt=%px, size=%zu\n",
&res->start, priv->mmio, (size_t)resource_size(res));
priv->ops = of_device_get_match_data(&pdev->dev);
if (!priv->ops) {
dev_err(dev, "no of match data provided\n");
return -EINVAL;
}
priv->phy = devm_phy_create(dev, NULL, &rochchip_p3phy_ops);
if (IS_ERR(priv->phy)) {
dev_err(dev, "failed to create combphy\n");
return PTR_ERR(priv->phy);
}
priv->apb_rst = devm_reset_control_get_shared(dev, "apb");
if (IS_ERR(priv->apb_rst)) {
return dev_err_probe(dev, PTR_ERR(priv->apb_rst),
"failed to get apb rst control\n");
}
if (!priv->apb_rst)
dev_info(dev, "no apb reset control specified\n");
priv->phy_rst = devm_reset_control_get_shared(dev, "phy");
if (IS_ERR(priv->phy_rst)) {
return dev_err_probe(dev, PTR_ERR(priv->phy_rst),
"failed to get phy rst control\n");
}
if (!priv->phy_rst)
dev_info(dev, "no phy reset control specified\n");
priv->num_clks = devm_clk_bulk_get_all(dev, &priv->clks);
if (priv->num_clks < 1)
return -ENODEV;
dev_info(dev, "num_clks = %d\n", priv->num_clks);
dev_set_drvdata(dev, priv);
phy_set_drvdata(priv->phy, priv);
phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
return PTR_ERR_OR_ZERO(phy_provider);
}
static const struct of_device_id zhihe_p3phy_of_match[] = {
{ .compatible = "zhihe,a210-pcie-phy", .data = &a210_ops },
{ },
};
MODULE_DEVICE_TABLE(of, zhihe_p3phy_of_match);
static struct platform_driver zhihe_p3phy_driver = {
.probe = zhihe_p3phy_probe,
.driver = {
.name = "zhihe-snps-pcie3-phy",
.of_match_table = zhihe_p3phy_of_match,
},
};
module_platform_driver(zhihe_p3phy_driver);
MODULE_DESCRIPTION("Zhihe Synopsys PCIe 3.0 PHY driver");
MODULE_LICENSE("GPL");