^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-1.0+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Renesas USB driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2011 Renesas Solutions Corp.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (C) 2019 Renesas Electronics Corporation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/gpio/consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/of_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/pm_runtime.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/reset.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/sysfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include "common.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include "rcar2.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include "rcar3.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include "rza.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * image of renesas_usbhs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * ex) gadget case
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * mod.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * mod_gadget.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * mod_host.c pipe.c fifo.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) * +-------+ +-----------+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * | pipe0 |------>| fifo pio |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) * +------------+ +-------+ +-----------+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) * | mod_gadget |=====> | pipe1 |--+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) * +------------+ +-------+ | +-----------+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) * | pipe2 | | +-| fifo dma0 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) * +------------+ +-------+ | | +-----------+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) * | mod_host | | pipe3 |<-|--+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) * +------------+ +-------+ | +-----------+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) * | .... | +--->| fifo dma1 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) * | .... | +-----------+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) * platform call back
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) * renesas usb support platform callback function.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) * Below macro call it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) * if platform doesn't have callback, it return 0 (no error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define usbhs_platform_call(priv, func, args...)\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) (!(priv) ? -ENODEV : \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) !((priv)->pfunc->func) ? 0 : \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) (priv)->pfunc->func(args))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) * common functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) u16 usbhs_read(struct usbhs_priv *priv, u32 reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) return ioread16(priv->base + reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) void usbhs_write(struct usbhs_priv *priv, u32 reg, u16 data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) iowrite16(data, priv->base + reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) void usbhs_bset(struct usbhs_priv *priv, u32 reg, u16 mask, u16 data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) u16 val = usbhs_read(priv, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) val &= ~mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) val |= data & mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) usbhs_write(priv, reg, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) struct usbhs_priv *usbhs_pdev_to_priv(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) return dev_get_drvdata(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) int usbhs_get_id_as_gadget(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) return USBHS_GADGET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) * syscfg functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) static void usbhs_sys_clock_ctrl(struct usbhs_priv *priv, int enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) usbhs_bset(priv, SYSCFG, SCKE, enable ? SCKE : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) void usbhs_sys_host_ctrl(struct usbhs_priv *priv, int enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) u16 mask = DCFM | DRPD | DPRPU | HSE | USBE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) u16 val = DCFM | DRPD | HSE | USBE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) * if enable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) * - select Host mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) * - D+ Line/D- Line Pull-down
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) usbhs_bset(priv, SYSCFG, mask, enable ? val : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) void usbhs_sys_function_ctrl(struct usbhs_priv *priv, int enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) u16 mask = DCFM | DRPD | DPRPU | HSE | USBE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) u16 val = HSE | USBE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) /* CNEN bit is required for function operation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) if (usbhs_get_dparam(priv, has_cnen)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) mask |= CNEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) val |= CNEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) * if enable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) * - select Function mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) * - D+ Line Pull-up is disabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) * When D+ Line Pull-up is enabled,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) * calling usbhs_sys_function_pullup(,1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) usbhs_bset(priv, SYSCFG, mask, enable ? val : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) void usbhs_sys_function_pullup(struct usbhs_priv *priv, int enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) usbhs_bset(priv, SYSCFG, DPRPU, enable ? DPRPU : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) void usbhs_sys_set_test_mode(struct usbhs_priv *priv, u16 mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) usbhs_write(priv, TESTMODE, mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) * frame functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) int usbhs_frame_get_num(struct usbhs_priv *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) return usbhs_read(priv, FRMNUM) & FRNM_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) * usb request functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) void usbhs_usbreq_get_val(struct usbhs_priv *priv, struct usb_ctrlrequest *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) u16 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) val = usbhs_read(priv, USBREQ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) req->bRequest = (val >> 8) & 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) req->bRequestType = (val >> 0) & 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) req->wValue = cpu_to_le16(usbhs_read(priv, USBVAL));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) req->wIndex = cpu_to_le16(usbhs_read(priv, USBINDX));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) req->wLength = cpu_to_le16(usbhs_read(priv, USBLENG));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) void usbhs_usbreq_set_val(struct usbhs_priv *priv, struct usb_ctrlrequest *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) usbhs_write(priv, USBREQ, (req->bRequest << 8) | req->bRequestType);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) usbhs_write(priv, USBVAL, le16_to_cpu(req->wValue));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) usbhs_write(priv, USBINDX, le16_to_cpu(req->wIndex));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) usbhs_write(priv, USBLENG, le16_to_cpu(req->wLength));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) usbhs_bset(priv, DCPCTR, SUREQ, SUREQ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) * bus/vbus functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) void usbhs_bus_send_sof_enable(struct usbhs_priv *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) u16 status = usbhs_read(priv, DVSTCTR) & (USBRST | UACT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) if (status != USBRST) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) struct device *dev = usbhs_priv_to_dev(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) dev_err(dev, "usbhs should be reset\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) usbhs_bset(priv, DVSTCTR, (USBRST | UACT), UACT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) void usbhs_bus_send_reset(struct usbhs_priv *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) usbhs_bset(priv, DVSTCTR, (USBRST | UACT), USBRST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) int usbhs_bus_get_speed(struct usbhs_priv *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) u16 dvstctr = usbhs_read(priv, DVSTCTR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) switch (RHST & dvstctr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) case RHST_LOW_SPEED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) return USB_SPEED_LOW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) case RHST_FULL_SPEED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) return USB_SPEED_FULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) case RHST_HIGH_SPEED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) return USB_SPEED_HIGH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) return USB_SPEED_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) int usbhs_vbus_ctrl(struct usbhs_priv *priv, int enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) struct platform_device *pdev = usbhs_priv_to_pdev(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) return usbhs_platform_call(priv, set_vbus, pdev, enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) static void usbhsc_bus_init(struct usbhs_priv *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) usbhs_write(priv, DVSTCTR, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) usbhs_vbus_ctrl(priv, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) * device configuration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) int usbhs_set_device_config(struct usbhs_priv *priv, int devnum,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) u16 upphub, u16 hubport, u16 speed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) struct device *dev = usbhs_priv_to_dev(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) u16 usbspd = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) u32 reg = DEVADD0 + (2 * devnum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) if (devnum > 10) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) dev_err(dev, "cannot set speed to unknown device %d\n", devnum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) if (upphub > 0xA) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) dev_err(dev, "unsupported hub number %d\n", upphub);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) switch (speed) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) case USB_SPEED_LOW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) usbspd = USBSPD_SPEED_LOW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) case USB_SPEED_FULL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) usbspd = USBSPD_SPEED_FULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) case USB_SPEED_HIGH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) usbspd = USBSPD_SPEED_HIGH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) dev_err(dev, "unsupported speed %d\n", speed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) usbhs_write(priv, reg, UPPHUB(upphub) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) HUBPORT(hubport)|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) USBSPD(usbspd));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) * interrupt functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) void usbhs_xxxsts_clear(struct usbhs_priv *priv, u16 sts_reg, u16 bit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) u16 pipe_mask = (u16)GENMASK(usbhs_get_dparam(priv, pipe_size), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) usbhs_write(priv, sts_reg, ~(1 << bit) & pipe_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) * local functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) static void usbhsc_set_buswait(struct usbhs_priv *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) int wait = usbhs_get_dparam(priv, buswait_bwait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) /* set bus wait if platform have */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) if (wait)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) usbhs_bset(priv, BUSWAIT, 0x000F, wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) static bool usbhsc_is_multi_clks(struct usbhs_priv *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) return priv->dparam.multi_clks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) static int usbhsc_clk_get(struct device *dev, struct usbhs_priv *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) if (!usbhsc_is_multi_clks(priv))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) /* The first clock should exist */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) priv->clks[0] = of_clk_get(dev_of_node(dev), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) if (IS_ERR(priv->clks[0]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) return PTR_ERR(priv->clks[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) * To backward compatibility with old DT, this driver checks the return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) * value if it's -ENOENT or not.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) priv->clks[1] = of_clk_get(dev_of_node(dev), 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) if (PTR_ERR(priv->clks[1]) == -ENOENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) priv->clks[1] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) else if (IS_ERR(priv->clks[1]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) return PTR_ERR(priv->clks[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) static void usbhsc_clk_put(struct usbhs_priv *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) if (!usbhsc_is_multi_clks(priv))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) for (i = 0; i < ARRAY_SIZE(priv->clks); i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) clk_put(priv->clks[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) static int usbhsc_clk_prepare_enable(struct usbhs_priv *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) int i, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) if (!usbhsc_is_multi_clks(priv))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) for (i = 0; i < ARRAY_SIZE(priv->clks); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) ret = clk_prepare_enable(priv->clks[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) while (--i >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) clk_disable_unprepare(priv->clks[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) static void usbhsc_clk_disable_unprepare(struct usbhs_priv *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) if (!usbhsc_is_multi_clks(priv))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) for (i = 0; i < ARRAY_SIZE(priv->clks); i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) clk_disable_unprepare(priv->clks[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) * platform default param
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) /* commonly used on old SH-Mobile SoCs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) static struct renesas_usbhs_driver_pipe_config usbhsc_default_pipe[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_CONTROL, 64, 0x00, false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_ISOC, 1024, 0x08, false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_ISOC, 1024, 0x18, false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_BULK, 512, 0x28, true),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_BULK, 512, 0x38, true),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_BULK, 512, 0x48, true),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_INT, 64, 0x04, false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_INT, 64, 0x05, false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_INT, 64, 0x06, false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_INT, 64, 0x07, false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) /* commonly used on newer SH-Mobile and R-Car SoCs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) static struct renesas_usbhs_driver_pipe_config usbhsc_new_pipe[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_CONTROL, 64, 0x00, false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_ISOC, 1024, 0x08, true),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_ISOC, 1024, 0x28, true),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_BULK, 512, 0x48, true),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_BULK, 512, 0x58, true),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_BULK, 512, 0x68, true),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_INT, 64, 0x04, false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_INT, 64, 0x05, false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_INT, 64, 0x06, false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_BULK, 512, 0x78, true),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_BULK, 512, 0x88, true),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_BULK, 512, 0x98, true),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_BULK, 512, 0xa8, true),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_BULK, 512, 0xb8, true),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_BULK, 512, 0xc8, true),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) RENESAS_USBHS_PIPE(USB_ENDPOINT_XFER_BULK, 512, 0xd8, true),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) * power control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) static void usbhsc_power_ctrl(struct usbhs_priv *priv, int enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) struct platform_device *pdev = usbhs_priv_to_pdev(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) struct device *dev = usbhs_priv_to_dev(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) if (enable) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) /* enable PM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) pm_runtime_get_sync(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) /* enable clks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) if (usbhsc_clk_prepare_enable(priv))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) /* enable platform power */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) usbhs_platform_call(priv, power_ctrl, pdev, priv->base, enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) /* USB on */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) usbhs_sys_clock_ctrl(priv, enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) /* USB off */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) usbhs_sys_clock_ctrl(priv, enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) /* disable platform power */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) usbhs_platform_call(priv, power_ctrl, pdev, priv->base, enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) /* disable clks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) usbhsc_clk_disable_unprepare(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) /* disable PM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) pm_runtime_put_sync(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) * hotplug
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) static void usbhsc_hotplug(struct usbhs_priv *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) struct platform_device *pdev = usbhs_priv_to_pdev(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) struct usbhs_mod *mod = usbhs_mod_get_current(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) int id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) int enable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) int cable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) * get vbus status from platform
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) enable = usbhs_mod_info_call(priv, get_vbus, pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) * get id from platform
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) id = usbhs_platform_call(priv, get_id, pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) if (enable && !mod) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) if (priv->edev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) cable = extcon_get_state(priv->edev, EXTCON_USB_HOST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) if ((cable > 0 && id != USBHS_HOST) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) (!cable && id != USBHS_GADGET)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) dev_info(&pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) "USB cable plugged in doesn't match the selected role!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) ret = usbhs_mod_change(priv, id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) dev_dbg(&pdev->dev, "%s enable\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) /* power on */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) if (usbhs_get_dparam(priv, runtime_pwctrl))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) usbhsc_power_ctrl(priv, enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) /* bus init */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) usbhsc_set_buswait(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) usbhsc_bus_init(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) /* module start */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) usbhs_mod_call(priv, start, priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) } else if (!enable && mod) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) dev_dbg(&pdev->dev, "%s disable\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) /* module stop */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) usbhs_mod_call(priv, stop, priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) /* bus init */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) usbhsc_bus_init(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) /* power off */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) if (usbhs_get_dparam(priv, runtime_pwctrl))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) usbhsc_power_ctrl(priv, enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) usbhs_mod_change(priv, -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) /* reset phy for next connection */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) usbhs_platform_call(priv, phy_reset, pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) * notify hotplug
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) static void usbhsc_notify_hotplug(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) struct usbhs_priv *priv = container_of(work,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) struct usbhs_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) notify_hotplug_work.work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) usbhsc_hotplug(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) int usbhsc_schedule_notify_hotplug(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) struct usbhs_priv *priv = usbhs_pdev_to_priv(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) int delay = usbhs_get_dparam(priv, detection_delay);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) * This functions will be called in interrupt.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) * To make sure safety context,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) * use workqueue for usbhs_notify_hotplug
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) schedule_delayed_work(&priv->notify_hotplug_work,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) msecs_to_jiffies(delay));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) * platform functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) static const struct of_device_id usbhs_of_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) .compatible = "renesas,usbhs-r8a774c0",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) .data = &usbhs_rcar_gen3_with_pll_plat_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) .compatible = "renesas,usbhs-r8a7790",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) .data = &usbhs_rcar_gen2_plat_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) .compatible = "renesas,usbhs-r8a7791",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) .data = &usbhs_rcar_gen2_plat_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) .compatible = "renesas,usbhs-r8a7794",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) .data = &usbhs_rcar_gen2_plat_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) .compatible = "renesas,usbhs-r8a7795",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) .data = &usbhs_rcar_gen3_plat_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) .compatible = "renesas,usbhs-r8a7796",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) .data = &usbhs_rcar_gen3_plat_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) .compatible = "renesas,usbhs-r8a77990",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) .data = &usbhs_rcar_gen3_with_pll_plat_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) .compatible = "renesas,usbhs-r8a77995",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) .data = &usbhs_rcar_gen3_with_pll_plat_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) .compatible = "renesas,rcar-gen2-usbhs",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) .data = &usbhs_rcar_gen2_plat_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) .compatible = "renesas,rcar-gen3-usbhs",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) .data = &usbhs_rcar_gen3_plat_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) .compatible = "renesas,rza1-usbhs",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) .data = &usbhs_rza1_plat_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) .compatible = "renesas,rza2-usbhs",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) .data = &usbhs_rza2_plat_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) { },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) MODULE_DEVICE_TABLE(of, usbhs_of_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) static int usbhs_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) const struct renesas_usbhs_platform_info *info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) struct usbhs_priv *priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) struct resource *irq_res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) struct device *dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) struct gpio_desc *gpiod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) u32 tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) /* check device node */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) if (dev_of_node(dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) info = of_device_get_match_data(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) info = renesas_usbhs_get_info(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) /* check platform information */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) if (!info) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) dev_err(dev, "no platform information\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) /* platform data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) if (!irq_res) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) dev_err(dev, "Not enough Renesas USB platform resources.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) /* usb private data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) if (!priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) priv->base = devm_platform_ioremap_resource(pdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) if (IS_ERR(priv->base))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) return PTR_ERR(priv->base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) if (of_property_read_bool(dev_of_node(dev), "extcon")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) priv->edev = extcon_get_edev_by_phandle(dev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) if (IS_ERR(priv->edev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) return PTR_ERR(priv->edev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) priv->rsts = devm_reset_control_array_get_optional_shared(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) if (IS_ERR(priv->rsts))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) return PTR_ERR(priv->rsts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) * care platform info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) priv->dparam = info->driver_param;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) if (!info->platform_callback.get_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) dev_err(dev, "no platform callbacks\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) priv->pfunc = &info->platform_callback;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) /* set default param if platform doesn't have */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) if (usbhs_get_dparam(priv, has_new_pipe_configs)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) priv->dparam.pipe_configs = usbhsc_new_pipe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) priv->dparam.pipe_size = ARRAY_SIZE(usbhsc_new_pipe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) } else if (!priv->dparam.pipe_configs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) priv->dparam.pipe_configs = usbhsc_default_pipe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) priv->dparam.pipe_size = ARRAY_SIZE(usbhsc_default_pipe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) if (!priv->dparam.pio_dma_border)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) priv->dparam.pio_dma_border = 64; /* 64byte */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) if (!of_property_read_u32(dev_of_node(dev), "renesas,buswait", &tmp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) priv->dparam.buswait_bwait = tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) gpiod = devm_gpiod_get_optional(dev, "renesas,enable", GPIOD_IN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) if (IS_ERR(gpiod))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) return PTR_ERR(gpiod);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) /* FIXME */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) /* runtime power control ? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) if (priv->pfunc->get_vbus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) usbhs_get_dparam(priv, runtime_pwctrl) = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) * priv settings
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) priv->irq = irq_res->start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) if (irq_res->flags & IORESOURCE_IRQ_SHAREABLE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) priv->irqflags = IRQF_SHARED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) priv->pdev = pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) INIT_DELAYED_WORK(&priv->notify_hotplug_work, usbhsc_notify_hotplug);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) spin_lock_init(usbhs_priv_to_lock(priv));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) /* call pipe and module init */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) ret = usbhs_pipe_probe(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) ret = usbhs_fifo_probe(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) goto probe_end_pipe_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) ret = usbhs_mod_probe(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) goto probe_end_fifo_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) /* dev_set_drvdata should be called after usbhs_mod_init */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) platform_set_drvdata(pdev, priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) ret = reset_control_deassert(priv->rsts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) goto probe_fail_rst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) ret = usbhsc_clk_get(dev, priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) goto probe_fail_clks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) * deviece reset here because
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) * USB device might be used in boot loader.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) usbhs_sys_clock_ctrl(priv, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) /* check GPIO determining if USB function should be enabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) if (gpiod) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) ret = !gpiod_get_value(gpiod);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) dev_warn(dev, "USB function not selected (GPIO)\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) ret = -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) goto probe_end_mod_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) * platform call
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) * USB phy setup might depend on CPU/Board.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) * If platform has its callback functions,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) * call it here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) ret = usbhs_platform_call(priv, hardware_init, pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) dev_err(dev, "platform init failed.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) goto probe_end_mod_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) /* reset phy for connection */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) usbhs_platform_call(priv, phy_reset, pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) /* power control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) pm_runtime_enable(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) if (!usbhs_get_dparam(priv, runtime_pwctrl)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) usbhsc_power_ctrl(priv, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) usbhs_mod_autonomy_mode(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) usbhs_mod_non_autonomy_mode(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) * manual call notify_hotplug for cold plug
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) usbhsc_schedule_notify_hotplug(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) dev_info(dev, "probed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) probe_end_mod_exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) usbhsc_clk_put(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) probe_fail_clks:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) reset_control_assert(priv->rsts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) probe_fail_rst:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) usbhs_mod_remove(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) probe_end_fifo_exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) usbhs_fifo_remove(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) probe_end_pipe_exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) usbhs_pipe_remove(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) dev_info(dev, "probe failed (%d)\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) static int usbhs_remove(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) struct usbhs_priv *priv = usbhs_pdev_to_priv(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) dev_dbg(&pdev->dev, "usb remove\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) /* power off */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) if (!usbhs_get_dparam(priv, runtime_pwctrl))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) usbhsc_power_ctrl(priv, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) pm_runtime_disable(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) usbhs_platform_call(priv, hardware_exit, pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) usbhsc_clk_put(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) reset_control_assert(priv->rsts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) usbhs_mod_remove(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) usbhs_fifo_remove(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) usbhs_pipe_remove(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) static __maybe_unused int usbhsc_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) struct usbhs_priv *priv = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) struct usbhs_mod *mod = usbhs_mod_get_current(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) if (mod) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) usbhs_mod_call(priv, stop, priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) usbhs_mod_change(priv, -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) if (mod || !usbhs_get_dparam(priv, runtime_pwctrl))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) usbhsc_power_ctrl(priv, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) static __maybe_unused int usbhsc_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) struct usbhs_priv *priv = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) struct platform_device *pdev = usbhs_priv_to_pdev(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) if (!usbhs_get_dparam(priv, runtime_pwctrl)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) usbhsc_power_ctrl(priv, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) usbhs_mod_autonomy_mode(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) usbhs_platform_call(priv, phy_reset, pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) usbhsc_schedule_notify_hotplug(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) static SIMPLE_DEV_PM_OPS(usbhsc_pm_ops, usbhsc_suspend, usbhsc_resume);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) static struct platform_driver renesas_usbhs_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) .name = "renesas_usbhs",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) .pm = &usbhsc_pm_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) .of_match_table = of_match_ptr(usbhs_of_match),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) .probe = usbhs_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) .remove = usbhs_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) module_platform_driver(renesas_usbhs_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) MODULE_DESCRIPTION("Renesas USB driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>");