Read in the "snps,ahb-burst" property and set the internal parameter. If
this property is set, it overrides the legacy param value, except for
BCM2835, which can't set this value.

Cc: Stefan Wahren <[email protected]>
Signed-off-by: John Youn <[email protected]>
---
 drivers/usb/dwc2/core.h   |  9 +++++++
 drivers/usb/dwc2/params.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 78 insertions(+)

diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h
index 9548d3e..75c238c 100644
--- a/drivers/usb/dwc2/core.h
+++ b/drivers/usb/dwc2/core.h
@@ -430,6 +430,12 @@ enum dwc2_ep0_state {
  *                     needed.
  *                     0 - No (default)
  *                     1 - Yes
+ * @ahb_burst:          Specifies the AHB burst.
+ *                       0 - Single
+ *                       1 - INCR
+ *                       3 - INCR4 (default)
+ *                       5 - INCR8
+ *                       7 - INCR16
  * @g_dma:              Enables gadget dma usage (default: autodetect).
  * @g_dma_desc:         Enables gadget descriptor DMA (default: autodetect).
  * @g_rx_fifo_size:    The periodic rx fifo size for the device, in
@@ -507,6 +513,9 @@ struct dwc2_core_params {
         * properties and cannot be set directly in this structure.
         */
 
+       /* Global parameters */
+       u8 ahb_burst;
+
        /* Host parameters */
        bool host_dma;
 
diff --git a/drivers/usb/dwc2/params.c b/drivers/usb/dwc2/params.c
index a786256..02ccac7 100644
--- a/drivers/usb/dwc2/params.c
+++ b/drivers/usb/dwc2/params.c
@@ -93,6 +93,13 @@ static const struct dwc2_core_params params_bcm2835 = {
        .host_ls_low_power_phy_clk      = 0,    /* 48 MHz */
        .ts_dline                       = 0,
        .reload_ctl                     = 0,
+
+       /*
+        * Although this value would normally be invalid, for BCM2835,
+        * the GAHBCFG.HBSTLEN field has a different meaning from that
+        * defined by Synopsys. See the BCM2835 databook section 15.2
+        * for details.
+        */
        .ahbcfg                         = 0x10,
        .uframe_sched                   = 0,
        .external_id_pin_ctl            = -1,
@@ -1091,6 +1098,66 @@ static void dwc2_set_param_tx_fifo_sizes(struct 
dwc2_hsotg *hsotg)
        }
 }
 
+static const char *const ahb_bursts[] = {
+       [GAHBCFG_HBSTLEN_SINGLE]        = "SINGLE",
+       [GAHBCFG_HBSTLEN_INCR]          = "INCR",
+       [GAHBCFG_HBSTLEN_INCR4]         = "INCR4",
+       [GAHBCFG_HBSTLEN_INCR8]         = "INCR8",
+       [GAHBCFG_HBSTLEN_INCR16]        = "INCR16",
+};
+
+static int dwc2_get_property_ahb_burst(struct dwc2_hsotg *hsotg)
+{
+       struct device_node *node = hsotg->dev->of_node;
+       const char *str = NULL;
+       int burst;
+       int ret;
+
+       ret = device_property_read_string(hsotg->dev,
+                                         "snps,ahb-burst", &str);
+       if (ret < 0) {
+               return ret;
+       } else if (of_device_is_compatible(node, "brcm,bcm2835-usb")) {
+               dev_warn(hsotg->dev,
+                        "snps,ahb-burst is not supported on this platform");
+               return -EINVAL;
+       }
+
+       burst = match_string(ahb_bursts,
+                            ARRAY_SIZE(ahb_bursts), str);
+       if (burst < 0) {
+               dev_err(hsotg->dev,
+                       "Invalid parameter '%s' for ahb-burst\n", str);
+       }
+
+       return burst;
+}
+
+static void dwc2_set_ahb_burst(struct dwc2_hsotg *hsotg)
+{
+       struct dwc2_core_params *p = &hsotg->params;
+       int burst;
+       int ret;
+
+       /* Default burst value */
+       burst = GAHBCFG_HBSTLEN_INCR4;
+
+       /* Get the legacy param value, if set. */
+       if (p->ahbcfg != -1) {
+               burst = (p->ahbcfg & GAHBCFG_HBSTLEN_MASK) >>
+                       GAHBCFG_HBSTLEN_SHIFT;
+       }
+
+       /* Override it from devicetree, if set. */
+       ret = dwc2_get_property_ahb_burst(hsotg);
+       if (ret >= 0)
+               burst = ret;
+
+       /* Set the parameter */
+       p->ahb_burst = (u8)burst;
+       dev_dbg(hsotg->dev, "Setting ahb-burst to %d\n", burst);
+}
+
 static void dwc2_set_gadget_dma(struct dwc2_hsotg *hsotg)
 {
        struct dwc2_hw_params *hw = &hsotg->hw_params;
@@ -1171,6 +1238,8 @@ static void dwc2_set_parameters(struct dwc2_hsotg *hsotg,
        dwc2_set_param_external_id_pin_ctl(hsotg, params->external_id_pin_ctl);
        dwc2_set_param_hibernation(hsotg, params->hibernation);
 
+       dwc2_set_ahb_burst(hsotg);
+
        /*
         * Set devicetree-only parameters. These parameters do not
         * take any values from @params.
-- 
2.10.0

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to