#include <linux/reset.h>
#include <linux/usb/otg.h>
-#define USB_STRAP_HOST 0x20000U
-#define USB_STRAP_DEVICE 0x40000U
+#define USB_STRAP_HOST (2 << 0x10)
+#define USB_STRAP_DEVICE (4 << 0X10)
#define USB_STRAP_MASK 0x70000U
-#define USB_SUSPENDM_HOST 0x80000U
-#define USB_SUSPENDM_DEVICE 0x0U
+#define USB_SUSPENDM_HOST (1 << 0x13)
+#define USB_SUSPENDM_DEVICE (0 << 0x13)
#define USB_SUSPENDM_MASK 0x80000U
-#define USB_SUSPENDM_BYPS_VALUE 0x100000U
-#define USB_SUSPENDM_BYPS_MASK 0x100000U
+#define USB_SUSPENDM_BYPS_SHIFT 0x14U
+#define USB_SUSPENDM_BYPS_MASK 0x100000U
-#define USB_REFCLK_MODE_VALUE 0x800000U
+#define USB_REFCLK_MODE_SHIFT 0x17U
#define USB_REFCLK_MODE_MASK 0x800000U
-#define USB_PLL_EN_VALUE 0x400000U
+#define USB_PLL_EN_SHIFT 0x16U
#define USB_PLL_EN_MASK 0x400000U
-#define USB_PDRSTN_SPLIT_USB30 0x20000U
-#define USB_PDRSTN_SPLIT_USB20 0x0U
+#define USB_PDRSTN_SPLIT_SHIFT 0x11
#define USB_PDRSTN_SPLIT_MASK 0x20000U
+#define PCIE_CKREF_SRC_SHIFT 0x12U
+#define PCIE_CKREF_SRC_MASK 0xC0000U
+#define PCIE_CLK_SEL_SHIFT 0x14U
+#define PCIE_CLK_SEL_MASK 0x300000U
+#define PCIE_PHY_MODE_SHIFT 0x14U
+#define PCIE_PHY_MODE_MASK 0x300000U
+#define PCIE_USB3_BUS_WIDTH_SHIFT 0x2U
+#define PCIE_USB3_BUS_WIDTH_MASK 0xCU
+#define PCIE_USB3_RATE_SHIFT 0x5U
+#define PCIE_USB3_RATE_MASK 0x60U
+#define PCIE_USB3_RX_STANDBY_SHIFT 0x7U
+#define PCIE_USB3_RX_STANDBY_MASK 0x80U
+#define PCIE_USB3_PHY_ENABLE_SHIFT 0x4U
+#define PCIE_USB3_PHY_ENABLE_MASK 0x10U
+
struct cdns_starfive {
struct device *dev;
struct regmap *stg_syscon;
struct clk_bulk_data *clks;
int num_clks;
u32 sys_offset;
- u32 stg_offset;
+ u32 stg_offset_4;
+ u32 stg_offset_196;
+ u32 stg_offset_328;
+ u32 stg_offset_500;
+ bool usb2_only;
};
static int cdns_mode_init(struct platform_device *pdev,
{
enum usb_dr_mode mode;
- regmap_update_bits(data->stg_syscon, data->stg_offset,
- USB_SUSPENDM_BYPS_MASK, USB_SUSPENDM_BYPS_VALUE);
- regmap_update_bits(data->stg_syscon, data->stg_offset,
- USB_PLL_EN_MASK, USB_PLL_EN_VALUE);
- regmap_update_bits(data->stg_syscon, data->stg_offset,
- USB_REFCLK_MODE_MASK, USB_REFCLK_MODE_VALUE);
- regmap_update_bits(data->stg_syscon, data->stg_offset,
- USB_PDRSTN_SPLIT_MASK, USB_PDRSTN_SPLIT_USB30);
-
+ /*usb 2.0 utmi phy init*/
+ regmap_update_bits(data->stg_syscon, data->stg_offset_4,
+ USB_SUSPENDM_BYPS_MASK, BIT(USB_SUSPENDM_BYPS_SHIFT));
+ regmap_update_bits(data->stg_syscon, data->stg_offset_4,
+ USB_PLL_EN_MASK, BIT(USB_PLL_EN_SHIFT));
+ regmap_update_bits(data->stg_syscon, data->stg_offset_4,
+ USB_REFCLK_MODE_MASK, BIT(USB_REFCLK_MODE_SHIFT));
+
+ if (data->usb2_only) {
+
+ /* disconnect usb 3.0 phy mode */
+ regmap_update_bits(data->sys_syscon, data->sys_offset,
+ USB_PDRSTN_SPLIT_MASK, BIT(USB_PDRSTN_SPLIT_SHIFT));
+ } else {
+ /*usb 3.0 pipe phy config*/
+ regmap_update_bits(data->stg_syscon, data->stg_offset_196,
+ PCIE_CKREF_SRC_MASK, (0<<PCIE_CKREF_SRC_SHIFT));
+ regmap_update_bits(data->stg_syscon, data->stg_offset_196,
+ PCIE_CLK_SEL_MASK, (0<<PCIE_CLK_SEL_SHIFT));
+ regmap_update_bits(data->stg_syscon, data->stg_offset_328,
+ PCIE_PHY_MODE_MASK, BIT(PCIE_PHY_MODE_SHIFT));
+ regmap_update_bits(data->stg_syscon, data->stg_offset_500,
+ PCIE_USB3_BUS_WIDTH_MASK, (0 << PCIE_USB3_BUS_WIDTH_SHIFT));
+ regmap_update_bits(data->stg_syscon, data->stg_offset_500,
+ PCIE_USB3_RATE_MASK, (0 << PCIE_USB3_RATE_SHIFT));
+ regmap_update_bits(data->stg_syscon, data->stg_offset_500,
+ PCIE_USB3_RX_STANDBY_MASK, (0 << PCIE_USB3_RX_STANDBY_SHIFT));
+ regmap_update_bits(data->stg_syscon, data->stg_offset_500,
+ PCIE_USB3_PHY_ENABLE_MASK, BIT(PCIE_USB3_PHY_ENABLE_SHIFT));
+
+ /* connect usb 3.0 phy mode */
+ regmap_update_bits(data->sys_syscon, data->sys_offset,
+ USB_PDRSTN_SPLIT_MASK, (0 << USB_PDRSTN_SPLIT_SHIFT));
+ }
mode = usb_get_dr_mode(&pdev->dev);
switch (mode) {
case USB_DR_MODE_HOST:
- regmap_update_bits(data->stg_syscon, data->stg_offset,
- USB_STRAP_MASK, USB_STRAP_HOST);
- regmap_update_bits(data->stg_syscon, data->stg_offset,
- USB_SUSPENDM_MASK, USB_SUSPENDM_HOST);
+ regmap_update_bits(data->stg_syscon,
+ data->stg_offset_4,
+ USB_STRAP_MASK,
+ USB_STRAP_HOST);
+ regmap_update_bits(data->stg_syscon,
+ data->stg_offset_4,
+ USB_SUSPENDM_MASK,
+ USB_SUSPENDM_HOST);
break;
case USB_DR_MODE_PERIPHERAL:
- regmap_update_bits(data->stg_syscon, data->stg_offset,
+ regmap_update_bits(data->stg_syscon, data->stg_offset_4,
USB_STRAP_MASK, USB_STRAP_DEVICE);
- regmap_update_bits(data->stg_syscon, data->stg_offset,
+ regmap_update_bits(data->stg_syscon, data->stg_offset_4,
USB_SUSPENDM_MASK, USB_SUSPENDM_DEVICE);
break;
data->dev = dev;
- ret = cdns_clk_rst_init(data);
- if (ret < 0) {
- dev_err(&pdev->dev, "Failed to init usb clk reset: %d\n", ret);
- goto exit;
- }
-
+ data->usb2_only = device_property_read_bool(dev, "starfive,usb2-only");
ret = of_parse_phandle_with_fixed_args(pdev->dev.of_node,
- "starfive,stg-syscon", 1, 0, &args);
+ "starfive,stg-syscon", 4, 0, &args);
if (ret < 0) {
dev_err(dev, "Failed to parse starfive,stg-syscon\n");
return -EINVAL;
of_node_put(args.np);
if (IS_ERR(data->stg_syscon))
return PTR_ERR(data->stg_syscon);
- data->stg_offset = args.args[0];
+ data->stg_offset_4 = args.args[0];
+ data->stg_offset_196 = args.args[1];
+ data->stg_offset_328 = args.args[2];
+ data->stg_offset_500 = args.args[3];
ret = of_parse_phandle_with_fixed_args(pdev->dev.of_node,
"starfive,sys-syscon", 1, 0, &args);
cdns_mode_init(pdev, data);
+ ret = cdns_clk_rst_init(data);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "Failed to init usb clk reset: %d\n", ret);
+ goto exit;
+ }
+
ret = of_platform_populate(node, NULL, NULL, dev);
if (ret) {
dev_err(dev, "failed to create children: %d\n", ret);