From patchwork Thu Jan 12 21:58:55 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Biju Das X-Patchwork-Id: 641939 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7E745C678D8 for ; Thu, 12 Jan 2023 22:09:09 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240313AbjALWJH (ORCPT ); Thu, 12 Jan 2023 17:09:07 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57872 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240365AbjALWIe (ORCPT ); Thu, 12 Jan 2023 17:08:34 -0500 Received: from relmlie5.idc.renesas.com (relmlor1.renesas.com [210.160.252.171]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id F4228225; Thu, 12 Jan 2023 13:59:16 -0800 (PST) X-IronPort-AV: E=Sophos;i="5.97,212,1669042800"; d="scan'208";a="146137073" Received: from unknown (HELO relmlir5.idc.renesas.com) ([10.200.68.151]) by relmlie5.idc.renesas.com with ESMTP; 13 Jan 2023 06:59:16 +0900 Received: from localhost.localdomain (unknown [10.226.92.132]) by relmlir5.idc.renesas.com (Postfix) with ESMTP id 20D15400A66D; Fri, 13 Jan 2023 06:59:12 +0900 (JST) From: Biju Das To: Rob Herring , Krzysztof Kozlowski Cc: Biju Das , Greg Kroah-Hartman , Lad Prabhakar , Yoshihiro Shimoda , linux-usb@vger.kernel.org, devicetree@vger.kernel.org, Geert Uytterhoeven , Fabrizio Castro , linux-renesas-soc@vger.kernel.org, Rob Herring Subject: [PATCH v2 01/12] dt-bindings: usb: renesas, usb-xhci: Document RZ/V2M support Date: Thu, 12 Jan 2023 21:58:55 +0000 Message-Id: <20230112215906.494394-2-biju.das.jz@bp.renesas.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230112215906.494394-1-biju.das.jz@bp.renesas.com> References: <20230112215906.494394-1-biju.das.jz@bp.renesas.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org Document the RZ/V2M SoC bindings. The RZ/V2M SoC is a little different to the R-Car implementations. You can access the registers associated with the currently set DRD mode, therefore as part of init, we have to set the DRD mode to host. Signed-off-by: Biju Das Reviewed-by: Rob Herring --- v1->v2: * Added Rb tag from Rob * Renamed clock-name "host_axi"->"axi" * Drop quotes around usb-xhci.yaml. --- .../bindings/usb/renesas,usb-xhci.yaml | 41 +++++++++++++++++-- 1 file changed, 37 insertions(+), 4 deletions(-) diff --git a/Documentation/devicetree/bindings/usb/renesas,usb-xhci.yaml b/Documentation/devicetree/bindings/usb/renesas,usb-xhci.yaml index 4c5efaf02308..1a07c0d2b1b1 100644 --- a/Documentation/devicetree/bindings/usb/renesas,usb-xhci.yaml +++ b/Documentation/devicetree/bindings/usb/renesas,usb-xhci.yaml @@ -10,9 +10,6 @@ maintainers: - Lad Prabhakar - Yoshihiro Shimoda -allOf: - - $ref: "usb-xhci.yaml" - properties: compatible: oneOf: @@ -37,6 +34,11 @@ properties: - renesas,xhci-r8a77965 # R-Car M3-N - renesas,xhci-r8a77990 # R-Car E3 - const: renesas,rcar-gen3-xhci # R-Car Gen3 and RZ/G2 + - items: + - enum: + - renesas,r9a09g011-xhci # RZ/V2M + - renesas,r9a09g055-xhci # RZ/V2MA + - const: renesas,rzv2m-xhci # RZ/{V2M, V2MA} reg: maxItems: 1 @@ -45,7 +47,16 @@ properties: maxItems: 1 clocks: - maxItems: 1 + minItems: 1 + items: + - description: Main clock for host + - description: Register access clock + + clock-names: + minItems: 1 + items: + - const: axi + - const: reg phys: maxItems: 1 @@ -68,6 +79,28 @@ required: - power-domains - resets +allOf: + - $ref: usb-xhci.yaml + + - if: + properties: + compatible: + contains: + enum: + - renesas,rzv2m-xhci + then: + properties: + clocks: + minItems: 2 + clock-names: + minItems: 2 + required: + - clock-names + else: + properties: + clocks: + maxItems: 1 + unevaluatedProperties: false examples: From patchwork Thu Jan 12 21:58:57 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Biju Das X-Patchwork-Id: 641938 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 767C7C54EBE for ; Thu, 12 Jan 2023 22:09:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240405AbjALWJM (ORCPT ); Thu, 12 Jan 2023 17:09:12 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56228 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240413AbjALWIf (ORCPT ); Thu, 12 Jan 2023 17:08:35 -0500 Received: from relmlie5.idc.renesas.com (relmlor1.renesas.com [210.160.252.171]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 43269F76; Thu, 12 Jan 2023 13:59:24 -0800 (PST) X-IronPort-AV: E=Sophos;i="5.97,212,1669042800"; d="scan'208";a="146137080" Received: from unknown (HELO relmlir5.idc.renesas.com) ([10.200.68.151]) by relmlie5.idc.renesas.com with ESMTP; 13 Jan 2023 06:59:24 +0900 Received: from localhost.localdomain (unknown [10.226.92.132]) by relmlir5.idc.renesas.com (Postfix) with ESMTP id D9C26400B9F8; Fri, 13 Jan 2023 06:59:20 +0900 (JST) From: Biju Das To: Rob Herring , Krzysztof Kozlowski Cc: Biju Das , Greg Kroah-Hartman , Yoshihiro Shimoda , linux-usb@vger.kernel.org, devicetree@vger.kernel.org, Geert Uytterhoeven , Fabrizio Castro , linux-renesas-soc@vger.kernel.org Subject: [PATCH v2 03/12] dt-bindings: usb: renesas,usb3-peri: Document RZ/V2MA bindings Date: Thu, 12 Jan 2023 21:58:57 +0000 Message-Id: <20230112215906.494394-4-biju.das.jz@bp.renesas.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230112215906.494394-1-biju.das.jz@bp.renesas.com> References: <20230112215906.494394-1-biju.das.jz@bp.renesas.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org Document RZ/V2MA usb3-peri bindings. RZ/V2MA usb3-peri is identical to one found on the RZ/V2M SoC. No driver changes are required as generic compatible string "renesas,rzv2m-usb3-peri" will be used as a fallback. Signed-off-by: Biju Das Acked-by: Rob Herring --- v1->v2: * No change --- Documentation/devicetree/bindings/usb/renesas,usb3-peri.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/usb/renesas,usb3-peri.yaml b/Documentation/devicetree/bindings/usb/renesas,usb3-peri.yaml index 4ba36ebf0f1e..b2b811a0ade8 100644 --- a/Documentation/devicetree/bindings/usb/renesas,usb3-peri.yaml +++ b/Documentation/devicetree/bindings/usb/renesas,usb3-peri.yaml @@ -28,6 +28,7 @@ properties: - items: - enum: - renesas,r9a09g011-usb3-peri # RZ/V2M + - renesas,r9a09g055-usb3-peri # RZ/V2MA - const: renesas,rzv2m-usb3-peri reg: From patchwork Thu Jan 12 21:58:59 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Biju Das X-Patchwork-Id: 641937 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3D1AEC61DB3 for ; Thu, 12 Jan 2023 22:09:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230178AbjALWJj (ORCPT ); Thu, 12 Jan 2023 17:09:39 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58862 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233096AbjALWIs (ORCPT ); Thu, 12 Jan 2023 17:08:48 -0500 Received: from relmlie6.idc.renesas.com (relmlor2.renesas.com [210.160.252.172]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id EF74DC61; Thu, 12 Jan 2023 13:59:32 -0800 (PST) X-IronPort-AV: E=Sophos;i="5.97,212,1669042800"; d="scan'208";a="149165229" Received: from unknown (HELO relmlir5.idc.renesas.com) ([10.200.68.151]) by relmlie6.idc.renesas.com with ESMTP; 13 Jan 2023 06:59:32 +0900 Received: from localhost.localdomain (unknown [10.226.92.132]) by relmlir5.idc.renesas.com (Postfix) with ESMTP id ED9DA400A8BB; Fri, 13 Jan 2023 06:59:27 +0900 (JST) From: Biju Das To: Philipp Zabel Cc: Biju Das , Greg Kroah-Hartman , Tony Lindgren , Arnd Bergmann , Jean Delvare , Hans-Christian Noren Egtvedt , Neal Liu , Linus Walleij , Randy Dunlap , Adam Ford , Yoshihiro Shimoda , Geert Uytterhoeven , linux-usb@vger.kernel.org, Fabrizio Castro , linux-renesas-soc@vger.kernel.org Subject: [PATCH v2 05/12] usb: gadget: Add support for RZ/V2M USB3DRD driver Date: Thu, 12 Jan 2023 21:58:59 +0000 Message-Id: <20230112215906.494394-6-biju.das.jz@bp.renesas.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230112215906.494394-1-biju.das.jz@bp.renesas.com> References: <20230112215906.494394-1-biju.das.jz@bp.renesas.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org The RZ/V2M USB3.1 Gen1 Interface (USB) composed of a USB3.1 Gen1 Dual Role Device controller (USB3DRD), a USB3.1 Gen1 Host controller (USB3HOST), a USB3.1 Gen1 Peripheral controller (USB3PERI). The reset for both host and peri are located in USB3DRD block. The USB3DRD registers are mapped in the AXI address space of the Peripheral module. Add USB3DRD driver to handle reset for both host and peri modules. Signed-off-by: Biju Das --- v1->v2: * Moved header file from include/linux/soc/renesas->include/linux/usb * Passing DRD irq resource to usb3_peri for handling it. * As drd_reg is now seperate, updated DRD reg handling in usb3 peri driver. * Removed usb3 peri reset from DRD driver. --- drivers/usb/gadget/udc/Kconfig | 7 ++ drivers/usb/gadget/udc/Makefile | 1 + drivers/usb/gadget/udc/renesas_usb3.c | 102 +++++++++++------- drivers/usb/gadget/udc/rzv2m_usb3drd.c | 139 +++++++++++++++++++++++++ include/linux/usb/rzv2m_usb3drd.h | 20 ++++ 5 files changed, 232 insertions(+), 37 deletions(-) create mode 100644 drivers/usb/gadget/udc/rzv2m_usb3drd.c create mode 100644 include/linux/usb/rzv2m_usb3drd.h diff --git a/drivers/usb/gadget/udc/Kconfig b/drivers/usb/gadget/udc/Kconfig index b3006d8b04ab..b6fecd9343dc 100644 --- a/drivers/usb/gadget/udc/Kconfig +++ b/drivers/usb/gadget/udc/Kconfig @@ -180,10 +180,17 @@ config USB_RENESAS_USBHS_UDC dynamically linked module called "renesas_usbhs" and force all gadget drivers to also be dynamically linked. +config USB_RZV2M_USB3DRD + depends on ARCH_R9A09G011 || COMPILE_TEST + bool + default y if USB_XHCI_RZV2M + default y if USB_RENESAS_USB3 + config USB_RENESAS_USB3 tristate 'Renesas USB3.0 Peripheral controller' depends on ARCH_RENESAS || COMPILE_TEST depends on EXTCON + select USB_RZV2M_USB3DRD if ARCH_R9A09G011 select USB_ROLE_SWITCH help Renesas USB3.0 Peripheral controller is a USB peripheral controller diff --git a/drivers/usb/gadget/udc/Makefile b/drivers/usb/gadget/udc/Makefile index 39daf36a2baa..223c09c685ab 100644 --- a/drivers/usb/gadget/udc/Makefile +++ b/drivers/usb/gadget/udc/Makefile @@ -27,6 +27,7 @@ obj-$(CONFIG_USB_TEGRA_XUDC) += tegra-xudc.o obj-$(CONFIG_USB_M66592) += m66592-udc.o obj-$(CONFIG_USB_R8A66597) += r8a66597-udc.o obj-$(CONFIG_USB_RENESAS_USB3) += renesas_usb3.o +obj-$(CONFIG_USB_RZV2M_USB3DRD) += rzv2m_usb3drd.o obj-$(CONFIG_USB_FSL_QE) += fsl_qe_udc.o obj-$(CONFIG_USB_S3C_HSUDC) += s3c-hsudc.o obj-$(CONFIG_USB_LPC32XX) += lpc32xx_udc.o diff --git a/drivers/usb/gadget/udc/renesas_usb3.c b/drivers/usb/gadget/udc/renesas_usb3.c index 615ba0a6fbee..8d694501bf02 100644 --- a/drivers/usb/gadget/udc/renesas_usb3.c +++ b/drivers/usb/gadget/udc/renesas_usb3.c @@ -27,6 +27,7 @@ #include #include #include +#include /* register definitions */ #define USB3_AXI_INT_STA 0x008 @@ -334,7 +335,7 @@ struct renesas_usb3_priv { struct renesas_usb3 { void __iomem *reg; - struct reset_control *drd_rstc; + void __iomem *drd_reg; struct reset_control *usbp_rstc; struct usb_gadget gadget; @@ -426,6 +427,46 @@ static void usb3_clear_bit(struct renesas_usb3 *usb3, u32 bits, u32 offs) usb3_write(usb3, val, offs); } +static void usb3_drd_write(struct renesas_usb3 *usb3, u32 data, u32 offs) +{ + void __iomem *reg; + + if (usb3->is_rzv2m) + reg = usb3->drd_reg + offs - USB3_DRD_CON(usb3); + else + reg = usb3->reg + offs; + + iowrite32(data, reg); +} + +static u32 usb3_drd_read(struct renesas_usb3 *usb3, u32 offs) +{ + void __iomem *reg; + + if (usb3->is_rzv2m) + reg = usb3->drd_reg + offs - USB3_DRD_CON(usb3); + else + reg = usb3->reg + offs; + + return ioread32(reg); +} + +static void usb3_drd_set_bit(struct renesas_usb3 *usb3, u32 bits, u32 offs) +{ + u32 val = usb3_drd_read(usb3, offs); + + val |= bits; + usb3_drd_write(usb3, val, offs); +} + +static void usb3_drd_clear_bit(struct renesas_usb3 *usb3, u32 bits, u32 offs) +{ + u32 val = usb3_drd_read(usb3, offs); + + val &= ~bits; + usb3_drd_write(usb3, val, offs); +} + static int usb3_wait(struct renesas_usb3 *usb3, u32 reg, u32 mask, u32 expected) { @@ -474,7 +515,7 @@ static void usb3_disable_pipe_irq(struct renesas_usb3 *usb3, int num) static bool usb3_is_host(struct renesas_usb3 *usb3) { - return !(usb3_read(usb3, USB3_DRD_CON(usb3)) & DRD_CON_PERI_CON); + return !(usb3_drd_read(usb3, USB3_DRD_CON(usb3)) & DRD_CON_PERI_CON); } static void usb3_init_axi_bridge(struct renesas_usb3 *usb3) @@ -683,18 +724,18 @@ static void usb3_set_mode(struct renesas_usb3 *usb3, bool host) { if (usb3->is_rzv2m) { if (host) { - usb3_set_bit(usb3, DRD_CON_PERI_RST, USB3_DRD_CON(usb3)); - usb3_clear_bit(usb3, DRD_CON_HOST_RST, USB3_DRD_CON(usb3)); + usb3_drd_set_bit(usb3, DRD_CON_PERI_RST, USB3_DRD_CON(usb3)); + usb3_drd_clear_bit(usb3, DRD_CON_HOST_RST, USB3_DRD_CON(usb3)); } else { - usb3_set_bit(usb3, DRD_CON_HOST_RST, USB3_DRD_CON(usb3)); - usb3_clear_bit(usb3, DRD_CON_PERI_RST, USB3_DRD_CON(usb3)); + usb3_drd_set_bit(usb3, DRD_CON_HOST_RST, USB3_DRD_CON(usb3)); + usb3_drd_clear_bit(usb3, DRD_CON_PERI_RST, USB3_DRD_CON(usb3)); } } if (host) - usb3_clear_bit(usb3, DRD_CON_PERI_CON, USB3_DRD_CON(usb3)); + usb3_drd_clear_bit(usb3, DRD_CON_PERI_CON, USB3_DRD_CON(usb3)); else - usb3_set_bit(usb3, DRD_CON_PERI_CON, USB3_DRD_CON(usb3)); + usb3_drd_set_bit(usb3, DRD_CON_PERI_CON, USB3_DRD_CON(usb3)); } static void usb3_set_mode_by_role_sw(struct renesas_usb3 *usb3, bool host) @@ -710,9 +751,9 @@ static void usb3_set_mode_by_role_sw(struct renesas_usb3 *usb3, bool host) static void usb3_vbus_out(struct renesas_usb3 *usb3, bool enable) { if (enable) - usb3_set_bit(usb3, DRD_CON_VBOUT, USB3_DRD_CON(usb3)); + usb3_drd_set_bit(usb3, DRD_CON_VBOUT, USB3_DRD_CON(usb3)); else - usb3_clear_bit(usb3, DRD_CON_VBOUT, USB3_DRD_CON(usb3)); + usb3_drd_clear_bit(usb3, DRD_CON_VBOUT, USB3_DRD_CON(usb3)); } static void usb3_mode_config(struct renesas_usb3 *usb3, bool host, bool a_dev) @@ -733,7 +774,7 @@ static void usb3_mode_config(struct renesas_usb3 *usb3, bool host, bool a_dev) static bool usb3_is_a_device(struct renesas_usb3 *usb3) { - return !(usb3_read(usb3, USB3_USB_OTG_STA(usb3)) & USB_OTG_IDMON(usb3)); + return !(usb3_drd_read(usb3, USB3_USB_OTG_STA(usb3)) & USB_OTG_IDMON(usb3)); } static void usb3_check_id(struct renesas_usb3 *usb3) @@ -756,8 +797,8 @@ static void renesas_usb3_init_controller(struct renesas_usb3 *usb3) usb3_set_bit(usb3, USB_COM_CON_PN_WDATAIF_NL | USB_COM_CON_PN_RDATAIF_NL | USB_COM_CON_PN_LSTTR_PP, USB3_USB_COM_CON); - usb3_write(usb3, USB_OTG_IDMON(usb3), USB3_USB_OTG_INT_STA(usb3)); - usb3_write(usb3, USB_OTG_IDMON(usb3), USB3_USB_OTG_INT_ENA(usb3)); + usb3_drd_write(usb3, USB_OTG_IDMON(usb3), USB3_USB_OTG_INT_STA(usb3)); + usb3_drd_write(usb3, USB_OTG_IDMON(usb3), USB3_USB_OTG_INT_ENA(usb3)); usb3_check_id(usb3); usb3_check_vbus(usb3); @@ -767,7 +808,7 @@ static void renesas_usb3_stop_controller(struct renesas_usb3 *usb3) { usb3_disconnect(usb3); usb3_write(usb3, 0, USB3_P0_INT_ENA); - usb3_write(usb3, 0, USB3_USB_OTG_INT_ENA(usb3)); + usb3_drd_write(usb3, 0, USB3_USB_OTG_INT_ENA(usb3)); usb3_write(usb3, 0, USB3_USB_INT_ENA_1); usb3_write(usb3, 0, USB3_USB_INT_ENA_2); usb3_write(usb3, 0, USB3_AXI_INT_ENA); @@ -2024,11 +2065,11 @@ static void usb3_irq_idmon_change(struct renesas_usb3 *usb3) static void usb3_irq_otg_int(struct renesas_usb3 *usb3) { - u32 otg_int_sta = usb3_read(usb3, USB3_USB_OTG_INT_STA(usb3)); + u32 otg_int_sta = usb3_drd_read(usb3, USB3_USB_OTG_INT_STA(usb3)); - otg_int_sta &= usb3_read(usb3, USB3_USB_OTG_INT_ENA(usb3)); + otg_int_sta &= usb3_drd_read(usb3, USB3_USB_OTG_INT_ENA(usb3)); if (otg_int_sta) - usb3_write(usb3, otg_int_sta, USB3_USB_OTG_INT_STA(usb3)); + usb3_drd_write(usb3, otg_int_sta, USB3_USB_OTG_INT_STA(usb3)); if (otg_int_sta & USB_OTG_IDMON(usb3)) usb3_irq_idmon_change(usb3); @@ -2600,7 +2641,6 @@ static int renesas_usb3_remove(struct platform_device *pdev) usb_del_gadget_udc(&usb3->gadget); reset_control_assert(usb3->usbp_rstc); - reset_control_assert(usb3->drd_rstc); renesas_usb3_dma_free_prd(usb3, &pdev->dev); __renesas_usb3_ep_free_request(usb3->ep0_req); @@ -2788,7 +2828,7 @@ static struct usb_role_switch_desc renesas_usb3_role_switch_desc = { static int renesas_usb3_probe(struct platform_device *pdev) { struct renesas_usb3 *usb3; - int irq, drd_irq, ret; + int irq, ret; const struct renesas_usb3_priv *priv; const struct soc_device_attribute *attr; @@ -2802,12 +2842,6 @@ static int renesas_usb3_probe(struct platform_device *pdev) if (irq < 0) return irq; - if (priv->is_rzv2m) { - drd_irq = platform_get_irq_byname(pdev, "drd"); - if (drd_irq < 0) - return drd_irq; - } - usb3 = devm_kzalloc(&pdev->dev, sizeof(*usb3), GFP_KERNEL); if (!usb3) return -ENOMEM; @@ -2836,9 +2870,12 @@ static int renesas_usb3_probe(struct platform_device *pdev) return ret; if (usb3->is_rzv2m) { - ret = devm_request_irq(&pdev->dev, drd_irq, + struct rzv2m_usb3drd *ddata = dev_get_drvdata(pdev->dev.parent); + + usb3->drd_reg = ddata->reg; + ret = devm_request_irq(ddata->dev, ddata->drd_irq, renesas_usb3_otg_irq, 0, - dev_name(&pdev->dev), usb3); + dev_name(ddata->dev), usb3); if (ret < 0) return ret; } @@ -2873,21 +2910,13 @@ static int renesas_usb3_probe(struct platform_device *pdev) goto err_add_udc; } - usb3->drd_rstc = devm_reset_control_get_optional_shared(&pdev->dev, - "drd_reset"); - if (IS_ERR(usb3->drd_rstc)) { - ret = PTR_ERR(usb3->drd_rstc); - goto err_add_udc; - } - usb3->usbp_rstc = devm_reset_control_get_optional_shared(&pdev->dev, - "aresetn_p"); + NULL); if (IS_ERR(usb3->usbp_rstc)) { ret = PTR_ERR(usb3->usbp_rstc); goto err_add_udc; } - reset_control_deassert(usb3->drd_rstc); reset_control_deassert(usb3->usbp_rstc); pm_runtime_enable(&pdev->dev); @@ -2933,7 +2962,6 @@ static int renesas_usb3_probe(struct platform_device *pdev) err_reset: reset_control_assert(usb3->usbp_rstc); - reset_control_assert(usb3->drd_rstc); err_add_udc: renesas_usb3_dma_free_prd(usb3, &pdev->dev); diff --git a/drivers/usb/gadget/udc/rzv2m_usb3drd.c b/drivers/usb/gadget/udc/rzv2m_usb3drd.c new file mode 100644 index 000000000000..3c8bbf843038 --- /dev/null +++ b/drivers/usb/gadget/udc/rzv2m_usb3drd.c @@ -0,0 +1,139 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Renesas RZ/V2M USB3DRD driver + * + * Copyright (C) 2022 Renesas Electronics Corporation + */ + +#include +#include +#include +#include +#include +#include + +#define USB_PERI_DRD_CON 0x000 + +#define USB_PERI_DRD_CON_PERI_RST BIT(31) +#define USB_PERI_DRD_CON_HOST_RST BIT(30) +#define USB_PERI_DRD_CON_PERI_CON BIT(24) + +static void rzv2m_usb3drd_set_bit(struct rzv2m_usb3drd *usb3, u32 bits, + u32 offs) +{ + u32 val = readl(usb3->reg + offs); + + val |= bits; + writel(val, usb3->reg + offs); +} + +static void rzv2m_usb3drd_clear_bit(struct rzv2m_usb3drd *usb3, u32 bits, + u32 offs) +{ + u32 val = readl(usb3->reg + offs); + + val &= ~bits; + writel(val, usb3->reg + offs); +} + +void rzv2m_usb3drd_reset(struct device *dev, bool host) +{ + struct rzv2m_usb3drd *usb3 = dev_get_drvdata(dev); + + if (host) { + rzv2m_usb3drd_clear_bit(usb3, USB_PERI_DRD_CON_PERI_CON, + USB_PERI_DRD_CON); + rzv2m_usb3drd_clear_bit(usb3, USB_PERI_DRD_CON_HOST_RST, + USB_PERI_DRD_CON); + rzv2m_usb3drd_set_bit(usb3, USB_PERI_DRD_CON_PERI_RST, + USB_PERI_DRD_CON); + } else { + rzv2m_usb3drd_set_bit(usb3, USB_PERI_DRD_CON_PERI_CON, + USB_PERI_DRD_CON); + rzv2m_usb3drd_set_bit(usb3, USB_PERI_DRD_CON_HOST_RST, + USB_PERI_DRD_CON); + rzv2m_usb3drd_clear_bit(usb3, USB_PERI_DRD_CON_PERI_RST, + USB_PERI_DRD_CON); + } +} +EXPORT_SYMBOL_GPL(rzv2m_usb3drd_reset); + +static int rzv2m_usb3drd_remove(struct platform_device *pdev) +{ + struct rzv2m_usb3drd *usb3 = platform_get_drvdata(pdev); + + of_platform_depopulate(usb3->dev); + pm_runtime_put(usb3->dev); + pm_runtime_disable(&pdev->dev); + reset_control_assert(usb3->drd_rstc); + + return 0; +} + +static int rzv2m_usb3drd_probe(struct platform_device *pdev) +{ + struct rzv2m_usb3drd *usb3; + int ret; + + usb3 = devm_kzalloc(&pdev->dev, sizeof(*usb3), GFP_KERNEL); + if (!usb3) + return -ENOMEM; + + usb3->dev = &pdev->dev; + + usb3->drd_irq = platform_get_irq_byname(pdev, "drd"); + if (usb3->drd_irq < 0) + return usb3->drd_irq; + + usb3->reg = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(usb3->reg)) + return PTR_ERR(usb3->reg); + + platform_set_drvdata(pdev, usb3); + + usb3->drd_rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL); + if (IS_ERR(usb3->drd_rstc)) + return dev_err_probe(&pdev->dev, PTR_ERR(usb3->drd_rstc), + "failed to get drd reset"); + + reset_control_deassert(usb3->drd_rstc); + pm_runtime_enable(&pdev->dev); + ret = pm_runtime_resume_and_get(usb3->dev); + if (ret) + goto err_rst; + + ret = of_platform_populate(usb3->dev->of_node, NULL, NULL, usb3->dev); + if (ret) + goto err_pm; + + return 0; + +err_pm: + pm_runtime_put(usb3->dev); + +err_rst: + pm_runtime_disable(&pdev->dev); + reset_control_assert(usb3->drd_rstc); + return ret; +} + +static const struct of_device_id rzv2m_usb3drd_of_match[] = { + { .compatible = "renesas,rzv2m-usb3drd", }, + { /* Sentinel */ } +}; +MODULE_DEVICE_TABLE(of, rzv2m_usb3drd_of_match); + +static struct platform_driver rzv2m_usb3drd_driver = { + .driver = { + .name = "rzv2m-usb3drd", + .of_match_table = of_match_ptr(rzv2m_usb3drd_of_match), + }, + .probe = rzv2m_usb3drd_probe, + .remove = rzv2m_usb3drd_remove, +}; +module_platform_driver(rzv2m_usb3drd_driver); + +MODULE_AUTHOR("Biju Das "); +MODULE_DESCRIPTION("Renesas RZ/V2M USB3DRD driver"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:rzv2m_usb3drd"); diff --git a/include/linux/usb/rzv2m_usb3drd.h b/include/linux/usb/rzv2m_usb3drd.h new file mode 100644 index 000000000000..4cc848de229f --- /dev/null +++ b/include/linux/usb/rzv2m_usb3drd.h @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __RZV2M_USB3DRD_H +#define __RZV2M_USB3DRD_H + +#include + +struct rzv2m_usb3drd { + void __iomem *reg; + int drd_irq; + struct device *dev; + struct reset_control *drd_rstc; +}; + +#if IS_ENABLED(CONFIG_USB_RZV2M_USB3DRD) +void rzv2m_usb3drd_reset(struct device *dev, bool host); +#else +static inline void rzv2m_usb3drd_reset(struct device *dev, bool host) { } +#endif + +#endif /* __RZV2M_USB3DRD_H */ From patchwork Thu Jan 12 21:59:01 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Biju Das X-Patchwork-Id: 641936 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 06F4BC54EBE for ; Thu, 12 Jan 2023 22:09:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240208AbjALWJx (ORCPT ); Thu, 12 Jan 2023 17:09:53 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57926 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240130AbjALWJE (ORCPT ); Thu, 12 Jan 2023 17:09:04 -0500 Received: from relmlie5.idc.renesas.com (relmlor1.renesas.com [210.160.252.171]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 32D953FA3D; Thu, 12 Jan 2023 13:59:40 -0800 (PST) X-IronPort-AV: E=Sophos;i="5.97,212,1669042800"; d="scan'208";a="146137088" Received: from unknown (HELO relmlir5.idc.renesas.com) ([10.200.68.151]) by relmlie5.idc.renesas.com with ESMTP; 13 Jan 2023 06:59:39 +0900 Received: from localhost.localdomain (unknown [10.226.92.132]) by relmlir5.idc.renesas.com (Postfix) with ESMTP id 8C1FF400A8BB; Fri, 13 Jan 2023 06:59:36 +0900 (JST) From: Biju Das To: Mathias Nyman , Greg Kroah-Hartman Cc: Biju Das , linux-usb@vger.kernel.org, Yoshihiro Shimoda , Geert Uytterhoeven , Fabrizio Castro , linux-renesas-soc@vger.kernel.org Subject: [PATCH v2 07/12] usb: host: xhci-plat: Improve clock handling in probe() Date: Thu, 12 Jan 2023 21:59:01 +0000 Message-Id: <20230112215906.494394-8-biju.das.jz@bp.renesas.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230112215906.494394-1-biju.das.jz@bp.renesas.com> References: <20230112215906.494394-1-biju.das.jz@bp.renesas.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org It is always better to acquire all the clock resources first and then do the clock operations. This patch acquires all the optional clocks first and then calls corresponding prepare_enable(). There is no functional change. Signed-off-by: Biju Das Reviewed-by: Geert Uytterhoeven --- v1->v2: * Added Rb tag from Geert. --- drivers/usb/host/xhci-plat.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c index 5fb55bf19493..11b3a0d6722d 100644 --- a/drivers/usb/host/xhci-plat.c +++ b/drivers/usb/host/xhci-plat.c @@ -257,16 +257,16 @@ static int xhci_plat_probe(struct platform_device *pdev) goto put_hcd; } - ret = clk_prepare_enable(xhci->reg_clk); - if (ret) - goto put_hcd; - xhci->clk = devm_clk_get_optional(&pdev->dev, NULL); if (IS_ERR(xhci->clk)) { ret = PTR_ERR(xhci->clk); - goto disable_reg_clk; + goto put_hcd; } + ret = clk_prepare_enable(xhci->reg_clk); + if (ret) + goto put_hcd; + ret = clk_prepare_enable(xhci->clk); if (ret) goto disable_reg_clk; From patchwork Thu Jan 12 21:59:03 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Biju Das X-Patchwork-Id: 641935 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9FEF3C61DB3 for ; Thu, 12 Jan 2023 22:10:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232791AbjALWKK (ORCPT ); Thu, 12 Jan 2023 17:10:10 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57130 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233096AbjALWJl (ORCPT ); Thu, 12 Jan 2023 17:09:41 -0500 Received: from relmlie6.idc.renesas.com (relmlor2.renesas.com [210.160.252.172]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 524B84FD67; Thu, 12 Jan 2023 13:59:48 -0800 (PST) X-IronPort-AV: E=Sophos;i="5.97,212,1669042800"; d="scan'208";a="149165244" Received: from unknown (HELO relmlir5.idc.renesas.com) ([10.200.68.151]) by relmlie6.idc.renesas.com with ESMTP; 13 Jan 2023 06:59:47 +0900 Received: from localhost.localdomain (unknown [10.226.92.132]) by relmlir5.idc.renesas.com (Postfix) with ESMTP id 6835A400A8BB; Fri, 13 Jan 2023 06:59:43 +0900 (JST) From: Biju Das To: Greg Kroah-Hartman , Mathias Nyman Cc: Biju Das , Colin Ian King , Felipe Balbi , Tomer Maimon , Arnd Bergmann , Linus Walleij , Artur Bujdoso , linux-usb@vger.kernel.org, Yoshihiro Shimoda , Geert Uytterhoeven , Fabrizio Castro , linux-renesas-soc@vger.kernel.org Subject: [PATCH v2 09/12] xhci: host: Add Renesas RZ/V2M SoC support Date: Thu, 12 Jan 2023 21:59:03 +0000 Message-Id: <20230112215906.494394-10-biju.das.jz@bp.renesas.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230112215906.494394-1-biju.das.jz@bp.renesas.com> References: <20230112215906.494394-1-biju.das.jz@bp.renesas.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org RZ/V2M is similar to R-Car XHCI but it doesn't require any firmware, we need to reset the USB Host reset release in DRD Module before accessing host registers. Signed-off-by: Biju Das --- v1->v2: * No change --- drivers/usb/host/Kconfig | 9 +++++++++ drivers/usb/host/Makefile | 3 +++ drivers/usb/host/xhci-plat.c | 11 ++++++++++ drivers/usb/host/xhci-rzv2m.c | 38 +++++++++++++++++++++++++++++++++++ drivers/usb/host/xhci-rzv2m.h | 16 +++++++++++++++ 5 files changed, 77 insertions(+) create mode 100644 drivers/usb/host/xhci-rzv2m.c create mode 100644 drivers/usb/host/xhci-rzv2m.h diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 8d799d23c476..7565ef021ab3 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -95,6 +95,15 @@ config USB_XHCI_RCAR Say 'Y' to enable the support for the xHCI host controller found in Renesas R-Car ARM SoCs. +config USB_XHCI_RZV2M + tristate "xHCI support for Renesas RZ/V2M SoC" + depends on USB_XHCI_PLATFORM + depends on ARCH_R9A09G011 || COMPILE_TEST + select USB_RZV2M_USB3DRD + help + Say 'Y' to enable the support for the xHCI host controller + found in Renesas RZ/V2M SoC. + config USB_XHCI_TEGRA tristate "xHCI support for NVIDIA Tegra SoCs" depends on PHY_TEGRA_XUSB diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile index 6d8ee264c9b2..6b1f9317f116 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile @@ -28,6 +28,9 @@ endif ifneq ($(CONFIG_USB_XHCI_RCAR), ) xhci-plat-hcd-y += xhci-rcar.o endif +ifneq ($(CONFIG_USB_XHCI_RZV2M), ) + xhci-plat-hcd-y += xhci-rzv2m.o +endif ifneq ($(CONFIG_DEBUG_FS),) xhci-hcd-y += xhci-debugfs.o diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c index c5fc175a5fd1..57269f1f318e 100644 --- a/drivers/usb/host/xhci-plat.c +++ b/drivers/usb/host/xhci-plat.c @@ -25,6 +25,7 @@ #include "xhci-plat.h" #include "xhci-mvebu.h" #include "xhci-rcar.h" +#include "xhci-rzv2m.h" static struct hc_driver __read_mostly xhci_plat_hc_driver; @@ -123,6 +124,13 @@ static const struct xhci_plat_priv xhci_plat_renesas_rcar_gen3 = { SET_XHCI_PLAT_PRIV_FOR_RCAR(XHCI_RCAR_FIRMWARE_NAME_V3) }; +static const struct xhci_plat_priv xhci_plat_renesas_rzv2m = { + .quirks = XHCI_NO_64BIT_SUPPORT | XHCI_TRUST_TX_LENGTH | + XHCI_SLOW_SUSPEND, + .init_quirk = xhci_rzv2m_init_quirk, + .plat_start = xhci_rzv2m_start, +}; + static const struct xhci_plat_priv xhci_plat_brcm = { .quirks = XHCI_RESET_ON_RESUME | XHCI_SUSPEND_RESUME_CLKS, }; @@ -162,6 +170,9 @@ static const struct of_device_id usb_xhci_of_match[] = { }, { .compatible = "renesas,rcar-gen3-xhci", .data = &xhci_plat_renesas_rcar_gen3, + }, { + .compatible = "renesas,rzv2m-xhci", + .data = &xhci_plat_renesas_rzv2m, }, { .compatible = "brcm,xhci-brcm-v2", .data = &xhci_plat_brcm, diff --git a/drivers/usb/host/xhci-rzv2m.c b/drivers/usb/host/xhci-rzv2m.c new file mode 100644 index 000000000000..ec65b24eafa8 --- /dev/null +++ b/drivers/usb/host/xhci-rzv2m.c @@ -0,0 +1,38 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * xHCI host controller driver for RZ/V2M + * + * Copyright (C) 2022 Renesas Electronics Corporation + */ + +#include +#include "xhci-plat.h" +#include "xhci-rzv2m.h" + +#define RZV2M_USB3_INTEN 0x1044 /* Interrupt Enable */ + +#define RZV2M_USB3_INT_XHC_ENA BIT(0) +#define RZV2M_USB3_INT_HSE_ENA BIT(2) +#define RZV2M_USB3_INT_ENA_VAL (RZV2M_USB3_INT_XHC_ENA \ + | RZV2M_USB3_INT_HSE_ENA) + +int xhci_rzv2m_init_quirk(struct usb_hcd *hcd) +{ + struct device *dev = hcd->self.controller; + + rzv2m_usb3drd_reset(dev->parent, true); + + return 0; +} + +void xhci_rzv2m_start(struct usb_hcd *hcd) +{ + u32 int_en; + + if (hcd->regs) { + /* Interrupt Enable */ + int_en = readl(hcd->regs + RZV2M_USB3_INTEN); + int_en |= RZV2M_USB3_INT_ENA_VAL; + writel(int_en, hcd->regs + RZV2M_USB3_INTEN); + } +} diff --git a/drivers/usb/host/xhci-rzv2m.h b/drivers/usb/host/xhci-rzv2m.h new file mode 100644 index 000000000000..12448b0e8d5b --- /dev/null +++ b/drivers/usb/host/xhci-rzv2m.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __XHCI_RZV2M_H +#define __XHCI_RZV2M_H + +#if IS_ENABLED(CONFIG_USB_XHCI_RZV2M) +void xhci_rzv2m_start(struct usb_hcd *hcd); +int xhci_rzv2m_init_quirk(struct usb_hcd *hcd); +#else +static inline void xhci_rzv2m_start(struct usb_hcd *hcd) {} +static inline int xhci_rzv2m_init_quirk(struct usb_hcd *hcd) +{ + return -EINVAL; +} +#endif + +#endif /* __XHCI_RZV2M_H */