From: Petr Kulhavy <petr-Qh/3xLP0EvwAvxtiuMwx3w@public.gmane.org>
To: robh+dt-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org,
balbi-l0cyMroinI0@public.gmane.org
Cc: devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-usb-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
Petr Kulhavy <petr-Qh/3xLP0EvwAvxtiuMwx3w@public.gmane.org>
Subject: [PATCH 2/2] Drivers: MUSB: Davinci MUSB: added DT support
Date: Thu, 21 Jan 2016 15:53:19 +0100 [thread overview]
Message-ID: <1453387999-4485-1-git-send-email-petr@barix.com> (raw)
TI DaVinci MUSB driver equipped with DeviceTree support.
Tested with AM1808 board and USB2.0 (OTG) in host mode.
Signed-off-by: Petr Kulhavy <petr-Qh/3xLP0EvwAvxtiuMwx3w@public.gmane.org>
---
.../devicetree/bindings/usb/da8xx-usb.txt | 52 +++++++
drivers/usb/musb/da8xx.c | 166 +++++++++++++++++++++
include/linux/platform_data/usb-davinci.h | 3 +-
3 files changed, 220 insertions(+), 1 deletion(-)
create mode 100644 Documentation/devicetree/bindings/usb/da8xx-usb.txt
diff --git a/Documentation/devicetree/bindings/usb/da8xx-usb.txt b/Documentation/devicetree/bindings/usb/da8xx-usb.txt
new file mode 100644
index 0000000..c81d665
--- /dev/null
+++ b/Documentation/devicetree/bindings/usb/da8xx-usb.txt
@@ -0,0 +1,52 @@
+TI DaVinci MUSB
+
+Required properties:
+
+ - compatible : Should be "ti,da850-musb" or "ti,da830-musb"
+
+ - mode : USB mode. "1" signifies HOST, "2" represents PERIPHERAL,
+ "3" represents OTG.
+
+ - power : This signifies the maximum current the controller can
+ supply in host mode. The unit size is 2mA, the maximum value is 510mA.
+
+ - num-eps : Specifies the number of endpoints. This is also a
+ MUSB configuration-specific setting.
+
+ - multipoint : Should be "1" indicating the musb controller supports
+ multipoint. This is a MUSB configuration-specific setting.
+
+ - ram-bits : Specifies the ram address size.
+
+
+Optional properties:
+
+ - da8xx,phy20-clkmux-cfg: Integer. Defines the USB 2.0 PHY reference clock source.
+ Supported values: "0" for external pin, "1" for internal PLL.
+
+ - da8xx,phy20-refclock-frequency : Integer. Defines the USB 2.0 PHY reference clock input
+ frequency in Hz in case the clock is generated by the internal PLL.
+ Supported values are 12MHz, 13MHz, 19.2MHz, 20MHz, 24MHz, 26MHz, 38.4MHz, 40MHz, 48MHz
+
+
+Example:
+
+ usb20: usb@1e00000 {
+ compatible = "ti,da850-musb";
+ ti,hwmods = "usb_otg_hs";
+ reg = <0x00200000 0x10000>;
+ interrupt-parent = <&intc>;
+ interrupts = <58>;
+ interrupt-names = "mc";
+
+ multipoint = <1>;
+ num-eps = <5>;
+ ram-bits = <10>;
+ mode = <1>; /* host */
+ power = <250>; /* max power 500mA */
+
+ da8xx,phy20-clkmux-cfg = <1>; /* PHY clock internally generated from the PLL */
+ da8xx,phy20-refclock-frequency = <24000000>;
+
+ status = "okay";
+ };
diff --git a/drivers/usb/musb/da8xx.c b/drivers/usb/musb/da8xx.c
index 4e13fe2..2c00e98 100644
--- a/drivers/usb/musb/da8xx.c
+++ b/drivers/usb/musb/da8xx.c
@@ -1,6 +1,9 @@
/*
* Texas Instruments DA8xx/OMAP-L1x "glue layer"
*
+ * DT support
+ * Copyright (c) 2015-2016 Petr Kulhavy, Barix AG <petr-Qh/3xLP0EvwAvxtiuMwx3w@public.gmane.org>
+ *
* Copyright (c) 2008-2009 MontaVista Software, Inc. <source-Igf4POYTYCDQT0dZR+AlfA@public.gmane.org>
*
* Based on the DaVinci "glue layer" code.
@@ -36,6 +39,7 @@
#include <mach/da8xx.h>
#include <linux/platform_data/usb-davinci.h>
+#include <linux/of_platform.h>
#include "musb_core.h"
@@ -134,6 +138,35 @@ static inline void phy_off(void)
__raw_writel(cfgchip2, CFGCHIP2);
}
+/* converts PHY refclk frequency in HZ into USB0REF_FREQ config value
+ * on unsupported frequency returns -1
+ */
+static inline int phy_refclk_cfg(int frequency)
+{
+ switch (frequency) {
+ case 12000000:
+ return 0x01;
+ case 13000000:
+ return 0x06;
+ case 19200000:
+ return 0x05;
+ case 20000000:
+ return 0x08;
+ case 24000000:
+ return 0x02;
+ case 26000000:
+ return 0x07;
+ case 38400000:
+ return 0x05;
+ case 40000000:
+ return 0x09;
+ case 48000000:
+ return 0x03;
+ default:
+ return -1;
+ }
+}
+
/*
* Because we don't set CTRL.UINT, it's "important" to:
* - not read/write INTRUSB/INTRUSBE (except during
@@ -527,6 +560,8 @@ static const struct platform_device_info da8xx_dev_info = {
.dma_mask = DMA_BIT_MASK(32),
};
+static u64 da8xx_dmamask = DMA_BIT_MASK(32);
+
static int da8xx_probe(struct platform_device *pdev)
{
struct resource musb_resources[2];
@@ -535,6 +570,7 @@ static int da8xx_probe(struct platform_device *pdev)
struct da8xx_glue *glue;
struct platform_device_info pinfo;
struct clk *clk;
+ struct device_node *np = pdev->dev.of_node;
int ret = -ENOMEM;
@@ -560,6 +596,120 @@ static int da8xx_probe(struct platform_device *pdev)
glue->dev = &pdev->dev;
glue->clk = clk;
+ if (np) {
+ struct musb_hdrc_config *config;
+ struct musb_hdrc_platform_data *data;
+ u32 phy20_refclock_freq, phy20_clkmux_cfg;
+
+ pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+ if (!pdata) {
+ ret = -ENOMEM;
+ goto err5;
+ }
+
+ data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
+ if (!data) {
+ ret = -ENOMEM;
+ goto err5;
+ }
+
+ config = devm_kzalloc(&pdev->dev, sizeof(*config), GFP_KERNEL);
+ if (!config) {
+ ret = -ENOMEM;
+ goto err5;
+ }
+
+ if (of_property_read_u32(np, "mode", (u32 *)&pdata->mode)) {
+ dev_err(&pdev->dev,
+ "failed to read the USB mode parameter\n");
+ ret = -EINVAL;
+ goto err5;
+ }
+
+ if (of_property_read_u32(np, "num-eps",
+ (u32 *)&config->num_eps)) {
+ dev_err(&pdev->dev,
+ "failed to read the number of endpoints\n");
+ ret = -EINVAL;
+ goto err5;
+ }
+
+ if (of_property_read_u32(np, "ram-bits",
+ (u32 *)&config->ram_bits)) {
+ dev_err(&pdev->dev,
+ "failed to read the ram-bits parameter\n");
+ ret = -EINVAL;
+ goto err5;
+ }
+
+ if (of_property_read_u32(np, "power", (u32 *)&pdata->power)) {
+ dev_err(&pdev->dev,
+ "failed to read the maximum power parameter\n");
+ ret = -EINVAL;
+ goto err5;
+ }
+
+ config->multipoint = of_property_read_bool(np, "multipoint");
+
+ pdata->board_data = data;
+ pdata->config = config;
+
+ /* optional parameter reference clock frequency */
+ if (!of_property_read_u32(np, "da8xx,phy20-clkmux-cfg",
+ &phy20_clkmux_cfg)) {
+ u32 cfgchip2;
+
+ /*
+ * Select internal reference clock for USB 2.0 PHY
+ * and use it as a clock source for USB 1.1 PHY
+ * (this is the default setting anyway).
+ */
+
+ cfgchip2 = __raw_readl(
+ DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
+
+ cfgchip2 &= ~CFGCHIP2_USB2PHYCLKMUX;
+ cfgchip2 |= (phy20_clkmux_cfg & 1) <<
+ CFGCHIP2_USB2PHYCLKMUX_OFFSET;
+
+ __raw_writel(cfgchip2,
+ DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
+
+ }
+
+ /* optional parameter reference clock frequency */
+ if (!of_property_read_u32(np, "da8xx,phy20-refclock-frequency",
+ &phy20_refclock_freq)) {
+ u32 cfgchip2;
+ int phy20_refclk_cfg;
+
+ phy20_refclk_cfg = phy_refclk_cfg(phy20_refclock_freq);
+ if (phy20_refclk_cfg < 0) {
+ dev_err(&pdev->dev,
+ "invalid PHY clock frequency %u Hz\n",
+ phy20_refclock_freq);
+ ret = -EINVAL;
+ goto err5;
+ }
+
+ /*
+ * Set up USB clock/mode in the CFGCHIP2 register.
+ */
+ cfgchip2 = __raw_readl(
+ DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
+
+ /* USB2.0 PHY reference clock is 24 MHz */
+ cfgchip2 &= ~CFGCHIP2_REFFREQ;
+ cfgchip2 |= phy20_refclk_cfg;
+
+ __raw_writel(cfgchip2,
+ DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
+ }
+
+ musb->dev.dma_mask = &da8xx_dmamask;
+ musb->dev.coherent_dma_mask = da8xx_dmamask;
+ }
+
pdata->platform_ops = &da8xx_ops;
glue->phy = usb_phy_generic_register();
@@ -627,11 +777,27 @@ static int da8xx_remove(struct platform_device *pdev)
return 0;
}
+#ifdef CONFIG_OF
+static const struct of_device_id da8xx_id_table[] = {
+ {
+ .compatible = "ti,da850-musb"
+ },
+ {
+ .compatible = "ti,da830-musb"
+ },
+ {},
+};
+MODULE_DEVICE_TABLE(of, da8xx_id_table);
+#endif
+
static struct platform_driver da8xx_driver = {
.probe = da8xx_probe,
.remove = da8xx_remove,
.driver = {
.name = "musb-da8xx",
+#ifdef CONFIG_OF
+ .of_match_table = of_match_ptr(da8xx_id_table),
+#endif
},
};
diff --git a/include/linux/platform_data/usb-davinci.h b/include/linux/platform_data/usb-davinci.h
index e0bc4ab..bd2a5a9 100644
--- a/include/linux/platform_data/usb-davinci.h
+++ b/include/linux/platform_data/usb-davinci.h
@@ -21,7 +21,8 @@
#define CFGCHIP2_FORCE_DEVICE (2 << 13)
#define CFGCHIP2_FORCE_HOST_VBUS_LOW (3 << 13)
#define CFGCHIP2_USB1PHYCLKMUX (1 << 12)
-#define CFGCHIP2_USB2PHYCLKMUX (1 << 11)
+#define CFGCHIP2_USB2PHYCLKMUX_OFFSET (11)
+#define CFGCHIP2_USB2PHYCLKMUX (1 << CFGCHIP2_USB2PHYCLKMUX_OFFSET)
#define CFGCHIP2_PHYPWRDN (1 << 10)
#define CFGCHIP2_OTGPWRDN (1 << 9)
#define CFGCHIP2_DATPOL (1 << 8)
--
1.9.1
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
next reply other threads:[~2016-01-21 14:53 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-01-21 14:53 Petr Kulhavy [this message]
[not found] ` <1453387999-4485-1-git-send-email-petr-Qh/3xLP0EvwAvxtiuMwx3w@public.gmane.org>
2016-01-21 18:05 ` [PATCH 2/2] Drivers: MUSB: Davinci MUSB: added DT support Sergei Shtylyov
2016-01-21 23:07 ` Rob Herring
2016-01-22 9:01 ` Petr Kulhavy
2016-01-22 9:03 ` Petr Kulhavy
2016-01-24 19:00 ` Sergei Shtylyov
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1453387999-4485-1-git-send-email-petr@barix.com \
--to=petr-qh/3xlp0evwavxtiumwx3w@public.gmane.org \
--cc=balbi-l0cyMroinI0@public.gmane.org \
--cc=devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
--cc=linux-usb-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
--cc=robh+dt-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).