From patchwork Tue Oct 20 08:57:48 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yoshihiro Shimoda X-Patchwork-Id: 7443931 X-Patchwork-Delegate: geert@linux-m68k.org Return-Path: X-Original-To: patchwork-linux-sh@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 740F6BF90C for ; Tue, 20 Oct 2015 08:59:24 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 293A8206A7 for ; Tue, 20 Oct 2015 08:59:23 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id A05B0206E6 for ; Tue, 20 Oct 2015 08:59:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751682AbbJTI7P (ORCPT ); Tue, 20 Oct 2015 04:59:15 -0400 Received: from relmlor4.renesas.com ([210.160.252.174]:52950 "EHLO relmlie3.idc.renesas.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1750885AbbJTI6I (ORCPT ); Tue, 20 Oct 2015 04:58:08 -0400 Received: from unknown (HELO relmlir2.idc.renesas.com) ([10.200.68.152]) by relmlie3.idc.renesas.com with ESMTP; 20 Oct 2015 17:58:06 +0900 Received: from relmlac3.idc.renesas.com (relmlac3.idc.renesas.com [10.200.69.23]) by relmlir2.idc.renesas.com (Postfix) with ESMTP id 619F453E47; Tue, 20 Oct 2015 17:58:06 +0900 (JST) Received: by relmlac3.idc.renesas.com (Postfix, from userid 0) id 419C81806F; Tue, 20 Oct 2015 17:58:06 +0900 (JST) Received: from relmlac3.idc.renesas.com (localhost [127.0.0.1]) by relmlac3.idc.renesas.com (Postfix) with ESMTP id 318F91800A; Tue, 20 Oct 2015 17:58:06 +0900 (JST) Received: from relmlii2.idc.renesas.com [10.200.68.66] by relmlac3.idc.renesas.com with ESMTP id TAE29115; Tue, 20 Oct 2015 17:58:06 +0900 X-IronPort-AV: E=Sophos;i="5.17,706,1437404400"; d="scan'";a="198065181" Received: from mail-sg2apc01lp0245.outbound.protection.outlook.com (HELO APC01-SG2-obe.outbound.protection.outlook.com) ([65.55.88.245]) by relmlii2.idc.renesas.com with ESMTP/TLS/AES256-SHA; 20 Oct 2015 17:58:04 +0900 Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=<>; Received: from localhost (211.11.155.144) by SG2PR06MB0919.apcprd06.prod.outlook.com (10.162.204.152) with Microsoft SMTP Server (TLS) id 15.1.300.14; Tue, 20 Oct 2015 08:58:02 +0000 From: Yoshihiro Shimoda To: , , , , , CC: , , , Yoshihiro Shimoda Subject: [PATCH v5 1/4] phy: rcar-gen3-usb2: Add R-Car Gen3 USB2 PHY driver Date: Tue, 20 Oct 2015 17:57:48 +0900 Message-ID: <1445331471-5028-2-git-send-email-yoshihiro.shimoda.uh@renesas.com> X-Mailer: git-send-email 1.9.4.msysgit.1 In-Reply-To: <1445331471-5028-1-git-send-email-yoshihiro.shimoda.uh@renesas.com> References: <1445331471-5028-1-git-send-email-yoshihiro.shimoda.uh@renesas.com> MIME-Version: 1.0 X-Originating-IP: [211.11.155.144] X-ClientProxiedBy: HK2PR02CA0007.apcprd02.prod.outlook.com (25.163.104.145) To SG2PR06MB0919.apcprd06.prod.outlook.com (25.162.204.152) X-Microsoft-Exchange-Diagnostics: 1; SG2PR06MB0919; 2:WWNx+sj3aWlzukibsTYxQ6Gjzbws6MRcZm0XbrCQxoJubvEKaLacefy66hBgMzk7wbmoDCQVYeXqxIXG4mXD5+Mu0fTZ2wTkSAu70cilps91E1u9uIruwOj0v/47/decX3o9fY8VXJj1ZzFDo8CAifT66yNHLwNH3WQx6Xvismw=; 3:VcjutGXcbNFHcCy1hbvu+rQVq9wUFIw8wGsu1gDHIbFFmJs0t0Jspj0qRHIXAcqTz1GAh0MqIgCfHjYImUNnTm98u6O4AW4KPPNCe3BijeMsre57a2g1jcDIc+5q3bofyvIrRh/q1rx7VVAw2w08Vw==; 25:L4Ks7/j0conZGbBa+p/FAksFZadBbvuNFlxENp7uiKnGt0Jg29Lmo4qHg1sM797GUIMe0JLpsTR9pf6Nj+peNreSN44Gpz36L0s2k1XCM3pnSzt2lbKLtbAhVjf2VqvjUl5DyuiRqejFRqbIpPayhMlpRefDPrDzcIBKdMMsmjeHZ2mpx9594WCiw1DqTYTgshauXHdVrJgivSy+UIveQ4V465jc5mGsRa7bv7g5y8eAEhUWM3aSet2W1q9CI/pD X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:SG2PR06MB0919; X-Microsoft-Exchange-Diagnostics: 1; SG2PR06MB0919; 20:LSWARcQ5XToSPMd7MIOL+l+82eKTWrpNI5u4P0wkv5oe6AAg9iIlp9jFyM7DGgdXnYmlKgSeHdtWLMC6WEbnb+qS8IVNUIZyrp9ZKenZ14iDDwN0b35nTH1BZIyHmI4qSSUzFp8TTf3IF5wypfOm0y7zyTHXzSnDI31C13kloRHaBCDsqJNd9w3GSlQCUd18whRIII09xMppBFVd4cDt/rEeu4XrJp0PCc/2c7LfTkdcE7gefDb3C+hWSVjaXfFyUowp4N4hF0yyxcDE6Iz0daBUPJ3I+eFzlfCvldzDrdUntv1Xoz94hEJnsLEolJ/OXHurimu1Tuk6K6s5KTH0+WNEXE9Hf/XXJQS/vrIK0KCPd8rd66DcSeNDcDz5m7tJSsp69xG4vxHIHZYOFcUM5PAoRjLFWVShj4qO4e1WOMBxZqANSDNXxdU+CD+VPTJ0GEosk7MpW0zod2ctaWPmtT53fftO1aSqc9MbTpIOogkgxt7dN7ltL1vs05Q41fIy; 4:GWnDKFrj06ox7VEIzDfC5GbnUsdRRLUv5RLsjGfCVaxzRDukCfJ0B7M/BccSwbbVop/BJEy6sMocApLDYutCSbRS7yPYzCYdNhYtMBlriENfvBNmL/ecXgg320KleDWUpRSN2LZetDlfP2Maw8alLq70o5yG6bDhTyYnHhqcphjHSSi7U7zNMJzHzyGNCwvz/ODiApNtmcvk/rN/JbPum+Om9qFLkWE5Stn3Ud4TwoaH58OJle04WsaMKqcAg0iZPaHqAubocxD5oNXihdd51FywlI15Xv2OSKVhPJ6e12fECs1enoQZ9JMYSM92VmryfBMC3fUnRKxTOvbceL5cos8D9xdb9ijo7X3/qenpD6A= X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(85106069007906); X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(601004)(2401047)(5005006)(520078)(8121501046)(3002001); SRVR:SG2PR06MB0919; BCL:0; PCL:0; RULEID:; SRVR:SG2PR06MB0919; X-Forefront-PRVS: 073515755F X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10019020)(6009001)(6069001)(199003)(189002)(105586002)(5003940100001)(42382002)(5001770100001)(19580405001)(87976001)(19580395003)(97736004)(81156007)(64706001)(47776003)(50226001)(575784001)(42186005)(66066001)(101416001)(92566002)(76176999)(229853001)(46102003)(78352002)(107886002)(50986999)(36756003)(50466002)(33646002)(5001960100002)(189998001)(230783001)(5007970100001)(48376002)(5004730100002)(2950100001)(77096005)(5008740100001)(76506005)(122386002)(40100003)(106356001)(2004002)(4001430100001); DIR:OUT; SFP:1102; SCL:1; SRVR:SG2PR06MB0919; H:localhost; FPR:; SPF:None; PTR:InfoNoRecords; A:0; MX:0; LANG:en; X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; SG2PR06MB0919; 23:ezHO11oeJ76JaiP16mrkLMNbVQLlfWb3Rs68tHcJ6?= =?us-ascii?Q?2wYWuWkPX811PdsUVJzkdSd7R5khelWfRgbDkBU++38b6kL78MCTm3jbTYk7?= =?us-ascii?Q?X7dR+SgIzn1kaBJ1lIOzPrz4eRxOmGt4YHYy21AykfqzG8LXSnjty1Ydft+3?= =?us-ascii?Q?/1aQbVvar/jikLLRJIptUkvjlUWQbGEwSx8pyrBE8mFp0yhpKAsqqpagAgun?= =?us-ascii?Q?TW5RleoeojSplLv1KDpthUr2Is0UkwmHXlyU+JFrO6xrct8vByjYMwu2pH0B?= =?us-ascii?Q?4Cbc2FHVB1ctSga22aY1ET7j0eEY+qVJcEKkBLySqmekJQFrYe2eGRK6mfxu?= =?us-ascii?Q?e2eZtJ8YcDHCqJqaM6cd04LChfTP6ICNlVTPDfhWYeTpYQF0i54bMJo2puC8?= =?us-ascii?Q?P9epK+yuFcy1C9aqWVBv/92yK36lq3c9XrmD9qR74TjSGrUBnUrw6H6le8Ir?= =?us-ascii?Q?f7WGkmeY8wr5wfk2AiyUwP/e6oUxkr6sBZg6j8UySGRyglvIyY4OJuulBxbk?= =?us-ascii?Q?w0TsRxi8s/ziAqFUzdXTEtvmdLJCibjo509BZ++u7aDIYXMjoZj7g8ECySPj?= =?us-ascii?Q?O3SNZ1P891IRKv8n6PDLwl6e5RGWCLsFudzhsnmGkJZz8Vlm6U5+TYQZ90yX?= =?us-ascii?Q?Vt84N/9GyULWoZsRrBR68qbPYGGEXSmsdv8njGEJ0gyozMvawWLYOfXdcKW3?= =?us-ascii?Q?yQ9THcpKHl0Dln8PpnzlZsRI23+C6SnrECA76XeBq5wkkED8Ed1+uHIkCh0k?= =?us-ascii?Q?Mp3BQDTk2KLk20MywGj75hmUqAmZucLa2OoVO/KAU2OS9PFJS82cirtEkiaj?= =?us-ascii?Q?vpxDKN2afxszQi+zB9shxzhHvMntt2H6CwtM7lKI87LfyIUYwmGiR9TYLjJu?= =?us-ascii?Q?OLSlQXmTpxXPo6SG45qI+yIZINuucxX7eKSt/5+6zKIcT7N5pkAFf2+3LYFZ?= =?us-ascii?Q?Ii8Avhy6o2T5Z95o3OExHFVf9lkqUI5ycukFej7rwulPooPjLuajP10lRp2/?= =?us-ascii?Q?HIdbRulDGVILIqerS5YFDaxfyLcWpQsfUaQUjSfs4EJJqzEozTOdjvPCM3qb?= =?us-ascii?Q?exXVzOggMLuQoKXVp8baddR6EmWIHrSMlvh5CSSLkGcmu76BUC2bjaPJmDtE?= =?us-ascii?Q?1eSn5IUaGT5uRQou2G3+n+xK7jTO6cO1wfldZeOOnyxWpXRwx07NEGj24Qm5?= =?us-ascii?Q?+i5unA29vsPxObvnUc95pbQuYVPAgnymR21?= X-Microsoft-Exchange-Diagnostics: 1; SG2PR06MB0919; 5:vmhQecKiLesvaBUu9npu8wwfL3xDyTT712pHyamGWsWTnicgRAZJ4unj/Cds5Pwa+m6+J30/9lqFBABeUEum9KeXJw/m3DFUlLQYG6aCn9xMeIW4gXcdEI2swuGLgDxK3XR/hni914jGLdaXni0y0Q==; 24:igZpZ8u+rt3sOR8Oxd1XNkIx4+X7UtAyXId97+hF7ms8bT2z8LzBzBeeAY17QIL+Xlqe2QVSom5yJeXmRnrnnX2SHF+VKJAkkvQ10Y+9lQU=; 20:/c4pSWg+wpfI6LVP0o08mdcme3C8cggZytFAJDWVEbdVrBE7Ebz5R9zPU05WctQS8zcBpIMRQgdN+QlV+tLcptX5dSWKhhpOGL/HV6ya7rOl9x5ulFuX5kzThPOEOMYdKhSy42VMDXdYfKe55lYdFWiSJVeD8RJ17Cn3yjVr54k= SpamDiagnosticOutput: 1:23 SpamDiagnosticMetadata: NSPM X-OriginatorOrg: renesas.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 20 Oct 2015 08:58:02.8400 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: SG2PR06MB0919 Sender: linux-sh-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-sh@vger.kernel.org X-Spam-Status: No, score=-5.7 required=5.0 tests=AXB_X_OUTLOOKPROT_ENVSDR, BAYES_00,RCVD_IN_DNSWL_HI,RP_MATCHES_RCVD,UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP This patch adds support for R-Car generation 3 USB2 PHY driver. This SoC has 3 EHCI/OHCI channels, and the channel 0 is shared with the HSUSB (USB2.0 peripheral) device. And each channel has independent registers about the PHYs. So, the purpose of this driver is: 1) initializes some registers of SoC specific to use the {ehci,ohci}-platform driver. 2) detects id pin to select host or peripheral on the channel 0. For now, this driver only supports 1) above. Signed-off-by: Yoshihiro Shimoda --- .../devicetree/bindings/phy/rcar-gen3-phy-usb2.txt | 37 ++++ drivers/phy/Kconfig | 7 + drivers/phy/Makefile | 1 + drivers/phy/phy-rcar-gen3-usb2.c | 219 +++++++++++++++++++++ 4 files changed, 264 insertions(+) create mode 100644 Documentation/devicetree/bindings/phy/rcar-gen3-phy-usb2.txt create mode 100644 drivers/phy/phy-rcar-gen3-usb2.c diff --git a/Documentation/devicetree/bindings/phy/rcar-gen3-phy-usb2.txt b/Documentation/devicetree/bindings/phy/rcar-gen3-phy-usb2.txt new file mode 100644 index 0000000..affa0f7 --- /dev/null +++ b/Documentation/devicetree/bindings/phy/rcar-gen3-phy-usb2.txt @@ -0,0 +1,37 @@ +* Renesas R-Car generation 3 USB 2.0 PHY + +This file provides information on what the device node for the R-Car generation +3 USB 2.0 PHY contains. + +Required properties: +- compatible: "renesas,usb2-phy-r8a7795" if the device is a part of an R8A7795 + SoC. +- reg: offset and length of the partial USB 2.0 Host register block. +- reg-names: must be "usb2_host". +- clocks: clock phandle and specifier pair(s). +- #phy-cells: see phy-bindings.txt in the same directory, must be <0>. + +Optional properties: +To use a USB channel where USB 2.0 Host and HSUSB (USB 2.0 Peripheral) are +combined, the device tree node should set HSUSB properties to reg and reg-names +properties. This is because HSUSB has registers to select USB 2.0 host or +peripheral at that channel: +- reg: offset and length of the partial HSUSB register block. +- reg-names: must be "hsusb". + +Example (R-Car H3): + + usb-phy@ee080200 { + compatible = "renesas,usb2-phy-r8a7795"; + reg = <0 0xee080200 0 0x700>, <0 0xe6590100 0 0x100>; + reg-names = "usb2_host", "hsusb"; + clocks = <&mstp7_clks R8A7795_CLK_EHCI0>, + <&mstp7_clks R8A7795_CLK_HSUSB>; + }; + + usb-phy@ee0a0200 { + compatible = "renesas,usb2-phy-r8a7795"; + reg = <0 0xee0a0200 0 0x700>; + reg-names = "usb2_host"; + clocks = <&mstp7_clks R8A7795_CLK_EHCI0>; + }; diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig index 7eb5859d..e9ab088 100644 --- a/drivers/phy/Kconfig +++ b/drivers/phy/Kconfig @@ -118,6 +118,13 @@ config PHY_RCAR_GEN2 help Support for USB PHY found on Renesas R-Car generation 2 SoCs. +config PHY_RCAR_GEN3_USB2 + tristate "Renesas R-Car generation 3 USB 2.0 PHY driver" + depends on OF && ARCH_SHMOBILE + select GENERIC_PHY + help + Support for USB 2.0 PHY found on Renesas R-Car generation 3 SoCs. + config OMAP_CONTROL_PHY tristate "OMAP CONTROL PHY Driver" depends on ARCH_OMAP2PLUS || COMPILE_TEST diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile index 075db1a..91d7a62 100644 --- a/drivers/phy/Makefile +++ b/drivers/phy/Makefile @@ -17,6 +17,7 @@ obj-$(CONFIG_PHY_MVEBU_SATA) += phy-mvebu-sata.o obj-$(CONFIG_PHY_MIPHY28LP) += phy-miphy28lp.o obj-$(CONFIG_PHY_MIPHY365X) += phy-miphy365x.o obj-$(CONFIG_PHY_RCAR_GEN2) += phy-rcar-gen2.o +obj-$(CONFIG_PHY_RCAR_GEN3_USB2) += phy-rcar-gen3-usb2.o obj-$(CONFIG_OMAP_CONTROL_PHY) += phy-omap-control.o obj-$(CONFIG_OMAP_USB2) += phy-omap-usb2.o obj-$(CONFIG_TI_PIPE3) += phy-ti-pipe3.o diff --git a/drivers/phy/phy-rcar-gen3-usb2.c b/drivers/phy/phy-rcar-gen3-usb2.c new file mode 100644 index 0000000..9d9cf26 --- /dev/null +++ b/drivers/phy/phy-rcar-gen3-usb2.c @@ -0,0 +1,219 @@ +/* + * Renesas R-Car Gen3 for USB2.0 PHY driver + * + * Copyright (C) 2015 Renesas Electronics Corporation + * + * This is based on the phy-rcar-gen2 driver: + * Copyright (C) 2014 Renesas Solutions Corp. + * Copyright (C) 2014 Cogent Embedded, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include + +/******* USB2.0 Host registers (original offset is +0x200) *******/ +#define USB2_INT_ENABLE 0x000 +#define USB2_USBCTR 0x00c +#define USB2_SPD_RSM_TIMSET 0x10c +#define USB2_OC_TIMSET 0x110 + +/* INT_ENABLE */ +#define USB2_INT_ENABLE_USBH_INTB_EN BIT(2) +#define USB2_INT_ENABLE_USBH_INTA_EN BIT(1) +#define USB2_INT_ENABLE_INIT (USB2_INT_ENABLE_USBH_INTB_EN | \ + USB2_INT_ENABLE_USBH_INTA_EN) + +/* USBCTR */ +#define USB2_USBCTR_DIRPD BIT(2) +#define USB2_USBCTR_PLL_RST BIT(1) + +/* SPD_RSM_TIMSET */ +#define USB2_SPD_RSM_TIMSET_INIT 0x014e029b + +/* OC_TIMSET */ +#define USB2_OC_TIMSET_INIT 0x000209ab + +/******* HSUSB registers (original offset is +0x100) *******/ +#define HSUSB_LPSTS 0x02 +#define HSUSB_UGCTRL2 0x84 + +/* Low Power Status register (LPSTS) */ +#define HSUSB_LPSTS_SUSPM 0x4000 + +/* USB General control register 2 (UGCTRL2) */ +#define HSUSB_UGCTRL2_MASK 0x00000031 /* bit[31:6] should be 0 */ +#define HSUSB_UGCTRL2_USB0SEL 0x00000030 +#define HSUSB_UGCTRL2_USB0SEL_HOST 0x00000010 +#define HSUSB_UGCTRL2_USB0SEL_HS_USB 0x00000020 +#define HSUSB_UGCTRL2_USB0SEL_OTG 0x00000030 + +struct rcar_gen3_data { + void __iomem *base; + struct clk *clk; +}; + +struct rcar_gen3_chan { + struct rcar_gen3_data usb2; + struct rcar_gen3_data hsusb; + struct phy *phy; +}; + +static int rcar_gen3_phy_usb2_init(struct phy *p) +{ + struct rcar_gen3_chan *channel = phy_get_drvdata(p); + void __iomem *usb2_base = channel->usb2.base; + void __iomem *hsusb_base = channel->hsusb.base; + u32 val; + + /* Initialize USB2 part */ + writel(USB2_INT_ENABLE_INIT, usb2_base + USB2_INT_ENABLE); + writel(USB2_SPD_RSM_TIMSET_INIT, usb2_base + USB2_SPD_RSM_TIMSET); + writel(USB2_OC_TIMSET_INIT, usb2_base + USB2_OC_TIMSET); + + /* Initialize HSUSB part */ + if (hsusb_base) { + /* TODO: support "OTG" mode */ + val = readl(hsusb_base + HSUSB_UGCTRL2); + val = (val & ~HSUSB_UGCTRL2_USB0SEL) | + HSUSB_UGCTRL2_USB0SEL_HOST; + writel(val & HSUSB_UGCTRL2_MASK, hsusb_base + HSUSB_UGCTRL2); + } + + return 0; +} + +static int rcar_gen3_phy_usb2_exit(struct phy *p) +{ + struct rcar_gen3_chan *channel = phy_get_drvdata(p); + + writel(0, channel->usb2.base + USB2_INT_ENABLE); + + return 0; +} + +static int rcar_gen3_phy_usb2_power_on(struct phy *p) +{ + struct rcar_gen3_chan *channel = phy_get_drvdata(p); + void __iomem *usb2_base = channel->usb2.base; + void __iomem *hsusb_base = channel->hsusb.base; + u32 val; + + val = readl(usb2_base + USB2_USBCTR); + val |= USB2_USBCTR_PLL_RST; + writel(val, usb2_base + USB2_USBCTR); + val &= ~USB2_USBCTR_PLL_RST; + writel(val, usb2_base + USB2_USBCTR); + + /* + * TODO: To reduce power consuming, this driver should set the SUSPM + * after the PHY detects ID pin as peripheral. + */ + if (hsusb_base) { + /* Power on HSUSB PHY */ + val = readw(hsusb_base + HSUSB_LPSTS); + val |= HSUSB_LPSTS_SUSPM; + writew(val, hsusb_base + HSUSB_LPSTS); + } + + return 0; +} + +static int rcar_gen3_phy_usb2_power_off(struct phy *p) +{ + struct rcar_gen3_chan *channel = phy_get_drvdata(p); + void __iomem *hsusb_base = channel->hsusb.base; + u32 val; + + if (hsusb_base) { + /* Power off HSUSB PHY */ + val = readw(hsusb_base + HSUSB_LPSTS); + val &= ~HSUSB_LPSTS_SUSPM; + writew(val, hsusb_base + HSUSB_LPSTS); + } + + return 0; +} + +static struct phy_ops rcar_gen3_phy_usb2_ops = { + .init = rcar_gen3_phy_usb2_init, + .exit = rcar_gen3_phy_usb2_exit, + .power_on = rcar_gen3_phy_usb2_power_on, + .power_off = rcar_gen3_phy_usb2_power_off, + .owner = THIS_MODULE, +}; + +static const struct of_device_id rcar_gen3_phy_usb2_match_table[] = { + { .compatible = "renesas,usb2-phy-r8a7795" }, + { } +}; +MODULE_DEVICE_TABLE(of, rcar_gen3_phy_usb2_match_table); + +static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct rcar_gen3_chan *channel; + struct phy_provider *provider; + struct resource *res; + + if (!dev->of_node) { + dev_err(dev, "This driver needs device tree\n"); + return -EINVAL; + } + + channel = devm_kzalloc(dev, sizeof(*channel), GFP_KERNEL); + if (!channel) + return -ENOMEM; + + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "usb2_host"); + channel->usb2.base = devm_ioremap_resource(dev, res); + if (IS_ERR(channel->usb2.base)) + return PTR_ERR(channel->usb2.base); + + /* "hsusb" memory resource is optional */ + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "hsusb"); + + /* To avoid error message by devm_ioremap_resource() */ + if (res) { + channel->hsusb.base = devm_ioremap_resource(dev, res); + if (IS_ERR(channel->hsusb.base)) + channel->hsusb.base = NULL; + } + + /* devm_phy_create() will call pm_runtime_enable(dev); */ + channel->phy = devm_phy_create(dev, NULL, &rcar_gen3_phy_usb2_ops); + if (IS_ERR(channel->phy)) { + dev_err(dev, "Failed to create USB2 PHY\n"); + return PTR_ERR(channel->phy); + } + + phy_set_drvdata(channel->phy, channel); + + provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); + if (IS_ERR(provider)) { + dev_err(dev, "Failed to register PHY provider\n"); + return PTR_ERR(provider); + } + + return 0; +} + +static struct platform_driver rcar_gen3_phy_usb2_driver = { + .driver = { + .name = "phy_rcar_gen3_usb2", + .of_match_table = rcar_gen3_phy_usb2_match_table, + }, + .probe = rcar_gen3_phy_usb2_probe, +}; +module_platform_driver(rcar_gen3_phy_usb2_driver); + +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("Renesas R-Car Gen3 USB 2.0 PHY"); +MODULE_AUTHOR("Yoshihiro Shimoda ");