Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0f38672c authored by Yoshihiro Shimoda's avatar Yoshihiro Shimoda Committed by Felipe Balbi
Browse files

usb: renesas_usbhs: add support for R-Car D3



This patch adds support for R-Car D3. This SoC needs to release
the PLL reset by the UGCTRL register. So, since this is not the same
as other R-Car Gen3 SoCs, this patch adds a new type as
"USBHS_TYPE_RCAR_GEN3_WITH_PLL".

Acked-by: default avatarRob Herring <robh@kernel.org>
Signed-off-by: default avatarYoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
Signed-off-by: default avatarFelipe Balbi <felipe.balbi@linux.intel.com>
parent a877b8e5
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -10,6 +10,7 @@ Required properties:
	- "renesas,usbhs-r8a7794" for r8a7794 (R-Car E2) compatible device
	- "renesas,usbhs-r8a7794" for r8a7794 (R-Car E2) compatible device
	- "renesas,usbhs-r8a7795" for r8a7795 (R-Car H3) compatible device
	- "renesas,usbhs-r8a7795" for r8a7795 (R-Car H3) compatible device
	- "renesas,usbhs-r8a7796" for r8a7796 (R-Car M3-W) compatible device
	- "renesas,usbhs-r8a7796" for r8a7796 (R-Car M3-W) compatible device
	- "renesas,usbhs-r8a77995" for r8a77995 (R-Car D3) compatible device
	- "renesas,rcar-gen2-usbhs" for R-Car Gen2 compatible device
	- "renesas,rcar-gen2-usbhs" for R-Car Gen2 compatible device
	- "renesas,rcar-gen3-usbhs" for R-Car Gen3 compatible device
	- "renesas,rcar-gen3-usbhs" for R-Car Gen3 compatible device


