usb: dwc3: core: configure TX/RX threshold for DWC3_IP
[platform/kernel/linux-starfive.git] / drivers / usb / dwc3 / core.c
index 343d257..d254909 100644 (file)
@@ -1094,6 +1094,111 @@ static void dwc3_set_power_down_clk_scale(struct dwc3 *dwc)
        }
 }
 
+static void dwc3_config_threshold(struct dwc3 *dwc)
+{
+       u32 reg;
+       u8 rx_thr_num;
+       u8 rx_maxburst;
+       u8 tx_thr_num;
+       u8 tx_maxburst;
+
+       /*
+        * Must config both number of packets and max burst settings to enable
+        * RX and/or TX threshold.
+        */
+       if (!DWC3_IP_IS(DWC3) && dwc->dr_mode == USB_DR_MODE_HOST) {
+               rx_thr_num = dwc->rx_thr_num_pkt_prd;
+               rx_maxburst = dwc->rx_max_burst_prd;
+               tx_thr_num = dwc->tx_thr_num_pkt_prd;
+               tx_maxburst = dwc->tx_max_burst_prd;
+
+               if (rx_thr_num && rx_maxburst) {
+                       reg = dwc3_readl(dwc->regs, DWC3_GRXTHRCFG);
+                       reg |= DWC31_RXTHRNUMPKTSEL_PRD;
+
+                       reg &= ~DWC31_RXTHRNUMPKT_PRD(~0);
+                       reg |= DWC31_RXTHRNUMPKT_PRD(rx_thr_num);
+
+                       reg &= ~DWC31_MAXRXBURSTSIZE_PRD(~0);
+                       reg |= DWC31_MAXRXBURSTSIZE_PRD(rx_maxburst);
+
+                       dwc3_writel(dwc->regs, DWC3_GRXTHRCFG, reg);
+               }
+
+               if (tx_thr_num && tx_maxburst) {
+                       reg = dwc3_readl(dwc->regs, DWC3_GTXTHRCFG);
+                       reg |= DWC31_TXTHRNUMPKTSEL_PRD;
+
+                       reg &= ~DWC31_TXTHRNUMPKT_PRD(~0);
+                       reg |= DWC31_TXTHRNUMPKT_PRD(tx_thr_num);
+
+                       reg &= ~DWC31_MAXTXBURSTSIZE_PRD(~0);
+                       reg |= DWC31_MAXTXBURSTSIZE_PRD(tx_maxburst);
+
+                       dwc3_writel(dwc->regs, DWC3_GTXTHRCFG, reg);
+               }
+       }
+
+       rx_thr_num = dwc->rx_thr_num_pkt;
+       rx_maxburst = dwc->rx_max_burst;
+       tx_thr_num = dwc->tx_thr_num_pkt;
+       tx_maxburst = dwc->tx_max_burst;
+
+       if (DWC3_IP_IS(DWC3)) {
+               if (rx_thr_num && rx_maxburst) {
+                       reg = dwc3_readl(dwc->regs, DWC3_GRXTHRCFG);
+                       reg |= DWC3_GRXTHRCFG_PKTCNTSEL;
+
+                       reg &= ~DWC3_GRXTHRCFG_RXPKTCNT(~0);
+                       reg |= DWC3_GRXTHRCFG_RXPKTCNT(rx_thr_num);
+
+                       reg &= ~DWC3_GRXTHRCFG_MAXRXBURSTSIZE(~0);
+                       reg |= DWC3_GRXTHRCFG_MAXRXBURSTSIZE(rx_maxburst);
+
+                       dwc3_writel(dwc->regs, DWC3_GRXTHRCFG, reg);
+               }
+
+               if (tx_thr_num && tx_maxburst) {
+                       reg = dwc3_readl(dwc->regs, DWC3_GTXTHRCFG);
+                       reg |= DWC3_GTXTHRCFG_PKTCNTSEL;
+
+                       reg &= ~DWC3_GTXTHRCFG_TXPKTCNT(~0);
+                       reg |= DWC3_GTXTHRCFG_TXPKTCNT(tx_thr_num);
+
+                       reg &= ~DWC3_GTXTHRCFG_MAXTXBURSTSIZE(~0);
+                       reg |= DWC3_GTXTHRCFG_MAXTXBURSTSIZE(tx_maxburst);
+
+                       dwc3_writel(dwc->regs, DWC3_GTXTHRCFG, reg);
+               }
+       } else {
+               if (rx_thr_num && rx_maxburst) {
+                       reg = dwc3_readl(dwc->regs, DWC3_GRXTHRCFG);
+                       reg |= DWC31_GRXTHRCFG_PKTCNTSEL;
+
+                       reg &= ~DWC31_GRXTHRCFG_RXPKTCNT(~0);
+                       reg |= DWC31_GRXTHRCFG_RXPKTCNT(rx_thr_num);
+
+                       reg &= ~DWC31_GRXTHRCFG_MAXRXBURSTSIZE(~0);
+                       reg |= DWC31_GRXTHRCFG_MAXRXBURSTSIZE(rx_maxburst);
+
+                       dwc3_writel(dwc->regs, DWC3_GRXTHRCFG, reg);
+               }
+
+               if (tx_thr_num && tx_maxburst) {
+                       reg = dwc3_readl(dwc->regs, DWC3_GTXTHRCFG);
+                       reg |= DWC31_GTXTHRCFG_PKTCNTSEL;
+
+                       reg &= ~DWC31_GTXTHRCFG_TXPKTCNT(~0);
+                       reg |= DWC31_GTXTHRCFG_TXPKTCNT(tx_thr_num);
+
+                       reg &= ~DWC31_GTXTHRCFG_MAXTXBURSTSIZE(~0);
+                       reg |= DWC31_GTXTHRCFG_MAXTXBURSTSIZE(tx_maxburst);
+
+                       dwc3_writel(dwc->regs, DWC3_GTXTHRCFG, reg);
+               }
+       }
+}
+
 /**
  * dwc3_core_init - Low-level initialization of DWC3 Core
  * @dwc: Pointer to our controller context structure
@@ -1246,42 +1351,7 @@ static int dwc3_core_init(struct dwc3 *dwc)
                dwc3_writel(dwc->regs, DWC3_GUCTL1, reg);
        }
 
-       /*
-        * Must config both number of packets and max burst settings to enable
-        * RX and/or TX threshold.
-        */
-       if (!DWC3_IP_IS(DWC3) && dwc->dr_mode == USB_DR_MODE_HOST) {
-               u8 rx_thr_num = dwc->rx_thr_num_pkt_prd;
-               u8 rx_maxburst = dwc->rx_max_burst_prd;
-               u8 tx_thr_num = dwc->tx_thr_num_pkt_prd;
-               u8 tx_maxburst = dwc->tx_max_burst_prd;
-
-               if (rx_thr_num && rx_maxburst) {
-                       reg = dwc3_readl(dwc->regs, DWC3_GRXTHRCFG);
-                       reg |= DWC31_RXTHRNUMPKTSEL_PRD;
-
-                       reg &= ~DWC31_RXTHRNUMPKT_PRD(~0);
-                       reg |= DWC31_RXTHRNUMPKT_PRD(rx_thr_num);
-
-                       reg &= ~DWC31_MAXRXBURSTSIZE_PRD(~0);
-                       reg |= DWC31_MAXRXBURSTSIZE_PRD(rx_maxburst);
-
-                       dwc3_writel(dwc->regs, DWC3_GRXTHRCFG, reg);
-               }
-
-               if (tx_thr_num && tx_maxburst) {
-                       reg = dwc3_readl(dwc->regs, DWC3_GTXTHRCFG);
-                       reg |= DWC31_TXTHRNUMPKTSEL_PRD;
-
-                       reg &= ~DWC31_TXTHRNUMPKT_PRD(~0);
-                       reg |= DWC31_TXTHRNUMPKT_PRD(tx_thr_num);
-
-                       reg &= ~DWC31_MAXTXBURSTSIZE_PRD(~0);
-                       reg |= DWC31_MAXTXBURSTSIZE_PRD(tx_maxburst);
-
-                       dwc3_writel(dwc->regs, DWC3_GTXTHRCFG, reg);
-               }
-       }
+       dwc3_config_threshold(dwc);
 
        return 0;
 
