Loading Documentation/devicetree/bindings/usb/msm-ssusb.txt +3 −0 Original line number Diff line number Diff line Loading @@ -69,6 +69,9 @@ Optional properties : events. - qcom,num-gsi-evt-buffs: If present, specifies number of GSI based hardware accelerated event buffers. 1 event buffer is needed per h/w accelerated endpoint. - qcom,gsi-reg-offset: USB GSI wrapper registers offset. It is must to provide this if qcom,num-gsi-evt-buffs property is specified. Check dwc3-msm driver for order and name of register offset need to provide. - qcom,pm-qos-latency: This represents max tolerable CPU latency in microsecs, which is used as a vote by driver to get max performance in perf mode. - qcom,smmu-s1-bypass: If present, configure SMMU to bypass stage 1 translation. Loading arch/arm64/boot/dts/qcom/kona-usb.dtsi +7 −0 Original line number Diff line number Diff line Loading @@ -42,6 +42,13 @@ qcom,core-clk-rate = <200000000>; qcom,core-clk-rate-hs = <66666667>; qcom,num-gsi-evt-buffs = <0x3>; qcom,gsi-reg-offset = <0x0fc /* GSI_GENERAL_CFG */ 0x110 /* GSI_DBL_ADDR_L */ 0x120 /* GSI_DBL_ADDR_H */ 0x130 /* GSI_RING_BASE_ADDR_L */ 0x144 /* GSI_RING_BASE_ADDR_H */ 0x1a4>; /* GSI_IF_STS */ qcom,dwc-usb3-msm-tx-fifo-size = <27696>; dwc3@a600000 { Loading drivers/usb/dwc3/dwc3-msm.c +64 −19 Original line number Diff line number Diff line Loading @@ -93,18 +93,18 @@ #define GSI_TRB_ADDR_BIT_53_MASK (1 << 21) #define GSI_TRB_ADDR_BIT_55_MASK (1 << 23) #define GSI_GENERAL_CFG_REG (QSCRATCH_REG_OFFSET + 0xFC) #define GSI_GENERAL_CFG_REG(offset) (QSCRATCH_REG_OFFSET + offset) #define GSI_RESTART_DBL_PNTR_MASK BIT(20) #define GSI_CLK_EN_MASK BIT(12) #define BLOCK_GSI_WR_GO_MASK BIT(1) #define GSI_EN_MASK BIT(0) #define GSI_DBL_ADDR_L(n) ((QSCRATCH_REG_OFFSET + 0x110) + (n*4)) #define GSI_DBL_ADDR_H(n) ((QSCRATCH_REG_OFFSET + 0x120) + (n*4)) #define GSI_RING_BASE_ADDR_L(n) ((QSCRATCH_REG_OFFSET + 0x130) + (n*4)) #define GSI_RING_BASE_ADDR_H(n) ((QSCRATCH_REG_OFFSET + 0x144) + (n*4)) #define GSI_DBL_ADDR_L(offset, n) ((QSCRATCH_REG_OFFSET + offset) + (n*4)) #define GSI_DBL_ADDR_H(offset, n) ((QSCRATCH_REG_OFFSET + offset) + (n*4)) #define GSI_RING_BASE_ADDR_L(offset, n) ((QSCRATCH_REG_OFFSET + offset) + (n*4)) #define GSI_RING_BASE_ADDR_H(offset, n) ((QSCRATCH_REG_OFFSET + offset) + (n*4)) #define GSI_IF_STS (QSCRATCH_REG_OFFSET + 0x1A4) #define GSI_IF_STS(offset) (QSCRATCH_REG_OFFSET + offset) #define GSI_WR_CTRL_STATE_MASK BIT(15) #define DWC3_GEVNTCOUNT_EVNTINTRPTMASK (1 << 31) Loading @@ -112,6 +112,16 @@ #define DWC3_GEVNTADRHI_EVNTADRHI_GSI_IDX(n) (n << 16) #define DWC3_GEVENT_TYPE_GSI 0x3 enum usb_gsi_reg { GENERAL_CFG_REG, DBL_ADDR_L, DBL_ADDR_H, RING_BASE_ADDR_L, RING_BASE_ADDR_H, IF_STS, GSI_REG_MAX, }; struct dwc3_msm_req_complete { struct list_head list_item; struct usb_request *req; Loading Loading @@ -262,6 +272,8 @@ struct dwc3_msm { struct mutex suspend_resume_mutex; enum usb_device_speed override_usb_speed; u32 *gsi_reg; int gsi_reg_offset_cnt; }; #define USB_HSPHY_3P3_VOL_MIN 3050000 /* uV */ Loading Loading @@ -926,7 +938,8 @@ static void gsi_store_ringbase_dbl_info(struct usb_ep *ep, struct dwc3_msm *mdwc = dev_get_drvdata(dwc->dev->parent); int n = ep->ep_intr_num - 1; dwc3_msm_write_reg(mdwc->base, GSI_RING_BASE_ADDR_L(n), dwc3_msm_write_reg(mdwc->base, GSI_RING_BASE_ADDR_L(mdwc->gsi_reg[RING_BASE_ADDR_L], (n)), dwc3_trb_dma_offset(dep, &dep->trb_pool[0])); if (request->mapped_db_reg_phs_addr_lsb) Loading @@ -944,12 +957,16 @@ static void gsi_store_ringbase_dbl_info(struct usb_ep *ep, ep->name, request->db_reg_phs_addr_lsb, (unsigned long long)request->mapped_db_reg_phs_addr_lsb); dwc3_msm_write_reg(mdwc->base, GSI_DBL_ADDR_L(n), dwc3_msm_write_reg(mdwc->base, GSI_DBL_ADDR_L(mdwc->gsi_reg[DBL_ADDR_L], (n)), (u32)request->mapped_db_reg_phs_addr_lsb); dev_dbg(mdwc->dev, "Ring Base Addr %d: %x (LSB)\n", n, dwc3_msm_read_reg(mdwc->base, GSI_RING_BASE_ADDR_L(n))); dwc3_msm_read_reg(mdwc->base, GSI_RING_BASE_ADDR_L(mdwc->gsi_reg[RING_BASE_ADDR_L], (n)))); dev_dbg(mdwc->dev, "GSI DB Addr %d: %x (LSB)\n", n, dwc3_msm_read_reg(mdwc->base, GSI_DBL_ADDR_L(n))); dwc3_msm_read_reg(mdwc->base, GSI_DBL_ADDR_L(mdwc->gsi_reg[DBL_ADDR_L], (n)))); } /** Loading Loading @@ -1282,14 +1299,18 @@ static void gsi_enable(struct usb_ep *ep) struct dwc3_msm *mdwc = dev_get_drvdata(dwc->dev->parent); dwc3_msm_write_reg_field(mdwc->base, GSI_GENERAL_CFG_REG, GSI_CLK_EN_MASK, 1); GSI_GENERAL_CFG_REG(mdwc->gsi_reg[GENERAL_CFG_REG]), GSI_CLK_EN_MASK, 1); dwc3_msm_write_reg_field(mdwc->base, GSI_GENERAL_CFG_REG, GSI_RESTART_DBL_PNTR_MASK, 1); GSI_GENERAL_CFG_REG(mdwc->gsi_reg[GENERAL_CFG_REG]), GSI_RESTART_DBL_PNTR_MASK, 1); dwc3_msm_write_reg_field(mdwc->base, GSI_GENERAL_CFG_REG, GSI_RESTART_DBL_PNTR_MASK, 0); GSI_GENERAL_CFG_REG(mdwc->gsi_reg[GENERAL_CFG_REG]), GSI_RESTART_DBL_PNTR_MASK, 0); dev_dbg(mdwc->dev, "%s: Enable GSI\n", __func__); dwc3_msm_write_reg_field(mdwc->base, GSI_GENERAL_CFG_REG, GSI_EN_MASK, 1); GSI_GENERAL_CFG_REG(mdwc->gsi_reg[GENERAL_CFG_REG]), GSI_EN_MASK, 1); } /** Loading @@ -1308,7 +1329,8 @@ static void gsi_set_clear_dbell(struct usb_ep *ep, struct dwc3_msm *mdwc = dev_get_drvdata(dwc->dev->parent); dwc3_msm_write_reg_field(mdwc->base, GSI_GENERAL_CFG_REG, BLOCK_GSI_WR_GO_MASK, block_db); GSI_GENERAL_CFG_REG(mdwc->gsi_reg[GENERAL_CFG_REG]), BLOCK_GSI_WR_GO_MASK, block_db); } /** Loading @@ -1325,7 +1347,7 @@ static bool gsi_check_ready_to_suspend(struct usb_ep *ep, bool f_suspend) struct dwc3_msm *mdwc = dev_get_drvdata(dwc->dev->parent); while (dwc3_msm_read_reg_field(mdwc->base, GSI_IF_STS, GSI_WR_CTRL_STATE_MASK)) { GSI_IF_STS(mdwc->gsi_reg[IF_STS]), GSI_WR_CTRL_STATE_MASK)) { if (!timeout--) { dev_err(mdwc->dev, "Unable to suspend GSI ch. WR_CTRL_STATE != 0\n"); Loading Loading @@ -3282,7 +3304,7 @@ static int dwc3_msm_probe(struct platform_device *pdev) struct dwc3 *dwc; struct resource *res; bool host_mode; int ret = 0, i; int ret = 0, size = 0, i; u32 val; unsigned long irq_type; Loading Loading @@ -3435,6 +3457,29 @@ static int dwc3_msm_probe(struct platform_device *pdev) ret = of_property_read_u32(node, "qcom,num-gsi-evt-buffs", &mdwc->num_gsi_event_buffers); if (mdwc->num_gsi_event_buffers) { of_get_property(node, "qcom,gsi-reg-offset", &size); if (size) { mdwc->gsi_reg = devm_kzalloc(dev, size, GFP_KERNEL); if (!mdwc->gsi_reg) return -ENOMEM; mdwc->gsi_reg_offset_cnt = (size / sizeof(*mdwc->gsi_reg)); if (mdwc->gsi_reg_offset_cnt != GSI_REG_MAX) { dev_err(dev, "invalid reg offset count\n"); return -EINVAL; } of_property_read_u32_array(dev->of_node, "qcom,gsi-reg-offset", mdwc->gsi_reg, mdwc->gsi_reg_offset_cnt); } else { dev_err(dev, "err provide qcom,gsi-reg-offset\n"); return -EINVAL; } } mdwc->use_pdc_interrupts = of_property_read_bool(node, "qcom,use-pdc-interrupts"); dwc3_set_notifier(&dwc3_msm_notify_event); Loading Loading
Documentation/devicetree/bindings/usb/msm-ssusb.txt +3 −0 Original line number Diff line number Diff line Loading @@ -69,6 +69,9 @@ Optional properties : events. - qcom,num-gsi-evt-buffs: If present, specifies number of GSI based hardware accelerated event buffers. 1 event buffer is needed per h/w accelerated endpoint. - qcom,gsi-reg-offset: USB GSI wrapper registers offset. It is must to provide this if qcom,num-gsi-evt-buffs property is specified. Check dwc3-msm driver for order and name of register offset need to provide. - qcom,pm-qos-latency: This represents max tolerable CPU latency in microsecs, which is used as a vote by driver to get max performance in perf mode. - qcom,smmu-s1-bypass: If present, configure SMMU to bypass stage 1 translation. Loading
arch/arm64/boot/dts/qcom/kona-usb.dtsi +7 −0 Original line number Diff line number Diff line Loading @@ -42,6 +42,13 @@ qcom,core-clk-rate = <200000000>; qcom,core-clk-rate-hs = <66666667>; qcom,num-gsi-evt-buffs = <0x3>; qcom,gsi-reg-offset = <0x0fc /* GSI_GENERAL_CFG */ 0x110 /* GSI_DBL_ADDR_L */ 0x120 /* GSI_DBL_ADDR_H */ 0x130 /* GSI_RING_BASE_ADDR_L */ 0x144 /* GSI_RING_BASE_ADDR_H */ 0x1a4>; /* GSI_IF_STS */ qcom,dwc-usb3-msm-tx-fifo-size = <27696>; dwc3@a600000 { Loading
drivers/usb/dwc3/dwc3-msm.c +64 −19 Original line number Diff line number Diff line Loading @@ -93,18 +93,18 @@ #define GSI_TRB_ADDR_BIT_53_MASK (1 << 21) #define GSI_TRB_ADDR_BIT_55_MASK (1 << 23) #define GSI_GENERAL_CFG_REG (QSCRATCH_REG_OFFSET + 0xFC) #define GSI_GENERAL_CFG_REG(offset) (QSCRATCH_REG_OFFSET + offset) #define GSI_RESTART_DBL_PNTR_MASK BIT(20) #define GSI_CLK_EN_MASK BIT(12) #define BLOCK_GSI_WR_GO_MASK BIT(1) #define GSI_EN_MASK BIT(0) #define GSI_DBL_ADDR_L(n) ((QSCRATCH_REG_OFFSET + 0x110) + (n*4)) #define GSI_DBL_ADDR_H(n) ((QSCRATCH_REG_OFFSET + 0x120) + (n*4)) #define GSI_RING_BASE_ADDR_L(n) ((QSCRATCH_REG_OFFSET + 0x130) + (n*4)) #define GSI_RING_BASE_ADDR_H(n) ((QSCRATCH_REG_OFFSET + 0x144) + (n*4)) #define GSI_DBL_ADDR_L(offset, n) ((QSCRATCH_REG_OFFSET + offset) + (n*4)) #define GSI_DBL_ADDR_H(offset, n) ((QSCRATCH_REG_OFFSET + offset) + (n*4)) #define GSI_RING_BASE_ADDR_L(offset, n) ((QSCRATCH_REG_OFFSET + offset) + (n*4)) #define GSI_RING_BASE_ADDR_H(offset, n) ((QSCRATCH_REG_OFFSET + offset) + (n*4)) #define GSI_IF_STS (QSCRATCH_REG_OFFSET + 0x1A4) #define GSI_IF_STS(offset) (QSCRATCH_REG_OFFSET + offset) #define GSI_WR_CTRL_STATE_MASK BIT(15) #define DWC3_GEVNTCOUNT_EVNTINTRPTMASK (1 << 31) Loading @@ -112,6 +112,16 @@ #define DWC3_GEVNTADRHI_EVNTADRHI_GSI_IDX(n) (n << 16) #define DWC3_GEVENT_TYPE_GSI 0x3 enum usb_gsi_reg { GENERAL_CFG_REG, DBL_ADDR_L, DBL_ADDR_H, RING_BASE_ADDR_L, RING_BASE_ADDR_H, IF_STS, GSI_REG_MAX, }; struct dwc3_msm_req_complete { struct list_head list_item; struct usb_request *req; Loading Loading @@ -262,6 +272,8 @@ struct dwc3_msm { struct mutex suspend_resume_mutex; enum usb_device_speed override_usb_speed; u32 *gsi_reg; int gsi_reg_offset_cnt; }; #define USB_HSPHY_3P3_VOL_MIN 3050000 /* uV */ Loading Loading @@ -926,7 +938,8 @@ static void gsi_store_ringbase_dbl_info(struct usb_ep *ep, struct dwc3_msm *mdwc = dev_get_drvdata(dwc->dev->parent); int n = ep->ep_intr_num - 1; dwc3_msm_write_reg(mdwc->base, GSI_RING_BASE_ADDR_L(n), dwc3_msm_write_reg(mdwc->base, GSI_RING_BASE_ADDR_L(mdwc->gsi_reg[RING_BASE_ADDR_L], (n)), dwc3_trb_dma_offset(dep, &dep->trb_pool[0])); if (request->mapped_db_reg_phs_addr_lsb) Loading @@ -944,12 +957,16 @@ static void gsi_store_ringbase_dbl_info(struct usb_ep *ep, ep->name, request->db_reg_phs_addr_lsb, (unsigned long long)request->mapped_db_reg_phs_addr_lsb); dwc3_msm_write_reg(mdwc->base, GSI_DBL_ADDR_L(n), dwc3_msm_write_reg(mdwc->base, GSI_DBL_ADDR_L(mdwc->gsi_reg[DBL_ADDR_L], (n)), (u32)request->mapped_db_reg_phs_addr_lsb); dev_dbg(mdwc->dev, "Ring Base Addr %d: %x (LSB)\n", n, dwc3_msm_read_reg(mdwc->base, GSI_RING_BASE_ADDR_L(n))); dwc3_msm_read_reg(mdwc->base, GSI_RING_BASE_ADDR_L(mdwc->gsi_reg[RING_BASE_ADDR_L], (n)))); dev_dbg(mdwc->dev, "GSI DB Addr %d: %x (LSB)\n", n, dwc3_msm_read_reg(mdwc->base, GSI_DBL_ADDR_L(n))); dwc3_msm_read_reg(mdwc->base, GSI_DBL_ADDR_L(mdwc->gsi_reg[DBL_ADDR_L], (n)))); } /** Loading Loading @@ -1282,14 +1299,18 @@ static void gsi_enable(struct usb_ep *ep) struct dwc3_msm *mdwc = dev_get_drvdata(dwc->dev->parent); dwc3_msm_write_reg_field(mdwc->base, GSI_GENERAL_CFG_REG, GSI_CLK_EN_MASK, 1); GSI_GENERAL_CFG_REG(mdwc->gsi_reg[GENERAL_CFG_REG]), GSI_CLK_EN_MASK, 1); dwc3_msm_write_reg_field(mdwc->base, GSI_GENERAL_CFG_REG, GSI_RESTART_DBL_PNTR_MASK, 1); GSI_GENERAL_CFG_REG(mdwc->gsi_reg[GENERAL_CFG_REG]), GSI_RESTART_DBL_PNTR_MASK, 1); dwc3_msm_write_reg_field(mdwc->base, GSI_GENERAL_CFG_REG, GSI_RESTART_DBL_PNTR_MASK, 0); GSI_GENERAL_CFG_REG(mdwc->gsi_reg[GENERAL_CFG_REG]), GSI_RESTART_DBL_PNTR_MASK, 0); dev_dbg(mdwc->dev, "%s: Enable GSI\n", __func__); dwc3_msm_write_reg_field(mdwc->base, GSI_GENERAL_CFG_REG, GSI_EN_MASK, 1); GSI_GENERAL_CFG_REG(mdwc->gsi_reg[GENERAL_CFG_REG]), GSI_EN_MASK, 1); } /** Loading @@ -1308,7 +1329,8 @@ static void gsi_set_clear_dbell(struct usb_ep *ep, struct dwc3_msm *mdwc = dev_get_drvdata(dwc->dev->parent); dwc3_msm_write_reg_field(mdwc->base, GSI_GENERAL_CFG_REG, BLOCK_GSI_WR_GO_MASK, block_db); GSI_GENERAL_CFG_REG(mdwc->gsi_reg[GENERAL_CFG_REG]), BLOCK_GSI_WR_GO_MASK, block_db); } /** Loading @@ -1325,7 +1347,7 @@ static bool gsi_check_ready_to_suspend(struct usb_ep *ep, bool f_suspend) struct dwc3_msm *mdwc = dev_get_drvdata(dwc->dev->parent); while (dwc3_msm_read_reg_field(mdwc->base, GSI_IF_STS, GSI_WR_CTRL_STATE_MASK)) { GSI_IF_STS(mdwc->gsi_reg[IF_STS]), GSI_WR_CTRL_STATE_MASK)) { if (!timeout--) { dev_err(mdwc->dev, "Unable to suspend GSI ch. WR_CTRL_STATE != 0\n"); Loading Loading @@ -3282,7 +3304,7 @@ static int dwc3_msm_probe(struct platform_device *pdev) struct dwc3 *dwc; struct resource *res; bool host_mode; int ret = 0, i; int ret = 0, size = 0, i; u32 val; unsigned long irq_type; Loading Loading @@ -3435,6 +3457,29 @@ static int dwc3_msm_probe(struct platform_device *pdev) ret = of_property_read_u32(node, "qcom,num-gsi-evt-buffs", &mdwc->num_gsi_event_buffers); if (mdwc->num_gsi_event_buffers) { of_get_property(node, "qcom,gsi-reg-offset", &size); if (size) { mdwc->gsi_reg = devm_kzalloc(dev, size, GFP_KERNEL); if (!mdwc->gsi_reg) return -ENOMEM; mdwc->gsi_reg_offset_cnt = (size / sizeof(*mdwc->gsi_reg)); if (mdwc->gsi_reg_offset_cnt != GSI_REG_MAX) { dev_err(dev, "invalid reg offset count\n"); return -EINVAL; } of_property_read_u32_array(dev->of_node, "qcom,gsi-reg-offset", mdwc->gsi_reg, mdwc->gsi_reg_offset_cnt); } else { dev_err(dev, "err provide qcom,gsi-reg-offset\n"); return -EINVAL; } } mdwc->use_pdc_interrupts = of_property_read_bool(node, "qcom,use-pdc-interrupts"); dwc3_set_notifier(&dwc3_msm_notify_event); Loading