+9 −1
Original line number Original line Diff line number Diff line
@@ -485,6 +485,10 @@ static const struct of_device_id usbhs_of_match[] = {
		.compatible = "renesas,usbhs-r8a7796",
		.compatible = "renesas,usbhs-r8a7796",
		.data = (void *)USBHS_TYPE_RCAR_GEN3,
		.data = (void *)USBHS_TYPE_RCAR_GEN3,
	},
	},
	{
		.compatible = "renesas,usbhs-r8a77995",
		.data = (void *)USBHS_TYPE_RCAR_GEN3_WITH_PLL,
	},
	{
	{
		.compatible = "renesas,rcar-gen2-usbhs",
		.compatible = "renesas,rcar-gen2-usbhs",
		.data = (void *)USBHS_TYPE_RCAR_GEN2,
		.data = (void *)USBHS_TYPE_RCAR_GEN2,
@@ -519,7 +523,8 @@ static struct renesas_usbhs_platform_info *usbhs_parse_dt(struct device *dev)
		dparam->enable_gpio = gpio;
		dparam->enable_gpio = gpio;


	if (dparam->type == USBHS_TYPE_RCAR_GEN2 ||
	if (dparam->type == USBHS_TYPE_RCAR_GEN2 ||
	    dparam->type == USBHS_TYPE_RCAR_GEN3) {
	    dparam->type == USBHS_TYPE_RCAR_GEN3 ||
	    dparam->type == USBHS_TYPE_RCAR_GEN3_WITH_PLL) {
		dparam->has_usb_dmac = 1;
		dparam->has_usb_dmac = 1;
		dparam->pipe_configs = usbhsc_new_pipe;
		dparam->pipe_configs = usbhsc_new_pipe;
		dparam->pipe_size = ARRAY_SIZE(usbhsc_new_pipe);
		dparam->pipe_size = ARRAY_SIZE(usbhsc_new_pipe);
@@ -584,6 +589,9 @@ static int usbhs_probe(struct platform_device *pdev)
	case USBHS_TYPE_RCAR_GEN3:
	case USBHS_TYPE_RCAR_GEN3:
		priv->pfunc = usbhs_rcar3_ops;
		priv->pfunc = usbhs_rcar3_ops;
		break;
		break;
	case USBHS_TYPE_RCAR_GEN3_WITH_PLL:
		priv->pfunc = usbhs_rcar3_with_pll_ops;
		break;
	default:
	default:
		if (!info->platform_callback.get_id) {
		if (!info->platform_callback.get_id) {
			dev_err(&pdev->dev, "no platform callbacks");
			dev_err(&pdev->dev, "no platform callbacks");
+48 −0
Original line number Original line Diff line number Diff line
@@ -15,24 +15,39 @@
#include "rcar3.h"
#include "rcar3.h"


#define LPSTS		0x102
#define LPSTS		0x102
#define UGCTRL		0x180	/* 32-bit register */
#define UGCTRL2		0x184	/* 32-bit register */
#define UGCTRL2		0x184	/* 32-bit register */
#define UGSTS		0x188	/* 32-bit register */


/* Low Power Status register (LPSTS) */
/* Low Power Status register (LPSTS) */
#define LPSTS_SUSPM	0x4000
#define LPSTS_SUSPM	0x4000


/* R-Car D3 only: USB General control register (UGCTRL) */
#define UGCTRL_PLLRESET		0x00000001
#define UGCTRL_CONNECT		0x00000004

/*
/*
 * USB General control register 2 (UGCTRL2)
 * USB General control register 2 (UGCTRL2)
 * Remarks: bit[31:11] and bit[9:6] should be 0
 * Remarks: bit[31:11] and bit[9:6] should be 0
 */
 */
#define UGCTRL2_RESERVED_3	0x00000001	/* bit[3:0] should be B'0001 */
#define UGCTRL2_RESERVED_3	0x00000001	/* bit[3:0] should be B'0001 */
#define UGCTRL2_USB0SEL_HSUSB	0x00000020
#define UGCTRL2_USB0SEL_OTG	0x00000030
#define UGCTRL2_USB0SEL_OTG	0x00000030
#define UGCTRL2_VBUSSEL		0x00000400
#define UGCTRL2_VBUSSEL		0x00000400


/* R-Car D3 only: USB General status register (UGSTS) */
#define UGSTS_LOCK		0x00000100

static void usbhs_write32(struct usbhs_priv *priv, u32 reg, u32 data)
static void usbhs_write32(struct usbhs_priv *priv, u32 reg, u32 data)
{
{
	iowrite32(data, priv->base + reg);
	iowrite32(data, priv->base + reg);
}
}


static u32 usbhs_read32(struct usbhs_priv *priv, u32 reg)
{
	return ioread32(priv->base + reg);
}

static int usbhs_rcar3_power_ctrl(struct platform_device *pdev,
static int usbhs_rcar3_power_ctrl(struct platform_device *pdev,
				void __iomem *base, int enable)
				void __iomem *base, int enable)
{
{
@@ -52,6 +67,34 @@ static int usbhs_rcar3_power_ctrl(struct platform_device *pdev,
	return 0;
	return 0;
}
}


/* R-Car D3 needs to release UGCTRL.PLLRESET */
static int usbhs_rcar3_power_and_pll_ctrl(struct platform_device *pdev,
					  void __iomem *base, int enable)
{
	struct usbhs_priv *priv = usbhs_pdev_to_priv(pdev);
	u32 val;
	int timeout = 1000;

	if (enable) {
		usbhs_write32(priv, UGCTRL, 0);	/* release PLLRESET */
		usbhs_write32(priv, UGCTRL2, UGCTRL2_RESERVED_3 |
			      UGCTRL2_USB0SEL_HSUSB);

		usbhs_bset(priv, LPSTS, LPSTS_SUSPM, LPSTS_SUSPM);
		do {
			val = usbhs_read32(priv, UGSTS);
			udelay(1);
		} while (!(val & UGSTS_LOCK) && timeout--);
		usbhs_write32(priv, UGCTRL, UGCTRL_CONNECT);
	} else {
		usbhs_write32(priv, UGCTRL, 0);
		usbhs_bset(priv, LPSTS, LPSTS_SUSPM, 0);
		usbhs_write32(priv, UGCTRL, UGCTRL_PLLRESET);
	}

	return 0;
}

static int usbhs_rcar3_get_id(struct platform_device *pdev)
static int usbhs_rcar3_get_id(struct platform_device *pdev)
{
{
	return USBHS_GADGET;
	return USBHS_GADGET;
@@ -61,3 +104,8 @@ const struct renesas_usbhs_platform_callback usbhs_rcar3_ops = {
	.power_ctrl = usbhs_rcar3_power_ctrl,
	.power_ctrl = usbhs_rcar3_power_ctrl,
	.get_id = usbhs_rcar3_get_id,
	.get_id = usbhs_rcar3_get_id,
};
};

const struct renesas_usbhs_platform_callback usbhs_rcar3_with_pll_ops = {
	.power_ctrl = usbhs_rcar3_power_and_pll_ctrl,
	.get_id = usbhs_rcar3_get_id,
};
+1 −0
Original line number Original line Diff line number Diff line
#include "common.h"
#include "common.h"


extern const struct renesas_usbhs_platform_callback usbhs_rcar3_ops;
extern const struct renesas_usbhs_platform_callback usbhs_rcar3_ops;
extern const struct renesas_usbhs_platform_callback usbhs_rcar3_with_pll_ops;
+3 −2
Original line number Original line Diff line number Diff line
@@ -185,6 +185,7 @@ struct renesas_usbhs_driver_param {


#define USBHS_TYPE_RCAR_GEN2		1
#define USBHS_TYPE_RCAR_GEN2		1
#define USBHS_TYPE_RCAR_GEN3		2
#define USBHS_TYPE_RCAR_GEN3		2
#define USBHS_TYPE_RCAR_GEN3_WITH_PLL	3


/*
/*
 * option:
 * option: