From 5f9f975b7984ffec0a25f55e58246aebf68794f4 Mon Sep 17 00:00:00 2001 From: Mark Knibbs Date: Sat, 4 Oct 2014 12:19:59 +0100 Subject: USB: serial: keyspan_pda: fix Entrega company name spelling Entrega is misspelled as Entregra or Entrgra, so fix that. Signed-off-by: Mark Knibbs Signed-off-by: Johan Hovold --- Documentation/usb/usb-serial.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/usb/usb-serial.txt b/Documentation/usb/usb-serial.txt index 5bd7926185e8..947fa62bccf2 100644 --- a/Documentation/usb/usb-serial.txt +++ b/Documentation/usb/usb-serial.txt @@ -145,7 +145,7 @@ Keyspan PDA Serial Adapter Single port DB-9 serial adapter, pushed as a PDA adapter for iMacs (mostly sold in Macintosh catalogs, comes in a translucent white/green dongle). Fairly simple device. Firmware is homebrew. - This driver also works for the Xircom/Entrgra single port serial adapter. + This driver also works for the Xircom/Entrega single port serial adapter. Current status: Things that work: -- cgit v1.2.3-59-g8ed1b From f2918ad89df5a5deb4773e13b5f6e21eabfce282 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Fri, 10 Oct 2014 15:21:56 -0500 Subject: usb: gadget: udc: document our sysfs ABI I noticed that this has been missing for quite some time so I decided it was about time to document it. Signed-off-by: Felipe Balbi --- Documentation/ABI/stable/sysfs-class-udc | 93 ++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 Documentation/ABI/stable/sysfs-class-udc (limited to 'Documentation') diff --git a/Documentation/ABI/stable/sysfs-class-udc b/Documentation/ABI/stable/sysfs-class-udc new file mode 100644 index 000000000000..85d3dac2e204 --- /dev/null +++ b/Documentation/ABI/stable/sysfs-class-udc @@ -0,0 +1,93 @@ +What: /sys/class/udc//a_alt_hnp_support +Date: June 2011 +KernelVersion: 3.1 +Contact: Felipe Balbi +Description: + Indicates if an OTG A-Host supports HNP at an alternate port. +Users: + +What: /sys/class/udc//a_hnp_support +Date: June 2011 +KernelVersion: 3.1 +Contact: Felipe Balbi +Description: + Indicates if an OTG A-Host supports HNP at this port. +Users: + +What: /sys/class/udc//b_hnp_enable +Date: June 2011 +KernelVersion: 3.1 +Contact: Felipe Balbi +Description: + Indicates if an OTG A-Host enabled HNP support. +Users: + +What: /sys/class/udc//current_speed +Date: June 2011 +KernelVersion: 3.1 +Contact: Felipe Balbi +Description: + Indicates the current negotiated speed at this port. +Users: + +What: /sys/class/udc//is_a_peripheral +Date: June 2011 +KernelVersion: 3.1 +Contact: Felipe Balbi +Description: + Indicates that this port is the default Host on an OTG session + but HNP was used to switch roles. +Users: + +What: /sys/class/udc//is_otg +Date: June 2011 +KernelVersion: 3.1 +Contact: Felipe Balbi +Description: + Indicates that this port support OTG. +Users: + +What: /sys/class/udc//maximum_speed +Date: June 2011 +KernelVersion: 3.1 +Contact: Felipe Balbi +Description: + Indicates the maximum USB speed supported by this port. +Users: + +What: /sys/class/udc//maximum_speed +Date: June 2011 +KernelVersion: 3.1 +Contact: Felipe Balbi +Description: + Indicates the maximum USB speed supported by this port. +Users: + +What: /sys/class/udc//soft_connect +Date: June 2011 +KernelVersion: 3.1 +Contact: Felipe Balbi +Description: + Allows users to disconnect data pullup resistors thus causing a + logical disconnection from the USB Host. +Users: + +What: /sys/class/udc//srp +Date: June 2011 +KernelVersion: 3.1 +Contact: Felipe Balbi +Description: + Allows users to manually start Session Request Protocol. +Users: + +What: /sys/class/udc//state +Date: June 2011 +KernelVersion: 3.1 +Contact: Felipe Balbi +Description: + Indicates current state of the USB Device Controller. Valid + states are: 'not-attached', 'attached', 'powered', + 'reconnecting', 'unauthenticated', 'default', 'addressed', + 'configured', and 'suspended'; however not all USB Device + Controllers support reporting all states. +Users: -- cgit v1.2.3-59-g8ed1b From 545d64a46c1ed04eb96802a3bf5b6627c4d28dbd Mon Sep 17 00:00:00 2001 From: Robert Jarzmik Date: Fri, 17 Oct 2014 22:43:04 +0200 Subject: usb: gadget: pxa27x_udc device-tree documentation Add documentation for device-tree binding of arm PXA 27x udc (usb device) driver. Signed-off-by: Robert Jarzmik Cc: devicetree@vger.kernel.org Acked-by: Arnd Bergmann Signed-off-by: Felipe Balbi --- Documentation/devicetree/bindings/usb/pxa-usb.txt | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/usb/pxa-usb.txt b/Documentation/devicetree/bindings/usb/pxa-usb.txt index 79729a948d5a..9c331799b87c 100644 --- a/Documentation/devicetree/bindings/usb/pxa-usb.txt +++ b/Documentation/devicetree/bindings/usb/pxa-usb.txt @@ -29,3 +29,25 @@ Example: marvell,port-mode = <2>; /* PMM_GLOBAL_MODE */ }; +UDC + +Required properties: + - compatible: Should be "marvell,pxa270-udc" for USB controllers + used in device mode. + - reg: usb device MMIO address space + - interrupts: single interrupt generated by the UDC IP + - clocks: input clock of the UDC IP (see clock-bindings.txt) + +Optional properties: + - gpios: + - gpio activated to control the USB D+ pullup (see gpio.txt) + +Example: + + pxa27x_udc: udc@40600000 { + compatible = "marvell,pxa270-udc"; + reg = <0x40600000 0x10000>; + interrupts = <11>; + clocks = <&pxa2xx_clks 11>; + gpios = <&gpio 22 GPIO_ACTIVE_LOW>; + }; -- cgit v1.2.3-59-g8ed1b From 3b81221a529c087171557d7c4aec02b0ba029bb1 Mon Sep 17 00:00:00 2001 From: Huang Rui Date: Tue, 28 Oct 2014 19:54:25 +0800 Subject: usb: dwc3: add disscramble quirk This patch adds disscramble quirk, and it only needs to be enabled at fpga board on some vendor platforms. Signed-off-by: Huang Rui Signed-off-by: Felipe Balbi --- Documentation/devicetree/bindings/usb/dwc3.txt | 2 ++ drivers/usb/dwc3/core.c | 14 +++++++++++++- drivers/usb/dwc3/core.h | 3 +++ drivers/usb/dwc3/platform_data.h | 2 ++ 4 files changed, 20 insertions(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/usb/dwc3.txt b/Documentation/devicetree/bindings/usb/dwc3.txt index 471366d6a129..8ec2256a4a09 100644 --- a/Documentation/devicetree/bindings/usb/dwc3.txt +++ b/Documentation/devicetree/bindings/usb/dwc3.txt @@ -14,6 +14,8 @@ Optional properties: - phys: from the *Generic PHY* bindings - phy-names: from the *Generic PHY* bindings - tx-fifo-resize: determines if the FIFO *has* to be reallocated. + - snps,disable_scramble_quirk: true when SW should disable data scrambling. + Only really useful for FPGA builds. This is usually a subnode to DWC3 glue to which it is connected. diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 9830f87b6940..a0ae1326b7e3 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -422,7 +422,6 @@ static int dwc3_core_init(struct dwc3 *dwc) reg = dwc3_readl(dwc->regs, DWC3_GCTL); reg &= ~DWC3_GCTL_SCALEDOWN_MASK; - reg &= ~DWC3_GCTL_DISSCRAMBLE; switch (DWC3_GHWPARAMS1_EN_PWROPT(dwc->hwparams.hwparams1)) { case DWC3_GHWPARAMS1_EN_PWROPT_CLK: @@ -466,6 +465,14 @@ static int dwc3_core_init(struct dwc3 *dwc) dwc->is_fpga = true; } + WARN_ONCE(dwc->disable_scramble_quirk && !dwc->is_fpga, + "disable_scramble cannot be used on non-FPGA builds\n"); + + if (dwc->disable_scramble_quirk && dwc->is_fpga) + reg |= DWC3_GCTL_DISSCRAMBLE; + else + reg &= ~DWC3_GCTL_DISSCRAMBLE; + /* * WORKAROUND: DWC3 revisions <1.90a have a bug * where the device can fail to connect at SuperSpeed @@ -710,11 +717,16 @@ static int dwc3_probe(struct platform_device *pdev) dwc->needs_fifo_resize = of_property_read_bool(node, "tx-fifo-resize"); dwc->dr_mode = of_usb_get_dr_mode(node); + + dwc->disable_scramble_quirk = of_property_read_bool(node, + "snps,disable_scramble_quirk"); } else if (pdata) { dwc->maximum_speed = pdata->maximum_speed; dwc->needs_fifo_resize = pdata->tx_fifo_resize; dwc->dr_mode = pdata->dr_mode; + + dwc->disable_scramble_quirk = pdata->disable_scramble_quirk; } /* default to superspeed if no maximum_speed passed */ diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index f6ee623e2d1b..56bada6c8604 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -672,6 +672,7 @@ struct dwc3_scratchpad_array { * @setup_packet_pending: true when there's a Setup Packet in FIFO. Workaround * @start_config_issued: true when StartConfig command has been issued * @three_stage_setup: set if we perform a three phase setup + * @disable_scramble_quirk: set if we enable the disable scramble quirk */ struct dwc3 { struct usb_ctrlrequest *ctrl_req; @@ -776,6 +777,8 @@ struct dwc3 { unsigned setup_packet_pending:1; unsigned start_config_issued:1; unsigned three_stage_setup:1; + + unsigned disable_scramble_quirk:1; }; /* -------------------------------------------------------------------------- */ diff --git a/drivers/usb/dwc3/platform_data.h b/drivers/usb/dwc3/platform_data.h index 7db34f00b89a..9209d025597b 100644 --- a/drivers/usb/dwc3/platform_data.h +++ b/drivers/usb/dwc3/platform_data.h @@ -24,4 +24,6 @@ struct dwc3_platform_data { enum usb_device_speed maximum_speed; enum usb_dr_mode dr_mode; bool tx_fifo_resize; + + unsigned disable_scramble_quirk:1; }; -- cgit v1.2.3-59-g8ed1b From 80caf7d21adca10c4621d511f6eb01f7ed2b342c Mon Sep 17 00:00:00 2001 From: Huang Rui Date: Tue, 28 Oct 2014 19:54:26 +0800 Subject: usb: dwc3: add lpm erratum support When parameter DWC_USB3_LPM_ERRATA_ENABLE is enabled in Andvanced Configuration of coreConsultant, it supports of xHCI BESL Errata Dated 10/19/2011 is enabled in host mode. In device mode it adds the capability to send NYET response threshold based on the BESL value received in the LPM token, and the threhold is configurable for each soc platform. This patch adds an entry that soc platform is able to define the lpm capacity with their own device tree or bus glue layer. [ balbi@ti.com : added devicetree documentation, spelled threshold completely, made sure threshold is only applied to proper core revisions. ] Signed-off-by: Huang Rui Signed-off-by: Felipe Balbi --- Documentation/devicetree/bindings/usb/dwc3.txt | 2 ++ drivers/usb/dwc3/core.c | 16 +++++++++++++++- drivers/usb/dwc3/core.h | 26 +++++++++++++++++--------- drivers/usb/dwc3/gadget.c | 13 +++++++++++++ drivers/usb/dwc3/platform_data.h | 3 +++ 5 files changed, 50 insertions(+), 10 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/usb/dwc3.txt b/Documentation/devicetree/bindings/usb/dwc3.txt index 8ec2256a4a09..2b0c1f2e6e27 100644 --- a/Documentation/devicetree/bindings/usb/dwc3.txt +++ b/Documentation/devicetree/bindings/usb/dwc3.txt @@ -16,6 +16,8 @@ Optional properties: - tx-fifo-resize: determines if the FIFO *has* to be reallocated. - snps,disable_scramble_quirk: true when SW should disable data scrambling. Only really useful for FPGA builds. + - snps,has-lpm-erratum: true when DWC3 was configured with LPM Erratum enabled + - snps,lpm-nyet-threshold: LPM NYET threshold This is usually a subnode to DWC3 glue to which it is connected. diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index a0ae1326b7e3..6f9e5b85977a 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -657,6 +657,7 @@ static int dwc3_probe(struct platform_device *pdev) struct device_node *node = dev->of_node; struct resource *res; struct dwc3 *dwc; + u8 lpm_nyet_threshold; int ret; @@ -712,16 +713,27 @@ static int dwc3_probe(struct platform_device *pdev) */ res->start -= DWC3_GLOBALS_REGS_START; + /* default to highest possible threshold */ + lpm_nyet_threshold = 0xff; + if (node) { dwc->maximum_speed = of_usb_get_maximum_speed(node); + dwc->has_lpm_erratum = of_property_read_bool(node, + "snps,has-lpm-erratum"); + of_property_read_u8(node, "snps,lpm-nyet-threshold", + &lpm_nyet_threshold); - dwc->needs_fifo_resize = of_property_read_bool(node, "tx-fifo-resize"); + dwc->needs_fifo_resize = of_property_read_bool(node, + "tx-fifo-resize"); dwc->dr_mode = of_usb_get_dr_mode(node); dwc->disable_scramble_quirk = of_property_read_bool(node, "snps,disable_scramble_quirk"); } else if (pdata) { dwc->maximum_speed = pdata->maximum_speed; + dwc->has_lpm_erratum = pdata->has_lpm_erratum; + if (pdata->lpm_nyet_threshold) + lpm_nyet_threshold = pdata->lpm_nyet_threshold; dwc->needs_fifo_resize = pdata->tx_fifo_resize; dwc->dr_mode = pdata->dr_mode; @@ -733,6 +745,8 @@ static int dwc3_probe(struct platform_device *pdev) if (dwc->maximum_speed == USB_SPEED_UNKNOWN) dwc->maximum_speed = USB_SPEED_SUPER; + dwc->lpm_nyet_threshold = lpm_nyet_threshold; + ret = dwc3_core_get_phy(dwc); if (ret) return ret; diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index 56bada6c8604..34f1e08988fe 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -246,16 +246,19 @@ #define DWC3_DCTL_TRGTULST_SS_INACT (DWC3_DCTL_TRGTULST(6)) /* These apply for core versions 1.94a and later */ -#define DWC3_DCTL_KEEP_CONNECT (1 << 19) -#define DWC3_DCTL_L1_HIBER_EN (1 << 18) -#define DWC3_DCTL_CRS (1 << 17) -#define DWC3_DCTL_CSS (1 << 16) +#define DWC3_DCTL_LPM_ERRATA_MASK DWC3_DCTL_LPM_ERRATA(0xf) +#define DWC3_DCTL_LPM_ERRATA(n) ((n) << 20) -#define DWC3_DCTL_INITU2ENA (1 << 12) -#define DWC3_DCTL_ACCEPTU2ENA (1 << 11) -#define DWC3_DCTL_INITU1ENA (1 << 10) -#define DWC3_DCTL_ACCEPTU1ENA (1 << 9) -#define DWC3_DCTL_TSTCTRL_MASK (0xf << 1) +#define DWC3_DCTL_KEEP_CONNECT (1 << 19) +#define DWC3_DCTL_L1_HIBER_EN (1 << 18) +#define DWC3_DCTL_CRS (1 << 17) +#define DWC3_DCTL_CSS (1 << 16) + +#define DWC3_DCTL_INITU2ENA (1 << 12) +#define DWC3_DCTL_ACCEPTU2ENA (1 << 11) +#define DWC3_DCTL_INITU1ENA (1 << 10) +#define DWC3_DCTL_ACCEPTU1ENA (1 << 9) +#define DWC3_DCTL_TSTCTRL_MASK (0xf << 1) #define DWC3_DCTL_ULSTCHNGREQ_MASK (0x0f << 5) #define DWC3_DCTL_ULSTCHNGREQ(n) (((n) << 5) & DWC3_DCTL_ULSTCHNGREQ_MASK) @@ -660,10 +663,13 @@ struct dwc3_scratchpad_array { * @regset: debugfs pointer to regdump file * @test_mode: true when we're entering a USB test mode * @test_mode_nr: test feature selector + * @lpm_nyet_threshold: LPM NYET response threshold * @delayed_status: true when gadget driver asks for delayed status * @ep0_bounced: true when we used bounce buffer * @ep0_expect_in: true when we expect a DATA IN transfer * @has_hibernation: true when dwc3 was configured with Hibernation + * @has_lpm_erratum: true when core was configured with LPM Erratum. Note that + * there's now way for software to detect this in runtime. * @is_selfpowered: true when we are selfpowered * @is_fpga: true when we are using the FPGA board * @needs_fifo_resize: not all users might want fifo resizing, flag it @@ -764,11 +770,13 @@ struct dwc3 { u8 test_mode; u8 test_mode_nr; + u8 lpm_nyet_threshold; unsigned delayed_status:1; unsigned ep0_bounced:1; unsigned ep0_expect_in:1; unsigned has_hibernation:1; + unsigned has_lpm_erratum:1; unsigned is_selfpowered:1; unsigned is_fpga:1; unsigned needs_fifo_resize:1; diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 20dda60b27c3..88a065f61150 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -2301,6 +2301,19 @@ static void dwc3_gadget_conndone_interrupt(struct dwc3 *dwc) */ reg |= DWC3_DCTL_HIRD_THRES(12); + /* + * When dwc3 revisions >= 2.40a, LPM Erratum is enabled and + * DCFG.LPMCap is set, core responses with an ACK and the + * BESL value in the LPM token is less than or equal to LPM + * NYET threshold. + */ + WARN_ONCE(dwc->revision < DWC3_REVISION_240A + && dwc->has_lpm_erratum, + "LPM Erratum not available on dwc3 revisisions < 2.40a\n"); + + if (dwc->has_lpm_erratum && dwc->revision >= DWC3_REVISION_240A) + reg |= DWC3_DCTL_LPM_ERRATA(dwc->lpm_nyet_threshold); + dwc3_writel(dwc->regs, DWC3_DCTL, reg); } else { reg = dwc3_readl(dwc->regs, DWC3_DCTL); diff --git a/drivers/usb/dwc3/platform_data.h b/drivers/usb/dwc3/platform_data.h index 9209d025597b..e1283080a49f 100644 --- a/drivers/usb/dwc3/platform_data.h +++ b/drivers/usb/dwc3/platform_data.h @@ -25,5 +25,8 @@ struct dwc3_platform_data { enum usb_dr_mode dr_mode; bool tx_fifo_resize; + u8 lpm_nyet_threshold; + unsigned disable_scramble_quirk:1; + unsigned has_lpm_erratum:1; }; -- cgit v1.2.3-59-g8ed1b From 9a5b2f3167c1f98b879d6a800ab138f04e34f9d5 Mon Sep 17 00:00:00 2001 From: Huang Rui Date: Tue, 28 Oct 2014 19:54:27 +0800 Subject: usb: dwc3: add u2exit lfps quirk This patch adds u2exit lfps quirk, and some special platforms can configure that if it is needed. [ balbi@ti.com : added DeviceTree binding documentation ] Signed-off-by: Huang Rui Signed-off-by: Felipe Balbi --- Documentation/devicetree/bindings/usb/dwc3.txt | 1 + drivers/usb/dwc3/core.c | 6 ++++++ drivers/usb/dwc3/core.h | 3 +++ drivers/usb/dwc3/platform_data.h | 1 + 4 files changed, 11 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/usb/dwc3.txt b/Documentation/devicetree/bindings/usb/dwc3.txt index 2b0c1f2e6e27..5fcd68008945 100644 --- a/Documentation/devicetree/bindings/usb/dwc3.txt +++ b/Documentation/devicetree/bindings/usb/dwc3.txt @@ -18,6 +18,7 @@ Optional properties: Only really useful for FPGA builds. - snps,has-lpm-erratum: true when DWC3 was configured with LPM Erratum enabled - snps,lpm-nyet-threshold: LPM NYET threshold + - snps,u2exit_lfps_quirk: set if we want to enable u2exit lfps quirk This is usually a subnode to DWC3 glue to which it is connected. diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 6f9e5b85977a..33cbea5c6dda 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -473,6 +473,9 @@ static int dwc3_core_init(struct dwc3 *dwc) else reg &= ~DWC3_GCTL_DISSCRAMBLE; + if (dwc->u2exit_lfps_quirk) + reg |= DWC3_GCTL_U2EXIT_LFPS; + /* * WORKAROUND: DWC3 revisions <1.90a have a bug * where the device can fail to connect at SuperSpeed @@ -729,6 +732,8 @@ static int dwc3_probe(struct platform_device *pdev) dwc->disable_scramble_quirk = of_property_read_bool(node, "snps,disable_scramble_quirk"); + dwc->u2exit_lfps_quirk = of_property_read_bool(node, + "snps,u2exit_lfps_quirk"); } else if (pdata) { dwc->maximum_speed = pdata->maximum_speed; dwc->has_lpm_erratum = pdata->has_lpm_erratum; @@ -739,6 +744,7 @@ static int dwc3_probe(struct platform_device *pdev) dwc->dr_mode = pdata->dr_mode; dwc->disable_scramble_quirk = pdata->disable_scramble_quirk; + dwc->u2exit_lfps_quirk = pdata->u2exit_lfps_quirk; } /* default to superspeed if no maximum_speed passed */ diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index 34f1e08988fe..f93145cb52f5 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -166,6 +166,7 @@ #define DWC3_GCTL_SCALEDOWN(n) ((n) << 4) #define DWC3_GCTL_SCALEDOWN_MASK DWC3_GCTL_SCALEDOWN(3) #define DWC3_GCTL_DISSCRAMBLE (1 << 3) +#define DWC3_GCTL_U2EXIT_LFPS (1 << 2) #define DWC3_GCTL_GBLHIBERNATIONEN (1 << 1) #define DWC3_GCTL_DSBLCLKGTNG (1 << 0) @@ -679,6 +680,7 @@ struct dwc3_scratchpad_array { * @start_config_issued: true when StartConfig command has been issued * @three_stage_setup: set if we perform a three phase setup * @disable_scramble_quirk: set if we enable the disable scramble quirk + * @u2exit_lfps_quirk: set if we enable u2exit lfps quirk */ struct dwc3 { struct usb_ctrlrequest *ctrl_req; @@ -787,6 +789,7 @@ struct dwc3 { unsigned three_stage_setup:1; unsigned disable_scramble_quirk:1; + unsigned u2exit_lfps_quirk:1; }; /* -------------------------------------------------------------------------- */ diff --git a/drivers/usb/dwc3/platform_data.h b/drivers/usb/dwc3/platform_data.h index e1283080a49f..3f2159108f7d 100644 --- a/drivers/usb/dwc3/platform_data.h +++ b/drivers/usb/dwc3/platform_data.h @@ -29,4 +29,5 @@ struct dwc3_platform_data { unsigned disable_scramble_quirk:1; unsigned has_lpm_erratum:1; + unsigned u2exit_lfps_quirk:1; }; -- cgit v1.2.3-59-g8ed1b From b5a65c406367e3e79ece6f687c83d4ffce4c174c Mon Sep 17 00:00:00 2001 From: Huang Rui Date: Tue, 28 Oct 2014 19:54:28 +0800 Subject: usb: dwc3: add P3 in U2 SS inactive quirk This patch adds P3 in U2 SS inactive quirk, and some special platforms can configure that if it is needed. [ balbi@ti.com : added DeviceTree binding documentation ] Signed-off-by: Huang Rui Signed-off-by: Felipe Balbi --- Documentation/devicetree/bindings/usb/dwc3.txt | 1 + drivers/usb/dwc3/core.c | 23 +++++++++++++++++++++++ drivers/usb/dwc3/core.h | 3 +++ drivers/usb/dwc3/platform_data.h | 1 + 4 files changed, 28 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/usb/dwc3.txt b/Documentation/devicetree/bindings/usb/dwc3.txt index 5fcd68008945..36e4287c40f5 100644 --- a/Documentation/devicetree/bindings/usb/dwc3.txt +++ b/Documentation/devicetree/bindings/usb/dwc3.txt @@ -19,6 +19,7 @@ Optional properties: - snps,has-lpm-erratum: true when DWC3 was configured with LPM Erratum enabled - snps,lpm-nyet-threshold: LPM NYET threshold - snps,u2exit_lfps_quirk: set if we want to enable u2exit lfps quirk + - snps,u2ss_inp3_quirk: set if we enable P3 OK for U2/SS Inactive quirk This is usually a subnode to DWC3 glue to which it is connected. diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 33cbea5c6dda..7c54da187062 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -364,6 +364,24 @@ static void dwc3_cache_hwparams(struct dwc3 *dwc) parms->hwparams8 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS8); } +/** + * dwc3_phy_setup - Configure USB PHY Interface of DWC3 Core + * @dwc: Pointer to our controller context structure + */ +static void dwc3_phy_setup(struct dwc3 *dwc) +{ + u32 reg; + + reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0)); + + if (dwc->u2ss_inp3_quirk) + reg |= DWC3_GUSB3PIPECTL_U2SSINP3OK; + + dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg); + + mdelay(100); +} + /** * dwc3_core_init - Low-level initialization of DWC3 Core * @dwc: Pointer to our controller context structure @@ -489,6 +507,8 @@ static int dwc3_core_init(struct dwc3 *dwc) dwc3_writel(dwc->regs, DWC3_GCTL, reg); + dwc3_phy_setup(dwc); + ret = dwc3_alloc_scratch_buffers(dwc); if (ret) goto err1; @@ -734,6 +754,8 @@ static int dwc3_probe(struct platform_device *pdev) "snps,disable_scramble_quirk"); dwc->u2exit_lfps_quirk = of_property_read_bool(node, "snps,u2exit_lfps_quirk"); + dwc->u2ss_inp3_quirk = of_property_read_bool(node, + "snps,u2ss_inp3_quirk"); } else if (pdata) { dwc->maximum_speed = pdata->maximum_speed; dwc->has_lpm_erratum = pdata->has_lpm_erratum; @@ -745,6 +767,7 @@ static int dwc3_probe(struct platform_device *pdev) dwc->disable_scramble_quirk = pdata->disable_scramble_quirk; dwc->u2exit_lfps_quirk = pdata->u2exit_lfps_quirk; + dwc->u2ss_inp3_quirk = pdata->u2ss_inp3_quirk; } /* default to superspeed if no maximum_speed passed */ diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index f93145cb52f5..66fd26bfdbfa 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -176,6 +176,7 @@ /* Global USB3 PIPE Control Register */ #define DWC3_GUSB3PIPECTL_PHYSOFTRST (1 << 31) +#define DWC3_GUSB3PIPECTL_U2SSINP3OK (1 << 29) #define DWC3_GUSB3PIPECTL_SUSPHY (1 << 17) /* Global TX Fifo Size Register */ @@ -681,6 +682,7 @@ struct dwc3_scratchpad_array { * @three_stage_setup: set if we perform a three phase setup * @disable_scramble_quirk: set if we enable the disable scramble quirk * @u2exit_lfps_quirk: set if we enable u2exit lfps quirk + * @u2ss_inp3_quirk: set if we enable P3 OK for U2/SS Inactive quirk */ struct dwc3 { struct usb_ctrlrequest *ctrl_req; @@ -790,6 +792,7 @@ struct dwc3 { unsigned disable_scramble_quirk:1; unsigned u2exit_lfps_quirk:1; + unsigned u2ss_inp3_quirk:1; }; /* -------------------------------------------------------------------------- */ diff --git a/drivers/usb/dwc3/platform_data.h b/drivers/usb/dwc3/platform_data.h index 3f2159108f7d..cf92c81e2e22 100644 --- a/drivers/usb/dwc3/platform_data.h +++ b/drivers/usb/dwc3/platform_data.h @@ -30,4 +30,5 @@ struct dwc3_platform_data { unsigned disable_scramble_quirk:1; unsigned has_lpm_erratum:1; unsigned u2exit_lfps_quirk:1; + unsigned u2ss_inp3_quirk:1; }; -- cgit v1.2.3-59-g8ed1b From df31f5b3a6d3ef0bb692edff13167e9a1c5aa25e Mon Sep 17 00:00:00 2001 From: Huang Rui Date: Tue, 28 Oct 2014 19:54:29 +0800 Subject: usb: dwc3: add request p1p2p3 quirk This patch adds request P1/P2/P3 quirk for U2/U2/U3, and some special platforms can configure that if it is needed. [ balbi@ti.com : added DeviceTree binding documentation ] Signed-off-by: Huang Rui Signed-off-by: Felipe Balbi --- Documentation/devicetree/bindings/usb/dwc3.txt | 2 ++ drivers/usb/dwc3/core.c | 6 ++++++ drivers/usb/dwc3/core.h | 3 +++ drivers/usb/dwc3/platform_data.h | 1 + 4 files changed, 12 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/usb/dwc3.txt b/Documentation/devicetree/bindings/usb/dwc3.txt index 36e4287c40f5..40edc78ca602 100644 --- a/Documentation/devicetree/bindings/usb/dwc3.txt +++ b/Documentation/devicetree/bindings/usb/dwc3.txt @@ -20,6 +20,8 @@ Optional properties: - snps,lpm-nyet-threshold: LPM NYET threshold - snps,u2exit_lfps_quirk: set if we want to enable u2exit lfps quirk - snps,u2ss_inp3_quirk: set if we enable P3 OK for U2/SS Inactive quirk + - snps,req_p1p2p3_quirk: when set, the core will always request for + P1/P2/P3 transition sequence. This is usually a subnode to DWC3 glue to which it is connected. diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 7c54da187062..600d3bc8d04d 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -377,6 +377,9 @@ static void dwc3_phy_setup(struct dwc3 *dwc) if (dwc->u2ss_inp3_quirk) reg |= DWC3_GUSB3PIPECTL_U2SSINP3OK; + if (dwc->req_p1p2p3_quirk) + reg |= DWC3_GUSB3PIPECTL_REQP1P2P3; + dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg); mdelay(100); @@ -756,6 +759,8 @@ static int dwc3_probe(struct platform_device *pdev) "snps,u2exit_lfps_quirk"); dwc->u2ss_inp3_quirk = of_property_read_bool(node, "snps,u2ss_inp3_quirk"); + dwc->req_p1p2p3_quirk = of_property_read_bool(node, + "snps,req_p1p2p3_quirk"); } else if (pdata) { dwc->maximum_speed = pdata->maximum_speed; dwc->has_lpm_erratum = pdata->has_lpm_erratum; @@ -768,6 +773,7 @@ static int dwc3_probe(struct platform_device *pdev) dwc->disable_scramble_quirk = pdata->disable_scramble_quirk; dwc->u2exit_lfps_quirk = pdata->u2exit_lfps_quirk; dwc->u2ss_inp3_quirk = pdata->u2ss_inp3_quirk; + dwc->req_p1p2p3_quirk = pdata->req_p1p2p3_quirk; } /* default to superspeed if no maximum_speed passed */ diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index 66fd26bfdbfa..ce331630fad9 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -177,6 +177,7 @@ /* Global USB3 PIPE Control Register */ #define DWC3_GUSB3PIPECTL_PHYSOFTRST (1 << 31) #define DWC3_GUSB3PIPECTL_U2SSINP3OK (1 << 29) +#define DWC3_GUSB3PIPECTL_REQP1P2P3 (1 << 24) #define DWC3_GUSB3PIPECTL_SUSPHY (1 << 17) /* Global TX Fifo Size Register */ @@ -683,6 +684,7 @@ struct dwc3_scratchpad_array { * @disable_scramble_quirk: set if we enable the disable scramble quirk * @u2exit_lfps_quirk: set if we enable u2exit lfps quirk * @u2ss_inp3_quirk: set if we enable P3 OK for U2/SS Inactive quirk + * @req_p1p2p3_quirk: set if we enable request p1p2p3 quirk */ struct dwc3 { struct usb_ctrlrequest *ctrl_req; @@ -793,6 +795,7 @@ struct dwc3 { unsigned disable_scramble_quirk:1; unsigned u2exit_lfps_quirk:1; unsigned u2ss_inp3_quirk:1; + unsigned req_p1p2p3_quirk:1; }; /* -------------------------------------------------------------------------- */ diff --git a/drivers/usb/dwc3/platform_data.h b/drivers/usb/dwc3/platform_data.h index cf92c81e2e22..d3e6ec210ef3 100644 --- a/drivers/usb/dwc3/platform_data.h +++ b/drivers/usb/dwc3/platform_data.h @@ -31,4 +31,5 @@ struct dwc3_platform_data { unsigned has_lpm_erratum:1; unsigned u2exit_lfps_quirk:1; unsigned u2ss_inp3_quirk:1; + unsigned req_p1p2p3_quirk:1; }; -- cgit v1.2.3-59-g8ed1b From a2a1d0f5838d6aa0d1306ef9bb1011f501faa695 Mon Sep 17 00:00:00 2001 From: Huang Rui Date: Tue, 28 Oct 2014 19:54:30 +0800 Subject: usb: dwc3: add delay p1p2p3 quirk This patch adds delay P0 to P1/P2/P3 quirk for U2/U2/U3, and some special platforms can configure that if it is needed. [ balbi@ti.com : added DeviceTree binding documentation ] Signed-off-by: Huang Rui Signed-off-by: Felipe Balbi --- Documentation/devicetree/bindings/usb/dwc3.txt | 2 ++ drivers/usb/dwc3/core.c | 6 ++++++ drivers/usb/dwc3/core.h | 5 +++++ drivers/usb/dwc3/platform_data.h | 1 + 4 files changed, 14 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/usb/dwc3.txt b/Documentation/devicetree/bindings/usb/dwc3.txt index 40edc78ca602..4c77ed6e7c07 100644 --- a/Documentation/devicetree/bindings/usb/dwc3.txt +++ b/Documentation/devicetree/bindings/usb/dwc3.txt @@ -22,6 +22,8 @@ Optional properties: - snps,u2ss_inp3_quirk: set if we enable P3 OK for U2/SS Inactive quirk - snps,req_p1p2p3_quirk: when set, the core will always request for P1/P2/P3 transition sequence. + - snps,del_p1p2p3_quirk: when set core will delay P1/P2/P3 until a certain + amount of 8B10B errors occur. This is usually a subnode to DWC3 glue to which it is connected. diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 600d3bc8d04d..c07651484c60 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -380,6 +380,9 @@ static void dwc3_phy_setup(struct dwc3 *dwc) if (dwc->req_p1p2p3_quirk) reg |= DWC3_GUSB3PIPECTL_REQP1P2P3; + if (dwc->del_p1p2p3_quirk) + reg |= DWC3_GUSB3PIPECTL_DEP1P2P3_EN; + dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg); mdelay(100); @@ -761,6 +764,8 @@ static int dwc3_probe(struct platform_device *pdev) "snps,u2ss_inp3_quirk"); dwc->req_p1p2p3_quirk = of_property_read_bool(node, "snps,req_p1p2p3_quirk"); + dwc->del_p1p2p3_quirk = of_property_read_bool(node, + "snps,del_p1p2p3_quirk"); } else if (pdata) { dwc->maximum_speed = pdata->maximum_speed; dwc->has_lpm_erratum = pdata->has_lpm_erratum; @@ -774,6 +779,7 @@ static int dwc3_probe(struct platform_device *pdev) dwc->u2exit_lfps_quirk = pdata->u2exit_lfps_quirk; dwc->u2ss_inp3_quirk = pdata->u2ss_inp3_quirk; dwc->req_p1p2p3_quirk = pdata->req_p1p2p3_quirk; + dwc->del_p1p2p3_quirk = pdata->del_p1p2p3_quirk; } /* default to superspeed if no maximum_speed passed */ diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index ce331630fad9..b8fbc4a1ee4a 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -178,6 +178,9 @@ #define DWC3_GUSB3PIPECTL_PHYSOFTRST (1 << 31) #define DWC3_GUSB3PIPECTL_U2SSINP3OK (1 << 29) #define DWC3_GUSB3PIPECTL_REQP1P2P3 (1 << 24) +#define DWC3_GUSB3PIPECTL_DEP1P2P3(n) ((n) << 19) +#define DWC3_GUSB3PIPECTL_DEP1P2P3_MASK DWC3_GUSB3PIPECTL_DEP1P2P3(7) +#define DWC3_GUSB3PIPECTL_DEP1P2P3_EN DWC3_GUSB3PIPECTL_DEP1P2P3(1) #define DWC3_GUSB3PIPECTL_SUSPHY (1 << 17) /* Global TX Fifo Size Register */ @@ -685,6 +688,7 @@ struct dwc3_scratchpad_array { * @u2exit_lfps_quirk: set if we enable u2exit lfps quirk * @u2ss_inp3_quirk: set if we enable P3 OK for U2/SS Inactive quirk * @req_p1p2p3_quirk: set if we enable request p1p2p3 quirk + * @del_p1p2p3_quirk: set if we enable delay p1p2p3 quirk */ struct dwc3 { struct usb_ctrlrequest *ctrl_req; @@ -796,6 +800,7 @@ struct dwc3 { unsigned u2exit_lfps_quirk:1; unsigned u2ss_inp3_quirk:1; unsigned req_p1p2p3_quirk:1; + unsigned del_p1p2p3_quirk:1; }; /* -------------------------------------------------------------------------- */ diff --git a/drivers/usb/dwc3/platform_data.h b/drivers/usb/dwc3/platform_data.h index d3e6ec210ef3..a421cecd6c16 100644 --- a/drivers/usb/dwc3/platform_data.h +++ b/drivers/usb/dwc3/platform_data.h @@ -32,4 +32,5 @@ struct dwc3_platform_data { unsigned u2exit_lfps_quirk:1; unsigned u2ss_inp3_quirk:1; unsigned req_p1p2p3_quirk:1; + unsigned del_p1p2p3_quirk:1; }; -- cgit v1.2.3-59-g8ed1b From 41c06ffdf9cc63edd875cc8ff8ae002cd9b14f96 Mon Sep 17 00:00:00 2001 From: Huang Rui Date: Tue, 28 Oct 2014 19:54:31 +0800 Subject: usb: dwc3: add delay phy power change quirk This patch adds delay PHY power change from P0 to P1/P2/P3 when link state changing from U0 to U1/U2/U3 respectively, and some special platforms can configure that if it is needed. [ balbi@ti.com : added DeviceTree binding documentation ] Signed-off-by: Huang Rui Signed-off-by: Felipe Balbi --- Documentation/devicetree/bindings/usb/dwc3.txt | 2 ++ drivers/usb/dwc3/core.c | 6 ++++++ drivers/usb/dwc3/core.h | 3 +++ drivers/usb/dwc3/platform_data.h | 1 + 4 files changed, 12 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/usb/dwc3.txt b/Documentation/devicetree/bindings/usb/dwc3.txt index 4c77ed6e7c07..a2598d3c7c12 100644 --- a/Documentation/devicetree/bindings/usb/dwc3.txt +++ b/Documentation/devicetree/bindings/usb/dwc3.txt @@ -24,6 +24,8 @@ Optional properties: P1/P2/P3 transition sequence. - snps,del_p1p2p3_quirk: when set core will delay P1/P2/P3 until a certain amount of 8B10B errors occur. + - snps,del_phy_power_chg_quirk: when set core will delay PHY power change + from P0 to P1/P2/P3. This is usually a subnode to DWC3 glue to which it is connected. diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index c07651484c60..de6a00969bc7 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -383,6 +383,9 @@ static void dwc3_phy_setup(struct dwc3 *dwc) if (dwc->del_p1p2p3_quirk) reg |= DWC3_GUSB3PIPECTL_DEP1P2P3_EN; + if (dwc->del_phy_power_chg_quirk) + reg |= DWC3_GUSB3PIPECTL_DEPOCHANGE; + dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg); mdelay(100); @@ -766,6 +769,8 @@ static int dwc3_probe(struct platform_device *pdev) "snps,req_p1p2p3_quirk"); dwc->del_p1p2p3_quirk = of_property_read_bool(node, "snps,del_p1p2p3_quirk"); + dwc->del_phy_power_chg_quirk = of_property_read_bool(node, + "snps,del_phy_power_chg_quirk"); } else if (pdata) { dwc->maximum_speed = pdata->maximum_speed; dwc->has_lpm_erratum = pdata->has_lpm_erratum; @@ -780,6 +785,7 @@ static int dwc3_probe(struct platform_device *pdev) dwc->u2ss_inp3_quirk = pdata->u2ss_inp3_quirk; dwc->req_p1p2p3_quirk = pdata->req_p1p2p3_quirk; dwc->del_p1p2p3_quirk = pdata->del_p1p2p3_quirk; + dwc->del_phy_power_chg_quirk = pdata->del_phy_power_chg_quirk; } /* default to superspeed if no maximum_speed passed */ diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index b8fbc4a1ee4a..5e8a75c3f3c8 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -181,6 +181,7 @@ #define DWC3_GUSB3PIPECTL_DEP1P2P3(n) ((n) << 19) #define DWC3_GUSB3PIPECTL_DEP1P2P3_MASK DWC3_GUSB3PIPECTL_DEP1P2P3(7) #define DWC3_GUSB3PIPECTL_DEP1P2P3_EN DWC3_GUSB3PIPECTL_DEP1P2P3(1) +#define DWC3_GUSB3PIPECTL_DEPOCHANGE (1 << 18) #define DWC3_GUSB3PIPECTL_SUSPHY (1 << 17) /* Global TX Fifo Size Register */ @@ -689,6 +690,7 @@ struct dwc3_scratchpad_array { * @u2ss_inp3_quirk: set if we enable P3 OK for U2/SS Inactive quirk * @req_p1p2p3_quirk: set if we enable request p1p2p3 quirk * @del_p1p2p3_quirk: set if we enable delay p1p2p3 quirk + * @del_phy_power_chg_quirk: set if we enable delay phy power change quirk */ struct dwc3 { struct usb_ctrlrequest *ctrl_req; @@ -801,6 +803,7 @@ struct dwc3 { unsigned u2ss_inp3_quirk:1; unsigned req_p1p2p3_quirk:1; unsigned del_p1p2p3_quirk:1; + unsigned del_phy_power_chg_quirk:1; }; /* -------------------------------------------------------------------------- */ diff --git a/drivers/usb/dwc3/platform_data.h b/drivers/usb/dwc3/platform_data.h index a421cecd6c16..ae67151dc870 100644 --- a/drivers/usb/dwc3/platform_data.h +++ b/drivers/usb/dwc3/platform_data.h @@ -33,4 +33,5 @@ struct dwc3_platform_data { unsigned u2ss_inp3_quirk:1; unsigned req_p1p2p3_quirk:1; unsigned del_p1p2p3_quirk:1; + unsigned del_phy_power_chg_quirk:1; }; -- cgit v1.2.3-59-g8ed1b From fb67afca177a215684d6124137f61e639c5483d4 Mon Sep 17 00:00:00 2001 From: Huang Rui Date: Tue, 28 Oct 2014 19:54:32 +0800 Subject: usb: dwc3: add lfps filter quirk This patch adds LFPS filter quirk, and some special platforms can configure that if it is needed. [ balbi@ti.com : added DeviceTree binding documentation ] Signed-off-by: Huang Rui Signed-off-by: Felipe Balbi --- Documentation/devicetree/bindings/usb/dwc3.txt | 1 + drivers/usb/dwc3/core.c | 6 ++++++ drivers/usb/dwc3/core.h | 3 +++ drivers/usb/dwc3/platform_data.h | 1 + 4 files changed, 11 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/usb/dwc3.txt b/Documentation/devicetree/bindings/usb/dwc3.txt index a2598d3c7c12..4edd29a24e74 100644 --- a/Documentation/devicetree/bindings/usb/dwc3.txt +++ b/Documentation/devicetree/bindings/usb/dwc3.txt @@ -26,6 +26,7 @@ Optional properties: amount of 8B10B errors occur. - snps,del_phy_power_chg_quirk: when set core will delay PHY power change from P0 to P1/P2/P3. + - snps,lfps_filter_quirk: when set core will filter LFPS reception. This is usually a subnode to DWC3 glue to which it is connected. diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index de6a00969bc7..29a7da0c3178 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -386,6 +386,9 @@ static void dwc3_phy_setup(struct dwc3 *dwc) if (dwc->del_phy_power_chg_quirk) reg |= DWC3_GUSB3PIPECTL_DEPOCHANGE; + if (dwc->lfps_filter_quirk) + reg |= DWC3_GUSB3PIPECTL_LFPSFILT; + dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg); mdelay(100); @@ -771,6 +774,8 @@ static int dwc3_probe(struct platform_device *pdev) "snps,del_p1p2p3_quirk"); dwc->del_phy_power_chg_quirk = of_property_read_bool(node, "snps,del_phy_power_chg_quirk"); + dwc->lfps_filter_quirk = of_property_read_bool(node, + "snps,lfps_filter_quirk"); } else if (pdata) { dwc->maximum_speed = pdata->maximum_speed; dwc->has_lpm_erratum = pdata->has_lpm_erratum; @@ -786,6 +791,7 @@ static int dwc3_probe(struct platform_device *pdev) dwc->req_p1p2p3_quirk = pdata->req_p1p2p3_quirk; dwc->del_p1p2p3_quirk = pdata->del_p1p2p3_quirk; dwc->del_phy_power_chg_quirk = pdata->del_phy_power_chg_quirk; + dwc->lfps_filter_quirk = pdata->lfps_filter_quirk; } /* default to superspeed if no maximum_speed passed */ diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index 5e8a75c3f3c8..368d32948e27 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -183,6 +183,7 @@ #define DWC3_GUSB3PIPECTL_DEP1P2P3_EN DWC3_GUSB3PIPECTL_DEP1P2P3(1) #define DWC3_GUSB3PIPECTL_DEPOCHANGE (1 << 18) #define DWC3_GUSB3PIPECTL_SUSPHY (1 << 17) +#define DWC3_GUSB3PIPECTL_LFPSFILT (1 << 9) /* Global TX Fifo Size Register */ #define DWC3_GTXFIFOSIZ_TXFDEF(n) ((n) & 0xffff) @@ -691,6 +692,7 @@ struct dwc3_scratchpad_array { * @req_p1p2p3_quirk: set if we enable request p1p2p3 quirk * @del_p1p2p3_quirk: set if we enable delay p1p2p3 quirk * @del_phy_power_chg_quirk: set if we enable delay phy power change quirk + * @lfps_filter_quirk: set if we enable LFPS filter quirk */ struct dwc3 { struct usb_ctrlrequest *ctrl_req; @@ -804,6 +806,7 @@ struct dwc3 { unsigned req_p1p2p3_quirk:1; unsigned del_p1p2p3_quirk:1; unsigned del_phy_power_chg_quirk:1; + unsigned lfps_filter_quirk:1; }; /* -------------------------------------------------------------------------- */ diff --git a/drivers/usb/dwc3/platform_data.h b/drivers/usb/dwc3/platform_data.h index ae67151dc870..dad0211e8743 100644 --- a/drivers/usb/dwc3/platform_data.h +++ b/drivers/usb/dwc3/platform_data.h @@ -34,4 +34,5 @@ struct dwc3_platform_data { unsigned req_p1p2p3_quirk:1; unsigned del_p1p2p3_quirk:1; unsigned del_phy_power_chg_quirk:1; + unsigned lfps_filter_quirk:1; }; -- cgit v1.2.3-59-g8ed1b From 14f4ac53dfb2321b07a0e690df797fba61102fa6 Mon Sep 17 00:00:00 2001 From: Huang Rui Date: Tue, 28 Oct 2014 19:54:33 +0800 Subject: usb: dwc3: add rx_detect to polling lfps quirk This patch adds RX_DETECT to Polling.LFPS control quirk, and some special platforms can configure that if it is needed. [ balbi@ti.com : added DeviceTree binding documentation ] Signed-off-by: Huang Rui Signed-off-by: Felipe Balbi --- Documentation/devicetree/bindings/usb/dwc3.txt | 2 ++ drivers/usb/dwc3/core.c | 6 ++++++ drivers/usb/dwc3/core.h | 3 +++ drivers/usb/dwc3/platform_data.h | 1 + 4 files changed, 12 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/usb/dwc3.txt b/Documentation/devicetree/bindings/usb/dwc3.txt index 4edd29a24e74..1ecc33315e1f 100644 --- a/Documentation/devicetree/bindings/usb/dwc3.txt +++ b/Documentation/devicetree/bindings/usb/dwc3.txt @@ -27,6 +27,8 @@ Optional properties: - snps,del_phy_power_chg_quirk: when set core will delay PHY power change from P0 to P1/P2/P3. - snps,lfps_filter_quirk: when set core will filter LFPS reception. + - snps,rx_detect_poll_quirk: when set core will disable a 400us delay to start + Polling LFPS after RX.Detect. This is usually a subnode to DWC3 glue to which it is connected. diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 29a7da0c3178..b440b2b29872 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -389,6 +389,9 @@ static void dwc3_phy_setup(struct dwc3 *dwc) if (dwc->lfps_filter_quirk) reg |= DWC3_GUSB3PIPECTL_LFPSFILT; + if (dwc->rx_detect_poll_quirk) + reg |= DWC3_GUSB3PIPECTL_RX_DETOPOLL; + dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg); mdelay(100); @@ -776,6 +779,8 @@ static int dwc3_probe(struct platform_device *pdev) "snps,del_phy_power_chg_quirk"); dwc->lfps_filter_quirk = of_property_read_bool(node, "snps,lfps_filter_quirk"); + dwc->rx_detect_poll_quirk = of_property_read_bool(node, + "snps,rx_detect_poll_quirk"); } else if (pdata) { dwc->maximum_speed = pdata->maximum_speed; dwc->has_lpm_erratum = pdata->has_lpm_erratum; @@ -792,6 +797,7 @@ static int dwc3_probe(struct platform_device *pdev) dwc->del_p1p2p3_quirk = pdata->del_p1p2p3_quirk; dwc->del_phy_power_chg_quirk = pdata->del_phy_power_chg_quirk; dwc->lfps_filter_quirk = pdata->lfps_filter_quirk; + dwc->rx_detect_poll_quirk = pdata->rx_detect_poll_quirk; } /* default to superspeed if no maximum_speed passed */ diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index 368d32948e27..8953d739b73d 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -184,6 +184,7 @@ #define DWC3_GUSB3PIPECTL_DEPOCHANGE (1 << 18) #define DWC3_GUSB3PIPECTL_SUSPHY (1 << 17) #define DWC3_GUSB3PIPECTL_LFPSFILT (1 << 9) +#define DWC3_GUSB3PIPECTL_RX_DETOPOLL (1 << 8) /* Global TX Fifo Size Register */ #define DWC3_GTXFIFOSIZ_TXFDEF(n) ((n) & 0xffff) @@ -693,6 +694,7 @@ struct dwc3_scratchpad_array { * @del_p1p2p3_quirk: set if we enable delay p1p2p3 quirk * @del_phy_power_chg_quirk: set if we enable delay phy power change quirk * @lfps_filter_quirk: set if we enable LFPS filter quirk + * @rx_detect_poll_quirk: set if we enable rx_detect to polling lfps quirk */ struct dwc3 { struct usb_ctrlrequest *ctrl_req; @@ -807,6 +809,7 @@ struct dwc3 { unsigned del_p1p2p3_quirk:1; unsigned del_phy_power_chg_quirk:1; unsigned lfps_filter_quirk:1; + unsigned rx_detect_poll_quirk:1; }; /* -------------------------------------------------------------------------- */ diff --git a/drivers/usb/dwc3/platform_data.h b/drivers/usb/dwc3/platform_data.h index dad0211e8743..4a0f06b2a6c7 100644 --- a/drivers/usb/dwc3/platform_data.h +++ b/drivers/usb/dwc3/platform_data.h @@ -35,4 +35,5 @@ struct dwc3_platform_data { unsigned del_p1p2p3_quirk:1; unsigned del_phy_power_chg_quirk:1; unsigned lfps_filter_quirk:1; + unsigned rx_detect_poll_quirk:1; }; -- cgit v1.2.3-59-g8ed1b From 6b6a0c9a3ffa3107994d92d5758cbe274c5a97b6 Mon Sep 17 00:00:00 2001 From: Huang Rui Date: Fri, 31 Oct 2014 11:11:12 +0800 Subject: usb: dwc3: add Tx de-emphasis quirk This patch adds Tx de-emphasis quirk, and the Tx de-emphasis value is configurable according to PIPE3 specification. Value Description 0 -6dB de-emphasis 1 -3.5dB de-emphasis 2 No de-emphasis 3 Reserved It can be configured on DT or platform data. Signed-off-by: Huang Rui Signed-off-by: Felipe Balbi --- Documentation/devicetree/bindings/usb/dwc3.txt | 3 +++ drivers/usb/dwc3/core.c | 17 +++++++++++++++++ drivers/usb/dwc3/core.h | 11 +++++++++++ drivers/usb/dwc3/platform_data.h | 3 +++ 4 files changed, 34 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/usb/dwc3.txt b/Documentation/devicetree/bindings/usb/dwc3.txt index 1ecc33315e1f..b724b2e78549 100644 --- a/Documentation/devicetree/bindings/usb/dwc3.txt +++ b/Documentation/devicetree/bindings/usb/dwc3.txt @@ -29,6 +29,9 @@ Optional properties: - snps,lfps_filter_quirk: when set core will filter LFPS reception. - snps,rx_detect_poll_quirk: when set core will disable a 400us delay to start Polling LFPS after RX.Detect. + - snps,tx_de_emphasis_quirk: when set core will set Tx de-emphasis value. + - snps,tx_de_emphasis: the value driven to the PHY is controlled by the + LTSSM during USB3 Compliance mode. This is usually a subnode to DWC3 glue to which it is connected. diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index aefb59d6db8f..c3dfb195f79c 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -401,6 +401,9 @@ static void dwc3_phy_setup(struct dwc3 *dwc) if (dwc->rx_detect_poll_quirk) reg |= DWC3_GUSB3PIPECTL_RX_DETOPOLL; + if (dwc->tx_de_emphasis_quirk) + reg |= DWC3_GUSB3PIPECTL_TX_DEEPH(dwc->tx_de_emphasis); + dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg); mdelay(100); @@ -720,6 +723,7 @@ static int dwc3_probe(struct platform_device *pdev) struct resource *res; struct dwc3 *dwc; u8 lpm_nyet_threshold; + u8 tx_de_emphasis; int ret; @@ -778,6 +782,9 @@ static int dwc3_probe(struct platform_device *pdev) /* default to highest possible threshold */ lpm_nyet_threshold = 0xff; + /* default to -3.5dB de-emphasis */ + tx_de_emphasis = 1; + if (node) { dwc->maximum_speed = of_usb_get_maximum_speed(node); dwc->has_lpm_erratum = of_property_read_bool(node, @@ -805,6 +812,11 @@ static int dwc3_probe(struct platform_device *pdev) "snps,lfps_filter_quirk"); dwc->rx_detect_poll_quirk = of_property_read_bool(node, "snps,rx_detect_poll_quirk"); + + dwc->tx_de_emphasis_quirk = of_property_read_bool(node, + "snps,tx_de_emphasis_quirk"); + of_property_read_u8(node, "snps,tx_de_emphasis", + &tx_de_emphasis); } else if (pdata) { dwc->maximum_speed = pdata->maximum_speed; dwc->has_lpm_erratum = pdata->has_lpm_erratum; @@ -822,6 +834,10 @@ static int dwc3_probe(struct platform_device *pdev) dwc->del_phy_power_chg_quirk = pdata->del_phy_power_chg_quirk; dwc->lfps_filter_quirk = pdata->lfps_filter_quirk; dwc->rx_detect_poll_quirk = pdata->rx_detect_poll_quirk; + + dwc->tx_de_emphasis_quirk = pdata->tx_de_emphasis_quirk; + if (pdata->tx_de_emphasis) + tx_de_emphasis = pdata->tx_de_emphasis; } /* default to superspeed if no maximum_speed passed */ @@ -829,6 +845,7 @@ static int dwc3_probe(struct platform_device *pdev) dwc->maximum_speed = USB_SPEED_SUPER; dwc->lpm_nyet_threshold = lpm_nyet_threshold; + dwc->tx_de_emphasis = tx_de_emphasis; ret = dwc3_core_get_phy(dwc); if (ret) diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index 8953d739b73d..cf9aaca6add0 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -185,6 +185,8 @@ #define DWC3_GUSB3PIPECTL_SUSPHY (1 << 17) #define DWC3_GUSB3PIPECTL_LFPSFILT (1 << 9) #define DWC3_GUSB3PIPECTL_RX_DETOPOLL (1 << 8) +#define DWC3_GUSB3PIPECTL_TX_DEEPH_MASK DWC3_GUSB3PIPECTL_TX_DEEPH(3) +#define DWC3_GUSB3PIPECTL_TX_DEEPH(n) ((n) << 1) /* Global TX Fifo Size Register */ #define DWC3_GTXFIFOSIZ_TXFDEF(n) ((n) & 0xffff) @@ -695,6 +697,12 @@ struct dwc3_scratchpad_array { * @del_phy_power_chg_quirk: set if we enable delay phy power change quirk * @lfps_filter_quirk: set if we enable LFPS filter quirk * @rx_detect_poll_quirk: set if we enable rx_detect to polling lfps quirk + * @tx_de_emphasis_quirk: set if we enable Tx de-emphasis quirk + * @tx_de_emphasis: Tx de-emphasis value + * 0 - -6dB de-emphasis + * 1 - -3.5dB de-emphasis + * 2 - No de-emphasis + * 3 - Reserved */ struct dwc3 { struct usb_ctrlrequest *ctrl_req; @@ -810,6 +818,9 @@ struct dwc3 { unsigned del_phy_power_chg_quirk:1; unsigned lfps_filter_quirk:1; unsigned rx_detect_poll_quirk:1; + + unsigned tx_de_emphasis_quirk:1; + unsigned tx_de_emphasis:2; }; /* -------------------------------------------------------------------------- */ diff --git a/drivers/usb/dwc3/platform_data.h b/drivers/usb/dwc3/platform_data.h index 4a0f06b2a6c7..e1ab900a8623 100644 --- a/drivers/usb/dwc3/platform_data.h +++ b/drivers/usb/dwc3/platform_data.h @@ -36,4 +36,7 @@ struct dwc3_platform_data { unsigned del_phy_power_chg_quirk:1; unsigned lfps_filter_quirk:1; unsigned rx_detect_poll_quirk:1; + + unsigned tx_de_emphasis_quirk:1; + unsigned tx_de_emphasis:2; }; -- cgit v1.2.3-59-g8ed1b From 59acfa208164205f94a11f454d08cd88f06b9908 Mon Sep 17 00:00:00 2001 From: Huang Rui Date: Fri, 31 Oct 2014 11:11:13 +0800 Subject: usb: dwc3: add disable usb3 suspend phy quirk This patch adds disable usb3 suspend phy quirk, and some special platforms can configure that if it is needed. Signed-off-by: Huang Rui Signed-off-by: Felipe Balbi --- Documentation/devicetree/bindings/usb/dwc3.txt | 1 + drivers/usb/dwc3/core.c | 6 ++++++ drivers/usb/dwc3/core.h | 2 ++ drivers/usb/dwc3/platform_data.h | 1 + 4 files changed, 10 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/usb/dwc3.txt b/Documentation/devicetree/bindings/usb/dwc3.txt index b724b2e78549..08b394ebeb3e 100644 --- a/Documentation/devicetree/bindings/usb/dwc3.txt +++ b/Documentation/devicetree/bindings/usb/dwc3.txt @@ -32,6 +32,7 @@ Optional properties: - snps,tx_de_emphasis_quirk: when set core will set Tx de-emphasis value. - snps,tx_de_emphasis: the value driven to the PHY is controlled by the LTSSM during USB3 Compliance mode. + - snps,dis_u3_susphy_quirk: when set core will disable USB3 suspend phy. This is usually a subnode to DWC3 glue to which it is connected. diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index c3dfb195f79c..87ffb86bc2f2 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -404,6 +404,9 @@ static void dwc3_phy_setup(struct dwc3 *dwc) if (dwc->tx_de_emphasis_quirk) reg |= DWC3_GUSB3PIPECTL_TX_DEEPH(dwc->tx_de_emphasis); + if (dwc->dis_u3_susphy_quirk && dwc->is_fpga) + reg &= ~DWC3_GUSB3PIPECTL_SUSPHY; + dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg); mdelay(100); @@ -812,6 +815,8 @@ static int dwc3_probe(struct platform_device *pdev) "snps,lfps_filter_quirk"); dwc->rx_detect_poll_quirk = of_property_read_bool(node, "snps,rx_detect_poll_quirk"); + dwc->dis_u3_susphy_quirk = of_property_read_bool(node, + "snps,dis_u3_susphy_quirk"); dwc->tx_de_emphasis_quirk = of_property_read_bool(node, "snps,tx_de_emphasis_quirk"); @@ -834,6 +839,7 @@ static int dwc3_probe(struct platform_device *pdev) dwc->del_phy_power_chg_quirk = pdata->del_phy_power_chg_quirk; dwc->lfps_filter_quirk = pdata->lfps_filter_quirk; dwc->rx_detect_poll_quirk = pdata->rx_detect_poll_quirk; + dwc->dis_u3_susphy_quirk = pdata->dis_u3_susphy_quirk; dwc->tx_de_emphasis_quirk = pdata->tx_de_emphasis_quirk; if (pdata->tx_de_emphasis) diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index cf9aaca6add0..fa778b0a5ab7 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -697,6 +697,7 @@ struct dwc3_scratchpad_array { * @del_phy_power_chg_quirk: set if we enable delay phy power change quirk * @lfps_filter_quirk: set if we enable LFPS filter quirk * @rx_detect_poll_quirk: set if we enable rx_detect to polling lfps quirk + * @dis_u3_susphy_quirk: set if we disable usb3 suspend phy * @tx_de_emphasis_quirk: set if we enable Tx de-emphasis quirk * @tx_de_emphasis: Tx de-emphasis value * 0 - -6dB de-emphasis @@ -818,6 +819,7 @@ struct dwc3 { unsigned del_phy_power_chg_quirk:1; unsigned lfps_filter_quirk:1; unsigned rx_detect_poll_quirk:1; + unsigned dis_u3_susphy_quirk:1; unsigned tx_de_emphasis_quirk:1; unsigned tx_de_emphasis:2; diff --git a/drivers/usb/dwc3/platform_data.h b/drivers/usb/dwc3/platform_data.h index e1ab900a8623..0f1d5adc657d 100644 --- a/drivers/usb/dwc3/platform_data.h +++ b/drivers/usb/dwc3/platform_data.h @@ -36,6 +36,7 @@ struct dwc3_platform_data { unsigned del_phy_power_chg_quirk:1; unsigned lfps_filter_quirk:1; unsigned rx_detect_poll_quirk:1; + unsigned dis_u3_susphy_quirk:1; unsigned tx_de_emphasis_quirk:1; unsigned tx_de_emphasis:2; -- cgit v1.2.3-59-g8ed1b From 0effe0a3e741c0e2318f541ce207c9bd6cfe985c Mon Sep 17 00:00:00 2001 From: Huang Rui Date: Fri, 31 Oct 2014 11:11:14 +0800 Subject: usb: dwc3: add disable usb2 suspend phy quirk This patch adds disable usb2 suspend phy quirk, and some special platforms can configure that if it is needed. Signed-off-by: Huang Rui Signed-off-by: Felipe Balbi --- Documentation/devicetree/bindings/usb/dwc3.txt | 1 + drivers/usb/dwc3/core.c | 6 ++++++ drivers/usb/dwc3/core.h | 2 ++ drivers/usb/dwc3/platform_data.h | 1 + 4 files changed, 10 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/usb/dwc3.txt b/Documentation/devicetree/bindings/usb/dwc3.txt index 08b394ebeb3e..f200ecc1f0dc 100644 --- a/Documentation/devicetree/bindings/usb/dwc3.txt +++ b/Documentation/devicetree/bindings/usb/dwc3.txt @@ -33,6 +33,7 @@ Optional properties: - snps,tx_de_emphasis: the value driven to the PHY is controlled by the LTSSM during USB3 Compliance mode. - snps,dis_u3_susphy_quirk: when set core will disable USB3 suspend phy. + - snps,dis_u2_susphy_quirk: when set core will disable USB2 suspend phy. This is usually a subnode to DWC3 glue to which it is connected. diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 87ffb86bc2f2..3ea55f214439 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -422,6 +422,9 @@ static void dwc3_phy_setup(struct dwc3 *dwc) if (dwc->revision > DWC3_REVISION_194A) reg |= DWC3_GUSB2PHYCFG_SUSPHY; + if (dwc->dis_u2_susphy_quirk && dwc->is_fpga) + reg &= ~DWC3_GUSB2PHYCFG_SUSPHY; + dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg); mdelay(100); @@ -817,6 +820,8 @@ static int dwc3_probe(struct platform_device *pdev) "snps,rx_detect_poll_quirk"); dwc->dis_u3_susphy_quirk = of_property_read_bool(node, "snps,dis_u3_susphy_quirk"); + dwc->dis_u2_susphy_quirk = of_property_read_bool(node, + "snps,dis_u2_susphy_quirk"); dwc->tx_de_emphasis_quirk = of_property_read_bool(node, "snps,tx_de_emphasis_quirk"); @@ -840,6 +845,7 @@ static int dwc3_probe(struct platform_device *pdev) dwc->lfps_filter_quirk = pdata->lfps_filter_quirk; dwc->rx_detect_poll_quirk = pdata->rx_detect_poll_quirk; dwc->dis_u3_susphy_quirk = pdata->dis_u3_susphy_quirk; + dwc->dis_u2_susphy_quirk = pdata->dis_u2_susphy_quirk; dwc->tx_de_emphasis_quirk = pdata->tx_de_emphasis_quirk; if (pdata->tx_de_emphasis) diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index fa778b0a5ab7..cf86d3022b52 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -698,6 +698,7 @@ struct dwc3_scratchpad_array { * @lfps_filter_quirk: set if we enable LFPS filter quirk * @rx_detect_poll_quirk: set if we enable rx_detect to polling lfps quirk * @dis_u3_susphy_quirk: set if we disable usb3 suspend phy + * @dis_u2_susphy_quirk: set if we disable usb2 suspend phy * @tx_de_emphasis_quirk: set if we enable Tx de-emphasis quirk * @tx_de_emphasis: Tx de-emphasis value * 0 - -6dB de-emphasis @@ -820,6 +821,7 @@ struct dwc3 { unsigned lfps_filter_quirk:1; unsigned rx_detect_poll_quirk:1; unsigned dis_u3_susphy_quirk:1; + unsigned dis_u2_susphy_quirk:1; unsigned tx_de_emphasis_quirk:1; unsigned tx_de_emphasis:2; diff --git a/drivers/usb/dwc3/platform_data.h b/drivers/usb/dwc3/platform_data.h index 0f1d5adc657d..245300be057a 100644 --- a/drivers/usb/dwc3/platform_data.h +++ b/drivers/usb/dwc3/platform_data.h @@ -37,6 +37,7 @@ struct dwc3_platform_data { unsigned lfps_filter_quirk:1; unsigned rx_detect_poll_quirk:1; unsigned dis_u3_susphy_quirk:1; + unsigned dis_u2_susphy_quirk:1; unsigned tx_de_emphasis_quirk:1; unsigned tx_de_emphasis:2; -- cgit v1.2.3-59-g8ed1b From 460d098cb6728134e0e4ba3d58e10bb43032daa5 Mon Sep 17 00:00:00 2001 From: Huang Rui Date: Fri, 31 Oct 2014 11:11:18 +0800 Subject: usb: dwc3: make HIRD threshold configurable HIRD threshold should be configurable by different platforms. From DesignWare databook: When HIRD_Threshold[4] is set to 1b1 and HIRD value is greater than or equal to the value in HIRD_Threshold[3:0], dwc3 asserts output signals utmi_l1_suspend_n to put PHY into Deep Low-Power mode in L1. When HIRD_Threshold[4] is set to 1b0 or the HIRD value is less than HIRD_Threshold[3:0], dwc3 asserts output signals utmi_sleep_n on L1. Signed-off-by: Huang Rui Signed-off-by: Felipe Balbi --- Documentation/devicetree/bindings/usb/dwc3.txt | 3 +++ drivers/usb/dwc3/core.c | 17 +++++++++++++++++ drivers/usb/dwc3/core.h | 6 ++++++ drivers/usb/dwc3/gadget.c | 6 +----- drivers/usb/dwc3/platform_data.h | 3 +++ 5 files changed, 30 insertions(+), 5 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/usb/dwc3.txt b/Documentation/devicetree/bindings/usb/dwc3.txt index f200ecc1f0dc..cd7f0454e13a 100644 --- a/Documentation/devicetree/bindings/usb/dwc3.txt +++ b/Documentation/devicetree/bindings/usb/dwc3.txt @@ -34,6 +34,9 @@ Optional properties: LTSSM during USB3 Compliance mode. - snps,dis_u3_susphy_quirk: when set core will disable USB3 suspend phy. - snps,dis_u2_susphy_quirk: when set core will disable USB2 suspend phy. + - snps,is-utmi-l1-suspend: true when DWC3 asserts output signal + utmi_l1_suspend_n, false when asserts utmi_sleep_n + - snps,hird-threshold: HIRD threshold This is usually a subnode to DWC3 glue to which it is connected. diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 3ea55f214439..8ae42b8db02b 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -730,6 +730,7 @@ static int dwc3_probe(struct platform_device *pdev) struct dwc3 *dwc; u8 lpm_nyet_threshold; u8 tx_de_emphasis; + u8 hird_threshold; int ret; @@ -791,12 +792,22 @@ static int dwc3_probe(struct platform_device *pdev) /* default to -3.5dB de-emphasis */ tx_de_emphasis = 1; + /* + * default to assert utmi_sleep_n and use maximum allowed HIRD + * threshold value of 0b1100 + */ + hird_threshold = 12; + if (node) { dwc->maximum_speed = of_usb_get_maximum_speed(node); dwc->has_lpm_erratum = of_property_read_bool(node, "snps,has-lpm-erratum"); of_property_read_u8(node, "snps,lpm-nyet-threshold", &lpm_nyet_threshold); + dwc->is_utmi_l1_suspend = of_property_read_bool(node, + "snps,is-utmi-l1-suspend"); + of_property_read_u8(node, "snps,hird-threshold", + &hird_threshold); dwc->needs_fifo_resize = of_property_read_bool(node, "tx-fifo-resize"); @@ -832,6 +843,9 @@ static int dwc3_probe(struct platform_device *pdev) dwc->has_lpm_erratum = pdata->has_lpm_erratum; if (pdata->lpm_nyet_threshold) lpm_nyet_threshold = pdata->lpm_nyet_threshold; + dwc->is_utmi_l1_suspend = pdata->is_utmi_l1_suspend; + if (pdata->hird_threshold) + hird_threshold = pdata->hird_threshold; dwc->needs_fifo_resize = pdata->tx_fifo_resize; dwc->dr_mode = pdata->dr_mode; @@ -859,6 +873,9 @@ static int dwc3_probe(struct platform_device *pdev) dwc->lpm_nyet_threshold = lpm_nyet_threshold; dwc->tx_de_emphasis = tx_de_emphasis; + dwc->hird_threshold = hird_threshold + | (dwc->is_utmi_l1_suspend << 4); + ret = dwc3_core_get_phy(dwc); if (ret) return ret; diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index cf86d3022b52..4bb9aa696ede 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -675,12 +675,16 @@ struct dwc3_scratchpad_array { * @test_mode: true when we're entering a USB test mode * @test_mode_nr: test feature selector * @lpm_nyet_threshold: LPM NYET response threshold + * @hird_threshold: HIRD threshold * @delayed_status: true when gadget driver asks for delayed status * @ep0_bounced: true when we used bounce buffer * @ep0_expect_in: true when we expect a DATA IN transfer * @has_hibernation: true when dwc3 was configured with Hibernation * @has_lpm_erratum: true when core was configured with LPM Erratum. Note that * there's now way for software to detect this in runtime. + * @is_utmi_l1_suspend: the core asserts output signal + * 0 - utmi_sleep_n + * 1 - utmi_l1_suspend_n * @is_selfpowered: true when we are selfpowered * @is_fpga: true when we are using the FPGA board * @needs_fifo_resize: not all users might want fifo resizing, flag it @@ -797,12 +801,14 @@ struct dwc3 { u8 test_mode; u8 test_mode_nr; u8 lpm_nyet_threshold; + u8 hird_threshold; unsigned delayed_status:1; unsigned ep0_bounced:1; unsigned ep0_expect_in:1; unsigned has_hibernation:1; unsigned has_lpm_erratum:1; + unsigned is_utmi_l1_suspend:1; unsigned is_selfpowered:1; unsigned is_fpga:1; unsigned needs_fifo_resize:1; diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 88a065f61150..398c12f5efe3 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -2295,11 +2295,7 @@ static void dwc3_gadget_conndone_interrupt(struct dwc3 *dwc) reg = dwc3_readl(dwc->regs, DWC3_DCTL); reg &= ~(DWC3_DCTL_HIRD_THRES_MASK | DWC3_DCTL_L1_HIBER_EN); - /* - * TODO: This should be configurable. For now using - * maximum allowed HIRD threshold value of 0b1100 - */ - reg |= DWC3_DCTL_HIRD_THRES(12); + reg |= DWC3_DCTL_HIRD_THRES(dwc->hird_threshold); /* * When dwc3 revisions >= 2.40a, LPM Erratum is enabled and diff --git a/drivers/usb/dwc3/platform_data.h b/drivers/usb/dwc3/platform_data.h index 245300be057a..a3a3b6d5668c 100644 --- a/drivers/usb/dwc3/platform_data.h +++ b/drivers/usb/dwc3/platform_data.h @@ -25,6 +25,9 @@ struct dwc3_platform_data { enum usb_dr_mode dr_mode; bool tx_fifo_resize; + unsigned is_utmi_l1_suspend:1; + u8 hird_threshold; + u8 lpm_nyet_threshold; unsigned disable_scramble_quirk:1; -- cgit v1.2.3-59-g8ed1b From c4b8692a0520331a0ede604e20a0a52b96a98607 Mon Sep 17 00:00:00 2001 From: Kevin Cernekee Date: Sat, 11 Oct 2014 11:10:48 -0700 Subject: USB: ohci-platform: Expose no_big_frame_no and num_ports in DT These quirks are currently set through platform_data; allow DT-based SoCs to use them too. Signed-off-by: Kevin Cernekee Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- Documentation/devicetree/bindings/usb/usb-ohci.txt | 2 ++ drivers/usb/host/ohci-platform.c | 6 ++++++ 2 files changed, 8 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/usb/usb-ohci.txt b/Documentation/devicetree/bindings/usb/usb-ohci.txt index b968a1aea995..19233b7365e1 100644 --- a/Documentation/devicetree/bindings/usb/usb-ohci.txt +++ b/Documentation/devicetree/bindings/usb/usb-ohci.txt @@ -9,6 +9,8 @@ Optional properties: - big-endian-regs : boolean, set this for hcds with big-endian registers - big-endian-desc : boolean, set this for hcds with big-endian descriptors - big-endian : boolean, for hcds with big-endian-regs + big-endian-desc +- no-big-frame-no : boolean, set if frame_no lives in bits [15:0] of HCCA +- num-ports : u32, to override the detected port count - clocks : a list of phandle + clock specifier pairs - phys : phandle + phy specifier pair - phy-names : "usb" diff --git a/drivers/usb/host/ohci-platform.c b/drivers/usb/host/ohci-platform.c index 4369299064c7..6fb03f88b51d 100644 --- a/drivers/usb/host/ohci-platform.c +++ b/drivers/usb/host/ohci-platform.c @@ -175,6 +175,12 @@ static int ohci_platform_probe(struct platform_device *dev) if (of_property_read_bool(dev->dev.of_node, "big-endian")) ohci->flags |= OHCI_QUIRK_BE_MMIO | OHCI_QUIRK_BE_DESC; + if (of_property_read_bool(dev->dev.of_node, "no-big-frame-no")) + ohci->flags |= OHCI_QUIRK_FRAME_NO; + + of_property_read_u32(dev->dev.of_node, "num-ports", + &ohci->num_ports); + priv->phy = devm_phy_get(&dev->dev, "usb"); if (IS_ERR(priv->phy)) { err = PTR_ERR(priv->phy); -- cgit v1.2.3-59-g8ed1b From 6f1de344557315a8e5de0d15a28276198ca7fdac Mon Sep 17 00:00:00 2001 From: Andrzej Pietrasiewicz Date: Thu, 16 Oct 2014 13:33:31 +0200 Subject: usb: gadget: f_midi: add configfs support Make the midi function available for gadgets composed with configfs. Signed-off-by: Andrzej Pietrasiewicz Signed-off-by: Felipe Balbi --- Documentation/ABI/testing/configfs-usb-gadget-midi | 12 ++ drivers/usb/gadget/Kconfig | 14 ++ drivers/usb/gadget/function/f_midi.c | 161 ++++++++++++++++++++- drivers/usb/gadget/function/u_midi.h | 8 + 4 files changed, 193 insertions(+), 2 deletions(-) create mode 100644 Documentation/ABI/testing/configfs-usb-gadget-midi (limited to 'Documentation') diff --git a/Documentation/ABI/testing/configfs-usb-gadget-midi b/Documentation/ABI/testing/configfs-usb-gadget-midi new file mode 100644 index 000000000000..6b341df7249c --- /dev/null +++ b/Documentation/ABI/testing/configfs-usb-gadget-midi @@ -0,0 +1,12 @@ +What: /config/usb-gadget/gadget/functions/midi.name +Date: Nov 2014 +KernelVersion: 3.19 +Description: + The attributes: + + index - index value for the USB MIDI adapter + id - ID string for the USB MIDI adapter + buflen - MIDI buffer length + qlen - USB read request queue length + in_ports - number of MIDI input ports + out_ports - number of MIDI output ports diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index b51307805151..501c2a38d071 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -396,6 +396,20 @@ config USB_CONFIGFS_F_UAC2 received from the USB Host and choose to provide whatever it wants as audio data to the USB Host. +config USB_CONFIGFS_F_MIDI + boolean "MIDI function" + depends on USB_CONFIGFS + depends on SND + select USB_LIBCOMPOSITE + select SND_RAWMIDI + select USB_F_MIDI + help + The MIDI Function acts as a USB Audio device, with one MIDI + input and one MIDI output. These MIDI jacks appear as + a sound "card" in the ALSA sound system. Other MIDI + connections can then be made on the gadget system, using + ALSA's aconnect utility etc. + source "drivers/usb/gadget/legacy/Kconfig" endchoice diff --git a/drivers/usb/gadget/function/f_midi.c b/drivers/usb/gadget/function/f_midi.c index ec2a9cee4589..1f94dad57307 100644 --- a/drivers/usb/gadget/function/f_midi.c +++ b/drivers/usb/gadget/function/f_midi.c @@ -896,12 +896,145 @@ fail_register: return status; } +static inline struct f_midi_opts *to_f_midi_opts(struct config_item *item) +{ + return container_of(to_config_group(item), struct f_midi_opts, + func_inst.group); +} + +CONFIGFS_ATTR_STRUCT(f_midi_opts); +CONFIGFS_ATTR_OPS(f_midi_opts); + +static void midi_attr_release(struct config_item *item) +{ + struct f_midi_opts *opts = to_f_midi_opts(item); + + usb_put_function_instance(&opts->func_inst); +} + +static struct configfs_item_operations midi_item_ops = { + .release = midi_attr_release, + .show_attribute = f_midi_opts_attr_show, + .store_attribute = f_midi_opts_attr_store, +}; + +#define F_MIDI_OPT(name, test_limit, limit) \ +static ssize_t f_midi_opts_##name##_show(struct f_midi_opts *opts, char *page) \ +{ \ + int result; \ + \ + mutex_lock(&opts->lock); \ + result = sprintf(page, "%d\n", opts->name); \ + mutex_unlock(&opts->lock); \ + \ + return result; \ +} \ + \ +static ssize_t f_midi_opts_##name##_store(struct f_midi_opts *opts, \ + const char *page, size_t len) \ +{ \ + int ret; \ + u32 num; \ + \ + mutex_lock(&opts->lock); \ + if (opts->refcnt) { \ + ret = -EBUSY; \ + goto end; \ + } \ + \ + ret = kstrtou32(page, 0, &num); \ + if (ret) \ + goto end; \ + \ + if (test_limit && num > limit) { \ + ret = -EINVAL; \ + goto end; \ + } \ + opts->name = num; \ + ret = len; \ + \ +end: \ + mutex_unlock(&opts->lock); \ + return ret; \ +} \ + \ +static struct f_midi_opts_attribute f_midi_opts_##name = \ + __CONFIGFS_ATTR(name, S_IRUGO | S_IWUSR, f_midi_opts_##name##_show, \ + f_midi_opts_##name##_store) + +F_MIDI_OPT(index, true, SNDRV_CARDS); +F_MIDI_OPT(buflen, false, 0); +F_MIDI_OPT(qlen, false, 0); +F_MIDI_OPT(in_ports, true, MAX_PORTS); +F_MIDI_OPT(out_ports, true, MAX_PORTS); + +static ssize_t f_midi_opts_id_show(struct f_midi_opts *opts, char *page) +{ + int result; + + mutex_lock(&opts->lock); + result = strlcpy(page, opts->id, PAGE_SIZE); + mutex_unlock(&opts->lock); + + return result; +} + +static ssize_t f_midi_opts_id_store(struct f_midi_opts *opts, + const char *page, size_t len) +{ + int ret; + char *c; + + mutex_lock(&opts->lock); + if (opts->refcnt) { + ret = -EBUSY; + goto end; + } + + c = kstrndup(page, len, GFP_KERNEL); + if (!c) { + ret = -ENOMEM; + goto end; + } + if (opts->id_allocated) + kfree(opts->id); + opts->id = c; + opts->id_allocated = true; + ret = len; +end: + mutex_unlock(&opts->lock); + return ret; +} + +static struct f_midi_opts_attribute f_midi_opts_id = + __CONFIGFS_ATTR(id, S_IRUGO | S_IWUSR, f_midi_opts_id_show, + f_midi_opts_id_store); + +static struct configfs_attribute *midi_attrs[] = { + &f_midi_opts_index.attr, + &f_midi_opts_buflen.attr, + &f_midi_opts_qlen.attr, + &f_midi_opts_in_ports.attr, + &f_midi_opts_out_ports.attr, + &f_midi_opts_id.attr, + NULL, +}; + +static struct config_item_type midi_func_type = { + .ct_item_ops = &midi_item_ops, + .ct_attrs = midi_attrs, + .ct_owner = THIS_MODULE, +}; + static void f_midi_free_inst(struct usb_function_instance *f) { struct f_midi_opts *opts; opts = container_of(f, struct f_midi_opts, func_inst); + if (opts->id_allocated) + kfree(opts->id); + kfree(opts); } @@ -912,7 +1045,18 @@ static struct usb_function_instance *f_midi_alloc_inst(void) opts = kzalloc(sizeof(*opts), GFP_KERNEL); if (!opts) return ERR_PTR(-ENOMEM); + + mutex_init(&opts->lock); opts->func_inst.free_func_inst = f_midi_free_inst; + opts->index = SNDRV_DEFAULT_IDX1; + opts->id = SNDRV_DEFAULT_STR1; + opts->buflen = 256; + opts->qlen = 32; + opts->in_ports = 1; + opts->out_ports = 1; + + config_group_init_type_name(&opts->func_inst.group, "", + &midi_func_type); return &opts->func_inst; } @@ -926,9 +1070,12 @@ static void f_midi_free(struct usb_function *f) midi = func_to_midi(f); opts = container_of(f->fi, struct f_midi_opts, func_inst); kfree(midi->id); + mutex_lock(&opts->lock); for (i = opts->in_ports - 1; i >= 0; --i) kfree(midi->in_port[i]); kfree(midi); + --opts->refcnt; + mutex_unlock(&opts->lock); } static void f_midi_unbind(struct usb_configuration *c, struct usb_function *f) @@ -957,20 +1104,27 @@ struct usb_function *f_midi_alloc(struct usb_function_instance *fi) int status, i; opts = container_of(fi, struct f_midi_opts, func_inst); + + mutex_lock(&opts->lock); /* sanity check */ - if (opts->in_ports > MAX_PORTS || opts->out_ports > MAX_PORTS) + if (opts->in_ports > MAX_PORTS || opts->out_ports > MAX_PORTS) { + mutex_unlock(&opts->lock); return ERR_PTR(-EINVAL); + } /* allocate and initialize one new instance */ midi = kzalloc(sizeof(*midi), GFP_KERNEL); - if (!midi) + if (!midi) { + mutex_unlock(&opts->lock); return ERR_PTR(-ENOMEM); + } for (i = 0; i < opts->in_ports; i++) { struct gmidi_in_port *port = kzalloc(sizeof(*port), GFP_KERNEL); if (!port) { status = -ENOMEM; + mutex_unlock(&opts->lock); goto setup_fail; } @@ -984,6 +1138,7 @@ struct usb_function *f_midi_alloc(struct usb_function_instance *fi) midi->id = kstrdup(opts->id, GFP_KERNEL); if (opts->id && !midi->id) { status = -ENOMEM; + mutex_unlock(&opts->lock); goto kstrdup_fail; } midi->in_ports = opts->in_ports; @@ -991,6 +1146,8 @@ struct usb_function *f_midi_alloc(struct usb_function_instance *fi) midi->index = opts->index; midi->buflen = opts->buflen; midi->qlen = opts->qlen; + ++opts->refcnt; + mutex_unlock(&opts->lock); midi->func.name = "gmidi function"; midi->func.bind = f_midi_bind; diff --git a/drivers/usb/gadget/function/u_midi.h b/drivers/usb/gadget/function/u_midi.h index 76bccc1fdbb4..22510189758e 100644 --- a/drivers/usb/gadget/function/u_midi.h +++ b/drivers/usb/gadget/function/u_midi.h @@ -22,10 +22,18 @@ struct f_midi_opts { struct usb_function_instance func_inst; int index; char *id; + bool id_allocated; unsigned int in_ports; unsigned int out_ports; unsigned int buflen; unsigned int qlen; + + /* + * Protect the data form concurrent access by read/write + * and create symlink/remove symlink. + */ + struct mutex lock; + int refcnt; }; #endif /* U_MIDI_H */ -- cgit v1.2.3-59-g8ed1b From 21a9476a7ba847e413bf1c144d7c614532aed6dd Mon Sep 17 00:00:00 2001 From: Andrzej Pietrasiewicz Date: Thu, 6 Nov 2014 11:12:03 +0100 Subject: usb: gadget: hid: add configfs support Make the hid function available for gadgets composed with configfs. Signed-off-by: Andrzej Pietrasiewicz Signed-off-by: Felipe Balbi --- Documentation/ABI/testing/configfs-usb-gadget-hid | 11 ++ Documentation/usb/gadget_hid.txt | 7 ++ drivers/usb/gadget/Kconfig | 10 ++ drivers/usb/gadget/function/f_hid.c | 144 +++++++++++++++++++++- drivers/usb/gadget/function/u_hid.h | 7 ++ 5 files changed, 178 insertions(+), 1 deletion(-) create mode 100644 Documentation/ABI/testing/configfs-usb-gadget-hid (limited to 'Documentation') diff --git a/Documentation/ABI/testing/configfs-usb-gadget-hid b/Documentation/ABI/testing/configfs-usb-gadget-hid new file mode 100644 index 000000000000..f12e00e6baa3 --- /dev/null +++ b/Documentation/ABI/testing/configfs-usb-gadget-hid @@ -0,0 +1,11 @@ +What: /config/usb-gadget/gadget/functions/hid.name +Date: Nov 2014 +KernelVersion: 3.19 +Description: + The attributes: + + protocol - HID protocol to use + report_desc - blob corresponding to HID report descriptors + except the data passed through /dev/hidg + report_length - HID report length + subclass - HID device subclass to use diff --git a/Documentation/usb/gadget_hid.txt b/Documentation/usb/gadget_hid.txt index 12696c2e43fb..7a0fb8e16e27 100644 --- a/Documentation/usb/gadget_hid.txt +++ b/Documentation/usb/gadget_hid.txt @@ -74,6 +74,13 @@ static struct platform_device my_hid = { You can add as many HID functions as you want, only limited by the amount of interrupt endpoints your gadget driver supports. +Configuration with configfs + + Instead of adding fake platform devices and drivers in order to pass + some data to the kernel, if HID is a part of a gadget composed with + configfs the hidg_func_descriptor.report_desc is passed to the kernel + by writing the appropriate stream of bytes to a configfs attribute. + Send and receive HID reports HID reports can be sent/received using read/write on the diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index ea2d7706db6c..747ef53bda14 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -413,6 +413,16 @@ config USB_CONFIGFS_F_MIDI connections can then be made on the gadget system, using ALSA's aconnect utility etc. +config USB_CONFIGFS_F_HID + boolean "HID function" + depends on USB_CONFIGFS + select USB_F_HID + help + The HID function driver provides generic emulation of USB + Human Interface Devices (HID). + + For more information, see Documentation/usb/gadget_hid.txt. + source "drivers/usb/gadget/legacy/Kconfig" endchoice diff --git a/drivers/usb/gadget/function/f_hid.c b/drivers/usb/gadget/function/f_hid.c index dfdb4327ef3e..56ca3fc81555 100644 --- a/drivers/usb/gadget/function/f_hid.c +++ b/drivers/usb/gadget/function/f_hid.c @@ -690,6 +690,136 @@ static inline int hidg_get_minor(void) return ret; } +static inline struct f_hid_opts *to_f_hid_opts(struct config_item *item) +{ + return container_of(to_config_group(item), struct f_hid_opts, + func_inst.group); +} + +CONFIGFS_ATTR_STRUCT(f_hid_opts); +CONFIGFS_ATTR_OPS(f_hid_opts); + +static void hid_attr_release(struct config_item *item) +{ + struct f_hid_opts *opts = to_f_hid_opts(item); + + usb_put_function_instance(&opts->func_inst); +} + +static struct configfs_item_operations hidg_item_ops = { + .release = hid_attr_release, + .show_attribute = f_hid_opts_attr_show, + .store_attribute = f_hid_opts_attr_store, +}; + +#define F_HID_OPT(name, prec, limit) \ +static ssize_t f_hid_opts_##name##_show(struct f_hid_opts *opts, char *page)\ +{ \ + int result; \ + \ + mutex_lock(&opts->lock); \ + result = sprintf(page, "%d\n", opts->name); \ + mutex_unlock(&opts->lock); \ + \ + return result; \ +} \ + \ +static ssize_t f_hid_opts_##name##_store(struct f_hid_opts *opts, \ + const char *page, size_t len) \ +{ \ + int ret; \ + u##prec num; \ + \ + mutex_lock(&opts->lock); \ + if (opts->refcnt) { \ + ret = -EBUSY; \ + goto end; \ + } \ + \ + ret = kstrtou##prec(page, 0, &num); \ + if (ret) \ + goto end; \ + \ + if (num > limit) { \ + ret = -EINVAL; \ + goto end; \ + } \ + opts->name = num; \ + ret = len; \ + \ +end: \ + mutex_unlock(&opts->lock); \ + return ret; \ +} \ + \ +static struct f_hid_opts_attribute f_hid_opts_##name = \ + __CONFIGFS_ATTR(name, S_IRUGO | S_IWUSR, f_hid_opts_##name##_show,\ + f_hid_opts_##name##_store) + +F_HID_OPT(subclass, 8, 255); +F_HID_OPT(protocol, 8, 255); +F_HID_OPT(report_length, 16, 65536); + +static ssize_t f_hid_opts_report_desc_show(struct f_hid_opts *opts, char *page) +{ + int result; + + mutex_lock(&opts->lock); + result = opts->report_desc_length; + memcpy(page, opts->report_desc, opts->report_desc_length); + mutex_unlock(&opts->lock); + + return result; +} + +static ssize_t f_hid_opts_report_desc_store(struct f_hid_opts *opts, + const char *page, size_t len) +{ + int ret = -EBUSY; + char *d; + + mutex_lock(&opts->lock); + + if (opts->refcnt) + goto end; + if (len > PAGE_SIZE) { + ret = -ENOSPC; + goto end; + } + d = kmemdup(page, len, GFP_KERNEL); + if (!d) { + ret = -ENOMEM; + goto end; + } + kfree(opts->report_desc); + opts->report_desc = d; + opts->report_desc_length = len; + opts->report_desc_alloc = true; + ret = len; +end: + mutex_unlock(&opts->lock); + return ret; +} + +static struct f_hid_opts_attribute f_hid_opts_report_desc = + __CONFIGFS_ATTR(report_desc, S_IRUGO | S_IWUSR, + f_hid_opts_report_desc_show, + f_hid_opts_report_desc_store); + +static struct configfs_attribute *hid_attrs[] = { + &f_hid_opts_subclass.attr, + &f_hid_opts_protocol.attr, + &f_hid_opts_report_length.attr, + &f_hid_opts_report_desc.attr, + NULL, +}; + +static struct config_item_type hid_func_type = { + .ct_item_ops = &hidg_item_ops, + .ct_attrs = hid_attrs, + .ct_owner = THIS_MODULE, +}; + static inline void hidg_put_minor(int minor) { ida_simple_remove(&hidg_ida, minor); @@ -724,7 +854,7 @@ static struct usb_function_instance *hidg_alloc_inst(void) opts = kzalloc(sizeof(*opts), GFP_KERNEL); if (!opts) return ERR_PTR(-ENOMEM); - + mutex_init(&opts->lock); opts->func_inst.free_func_inst = hidg_free_inst; ret = &opts->func_inst; @@ -746,6 +876,7 @@ static struct usb_function_instance *hidg_alloc_inst(void) if (idr_is_empty(&hidg_ida.idr)) ghid_cleanup(); } + config_group_init_type_name(&opts->func_inst.group, "", &hid_func_type); unlock: mutex_unlock(&hidg_ida_lock); @@ -755,10 +886,15 @@ unlock: static void hidg_free(struct usb_function *f) { struct f_hidg *hidg; + struct f_hid_opts *opts; hidg = func_to_hidg(f); + opts = container_of(f->fi, struct f_hid_opts, func_inst); kfree(hidg->report_desc); kfree(hidg); + mutex_lock(&opts->lock); + --opts->refcnt; + mutex_unlock(&opts->lock); } static void hidg_unbind(struct usb_configuration *c, struct usb_function *f) @@ -789,6 +925,9 @@ struct usb_function *hidg_alloc(struct usb_function_instance *fi) opts = container_of(fi, struct f_hid_opts, func_inst); + mutex_lock(&opts->lock); + ++opts->refcnt; + hidg->minor = opts->minor; hidg->bInterfaceSubClass = opts->subclass; hidg->bInterfaceProtocol = opts->protocol; @@ -800,10 +939,13 @@ struct usb_function *hidg_alloc(struct usb_function_instance *fi) GFP_KERNEL); if (!hidg->report_desc) { kfree(hidg); + mutex_unlock(&opts->lock); return ERR_PTR(-ENOMEM); } } + mutex_unlock(&opts->lock); + hidg->func.name = "hid"; hidg->func.bind = hidg_bind; hidg->func.unbind = hidg_unbind; diff --git a/drivers/usb/gadget/function/u_hid.h b/drivers/usb/gadget/function/u_hid.h index 3edfc9567ab7..aaa0e368a159 100644 --- a/drivers/usb/gadget/function/u_hid.h +++ b/drivers/usb/gadget/function/u_hid.h @@ -27,6 +27,13 @@ struct f_hid_opts { unsigned short report_desc_length; unsigned char *report_desc; bool report_desc_alloc; + + /* + * Protect the data form concurrent access by read/write + * and create symlink/remove symlink. + */ + struct mutex lock; + int refcnt; }; int ghid_setup(struct usb_gadget *g, int count); -- cgit v1.2.3-59-g8ed1b From 5de985de12d18ceca5d60cfd9d72a03cdfa94f4f Mon Sep 17 00:00:00 2001 From: Gabriel FERNANDEZ Date: Tue, 4 Nov 2014 11:51:17 +0100 Subject: phy: miphy28lp: Add Device Tree bindings for the MiPHY28lp The MiPHY28lp is a Generic PHY which can serve various SATA or PCIe or USB3 devices. Signed-off-by: alexandre torgue Signed-off-by: Giuseppe Cavallaro Signed-off-by: Gabriel Fernandez Signed-off-by: Kishon Vijay Abraham I --- .../devicetree/bindings/phy/phy-miphy28lp.txt | 126 +++++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 Documentation/devicetree/bindings/phy/phy-miphy28lp.txt (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/phy/phy-miphy28lp.txt b/Documentation/devicetree/bindings/phy/phy-miphy28lp.txt new file mode 100644 index 000000000000..b7c13ad81a22 --- /dev/null +++ b/Documentation/devicetree/bindings/phy/phy-miphy28lp.txt @@ -0,0 +1,126 @@ +STMicroelectronics STi MIPHY28LP PHY binding +============================================ + +This binding describes a miphy device that is used to control PHY hardware +for SATA, PCIe or USB3. + +Required properties (controller (parent) node): +- compatible : Should be "st,miphy28lp-phy". +- st,syscfg : Should be a phandle of the system configuration register group + which contain the SATA, PCIe or USB3 mode setting bits. + +Required nodes : A sub-node is required for each channel the controller + provides. Address range information including the usual + 'reg' and 'reg-names' properties are used inside these + nodes to describe the controller's topology. These nodes + are translated by the driver's .xlate() function. + +Required properties (port (child) node): +- #phy-cells : Should be 1 (See second example) + Cell after port phandle is device type from: + - PHY_TYPE_SATA + - PHY_TYPE_PCI + - PHY_TYPE_USB3 +- reg : Address and length of the register set for the device. +- reg-names : The names of the register addresses corresponding to the registers + filled in "reg". It can also contain the offset of the system configuration + registers used as glue-logic to setup the device for SATA/PCIe or USB3 + devices. +- resets : phandle to the parent reset controller. +- reset-names : Associated name must be "miphy-sw-rst". + +Optional properties (port (child) node): +- st,osc-rdy : to check the MIPHY0_OSC_RDY status in the glue-logic. This + is not available in all the MiPHY. For example, for STiH407, only the + MiPHY0 has this bit. +- st,osc-force-ext : to select the external oscillator. This can change from + different MiPHY inside the same SoC. +- st,sata_gen : to select which SATA_SPDMODE has to be set in the SATA system config + register. +- st,px_rx_pol_inv : to invert polarity of RXn/RXp (respectively negative line and positive + line). + +example: + + miphy28lp_phy: miphy28lp@9b22000 { + compatible = "st,miphy28lp-phy"; + st,syscfg = <&syscfg_core>; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + phy_port0: port@9b22000 { + reg = <0x9b22000 0xff>, + <0x9b09000 0xff>, + <0x9b04000 0xff>, + <0x114 0x4>, /* sysctrl MiPHY cntrl */ + <0x818 0x4>, /* sysctrl MiPHY status*/ + <0xe0 0x4>, /* sysctrl PCIe */ + <0xec 0x4>; /* sysctrl SATA */ + reg-names = "sata-up", + "pcie-up", + "pipew", + "miphy-ctrl-glue", + "miphy-status-glue", + "pcie-glue", + "sata-glue"; + #phy-cells = <1>; + st,osc-rdy; + reset-names = "miphy-sw-rst"; + resets = <&softreset STIH407_MIPHY0_SOFTRESET>; + }; + + phy_port1: port@9b2a000 { + reg = <0x9b2a000 0xff>, + <0x9b19000 0xff>, + <0x9b14000 0xff>, + <0x118 0x4>, + <0x81c 0x4>, + <0xe4 0x4>, + <0xf0 0x4>; + reg-names = "sata-up", + "pcie-up", + "pipew", + "miphy-ctrl-glue", + "miphy-status-glue", + "pcie-glue", + "sata-glue"; + #phy-cells = <1>; + st,osc-force-ext; + reset-names = "miphy-sw-rst"; + resets = <&softreset STIH407_MIPHY1_SOFTRESET>; + }; + + phy_port2: port@8f95000 { + reg = <0x8f95000 0xff>, + <0x8f90000 0xff>, + <0x11c 0x4>, + <0x820 0x4>; + reg-names = "pipew", + "usb3-up", + "miphy-ctrl-glue", + "miphy-status-glue"; + #phy-cells = <1>; + reset-names = "miphy-sw-rst"; + resets = <&softreset STIH407_MIPHY2_SOFTRESET>; + }; + }; + + +Specifying phy control of devices +================================= + +Device nodes should specify the configuration required in their "phys" +property, containing a phandle to the miphy device node and an index +specifying which configuration to use, as described in phy-bindings.txt. + +example: + sata0: sata@9b20000 { + ... + phys = <&phy_port0 PHY_TYPE_SATA>; + ... + }; + +Macro definitions for the supported miphy configuration can be found in: + +include/dt-bindings/phy/phy-miphy28lp.h -- cgit v1.2.3-59-g8ed1b From 2b041b27a83fbe951d4b1cb1523001d4a8a5cccb Mon Sep 17 00:00:00 2001 From: Gabriel FERNANDEZ Date: Tue, 4 Nov 2014 11:51:21 +0100 Subject: phy: miphy28lp: Add SSC support for SATA This patch to tune on/off the ssc on miphy sata setup. User can now enable ssc via dt blob, it is useful to reduce effects of EMI. Signed-off-by: Giuseppe Condorelli Signed-off-by: Gabriel Fernandez Signed-off-by: Kishon Vijay Abraham I --- .../devicetree/bindings/phy/phy-miphy28lp.txt | 1 + drivers/phy/phy-miphy28lp.c | 46 ++++++++++++++++++++++ 2 files changed, 47 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/phy/phy-miphy28lp.txt b/Documentation/devicetree/bindings/phy/phy-miphy28lp.txt index b7c13ad81a22..4a3b4af3c1e6 100644 --- a/Documentation/devicetree/bindings/phy/phy-miphy28lp.txt +++ b/Documentation/devicetree/bindings/phy/phy-miphy28lp.txt @@ -39,6 +39,7 @@ Optional properties (port (child) node): register. - st,px_rx_pol_inv : to invert polarity of RXn/RXp (respectively negative line and positive line). +- st,scc-on : enable ssc to reduce effects of EMI (only for sata or PCIe). example: diff --git a/drivers/phy/phy-miphy28lp.c b/drivers/phy/phy-miphy28lp.c index 7d592e6392ac..d2f797c79fbc 100644 --- a/drivers/phy/phy-miphy28lp.c +++ b/drivers/phy/phy-miphy28lp.c @@ -191,6 +191,8 @@ #define SYSCFG_PCIE_PCIE_VAL 0x80 #define SATA_SPDMODE 1 +#define MIPHY_SATA_BANK_NB 3 + struct miphy28lp_phy { struct phy *phy; struct miphy28lp_dev *phydev; @@ -200,6 +202,7 @@ struct miphy28lp_phy { bool osc_force_ext; bool osc_rdy; bool px_rx_pol_inv; + bool ssc; struct reset_control *miphy_rst; @@ -550,6 +553,44 @@ static inline void miphy28_usb3_miphy_reset(struct miphy28lp_phy *miphy_phy) writeb_relaxed(0x00, base + MIPHY_CONF); } +static void miphy_sata_tune_ssc(struct miphy28lp_phy *miphy_phy) +{ + void __iomem *base = miphy_phy->base; + u8 val; + + /* Compensate Tx impedance to avoid out of range values */ + /* + * Enable the SSC on PLL for all banks + * SSC Modulation @ 31 KHz and 4000 ppm modulation amp + */ + val = readb_relaxed(base + MIPHY_BOUNDARY_2); + val |= SSC_EN_SW; + writeb_relaxed(val, base + MIPHY_BOUNDARY_2); + + val = readb_relaxed(base + MIPHY_BOUNDARY_SEL); + val |= SSC_SEL; + writeb_relaxed(val, base + MIPHY_BOUNDARY_SEL); + + for (val = 0; val < MIPHY_SATA_BANK_NB; val++) { + writeb_relaxed(val, base + MIPHY_CONF); + + /* Add value to each reference clock cycle */ + /* and define the period length of the SSC */ + writeb_relaxed(0x3c, base + MIPHY_PLL_SBR_2); + writeb_relaxed(0x6c, base + MIPHY_PLL_SBR_3); + writeb_relaxed(0x81, base + MIPHY_PLL_SBR_4); + + /* Clear any previous request */ + writeb_relaxed(0x00, base + MIPHY_PLL_SBR_1); + + /* requests the PLL to take in account new parameters */ + writeb_relaxed(SET_NEW_CHANGE, base + MIPHY_PLL_SBR_1); + + /* To be sure there is no other pending requests */ + writeb_relaxed(0x00, base + MIPHY_PLL_SBR_1); + } +} + static inline int miphy28lp_configure_sata(struct miphy28lp_phy *miphy_phy) { void __iomem *base = miphy_phy->base; @@ -585,6 +626,9 @@ static inline int miphy28lp_configure_sata(struct miphy28lp_phy *miphy_phy) writeb_relaxed(val, miphy_phy->base + MIPHY_CONTROL); } + if (miphy_phy->ssc) + miphy_sata_tune_ssc(miphy_phy); + return 0; } @@ -1064,6 +1108,8 @@ static int miphy28lp_of_probe(struct device_node *np, miphy_phy->px_rx_pol_inv = of_property_read_bool(np, "st,px_rx_pol_inv"); + miphy_phy->ssc = of_property_read_bool(np, "st,ssc-on"); + of_property_read_u32(np, "st,sata-gen", &miphy_phy->sata_gen); if (!miphy_phy->sata_gen) miphy_phy->sata_gen = SATA_GEN1; -- cgit v1.2.3-59-g8ed1b From 28ba384dc5e42a23328dca7e5e72d19e2dd4c9ce Mon Sep 17 00:00:00 2001 From: Gabriel FERNANDEZ Date: Tue, 4 Nov 2014 11:51:23 +0100 Subject: phy: miphy28lp: Tune tx impedance across Soc cuts This patch to compensate tx impedance (Sata, PCIe) depending on Soc cuts the kernel is built for. Signed-off-by: Giuseppe Condorelli Signed-off-by: Gabriel Fernandez Signed-off-by: Kishon Vijay Abraham I --- Documentation/devicetree/bindings/phy/phy-miphy28lp.txt | 1 + drivers/phy/phy-miphy28lp.c | 16 ++++++++++++++++ 2 files changed, 17 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/phy/phy-miphy28lp.txt b/Documentation/devicetree/bindings/phy/phy-miphy28lp.txt index 4a3b4af3c1e6..46a135dae6b3 100644 --- a/Documentation/devicetree/bindings/phy/phy-miphy28lp.txt +++ b/Documentation/devicetree/bindings/phy/phy-miphy28lp.txt @@ -40,6 +40,7 @@ Optional properties (port (child) node): - st,px_rx_pol_inv : to invert polarity of RXn/RXp (respectively negative line and positive line). - st,scc-on : enable ssc to reduce effects of EMI (only for sata or PCIe). +- st,tx-impedance-comp : to compensate tx impedance avoiding out of range values. example: diff --git a/drivers/phy/phy-miphy28lp.c b/drivers/phy/phy-miphy28lp.c index d8ff8956ed05..87dcc9ab7f23 100644 --- a/drivers/phy/phy-miphy28lp.c +++ b/drivers/phy/phy-miphy28lp.c @@ -204,6 +204,7 @@ struct miphy28lp_phy { bool osc_rdy; bool px_rx_pol_inv; bool ssc; + bool tx_impedance; struct reset_control *miphy_rst; @@ -632,6 +633,12 @@ static void miphy_pcie_tune_ssc(struct miphy28lp_phy *miphy_phy) } } +static inline void miphy_tune_tx_impedance(struct miphy28lp_phy *miphy_phy) +{ + /* Compensate Tx impedance to avoid out of range values */ + writeb_relaxed(0x02, miphy_phy->base + MIPHY_COMP_POSTP); +} + static inline int miphy28lp_configure_sata(struct miphy28lp_phy *miphy_phy) { void __iomem *base = miphy_phy->base; @@ -670,6 +677,9 @@ static inline int miphy28lp_configure_sata(struct miphy28lp_phy *miphy_phy) if (miphy_phy->ssc) miphy_sata_tune_ssc(miphy_phy); + if (miphy_phy->tx_impedance) + miphy_tune_tx_impedance(miphy_phy); + return 0; } @@ -703,6 +713,9 @@ static inline int miphy28lp_configure_pcie(struct miphy28lp_phy *miphy_phy) if (miphy_phy->ssc) miphy_pcie_tune_ssc(miphy_phy); + if (miphy_phy->tx_impedance) + miphy_tune_tx_impedance(miphy_phy); + return 0; } @@ -1154,6 +1167,9 @@ static int miphy28lp_of_probe(struct device_node *np, miphy_phy->ssc = of_property_read_bool(np, "st,ssc-on"); + miphy_phy->tx_impedance = + of_property_read_bool(np, "st,tx-impedance-comp"); + of_property_read_u32(np, "st,sata-gen", &miphy_phy->sata_gen); if (!miphy_phy->sata_gen) miphy_phy->sata_gen = SATA_GEN1; -- cgit v1.2.3-59-g8ed1b From ec4637bfff1c7d5f2bc7e51d180dd4aa51883af0 Mon Sep 17 00:00:00 2001 From: Sebastian Hesselbarth Date: Thu, 30 Oct 2014 11:21:26 +0100 Subject: phy: berlin-sata: Document BG2 compatible MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Berlin BG2 SATA PHY is slightly different from currently supported BG2Q SATA PHY. Document the new compatible for BG2's PHY. Acked-by: Antoine Ténart Signed-off-by: Sebastian Hesselbarth Signed-off-by: Kishon Vijay Abraham I --- Documentation/devicetree/bindings/phy/berlin-sata-phy.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/phy/berlin-sata-phy.txt b/Documentation/devicetree/bindings/phy/berlin-sata-phy.txt index 88f8c23384c0..c0155f842f62 100644 --- a/Documentation/devicetree/bindings/phy/berlin-sata-phy.txt +++ b/Documentation/devicetree/bindings/phy/berlin-sata-phy.txt @@ -2,7 +2,9 @@ Berlin SATA PHY --------------- Required properties: -- compatible: should be "marvell,berlin2q-sata-phy" +- compatible: should be one of + "marvell,berlin2-sata-phy" + "marvell,berlin2q-sata-phy" - address-cells: should be 1 - size-cells: should be 0 - phy-cells: from the generic PHY bindings, must be 1 -- cgit v1.2.3-59-g8ed1b From 2f3fa3a0e5672f87f5b972910737a2ef60941b62 Mon Sep 17 00:00:00 2001 From: Antoine Tenart Date: Thu, 20 Nov 2014 22:53:26 +0100 Subject: Documentation: bindings: add doc for the Berlin USB PHY Document the bindings of the Marvell Berlin USB PHY driver. Signed-off-by: Antoine Tenart Signed-off-by: Kishon Vijay Abraham I --- Documentation/devicetree/bindings/phy/berlin-usb-phy.txt | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 Documentation/devicetree/bindings/phy/berlin-usb-phy.txt (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/phy/berlin-usb-phy.txt b/Documentation/devicetree/bindings/phy/berlin-usb-phy.txt new file mode 100644 index 000000000000..be33780f668e --- /dev/null +++ b/Documentation/devicetree/bindings/phy/berlin-usb-phy.txt @@ -0,0 +1,16 @@ +* Marvell Berlin USB PHY + +Required properties: +- compatible: "marvell,berlin2-usb-phy" or "marvell,berlin2cd-usb-phy" +- reg: base address and length of the registers +- #phys-cells: should be 0 +- resets: reference to the reset controller + +Example: + + usb-phy@f774000 { + compatible = "marvell,berlin2-usb-phy"; + reg = <0xf774000 0x128>; + #phy-cells = <0>; + resets = <&chip 0x104 14>; + }; -- cgit v1.2.3-59-g8ed1b From b7bc15b98e843926d01eb03b9c0e196d8ddbadeb Mon Sep 17 00:00:00 2001 From: Heikki Krogerus Date: Wed, 19 Nov 2014 17:28:18 +0200 Subject: phy: improved lookup method Separates registration of the phy and the lookup. The method is copied from clkdev.c, Signed-off-by: Heikki Krogerus Signed-off-by: Kishon Vijay Abraham I --- Documentation/phy.txt | 60 ++++++++++------------------------- drivers/phy/phy-core.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++++- include/linux/phy/phy.h | 16 ++++++++++ 3 files changed, 115 insertions(+), 45 deletions(-) (limited to 'Documentation') diff --git a/Documentation/phy.txt b/Documentation/phy.txt index c6594af94d25..371361c69a4b 100644 --- a/Documentation/phy.txt +++ b/Documentation/phy.txt @@ -54,18 +54,14 @@ The PHY driver should create the PHY in order for other peripheral controllers to make use of it. The PHY framework provides 2 APIs to create the PHY. struct phy *phy_create(struct device *dev, struct device_node *node, - const struct phy_ops *ops, - struct phy_init_data *init_data); + const struct phy_ops *ops); struct phy *devm_phy_create(struct device *dev, struct device_node *node, - const struct phy_ops *ops, - struct phy_init_data *init_data); + const struct phy_ops *ops); The PHY drivers can use one of the above 2 APIs to create the PHY by passing -the device pointer, phy ops and init_data. +the device pointer and phy ops. phy_ops is a set of function pointers for performing PHY operations such as -init, exit, power_on and power_off. *init_data* is mandatory to get a reference -to the PHY in the case of non-dt boot. See section *Board File Initialization* -on how init_data should be used. +init, exit, power_on and power_off. Inorder to dereference the private data (in phy_ops), the phy provider driver can use phy_set_drvdata() after creating the PHY and use phy_get_drvdata() in @@ -137,42 +133,18 @@ There are exported APIs like phy_pm_runtime_get, phy_pm_runtime_get_sync, phy_pm_runtime_put, phy_pm_runtime_put_sync, phy_pm_runtime_allow and phy_pm_runtime_forbid for performing PM operations. -8. Board File Initialization - -Certain board file initialization is necessary in order to get a reference -to the PHY in the case of non-dt boot. -Say we have a single device that implements 3 PHYs that of USB, SATA and PCIe, -then in the board file the following initialization should be done. - -struct phy_consumer consumers[] = { - PHY_CONSUMER("dwc3.0", "usb"), - PHY_CONSUMER("pcie.0", "pcie"), - PHY_CONSUMER("sata.0", "sata"), -}; -PHY_CONSUMER takes 2 parameters, first is the device name of the controller -(PHY consumer) and second is the port name. - -struct phy_init_data init_data = { - .consumers = consumers, - .num_consumers = ARRAY_SIZE(consumers), -}; - -static const struct platform_device pipe3_phy_dev = { - .name = "pipe3-phy", - .id = -1, - .dev = { - .platform_data = { - .init_data = &init_data, - }, - }, -}; - -then, while doing phy_create, the PHY driver should pass this init_data - phy_create(dev, ops, pdata->init_data); - -and the controller driver (phy consumer) should pass the port name along with -the device to get a reference to the PHY - phy_get(dev, "pcie"); +8. PHY Mappings + +In order to get reference to a PHY without help from DeviceTree, the framework +offers lookups which can be compared to clkdev that allow clk structures to be +bound to devices. A lookup can be made be made during runtime when a handle to +the struct phy already exists. + +The framework offers the following API for registering and unregistering the +lookups. + +int phy_create_lookup(struct phy *phy, const char *con_id, const char *dev_id); +void phy_remove_lookup(struct phy *phy, const char *con_id, const char *dev_id); 9. DeviceTree Binding diff --git a/drivers/phy/phy-core.c b/drivers/phy/phy-core.c index 1606ce9805d0..bc830773fe05 100644 --- a/drivers/phy/phy-core.c +++ b/drivers/phy/phy-core.c @@ -26,6 +26,7 @@ static struct class *phy_class; static DEFINE_MUTEX(phy_provider_mutex); static LIST_HEAD(phy_provider_list); +static LIST_HEAD(phys); static DEFINE_IDA(phy_ida); static void devm_phy_release(struct device *dev, void *res) @@ -84,6 +85,87 @@ static struct phy *phy_lookup(struct device *device, const char *port) return ERR_PTR(-ENODEV); } +/** + * phy_create_lookup() - allocate and register PHY/device association + * @phy: the phy of the association + * @con_id: connection ID string on device + * @dev_id: the device of the association + * + * Creates and registers phy_lookup entry. + */ +int phy_create_lookup(struct phy *phy, const char *con_id, const char *dev_id) +{ + struct phy_lookup *pl; + + if (!phy || !dev_id || !con_id) + return -EINVAL; + + pl = kzalloc(sizeof(*pl), GFP_KERNEL); + if (!pl) + return -ENOMEM; + + pl->dev_id = dev_id; + pl->con_id = con_id; + pl->phy = phy; + + mutex_lock(&phy_provider_mutex); + list_add_tail(&pl->node, &phys); + mutex_unlock(&phy_provider_mutex); + + return 0; +} +EXPORT_SYMBOL_GPL(phy_create_lookup); + +/** + * phy_remove_lookup() - find and remove PHY/device association + * @phy: the phy of the association + * @con_id: connection ID string on device + * @dev_id: the device of the association + * + * Finds and unregisters phy_lookup entry that was created with + * phy_create_lookup(). + */ +void phy_remove_lookup(struct phy *phy, const char *con_id, const char *dev_id) +{ + struct phy_lookup *pl; + + if (!phy || !dev_id || !con_id) + return; + + mutex_lock(&phy_provider_mutex); + list_for_each_entry(pl, &phys, node) + if (pl->phy == phy && !strcmp(pl->dev_id, dev_id) && + !strcmp(pl->con_id, con_id)) { + list_del(&pl->node); + kfree(pl); + break; + } + mutex_unlock(&phy_provider_mutex); +} +EXPORT_SYMBOL_GPL(phy_remove_lookup); + +static struct phy *phy_find(struct device *dev, const char *con_id) +{ + const char *dev_id = dev_name(dev); + struct phy_lookup *p, *pl = NULL; + struct phy *phy; + + mutex_lock(&phy_provider_mutex); + list_for_each_entry(p, &phys, node) + if (!strcmp(p->dev_id, dev_id) && !strcmp(p->con_id, con_id)) { + pl = p; + break; + } + mutex_unlock(&phy_provider_mutex); + + phy = pl ? pl->phy : ERR_PTR(-ENODEV); + + /* fall-back to the old lookup method for now */ + if (IS_ERR(phy)) + phy = phy_lookup(dev, con_id); + return phy; +} + static struct phy_provider *of_phy_provider_lookup(struct device_node *node) { struct phy_provider *phy_provider; @@ -455,7 +537,7 @@ struct phy *phy_get(struct device *dev, const char *string) string); phy = _of_phy_get(dev->of_node, index); } else { - phy = phy_lookup(dev, string); + phy = phy_find(dev, string); } if (IS_ERR(phy)) return phy; diff --git a/include/linux/phy/phy.h b/include/linux/phy/phy.h index 9fda68324298..849284e5873f 100644 --- a/include/linux/phy/phy.h +++ b/include/linux/phy/phy.h @@ -110,6 +110,13 @@ struct phy_init_data { .port = _port, \ } +struct phy_lookup { + struct list_head node; + const char *dev_id; + const char *con_id; + struct phy *phy; +}; + #define to_phy(a) (container_of((a), struct phy, dev)) #define of_phy_provider_register(dev, xlate) \ @@ -174,6 +181,8 @@ struct phy_provider *__devm_of_phy_provider_register(struct device *dev, void of_phy_provider_unregister(struct phy_provider *phy_provider); void devm_of_phy_provider_unregister(struct device *dev, struct phy_provider *phy_provider); +int phy_create_lookup(struct phy *phy, const char *con_id, const char *dev_id); +void phy_remove_lookup(struct phy *phy, const char *con_id, const char *dev_id); #else static inline int phy_pm_runtime_get(struct phy *phy) { @@ -345,6 +354,13 @@ static inline void devm_of_phy_provider_unregister(struct device *dev, struct phy_provider *phy_provider) { } +static inline int +phy_create_lookup(struct phy *phy, const char *con_id, const char *dev_id) +{ + return 0; +} +static inline void phy_remove_lookup(struct phy *phy, const char *con_id, + const char *dev_id) { } #endif #endif /* __DRIVERS_PHY_H */ -- cgit v1.2.3-59-g8ed1b From ed692a99f31c92ec649ee2f7a0ecb4aa0f69d853 Mon Sep 17 00:00:00 2001 From: Vivek Gautam Date: Fri, 21 Nov 2014 19:05:47 +0530 Subject: usb: dwc3: exynos: Add provision for AXI UpScaler clock on exynos7 DWC3 controller on Exynos7 SoC has separate control for AXI UpScaler which connects DWC3 DRD controller to AXI bus. Get the gate clock for the same to control it across power cycles. Suggested-by: Anton Tikhomirov Signed-off-by: Vivek Gautam Signed-off-by: Felipe Balbi --- Documentation/devicetree/bindings/usb/exynos-usb.txt | 6 ++++-- drivers/usb/dwc3/dwc3-exynos.c | 17 +++++++++++++++++ 2 files changed, 21 insertions(+), 2 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/usb/exynos-usb.txt b/Documentation/devicetree/bindings/usb/exynos-usb.txt index a3b5990d0f2c..9b4dbe3b2acc 100644 --- a/Documentation/devicetree/bindings/usb/exynos-usb.txt +++ b/Documentation/devicetree/bindings/usb/exynos-usb.txt @@ -82,8 +82,10 @@ Example: DWC3 Required properties: - - compatible: should be "samsung,exynos5250-dwusb3" for USB 3.0 DWC3 - controller. + - compatible: should be one of the following - + "samsung,exynos5250-dwusb3": for USB 3.0 DWC3 controller on + Exynos5250/5420. + "samsung,exynos7-dwusb3": for USB 3.0 DWC3 controller on Exynos7. - #address-cells, #size-cells : should be '1' if the device has sub-nodes with 'reg' property. - ranges: allows valid 1:1 translation between child's address space and diff --git a/drivers/usb/dwc3/dwc3-exynos.c b/drivers/usb/dwc3/dwc3-exynos.c index a1782d86a226..7bd0a95b2815 100644 --- a/drivers/usb/dwc3/dwc3-exynos.c +++ b/drivers/usb/dwc3/dwc3-exynos.c @@ -35,6 +35,7 @@ struct dwc3_exynos { struct clk *clk; struct clk *susp_clk; + struct clk *axius_clk; struct regulator *vdd33; struct regulator *vdd10; @@ -149,6 +150,17 @@ static int dwc3_exynos_probe(struct platform_device *pdev) } clk_prepare_enable(exynos->susp_clk); + if (of_device_is_compatible(node, "samsung,exynos7-dwusb3")) { + exynos->axius_clk = devm_clk_get(dev, "usbdrd30_axius_clk"); + if (IS_ERR(exynos->axius_clk)) { + dev_err(dev, "no AXI UpScaler clk specified\n"); + return -ENODEV; + } + clk_prepare_enable(exynos->axius_clk); + } else { + exynos->axius_clk = NULL; + } + exynos->vdd33 = devm_regulator_get(dev, "vdd33"); if (IS_ERR(exynos->vdd33)) { ret = PTR_ERR(exynos->vdd33); @@ -190,6 +202,7 @@ err4: err3: regulator_disable(exynos->vdd33); err2: + clk_disable_unprepare(exynos->axius_clk); clk_disable_unprepare(exynos->susp_clk); clk_disable_unprepare(exynos->clk); return ret; @@ -203,6 +216,7 @@ static int dwc3_exynos_remove(struct platform_device *pdev) platform_device_unregister(exynos->usb2_phy); platform_device_unregister(exynos->usb3_phy); + clk_disable_unprepare(exynos->axius_clk); clk_disable_unprepare(exynos->susp_clk); clk_disable_unprepare(exynos->clk); @@ -214,6 +228,7 @@ static int dwc3_exynos_remove(struct platform_device *pdev) static const struct of_device_id exynos_dwc3_match[] = { { .compatible = "samsung,exynos5250-dwusb3" }, + { .compatible = "samsung,exynos7-dwusb3" }, {}, }; MODULE_DEVICE_TABLE(of, exynos_dwc3_match); @@ -223,6 +238,7 @@ static int dwc3_exynos_suspend(struct device *dev) { struct dwc3_exynos *exynos = dev_get_drvdata(dev); + clk_disable(exynos->axius_clk); clk_disable(exynos->clk); regulator_disable(exynos->vdd33); @@ -248,6 +264,7 @@ static int dwc3_exynos_resume(struct device *dev) } clk_enable(exynos->clk); + clk_enable(exynos->axius_clk); /* runtime set active to reflect active state. */ pm_runtime_disable(dev); -- cgit v1.2.3-59-g8ed1b From 9bde18c1b5d2c9a1b90fc0f3bbe1a314194f6fdf Mon Sep 17 00:00:00 2001 From: Vivek Gautam Date: Fri, 21 Nov 2014 19:05:48 +0530 Subject: phy: exynos5-usbdrd: Add pipe-clk, utmi-clk and itp-clk support Exynos7 SoC has now separate gate control for 125MHz pipe3 phy clock, as well as 60MHz utmi phy clock. Additionally, separate gate control is available for the clock used for ITP (Isochronous Transfer Packet) generation. So get the same and control in the phy-exynos5-usbdrd driver. Suggested-by: Anton Tikhomirov Signed-off-by: Vivek Gautam Signed-off-by: Kishon Vijay Abraham I --- .../devicetree/bindings/phy/samsung-phy.txt | 6 ++ drivers/phy/phy-exynos5-usbdrd.c | 104 +++++++++++++++++---- 2 files changed, 92 insertions(+), 18 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/phy/samsung-phy.txt b/Documentation/devicetree/bindings/phy/samsung-phy.txt index 15e0f2c7130f..d5bad920827f 100644 --- a/Documentation/devicetree/bindings/phy/samsung-phy.txt +++ b/Documentation/devicetree/bindings/phy/samsung-phy.txt @@ -128,6 +128,7 @@ Required properties: - compatible : Should be set to one of the following supported values: - "samsung,exynos5250-usbdrd-phy" - for exynos5250 SoC, - "samsung,exynos5420-usbdrd-phy" - for exynos5420 SoC. + - "samsung,exynos7-usbdrd-phy" - for exynos7 SoC. - reg : Register offset and length of USB DRD PHY register set; - clocks: Clock IDs array as required by the controller - clock-names: names of clocks correseponding to IDs in the clock property; @@ -138,6 +139,11 @@ Required properties: PHY operations, associated by phy name. It is used to determine bit values for clock settings register. For Exynos5420 this is given as 'sclk_usbphy30' in CMU. + - optional clocks: Exynos7 SoC has now following additional + gate clocks available: + - phy_pipe: for PIPE3 phy + - phy_utmi: for UTMI+ phy + - itp: for ITP generation - samsung,pmu-syscon: phandle for PMU system controller interface, used to control pmu registers for power isolation. - #phy-cells : from the generic PHY bindings, must be 1; diff --git a/drivers/phy/phy-exynos5-usbdrd.c b/drivers/phy/phy-exynos5-usbdrd.c index b3ca3bc2314f..99ba56dc63dd 100644 --- a/drivers/phy/phy-exynos5-usbdrd.c +++ b/drivers/phy/phy-exynos5-usbdrd.c @@ -141,6 +141,7 @@ struct exynos5_usbdrd_phy_drvdata { const struct exynos5_usbdrd_phy_config *phy_cfg; u32 pmu_offset_usbdrd0_phy; u32 pmu_offset_usbdrd1_phy; + bool has_common_clk_gate; }; /** @@ -148,6 +149,9 @@ struct exynos5_usbdrd_phy_drvdata { * @dev: pointer to device instance of this platform device * @reg_phy: usb phy controller register memory base * @clk: phy clock for register access + * @pipeclk: clock for pipe3 phy + * @utmiclk: clock for utmi+ phy + * @itpclk: clock for ITP generation * @drv_data: pointer to SoC level driver data structure * @phys[]: array for 'EXYNOS5_DRDPHYS_NUM' number of PHY * instances each with its 'phy' and 'phy_cfg'. @@ -155,12 +159,14 @@ struct exynos5_usbdrd_phy_drvdata { * reference clocks' for SS and HS operations * @ref_clk: reference clock to PHY block from which PHY's * operational clocks are derived - * @ref_rate: rate of above reference clock */ struct exynos5_usbdrd_phy { struct device *dev; void __iomem *reg_phy; struct clk *clk; + struct clk *pipeclk; + struct clk *utmiclk; + struct clk *itpclk; const struct exynos5_usbdrd_phy_drvdata *drv_data; struct phy_usb_instance { struct phy *phy; @@ -447,6 +453,11 @@ static int exynos5_usbdrd_phy_power_on(struct phy *phy) dev_dbg(phy_drd->dev, "Request to power_on usbdrd_phy phy\n"); clk_prepare_enable(phy_drd->ref_clk); + if (!phy_drd->drv_data->has_common_clk_gate) { + clk_prepare_enable(phy_drd->pipeclk); + clk_prepare_enable(phy_drd->utmiclk); + clk_prepare_enable(phy_drd->itpclk); + } /* Enable VBUS supply */ if (phy_drd->vbus) { @@ -464,6 +475,11 @@ static int exynos5_usbdrd_phy_power_on(struct phy *phy) fail_vbus: clk_disable_unprepare(phy_drd->ref_clk); + if (!phy_drd->drv_data->has_common_clk_gate) { + clk_disable_unprepare(phy_drd->itpclk); + clk_disable_unprepare(phy_drd->utmiclk); + clk_disable_unprepare(phy_drd->pipeclk); + } return ret; } @@ -483,6 +499,11 @@ static int exynos5_usbdrd_phy_power_off(struct phy *phy) regulator_disable(phy_drd->vbus); clk_disable_unprepare(phy_drd->ref_clk); + if (!phy_drd->drv_data->has_common_clk_gate) { + clk_disable_unprepare(phy_drd->itpclk); + clk_disable_unprepare(phy_drd->pipeclk); + clk_disable_unprepare(phy_drd->utmiclk); + } return 0; } @@ -506,6 +527,57 @@ static struct phy_ops exynos5_usbdrd_phy_ops = { .owner = THIS_MODULE, }; +static int exynos5_usbdrd_phy_clk_handle(struct exynos5_usbdrd_phy *phy_drd) +{ + unsigned long ref_rate; + int ret; + + phy_drd->clk = devm_clk_get(phy_drd->dev, "phy"); + if (IS_ERR(phy_drd->clk)) { + dev_err(phy_drd->dev, "Failed to get phy clock\n"); + return PTR_ERR(phy_drd->clk); + } + + phy_drd->ref_clk = devm_clk_get(phy_drd->dev, "ref"); + if (IS_ERR(phy_drd->ref_clk)) { + dev_err(phy_drd->dev, "Failed to get phy reference clock\n"); + return PTR_ERR(phy_drd->ref_clk); + } + ref_rate = clk_get_rate(phy_drd->ref_clk); + + ret = exynos5_rate_to_clk(ref_rate, &phy_drd->extrefclk); + if (ret) { + dev_err(phy_drd->dev, "Clock rate (%ld) not supported\n", + ref_rate); + return ret; + } + + if (!phy_drd->drv_data->has_common_clk_gate) { + phy_drd->pipeclk = devm_clk_get(phy_drd->dev, "phy_pipe"); + if (IS_ERR(phy_drd->pipeclk)) { + dev_info(phy_drd->dev, + "PIPE3 phy operational clock not specified\n"); + phy_drd->pipeclk = NULL; + } + + phy_drd->utmiclk = devm_clk_get(phy_drd->dev, "phy_utmi"); + if (IS_ERR(phy_drd->utmiclk)) { + dev_info(phy_drd->dev, + "UTMI phy operational clock not specified\n"); + phy_drd->utmiclk = NULL; + } + + phy_drd->itpclk = devm_clk_get(phy_drd->dev, "itp"); + if (IS_ERR(phy_drd->itpclk)) { + dev_info(phy_drd->dev, + "ITP clock from main OSC not specified\n"); + phy_drd->itpclk = NULL; + } + } + + return 0; +} + static const struct exynos5_usbdrd_phy_config phy_cfg_exynos5[] = { { .id = EXYNOS5_DRDPHY_UTMI, @@ -525,11 +597,19 @@ static const struct exynos5_usbdrd_phy_drvdata exynos5420_usbdrd_phy = { .phy_cfg = phy_cfg_exynos5, .pmu_offset_usbdrd0_phy = EXYNOS5_USBDRD_PHY_CONTROL, .pmu_offset_usbdrd1_phy = EXYNOS5420_USBDRD1_PHY_CONTROL, + .has_common_clk_gate = true, }; static const struct exynos5_usbdrd_phy_drvdata exynos5250_usbdrd_phy = { .phy_cfg = phy_cfg_exynos5, .pmu_offset_usbdrd0_phy = EXYNOS5_USBDRD_PHY_CONTROL, + .has_common_clk_gate = true, +}; + +static const struct exynos5_usbdrd_phy_drvdata exynos7_usbdrd_phy = { + .phy_cfg = phy_cfg_exynos5, + .pmu_offset_usbdrd0_phy = EXYNOS5_USBDRD_PHY_CONTROL, + .has_common_clk_gate = false, }; static const struct of_device_id exynos5_usbdrd_phy_of_match[] = { @@ -539,6 +619,9 @@ static const struct of_device_id exynos5_usbdrd_phy_of_match[] = { }, { .compatible = "samsung,exynos5420-usbdrd-phy", .data = &exynos5420_usbdrd_phy + }, { + .compatible = "samsung,exynos7-usbdrd-phy", + .data = &exynos7_usbdrd_phy }, { }, }; @@ -555,7 +638,6 @@ static int exynos5_usbdrd_phy_probe(struct platform_device *pdev) const struct exynos5_usbdrd_phy_drvdata *drv_data; struct regmap *reg_pmu; u32 pmu_offset; - unsigned long ref_rate; int i, ret; int channel; @@ -576,23 +658,9 @@ static int exynos5_usbdrd_phy_probe(struct platform_device *pdev) drv_data = match->data; phy_drd->drv_data = drv_data; - phy_drd->clk = devm_clk_get(dev, "phy"); - if (IS_ERR(phy_drd->clk)) { - dev_err(dev, "Failed to get clock of phy controller\n"); - return PTR_ERR(phy_drd->clk); - } - - phy_drd->ref_clk = devm_clk_get(dev, "ref"); - if (IS_ERR(phy_drd->ref_clk)) { - dev_err(dev, "Failed to get reference clock of usbdrd phy\n"); - return PTR_ERR(phy_drd->ref_clk); - } - ref_rate = clk_get_rate(phy_drd->ref_clk); - - ret = exynos5_rate_to_clk(ref_rate, &phy_drd->extrefclk); + ret = exynos5_usbdrd_phy_clk_handle(phy_drd); if (ret) { - dev_err(phy_drd->dev, "Clock rate (%ld) not supported\n", - ref_rate); + dev_err(dev, "Failed to initialize clocks\n"); return ret; } -- cgit v1.2.3-59-g8ed1b From aa1facbd2847263cf168ec7d66e6c8951c413905 Mon Sep 17 00:00:00 2001 From: Andrew Lunn Date: Thu, 13 Nov 2014 12:47:44 +0100 Subject: Phy: DT binding documentation for Marvell MVEBU SATA phy. Describe the binding for the Marvell MVEBU SATA phy. This driver can be used at least with Kirkwood, Dove and maybe others. Additionally, update the SATA binding with the properties to link to the phy nodes. Signed-off-by: Andrew Lunn Acked-by: Jason Cooper Signed-off-by: Kishon Vijay Abraham I --- Documentation/devicetree/bindings/ata/marvell.txt | 6 ++++++ .../devicetree/bindings/phy/phy-mvebu.txt | 22 ++++++++++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 Documentation/devicetree/bindings/phy/phy-mvebu.txt (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/ata/marvell.txt b/Documentation/devicetree/bindings/ata/marvell.txt index 1c8351604d38..b460edd12766 100644 --- a/Documentation/devicetree/bindings/ata/marvell.txt +++ b/Documentation/devicetree/bindings/ata/marvell.txt @@ -6,11 +6,17 @@ Required Properties: - interrupts : Interrupt controller is using - nr-ports : Number of SATA ports in use. +Optional Properties: +- phys : List of phandles to sata phys +- phy-names : Should be "0", "1", etc, one number per phandle + Example: sata@80000 { compatible = "marvell,orion-sata"; reg = <0x80000 0x5000>; interrupts = <21>; + phys = <&sata_phy0>, <&sata_phy1>; + phy-names = "0", "1"; nr-ports = <2>; } diff --git a/Documentation/devicetree/bindings/phy/phy-mvebu.txt b/Documentation/devicetree/bindings/phy/phy-mvebu.txt new file mode 100644 index 000000000000..6cb3364aeafb --- /dev/null +++ b/Documentation/devicetree/bindings/phy/phy-mvebu.txt @@ -0,0 +1,22 @@ +* Marvell MVEBU SATA PHY + +Power control for the SATA phy found on Marvell MVEBU SoCs. + +This document extends the binding described in phy-bindings.txt + +Required properties : + + - reg : Offset and length of the register set for the SATA device + - compatible : Should be "marvell,mvebu-sata-phy" + - clocks : phandle of clock and specifier that supplies the device + - clock-names : Should be "sata" + +Example: + sata-phy@84000 { + compatible = "marvell,mvebu-sata-phy"; + reg = <0x84000 0x0334>; + clocks = <&gate_clk 15>; + clock-names = "sata"; + #phy-cells = <0>; + status = "ok"; + }; -- cgit v1.2.3-59-g8ed1b From 1a6ab1c0e844041524f8edd1acf0de94df991aaa Mon Sep 17 00:00:00 2001 From: Gregory CLEMENT Date: Thu, 13 Nov 2014 12:47:45 +0100 Subject: Phy: DT binding documentation for the Armada 375 USB cluster binding Armada 375 comes with an USB2 host and device controller and an USB3 controller. The USB cluster control register allows to manage common features of both USB controllers. This commit adds the Device Tree binding documentation for this piece of hardware. Signed-off-by: Gregory CLEMENT Acked-by: Jason Cooper Signed-off-by: Kishon Vijay Abraham I --- Documentation/devicetree/bindings/phy/phy-mvebu.txt | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/phy/phy-mvebu.txt b/Documentation/devicetree/bindings/phy/phy-mvebu.txt index 6cb3364aeafb..f95b6260a3b3 100644 --- a/Documentation/devicetree/bindings/phy/phy-mvebu.txt +++ b/Documentation/devicetree/bindings/phy/phy-mvebu.txt @@ -20,3 +20,24 @@ Example: #phy-cells = <0>; status = "ok"; }; + +Armada 375 USB cluster +---------------------- + +Armada 375 comes with an USB2 host and device controller and an USB3 +controller. The USB cluster control register allows to manage common +features of both USB controllers. + +Required properties: + +- compatible: "marvell,armada-375-usb-cluster" +- reg: Should contain usb cluster register location and length. +- #phy-cells : from the generic phy bindings, must be 1. Possible +values are 1 (USB2), 2 (USB3). + +Example: + usbcluster: usb-cluster@18400 { + compatible = "marvell,armada-375-usb-cluster"; + reg = <0x18400 0x4>; + #phy-cells = <1> + }; -- cgit v1.2.3-59-g8ed1b From d7d30c911dd957e274c3da6910d4286862ab1d78 Mon Sep 17 00:00:00 2001 From: Antoine Tenart Date: Wed, 26 Nov 2014 13:44:37 +0800 Subject: Documentation: bindings: add doc for the USB2 ChipIdea USB driver Document the USB2 ChipIdea driver (ci13xxx) bindings. Signed-off-by: Antoine Tenart Acked-by: Peter Chen Signed-off-by: Peter Chen Signed-off-by: Greg Kroah-Hartman --- .../devicetree/bindings/usb/ci-hdrc-usb2.txt | 24 ++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt b/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt new file mode 100644 index 000000000000..27f8b1e5ee46 --- /dev/null +++ b/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt @@ -0,0 +1,24 @@ +* USB2 ChipIdea USB controller for ci13xxx + +Required properties: +- compatible: should be "chipidea,usb2" +- reg: base address and length of the registers +- interrupts: interrupt for the USB controller + +Optional properties: +- clocks: reference to the USB clock +- phys: reference to the USB PHY +- phy-names: should be "usb-phy" +- vbus-supply: reference to the VBUS regulator + +Example: + + usb@f7ed0000 { + compatible = "chipidea,usb2"; + reg = <0xf7ed0000 0x10000>; + interrupts = ; + clocks = <&chip CLKID_USB0>; + phys = <&usb_phy0>; + phy-names = "usb-phy"; + vbus-supply = <®_usb0_vbus>; + }; -- cgit v1.2.3-59-g8ed1b