@@ -1417,6 +1487,10 @@ static void dwc3_get_properties(struct dwc3 *dwc)
        u8                      lpm_nyet_threshold;
        u8                      tx_de_emphasis;
        u8                      hird_threshold;
+       u8                      rx_thr_num_pkt = 0;
+       u8                      rx_max_burst = 0;
+       u8                      tx_thr_num_pkt = 0;
+       u8                      tx_max_burst = 0;
        u8                      rx_thr_num_pkt_prd = 0;
        u8                      rx_max_burst_prd = 0;
        u8                      tx_thr_num_pkt_prd = 0;
@@ -1479,6 +1553,14 @@ static void dwc3_get_properties(struct dwc3 *dwc)
                                "snps,usb2-lpm-disable");
        dwc->usb2_gadget_lpm_disable = device_property_read_bool(dev,
                                "snps,usb2-gadget-lpm-disable");
+       device_property_read_u8(dev, "snps,rx-thr-num-pkt",
+                               &rx_thr_num_pkt);
+       device_property_read_u8(dev, "snps,rx-max-burst",
+                               &rx_max_burst);
+       device_property_read_u8(dev, "snps,tx-thr-num-pkt",
+                               &tx_thr_num_pkt);
+       device_property_read_u8(dev, "snps,tx-max-burst",
+                               &tx_max_burst);
        device_property_read_u8(dev, "snps,rx-thr-num-pkt-prd",
                                &rx_thr_num_pkt_prd);
        device_property_read_u8(dev, "snps,rx-max-burst-prd",
@@ -1560,6 +1642,12 @@ static void dwc3_get_properties(struct dwc3 *dwc)
 
        dwc->hird_threshold = hird_threshold;
 
+       dwc->rx_thr_num_pkt = rx_thr_num_pkt;
+       dwc->rx_max_burst = rx_max_burst;
+
+       dwc->tx_thr_num_pkt = tx_thr_num_pkt;
+       dwc->tx_max_burst = tx_max_burst;
+
        dwc->rx_thr_num_pkt_prd = rx_thr_num_pkt_prd;
        dwc->rx_max_burst_prd = rx_max_burst_prd;