Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    3)  * Rockchip USB3.0 and PCIE COMBPHY with Innosilicon IP block driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    5)  * Copyright (C) 2018 Fuzhou Rockchip Electronics Co., Ltd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    6)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    7) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    8) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    9) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   10) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   11) #include <linux/iopoll.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   12) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   13) #include <linux/mfd/syscon.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   14) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   15) #include <linux/of_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   16) #include <linux/phy/phy.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   17) #include <linux/phy/pcie.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   18) #include <linux/regmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   19) #include <linux/reset.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   20) #include <dt-bindings/phy/phy.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   21) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   22) #define BIT_WRITEABLE_SHIFT		16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   23) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   24) struct rockchip_combphy_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   25) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   26) enum rockchip_combphy_rst {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   27) 	OTG_RSTN	= 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   28) 	PHY_POR_RSTN	= 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   29) 	PHY_APB_RSTN	= 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   30) 	PHY_PIPE_RSTN	= 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   31) 	PHY_GRF_P_RSTN  = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   32) 	PHY_RESET_MAX	= 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   33) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   34) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   35) struct combphy_reg {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   36) 	u32	offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   37) 	u32	bitend;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   38) 	u32	bitstart;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   39) 	u32	disable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   40) 	u32	enable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   41) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   42) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   43) struct rockchip_combphy_grfcfg {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   44) 	struct combphy_reg	pipe_l1_sel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   45) 	struct combphy_reg	pipe_l1_set;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   46) 	struct combphy_reg	pipe_l1pd_sel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   47) 	struct combphy_reg	pipe_l1pd_p3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   48) 	struct combphy_reg	pipe_l0pd_sel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   49) 	struct combphy_reg	pipe_l0pd_p3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   50) 	struct combphy_reg	pipe_clk_sel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   51) 	struct combphy_reg	pipe_clk_set;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   52) 	struct combphy_reg	pipe_rate_sel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   53) 	struct combphy_reg	pipe_rate_set;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   54) 	struct combphy_reg	pipe_mode_sel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   55) 	struct combphy_reg	pipe_mode_set;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   56) 	struct combphy_reg	pipe_txrx_sel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   57) 	struct combphy_reg	pipe_txrx_set;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   58) 	struct combphy_reg	pipe_width_sel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   59) 	struct combphy_reg	pipe_width_set;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   60) 	struct combphy_reg	pipe_usb3_sel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   61) 	struct combphy_reg	pipe_pll_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   62) 	struct combphy_reg	pipe_status_l0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   63) 	struct combphy_reg	pipe_l0rxterm_sel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   64) 	struct combphy_reg	pipe_l1rxterm_sel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   65) 	struct combphy_reg	pipe_l0rxterm_set;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   66) 	struct combphy_reg	pipe_l1rxterm_set;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   67) 	struct combphy_reg	pipe_l0rxelec_set;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   68) 	struct combphy_reg	u3_port_disable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   69) 	struct combphy_reg      u3_port_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   70) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   71) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   72) struct rockchip_combphy_cfg {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   73) 	const struct rockchip_combphy_grfcfg grfcfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   74) 	int (*combphy_cfg)(struct rockchip_combphy_priv *priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   75) 	int (*combphy_low_power_ctrl)(struct rockchip_combphy_priv *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   76) 				      bool en);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   77) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   78) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   79) struct rockchip_combphy_priv {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   80) 	bool phy_initialized;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   81) 	bool phy_suspended;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   82) 	u8 phy_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   83) 	void __iomem *mmio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   84) 	struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   85) 	struct clk *ref_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   86) 	struct phy *phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   87) 	struct regmap *combphy_grf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   88) 	struct regmap *usb_pcie_grf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   89) 	struct reset_control *rsts[PHY_RESET_MAX];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   90) 	const struct rockchip_combphy_cfg *cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   91) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   92) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   93) static const char *get_reset_name(enum rockchip_combphy_rst rst)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   94) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   95) 	switch (rst) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   96) 	case OTG_RSTN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   97) 		return "otg-rst";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   98) 	case PHY_POR_RSTN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   99) 		return "combphy-por";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  100) 	case PHY_APB_RSTN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  101) 		return "combphy-apb";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  102) 	case PHY_PIPE_RSTN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  103) 		return "combphy-pipe";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  104) 	case PHY_GRF_P_RSTN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  105) 		return "usb3phy_grf_p";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  106) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  107) 		return "invalid";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  108) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  109) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  110) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  111) static inline bool param_read(struct regmap *base,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  112) 			      const struct combphy_reg *reg, u32 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  113) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  114) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  115) 	u32 mask, orig, tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  116) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  117) 	ret = regmap_read(base, reg->offset, &orig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  118) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  119) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  120) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  121) 	mask = GENMASK(reg->bitend, reg->bitstart);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  122) 	tmp = (orig & mask) >> reg->bitstart;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  123) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  124) 	return tmp == val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  125) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  126) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  127) static inline int param_write(struct regmap *base,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  128) 			      const struct combphy_reg *reg, bool en)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  129) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  130) 	u32 val, mask, tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  131) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  132) 	tmp = en ? reg->enable : reg->disable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  133) 	mask = GENMASK(reg->bitend, reg->bitstart);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  134) 	val = (tmp << reg->bitstart) | (mask << BIT_WRITEABLE_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  135) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  136) 	return regmap_write(base, reg->offset, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  137) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  138) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  139) static ssize_t u3phy_mode_show(struct device *device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  140) 			       struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  141) 			       char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  142) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  143) 	struct rockchip_combphy_priv *priv = dev_get_drvdata(device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  144) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  145) 	if (param_read(priv->usb_pcie_grf, &priv->cfg->grfcfg.u3_port_num, 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  146) 		return sprintf(buf, "u2\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  147) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  148) 		return sprintf(buf, "u3\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  149) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  150) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  151) static ssize_t u3phy_mode_store(struct device *device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  152) 				struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  153) 				const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  154) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  155) 	struct rockchip_combphy_priv *priv = dev_get_drvdata(device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  156) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  157) 	if (!strncmp(buf, "u3", 2) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  158) 	    param_read(priv->usb_pcie_grf, &priv->cfg->grfcfg.u3_port_num, 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  159) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  160) 		 * Enable USB 3.0 rx termination, need to select
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  161) 		 * pipe_l0_rxtermination from USB 3.0 controller.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  162) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  163) 		param_write(priv->combphy_grf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  164) 			    &priv->cfg->grfcfg.pipe_l0rxterm_sel, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  165) 		/* Set xHCI USB 3.0 port number to 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  166) 		param_write(priv->usb_pcie_grf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  167) 			    &priv->cfg->grfcfg.u3_port_num, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  168) 		/* Enable xHCI USB 3.0 port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  169) 		param_write(priv->usb_pcie_grf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  170) 			    &priv->cfg->grfcfg.u3_port_disable, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  171) 		dev_info(priv->dev, "Set usb3.0 and usb2.0 mode successfully\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  172) 	} else if (!strncmp(buf, "u2", 2) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  173) 		   param_read(priv->usb_pcie_grf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  174) 			      &priv->cfg->grfcfg.u3_port_num, 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  175) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  176) 		 * Disable USB 3.0 rx termination, need to select
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  177) 		 * pipe_l0_rxtermination from grf and remove rx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  178) 		 * termimation by grf.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  179) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  180) 		param_write(priv->combphy_grf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  181) 			    &priv->cfg->grfcfg.pipe_l0rxterm_set, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  182) 		param_write(priv->combphy_grf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  183) 			    &priv->cfg->grfcfg.pipe_l0rxterm_sel, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  184) 		/* Set xHCI USB 3.0 port number to 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  185) 		param_write(priv->usb_pcie_grf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  186) 			    &priv->cfg->grfcfg.u3_port_num, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  187) 		/* Disable xHCI USB 3.0 port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  188) 		param_write(priv->usb_pcie_grf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  189) 			    &priv->cfg->grfcfg.u3_port_disable, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  190) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  191) 		 * Note:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  192) 		 * Don't disable the USB 3.0 PIPE pclk here(set reg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  193) 		 * pipe_usb3_sel to false), because USB 3.0 PHY depend
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  194) 		 * on this clk, if we disable it, we need to reinit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  195) 		 * the USB 3.0 PHY when use USB 3.0 mode, in order to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  196) 		 * simplify the process, don't disable this PIPE pclk.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  197) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  198) 		dev_info(priv->dev, "Set usb2.0 only mode successfully\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  199) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  200) 		dev_info(priv->dev, "Same or illegal mode\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  201) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  202) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  203) 	return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  204) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  205) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  206) static DEVICE_ATTR_RW(u3phy_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  207) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  208) static struct attribute *rockchip_combphy_u3phy_mode_attrs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  209) 	&dev_attr_u3phy_mode.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  210) 	NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  211) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  212) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  213) static struct attribute_group rockchip_combphy_u3phy_mode_attr_group = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  214) 	.name = NULL,	/* we want them in the same directory */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  215) 	.attrs = rockchip_combphy_u3phy_mode_attrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  216) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  217) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  218) static u32 rockchip_combphy_pll_lock(struct rockchip_combphy_priv *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  219) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  220) 	const struct rockchip_combphy_grfcfg *grfcfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  221) 	u32 mask, val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  222) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  223) 	grfcfg = &priv->cfg->grfcfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  224) 	mask = GENMASK(grfcfg->pipe_pll_lock.bitend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  225) 		       grfcfg->pipe_pll_lock.bitstart);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  226) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  227) 	regmap_read(priv->combphy_grf, grfcfg->pipe_pll_lock.offset, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  228) 	val = (val & mask) >> grfcfg->pipe_pll_lock.bitstart;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  229) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  230) 	return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  231) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  232) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  233) static u32 rockchip_combphy_is_ready(struct rockchip_combphy_priv *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  234) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  235) 	const struct rockchip_combphy_grfcfg *grfcfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  236) 	u32 mask, val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  237) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  238) 	grfcfg = &priv->cfg->grfcfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  239) 	mask = GENMASK(grfcfg->pipe_status_l0.bitend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  240) 		       grfcfg->pipe_status_l0.bitstart);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  241) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  242) 	regmap_read(priv->combphy_grf, grfcfg->pipe_status_l0.offset, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  243) 	val = (val & mask) >> grfcfg->pipe_status_l0.bitstart;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  244) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  245) 	return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  246) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  247) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  248) static int phy_pcie_init(struct rockchip_combphy_priv *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  249) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  250) 	const struct rockchip_combphy_grfcfg *grfcfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  251) 	u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  252) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  253) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  254) 	grfcfg = &priv->cfg->grfcfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  255) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  256) 	/* reset PCIe phy to default configuration */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  257) 	reset_control_assert(priv->rsts[PHY_POR_RSTN]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  258) 	reset_control_assert(priv->rsts[PHY_APB_RSTN]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  259) 	reset_control_assert(priv->rsts[PHY_PIPE_RSTN]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  260) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  261) 	reset_control_deassert(priv->rsts[PHY_POR_RSTN]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  262) 	/* Wait PHY power on stable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  263) 	udelay(5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  264) 	reset_control_deassert(priv->rsts[PHY_APB_RSTN]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  265) 	udelay(5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  266) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  267) 	/* Set rxtermination for lane0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  268) 	param_write(priv->combphy_grf, &grfcfg->pipe_l0rxterm_set, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  269) 	/* Set rxtermination for lane1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  270) 	param_write(priv->combphy_grf, &grfcfg->pipe_l1rxterm_set, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  271) 	/* Select pipe_l0_rxtermination from grf */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  272) 	param_write(priv->combphy_grf, &grfcfg->pipe_l0rxterm_sel, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  273) 	/* Select pipe_l1_rxtermination from grf */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  274) 	param_write(priv->combphy_grf, &grfcfg->pipe_l1rxterm_sel, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  275) 	/* Select rxelecidle_disable and txcommonmode from PCIe controller */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  276) 	param_write(priv->combphy_grf, &grfcfg->pipe_txrx_sel, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  277) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  278) 	/* Start to configurate PHY registers for PCIE. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  279) 	if (priv->cfg->combphy_cfg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  280) 		ret = priv->cfg->combphy_cfg(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  281) 		if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  282) 			goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  283) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  284) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  285) 	/* Wait Tx PLL lock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  286) 	usleep_range(300, 350);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  287) 	ret = readx_poll_timeout_atomic(rockchip_combphy_pll_lock, priv, val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  288) 					val == grfcfg->pipe_pll_lock.enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  289) 					10, 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  290) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  291) 		dev_err(priv->dev, "wait phy PLL lock timeout\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  292) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  293) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  294) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  295) 	reset_control_deassert(priv->rsts[PHY_PIPE_RSTN]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  296) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  297) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  298) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  299) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  300) static int phy_u3_init(struct rockchip_combphy_priv *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  301) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  302) 	const struct rockchip_combphy_grfcfg *grfcfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  303) 	u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  304) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  305) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  306) 	grfcfg = &priv->cfg->grfcfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  307) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  308) 	/* Reset the USB3 controller first. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  309) 	reset_control_assert(priv->rsts[OTG_RSTN]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  310) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  311) 	reset_control_deassert(priv->rsts[PHY_POR_RSTN]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  312) 	/* Wait PHY power on stable. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  313) 	udelay(5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  314) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  315) 	reset_control_deassert(priv->rsts[PHY_APB_RSTN]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  316) 	udelay(5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  317) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  318) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  319) 	 * Start to configurate PHY registers for USB3.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  320) 	 * Note: set operation must be done before corresponding
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  321) 	 * sel operation, otherwise, the PIPE PHY status lane0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  322) 	 * may be unable to get ready.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  323) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  324) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  325) 	/* Disable PHY lane1 which isn't needed for USB3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  326) 	param_write(priv->combphy_grf, &grfcfg->pipe_l1_set, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  327) 	param_write(priv->combphy_grf, &grfcfg->pipe_l1_sel, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  328) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  329) 	/* Set PHY Tx and Rx for USB3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  330) 	param_write(priv->combphy_grf, &grfcfg->pipe_txrx_set, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  331) 	param_write(priv->combphy_grf, &grfcfg->pipe_txrx_sel, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  332) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  333) 	/* Set PHY PIPE MAC pclk request */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  334) 	param_write(priv->combphy_grf, &grfcfg->pipe_clk_set, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  335) 	param_write(priv->combphy_grf, &grfcfg->pipe_clk_sel, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  336) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  337) 	/* Set PHY PIPE rate for USB3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  338) 	param_write(priv->combphy_grf, &grfcfg->pipe_rate_set, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  339) 	param_write(priv->combphy_grf, &grfcfg->pipe_rate_sel, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  340) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  341) 	/* Set PHY mode for USB3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  342) 	param_write(priv->combphy_grf, &grfcfg->pipe_mode_set, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  343) 	param_write(priv->combphy_grf, &grfcfg->pipe_mode_sel, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  344) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  345) 	/* Set PHY data bus width for USB3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  346) 	param_write(priv->combphy_grf, &grfcfg->pipe_width_set, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  347) 	param_write(priv->combphy_grf, &grfcfg->pipe_width_sel, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  348) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  349) 	/* Select PIPE for USB3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  350) 	param_write(priv->combphy_grf, &grfcfg->pipe_usb3_sel, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  351) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  352) 	if (priv->cfg->combphy_cfg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  353) 		ret = priv->cfg->combphy_cfg(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  354) 		if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  355) 			goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  356) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  357) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  358) 	/* Wait Tx PLL lock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  359) 	usleep_range(300, 350);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  360) 	ret = readx_poll_timeout_atomic(rockchip_combphy_pll_lock, priv, val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  361) 					val == grfcfg->pipe_pll_lock.enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  362) 					10, 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  363) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  364) 		dev_err(priv->dev, "wait phy PLL lock timeout\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  365) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  366) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  367) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  368) 	reset_control_deassert(priv->rsts[PHY_PIPE_RSTN]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  369) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  370) 	/* Wait PIPE PHY status lane0 ready */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  371) 	ret = readx_poll_timeout_atomic(rockchip_combphy_is_ready, priv, val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  372) 					val == grfcfg->pipe_status_l0.enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  373) 					10, 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  374) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  375) 		dev_err(priv->dev, "wait phy status lane0 ready timeout\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  376) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  377) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  378) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  379) 	reset_control_deassert(priv->rsts[OTG_RSTN]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  380) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  381) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  382) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  383) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  384) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  385) static int rockchip_combphy_set_phy_type(struct rockchip_combphy_priv *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  386) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  387) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  388) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  389) 	if (priv->phy_initialized)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  390) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  391) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  392) 	switch (priv->phy_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  393) 	case PHY_TYPE_PCIE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  394) 		ret = phy_pcie_init(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  395) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  396) 	case PHY_TYPE_USB3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  397) 		ret = phy_u3_init(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  398) 		if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  399) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  400) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  401) 		/* Attributes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  402) 		ret = sysfs_create_group(&priv->dev->kobj,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  403) 					 &rockchip_combphy_u3phy_mode_attr_group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  404) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  405) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  406) 		dev_err(priv->dev, "incompatible PHY type\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  407) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  408) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  409) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  410) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  411) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  412) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  413) static int rockchip_combphy_init(struct phy *phy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  414) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  415) 	struct rockchip_combphy_priv *priv = phy_get_drvdata(phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  416) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  417) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  418) 	ret = clk_prepare_enable(priv->ref_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  419) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  420) 		dev_err(priv->dev, "failed to enable ref_clk\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  421) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  422) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  423) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  424) 	ret = rockchip_combphy_set_phy_type(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  425) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  426) 		dev_err(priv->dev, "failed to set phy type\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  427) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  428) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  429) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  430) 	priv->phy_initialized = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  431) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  432) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  433) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  434) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  435) static int rockchip_combphy_exit(struct phy *phy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  436) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  437) 	struct rockchip_combphy_priv *priv = phy_get_drvdata(phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  438) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  439) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  440) 	 * Note: don't assert PHY reset here, because
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  441) 	 * we set many phy configurations during phy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  442) 	 * init to reduce PHY power consumption, if we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  443) 	 * assert PHY reset here, these configurations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  444) 	 * will be lost, and increase power consumption.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  445) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  446) 	clk_disable_unprepare(priv->ref_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  447) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  448) 	/* in case of waiting phy PLL lock timeout */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  449) 	if (priv->phy_type == PHY_TYPE_PCIE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  450) 		reset_control_assert(priv->rsts[PHY_GRF_P_RSTN]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  451) 		udelay(5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  452) 		reset_control_deassert(priv->rsts[PHY_GRF_P_RSTN]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  453) 		priv->phy_initialized = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  454) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  455) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  456) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  457) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  458) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  459) static int rockchip_combphy_power_on(struct phy *phy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  460) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  461) 	struct rockchip_combphy_priv *priv = phy_get_drvdata(phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  462) 	const struct rockchip_combphy_grfcfg *grfcfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  463) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  464) 	if (!priv->phy_suspended)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  465) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  466) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  467) 	grfcfg = &priv->cfg->grfcfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  468) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  469) 	if (priv->phy_type == PHY_TYPE_USB3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  470) 		if (priv->cfg->combphy_low_power_ctrl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  471) 			priv->cfg->combphy_low_power_ctrl(priv, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  472) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  473) 		/* Enable lane 0 squelch detection  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  474) 		param_write(priv->combphy_grf, &grfcfg->pipe_l0rxelec_set,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  475) 			    false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  476) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  477) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  478) 		 * Check if lane 0 powerdown is already
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  479) 		 * controlled by USB 3.0 controller.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  480) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  481) 		if (param_read(priv->combphy_grf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  482) 			       &grfcfg->pipe_l0pd_sel, 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  483) 			goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  484) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  485) 		/* Exit to P0 from P3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  486) 		param_write(priv->combphy_grf, &grfcfg->pipe_l0pd_p3, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  487) 		usleep_range(250, 300);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  488) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  489) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  490) 		 * Set lane 0 powerdown to be controlled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  491) 		 * by USB 3.0 controller.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  492) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  493) 		param_write(priv->combphy_grf, &grfcfg->pipe_l0pd_sel, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  494) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  495) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  496) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  497) 	priv->phy_suspended = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  498) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  499) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  500) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  501) static int rockchip_combphy_power_off(struct phy *phy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  502) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  503) 	struct rockchip_combphy_priv *priv = phy_get_drvdata(phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  504) 	const struct rockchip_combphy_grfcfg *grfcfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  505) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  506) 	if (priv->phy_suspended)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  507) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  508) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  509) 	grfcfg = &priv->cfg->grfcfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  510) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  511) 	if (priv->phy_type == PHY_TYPE_USB3 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  512) 	    priv->phy_type == PHY_TYPE_PCIE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  513) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  514) 		 * Check if lane 0 powerdown is already
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  515) 		 * controlled by grf and in P3 state.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  516) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  517) 		if (param_read(priv->combphy_grf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  518) 			       &grfcfg->pipe_l0pd_sel, 1) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  519) 		    param_read(priv->combphy_grf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  520) 			       &grfcfg->pipe_l0pd_p3, 3))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  521) 			goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  522) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  523) 		/* Exit to P0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  524) 		param_write(priv->combphy_grf, &grfcfg->pipe_l0pd_p3, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  525) 		param_write(priv->combphy_grf, &grfcfg->pipe_l0pd_sel, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  526) 		udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  527) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  528) 		/* Enter to P3 from P0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  529) 		param_write(priv->combphy_grf, &grfcfg->pipe_l0pd_p3, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  530) 		udelay(2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  531) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  532) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  533) 		 * Disable lane 0 squelch detection.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  534) 		 * Note: if squelch detection is disabled,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  535) 		 * the PHY can't detect LFPS.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  536) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  537) 		param_write(priv->combphy_grf, &grfcfg->pipe_l0rxelec_set,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  538) 			    true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  539) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  540) 		if (priv->cfg->combphy_low_power_ctrl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  541) 			priv->cfg->combphy_low_power_ctrl(priv, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  542) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  543) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  544) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  545) 	priv->phy_suspended = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  546) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  547) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  548) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  549) static int rockchip_combphy_set_mode(struct phy *phy, enum phy_mode mode, int submode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  550) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  551) 	struct rockchip_combphy_priv *priv = phy_get_drvdata(phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  552) 	u32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  553) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  554) 	if (priv->phy_type != PHY_TYPE_PCIE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  555) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  556) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  557) 	reg = readl(priv->mmio + 0x21a8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  558) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  559) 	if (PHY_MODE_PCIE_EP == submode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  560) 		reg |= (0x1 << 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  561) 	else if (PHY_MODE_PCIE_RC == submode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  562) 		reg &= ~(0x1 << 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  563) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  564) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  565) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  566) 	writel(reg, priv->mmio + 0x21a8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  567) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  568) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  569) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  570) static const struct phy_ops rockchip_combphy_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  571) 	.init		= rockchip_combphy_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  572) 	.exit		= rockchip_combphy_exit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  573) 	.power_on	= rockchip_combphy_power_on,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  574) 	.power_off	= rockchip_combphy_power_off,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  575) 	.set_mode       = rockchip_combphy_set_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  576) 	.owner		= THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  577) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  578) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  579) static struct phy *rockchip_combphy_xlate(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  580) 					  struct of_phandle_args *args)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  581) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  582) 	struct rockchip_combphy_priv *priv = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  583) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  584) 	if (args->args_count < 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  585) 		dev_err(dev, "invalid number of arguments\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  586) 		return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  587) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  588) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  589) 	if (priv->phy_type != PHY_NONE && priv->phy_type != args->args[0]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  590) 		dev_err(dev, "type select %d overwriting phy type %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  591) 			args->args[0], priv->phy_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  592) 		return ERR_PTR(-ENODEV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  593) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  594) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  595) 	priv->phy_type = args->args[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  596) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  597) 	if (priv->phy_type < PHY_TYPE_SATA || priv->phy_type > PHY_TYPE_USB3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  598) 		dev_err(dev, "invalid phy type select argument\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  599) 		return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  600) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  601) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  602) 	return priv->phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  603) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  604) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  605) static int rockchip_combphy_parse_dt(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  606) 				     struct rockchip_combphy_priv *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  607) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  608) 	u32 i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  609) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  610) 	priv->combphy_grf = syscon_regmap_lookup_by_phandle(dev->of_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  611) 							    "rockchip,combphygrf");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  612) 	if (IS_ERR(priv->combphy_grf)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  613) 		dev_err(dev, "failed to find combphy grf regmap\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  614) 		return PTR_ERR(priv->combphy_grf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  615) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  616) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  617) 	priv->usb_pcie_grf = syscon_regmap_lookup_by_phandle(dev->of_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  618) 							 "rockchip,usbpciegrf");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  619) 	if (IS_ERR(priv->usb_pcie_grf)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  620) 		dev_err(dev, "failed to find usb_pcie_grf regmap\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  621) 		return PTR_ERR(priv->usb_pcie_grf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  622) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  623) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  624) 	priv->ref_clk = devm_clk_get(dev, "refclk");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  625) 	if (IS_ERR(priv->ref_clk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  626) 		dev_err(dev, "failed to find ref clock\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  627) 		return PTR_ERR(priv->ref_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  628) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  629) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  630) 	for (i = 0; i < PHY_RESET_MAX; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  631) 		priv->rsts[i] = devm_reset_control_get(dev, get_reset_name(i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  632) 		if (IS_ERR(priv->rsts[i])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  633) 			dev_warn(dev, "no %s reset control specified\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  634) 				 get_reset_name(i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  635) 			priv->rsts[i] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  636) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  637) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  638) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  639) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  640) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  641) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  642) static int rockchip_combphy_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  643) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  644) 	struct phy_provider *phy_provider;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  645) 	struct device *dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  646) 	struct rockchip_combphy_priv *priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  647) 	struct resource *res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  648) 	const struct rockchip_combphy_cfg *phy_cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  649) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  650) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  651) 	phy_cfg = of_device_get_match_data(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  652) 	if (!phy_cfg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  653) 		dev_err(dev, "No OF match data provided\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  654) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  655) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  656) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  657) 	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  658) 	if (!priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  659) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  660) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  661) 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  662) 	priv->mmio = devm_ioremap_resource(dev, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  663) 	if (IS_ERR(priv->mmio)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  664) 		ret = PTR_ERR(priv->mmio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  665) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  666) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  667) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  668) 	ret = rockchip_combphy_parse_dt(dev, priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  669) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  670) 		dev_err(dev, "parse dt failed, ret(%d)\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  671) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  672) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  673) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  674) 	reset_control_assert(priv->rsts[PHY_POR_RSTN]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  675) 	reset_control_assert(priv->rsts[PHY_APB_RSTN]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  676) 	reset_control_assert(priv->rsts[PHY_PIPE_RSTN]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  677) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  678) 	priv->phy_type = PHY_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  679) 	priv->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  680) 	priv->cfg = phy_cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  681) 	priv->phy = devm_phy_create(dev, NULL, &rockchip_combphy_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  682) 	if (IS_ERR(priv->phy)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  683) 		dev_err(dev, "failed to create combphy\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  684) 		return PTR_ERR(priv->phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  685) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  686) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  687) 	dev_set_drvdata(dev, priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  688) 	phy_set_drvdata(priv->phy, priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  689) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  690) 	phy_provider = devm_of_phy_provider_register(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  691) 						     rockchip_combphy_xlate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  692) 	return PTR_ERR_OR_ZERO(phy_provider);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  693) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  694) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  695) static int rockchip_combphy_remove(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  696) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  697) 	struct rockchip_combphy_priv *priv = platform_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  698) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  699) 	if (priv->phy_type == PHY_TYPE_USB3 && priv->phy_initialized)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  700) 		sysfs_remove_group(&priv->dev->kobj,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  701) 				   &rockchip_combphy_u3phy_mode_attr_group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  702) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  703) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  704) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  705) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  706) static int rk1808_combphy_cfg(struct rockchip_combphy_priv *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  707) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  708) 	unsigned long rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  709) 	u32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  710) 	bool ssc_en = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  711) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  712) 	rate = clk_get_rate(priv->ref_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  713) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  714) 	/* Configure PHY reference clock frequency */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  715) 	switch (rate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  716) 	case 24000000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  717) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  718) 		 * The default PHY refclk frequency
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  719) 		 * configuration is 24MHz.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  720) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  721) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  722) 	case 25000000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  723) 		writel(0x00, priv->mmio + 0x2118);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  724) 		writel(0x64, priv->mmio + 0x211c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  725) 		writel(0x01, priv->mmio + 0x2020);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  726) 		writel(0x64, priv->mmio + 0x2028);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  727) 		writel(0x21, priv->mmio + 0x2030);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  728) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  729) 		if (priv->phy_type == PHY_TYPE_PCIE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  730) 			writel(0x1,  priv->mmio + 0x3020);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  731) 			writel(0x64, priv->mmio + 0x3028);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  732) 			writel(0x21, priv->mmio + 0x3030);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  733) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  734) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  735) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  736) 	case 50000000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  737) 		writel(0x00, priv->mmio + 0x2118);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  738) 		writel(0x32, priv->mmio + 0x211c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  739) 		writel(0x01, priv->mmio + 0x2020);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  740) 		writel(0x32, priv->mmio + 0x2028);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  741) 		writel(0x21, priv->mmio + 0x2030);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  742) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  743) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  744) 		dev_err(priv->dev, "Unsupported rate: %lu\n", rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  745) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  746) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  747) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  748) 	if (priv->phy_type == PHY_TYPE_PCIE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  749) 		/* turn on pcie phy pd */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  750) 		writel(0x08400000, priv->mmio + 0x0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  751) 		writel(0x03030000, priv->mmio + 0x8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  752) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  753) 		/* Adjust Lane 0 Rx interface timing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  754) 		writel(0x20, priv->mmio + 0x20ac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  755) 		writel(0x12, priv->mmio + 0x20c8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  756) 		writel(0x76, priv->mmio + 0x2150);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  757) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  758) 		/* Adjust Lane 1 Rx interface timing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  759) 		writel(0x20, priv->mmio + 0x30ac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  760) 		writel(0x12, priv->mmio + 0x30c8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  761) 		writel(0x76, priv->mmio + 0x3150);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  762) 		/* Set PHY output refclk path */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  763) 		writel(0x0, priv->mmio + 0x21a4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  764) 		writel(0x0, priv->mmio + 0x21a8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  765) 		writel(0xb, priv->mmio + 0x21ec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  766) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  767) 		/* Physical ordered set for PCIe */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  768) 		writel(0x02, priv->mmio + 0x45c0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  769) 		writel(0x83, priv->mmio + 0x45c4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  770) 		writel(0x03, priv->mmio + 0x45c8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  771) 		writel(0x43, priv->mmio + 0x45cc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  772) 		writel(0x00, priv->mmio + 0x45d0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  773) 		writel(0xbc, priv->mmio + 0x45d4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  774) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  775) 		/* Boost pre-emphasis */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  776) 		writel(0xaa, priv->mmio + 0x21b8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  777) 		writel(0xaa, priv->mmio + 0x31b8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  778) 	} else if (priv->phy_type == PHY_TYPE_USB3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  779) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  780) 		 * Disable PHY Lane 1 which isn't needed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  781) 		 * for USB3 to reduce power consumption.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  782) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  783) 		/* Lane 1 cdr power down */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  784) 		writel(0x09, priv->mmio + 0x3148);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  785) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  786) 		/* Lane 1 rx bias disable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  787) 		writel(0x01, priv->mmio + 0x21cc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  788) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  789) 		/* Lane 1 cdr disable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  790) 		writel(0x08, priv->mmio + 0x30c4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  791) 		writel(0x08, priv->mmio + 0x20f4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  792) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  793) 		/* Lane 1 rx lock disable and tx bias disable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  794) 		writel(0x12, priv->mmio + 0x3150);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  795) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  796) 		/* Lane 1 rx termination disable, and tx_cmenb disable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  797) 		writel(0x04, priv->mmio + 0x3080);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  798) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  799) 		/* Lane 1 tx termination disable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  800) 		writel(0x1d, priv->mmio + 0x3090);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  801) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  802) 		/* Lane 1 tx driver disable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  803) 		writel(0x50, priv->mmio + 0x21c4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  804) 		writel(0x10, priv->mmio + 0x2050);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  805) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  806) 		/* Lane 1 txldo_refsel disable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  807) 		writel(0x81, priv->mmio + 0x31a8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  808) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  809) 		/* Lane 1 txdetrx_en disable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  810) 		writel(0x00, priv->mmio + 0x31e8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  811) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  812) 		/* Lane 1 rxcm_en disable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  813) 		writel(0x08, priv->mmio + 0x30c0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  814) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  815) 		/* Adjust Lane 0 Rx interface timing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  816) 		writel(0x20, priv->mmio + 0x20ac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  817) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  818) 		/* Set and enable SSC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  819) 		switch (rate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  820) 		case 24000000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  821) 			/* Set SSC rate to 31.25KHz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  822) 			reg = readl(priv->mmio + 0x2108);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  823) 			reg = (reg & ~0xf) | 0x1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  824) 			writel(reg, priv->mmio + 0x2108);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  825) 			ssc_en = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  826) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  827) 		case 25000000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  828) 			/* Set SSC rate to 32.55KHz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  829) 			reg = readl(priv->mmio + 0x2108);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  830) 			reg = (reg & ~0xf) | 0x6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  831) 			writel(reg, priv->mmio + 0x2108);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  832) 			ssc_en = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  833) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  834) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  835) 			dev_warn(priv->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  836) 				 "failed to set SSC on rate: %lu\n", rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  837) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  838) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  839) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  840) 		if (ssc_en) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  841) 			/* Enable SSC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  842) 			reg = readl(priv->mmio + 0x2120);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  843) 			reg &= ~BIT(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  844) 			writel(reg, priv->mmio + 0x2120);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  845) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  846) 			reg = readl(priv->mmio + 0x2000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  847) 			reg &= ~0x6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  848) 			writel(reg, priv->mmio + 0x2000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  849) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  850) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  851) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  852) 		 * Tuning Tx:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  853) 		 * offset 0x21b8 bit[7:4]: lane 0 TX driver swing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  854) 		 * tuning bits with weight, "1111" represents the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  855) 		 * largest swing and "0000" the smallest.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  856) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  857) 		reg = readl(priv->mmio + 0x21b8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  858) 		reg = (reg & ~0xf0) | 0xe0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  859) 		writel(reg, priv->mmio + 0x21b8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  860) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  861) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  862) 		 * Tuning Rx for RJTL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  863) 		 * Decrease CDR Chump Bump current.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  864) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  865) 		reg = readl(priv->mmio + 0x20c8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  866) 		reg = (reg & ~0x6) | BIT(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  867) 		writel(reg, priv->mmio + 0x20c8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  868) 		reg = readl(priv->mmio + 0x2150);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  869) 		reg |= BIT(2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  870) 		writel(reg, priv->mmio + 0x2150);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  871) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  872) 		dev_err(priv->dev, "failed to cfg incompatible PHY type\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  873) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  874) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  875) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  876) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  877) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  878) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  879) static int rk1808_combphy_low_power_control(struct rockchip_combphy_priv *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  880) 					    bool en)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  881) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  882) 	if (priv->phy_type != PHY_TYPE_USB3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  883) 		/* turn off pcie phy pd */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  884) 		writel(0x08400840, priv->mmio + 0x0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  885) 		writel(0x03030303, priv->mmio + 0x8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  886) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  887) 		/* enter PCIe phy low power mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  888) 		writel(0x36, priv->mmio + 0x2150);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  889) 		writel(0x36, priv->mmio + 0x3150);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  890) 		writel(0x02, priv->mmio + 0x21e8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  891) 		writel(0x02, priv->mmio + 0x31e8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  892) 		writel(0x0c, priv->mmio + 0x2080);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  893) 		writel(0x0c, priv->mmio + 0x3080);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  894) 		writel(0x08, priv->mmio + 0x20c0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  895) 		writel(0x08, priv->mmio + 0x30c0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  896) 		writel(0x08, priv->mmio + 0x2058);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  897) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  898) 		writel(0x10, priv->mmio + 0x2044);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  899) 		writel(0x10, priv->mmio + 0x21a8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  900) 		writel(0x10, priv->mmio + 0x31a8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  901) 		writel(0x08, priv->mmio + 0x2058);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  902) 		writel(0x08, priv->mmio + 0x3058);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  903) 		writel(0x40, priv->mmio + 0x205c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  904) 		writel(0x40, priv->mmio + 0x305c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  905) 		writel(0x08, priv->mmio + 0x2184);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  906) 		writel(0x08, priv->mmio + 0x3184);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  907) 		writel(0x00, priv->mmio + 0x2150);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  908) 		writel(0x00, priv->mmio + 0x3150);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  909) 		writel(0x10, priv->mmio + 0x20e0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  910) 		writel(0x00, priv->mmio + 0x21e8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  911) 		writel(0x00, priv->mmio + 0x31e8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  912) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  913) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  914) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  915) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  916) 	if (en) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  917) 		/* Lane 0 tx_biasen disable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  918) 		writel(0x36, priv->mmio + 0x2150);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  919) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  920) 		/* Lane 0 txdetrx_en disable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  921) 		writel(0x02, priv->mmio + 0x21e8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  922) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  923) 		/* Lane 0 tx_cmenb disable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  924) 		writel(0x0c, priv->mmio + 0x2080);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  925) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  926) 		/* Lane 0 rxcm_en disable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  927) 		writel(0x08, priv->mmio + 0x20c0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  928) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  929) 		/* Lane 0 and Lane 1 bg_pwrdn */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  930) 		writel(0x10, priv->mmio + 0x2044);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  931) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  932) 		/* Lane 0 and Lane 1 rcomp_osenseampen disable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  933) 		writel(0x08, priv->mmio + 0x2058);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  934) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  935) 		/* Lane 0 txldo_refsel disable and LDO disable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  936) 		writel(0x91, priv->mmio + 0x21a8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  937) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  938) 		/* Lane 1 LDO disable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  939) 		writel(0x91, priv->mmio + 0x31a8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  940) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  941) 		/* Lane 0 tx_biasen enable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  942) 		writel(0x76, priv->mmio + 0x2150);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  943) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  944) 		/* Lane 0 txdetrx_en enable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  945) 		writel(0x02, priv->mmio + 0x21e8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  946) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  947) 		/* Lane 0 tx_cmenb enable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  948) 		writel(0x08, priv->mmio + 0x2080);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  949) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  950) 		/* Lane 0 rxcm_en enable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  951) 		writel(0x18, priv->mmio + 0x20c0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  952) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  953) 		/* Lane 0 and Lane 1 bg_pwrdn */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  954) 		writel(0x00, priv->mmio + 0x2044);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  955) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  956) 		/* Lane 0 and Lane 1 rcomp_osenseampen enable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  957) 		writel(0x28, priv->mmio + 0x2058);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  958) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  959) 		/* Lane 0 txldo_refsel enable and LDO enable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  960) 		writel(0x01, priv->mmio + 0x21a8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  961) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  962) 		/* Lane 1 LDO enable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  963) 		writel(0x81, priv->mmio + 0x31a8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  964) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  965) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  966) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  967) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  968) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  969) static const struct rockchip_combphy_cfg rk1808_combphy_cfgs = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  970) 	.grfcfg	= {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  971) 		.pipe_l1_sel	= { 0x0000, 15, 11, 0x00, 0x1f },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  972) 		.pipe_l1_set	= { 0x0008, 13, 8, 0x00, 0x13 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  973) 		.pipe_l1rxterm_sel = { 0x0000, 12, 12, 0x0, 0x1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  974) 		.pipe_l1pd_sel	= { 0x0000, 11, 11, 0x0, 0x1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  975) 		.pipe_l1pd_p3	= { 0x0008, 9, 8, 0x0, 0x3 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  976) 		.pipe_l0rxterm_sel = { 0x0000, 7, 7, 0x0, 0x1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  977) 		.pipe_l0pd_sel	= { 0x0000, 6, 6, 0x0, 0x1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  978) 		.pipe_l0pd_p3	= { 0x0008, 1, 0, 0x0, 0x3 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  979) 		.pipe_clk_sel	= { 0x0000, 3, 3, 0x0, 0x1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  980) 		.pipe_clk_set	= { 0x0004, 7, 6, 0x1, 0x0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  981) 		.pipe_rate_sel	= { 0x0000, 2, 2, 0x0, 0x1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  982) 		.pipe_rate_set	= { 0x0004, 5, 4, 0x0, 0x1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  983) 		.pipe_mode_sel	= { 0x0000, 1, 1, 0x0, 0x1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  984) 		.pipe_mode_set	= { 0x0004, 3, 2, 0x0, 0x1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  985) 		.pipe_txrx_sel	= { 0x0004, 15, 8, 0x10, 0x2f },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  986) 		.pipe_txrx_set	= { 0x0008, 15, 14, 0x0, 0x3 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  987) 		.pipe_l1rxterm_set = { 0x0008, 10, 10, 0x0, 0x1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  988) 		.pipe_l0rxterm_set = { 0x0008, 2, 2, 0x0, 0x1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  989) 		.pipe_l0rxelec_set = { 0x0008, 6, 6, 0x0, 0x1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  990) 		.pipe_width_sel	= { 0x0000, 0, 0, 0x0, 0x1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  991) 		.pipe_width_set	= { 0x0004, 1, 0, 0x2, 0x0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  992) 		.pipe_usb3_sel	= { 0x000c, 0, 0, 0x0, 0x1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  993) 		.pipe_pll_lock	= { 0x0034, 14, 14, 0x0, 0x1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  994) 		.pipe_status_l0	= { 0x0034, 7, 7, 0x1, 0x0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  995) 		.u3_port_disable = { 0x0434, 0, 0, 0, 1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  996) 		.u3_port_num	= { 0x0434, 15, 12, 0, 1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  997) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  998) 	.combphy_cfg		= rk1808_combphy_cfg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  999) 	.combphy_low_power_ctrl	= rk1808_combphy_low_power_control,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) static const struct of_device_id rockchip_combphy_of_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) 		.compatible = "rockchip,rk1808-combphy",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) 		.data = &rk1808_combphy_cfgs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) 	{ },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) MODULE_DEVICE_TABLE(of, rockchip_combphy_of_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) static struct platform_driver rockchip_combphy_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) 	.probe	= rockchip_combphy_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) 	.remove = rockchip_combphy_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) 	.driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) 		.name = "rockchip-combphy",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) 		.of_match_table = rockchip_combphy_of_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) module_platform_driver(rockchip_combphy_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) MODULE_AUTHOR("William Wu <william.wu@rock-chips.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) MODULE_DESCRIPTION("Rockchip USB3.0 and PCIE COMBPHY driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) MODULE_LICENSE("GPL v2");