cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

phy-sun4i-usb.c (26416B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * Allwinner sun4i USB phy driver
      4 *
      5 * Copyright (C) 2014-2015 Hans de Goede <hdegoede@redhat.com>
      6 *
      7 * Based on code from
      8 * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
      9 *
     10 * Modelled after: Samsung S5P/Exynos SoC series MIPI CSIS/DSIM DPHY driver
     11 * Copyright (C) 2013 Samsung Electronics Co., Ltd.
     12 * Author: Sylwester Nawrocki <s.nawrocki@samsung.com>
     13 */
     14
     15#include <linux/clk.h>
     16#include <linux/delay.h>
     17#include <linux/err.h>
     18#include <linux/extcon-provider.h>
     19#include <linux/gpio/consumer.h>
     20#include <linux/io.h>
     21#include <linux/interrupt.h>
     22#include <linux/kernel.h>
     23#include <linux/module.h>
     24#include <linux/mutex.h>
     25#include <linux/of.h>
     26#include <linux/of_address.h>
     27#include <linux/of_device.h>
     28#include <linux/of_gpio.h>
     29#include <linux/phy/phy.h>
     30#include <linux/phy/phy-sun4i-usb.h>
     31#include <linux/platform_device.h>
     32#include <linux/power_supply.h>
     33#include <linux/regulator/consumer.h>
     34#include <linux/reset.h>
     35#include <linux/spinlock.h>
     36#include <linux/usb/of.h>
     37#include <linux/workqueue.h>
     38
     39#define REG_ISCR			0x00
     40#define REG_PHYCTL_A10			0x04
     41#define REG_PHYBIST			0x08
     42#define REG_PHYTUNE			0x0c
     43#define REG_PHYCTL_A33			0x10
     44#define REG_PHY_OTGCTL			0x20
     45
     46#define REG_HCI_PHY_CTL			0x10
     47
     48#define PHYCTL_DATA			BIT(7)
     49
     50#define OTGCTL_ROUTE_MUSB		BIT(0)
     51
     52#define SUNXI_AHB_ICHR8_EN		BIT(10)
     53#define SUNXI_AHB_INCR4_BURST_EN	BIT(9)
     54#define SUNXI_AHB_INCRX_ALIGN_EN	BIT(8)
     55#define SUNXI_ULPI_BYPASS_EN		BIT(0)
     56
     57/* ISCR, Interface Status and Control bits */
     58#define ISCR_ID_PULLUP_EN		(1 << 17)
     59#define ISCR_DPDM_PULLUP_EN	(1 << 16)
     60/* sunxi has the phy id/vbus pins not connected, so we use the force bits */
     61#define ISCR_FORCE_ID_MASK	(3 << 14)
     62#define ISCR_FORCE_ID_LOW		(2 << 14)
     63#define ISCR_FORCE_ID_HIGH	(3 << 14)
     64#define ISCR_FORCE_VBUS_MASK	(3 << 12)
     65#define ISCR_FORCE_VBUS_LOW	(2 << 12)
     66#define ISCR_FORCE_VBUS_HIGH	(3 << 12)
     67
     68/* Common Control Bits for Both PHYs */
     69#define PHY_PLL_BW			0x03
     70#define PHY_RES45_CAL_EN		0x0c
     71
     72/* Private Control Bits for Each PHY */
     73#define PHY_TX_AMPLITUDE_TUNE		0x20
     74#define PHY_TX_SLEWRATE_TUNE		0x22
     75#define PHY_VBUSVALID_TH_SEL		0x25
     76#define PHY_PULLUP_RES_SEL		0x27
     77#define PHY_OTG_FUNC_EN			0x28
     78#define PHY_VBUS_DET_EN			0x29
     79#define PHY_DISCON_TH_SEL		0x2a
     80#define PHY_SQUELCH_DETECT		0x3c
     81
     82/* A83T specific control bits for PHY0 */
     83#define PHY_CTL_VBUSVLDEXT		BIT(5)
     84#define PHY_CTL_SIDDQ			BIT(3)
     85#define PHY_CTL_H3_SIDDQ		BIT(1)
     86
     87/* A83T specific control bits for PHY2 HSIC */
     88#define SUNXI_EHCI_HS_FORCE		BIT(20)
     89#define SUNXI_HSIC_CONNECT_DET		BIT(17)
     90#define SUNXI_HSIC_CONNECT_INT		BIT(16)
     91#define SUNXI_HSIC			BIT(1)
     92
     93#define MAX_PHYS			4
     94
     95/*
     96 * Note do not raise the debounce time, we must report Vusb high within 100ms
     97 * otherwise we get Vbus errors
     98 */
     99#define DEBOUNCE_TIME			msecs_to_jiffies(50)
    100#define POLL_TIME			msecs_to_jiffies(250)
    101
    102enum sun4i_usb_phy_type {
    103	sun4i_a10_phy,
    104	sun6i_a31_phy,
    105	sun8i_a33_phy,
    106	sun8i_a83t_phy,
    107	sun8i_h3_phy,
    108	sun8i_r40_phy,
    109	sun8i_v3s_phy,
    110	sun50i_a64_phy,
    111	sun50i_h6_phy,
    112};
    113
    114struct sun4i_usb_phy_cfg {
    115	int num_phys;
    116	int hsic_index;
    117	enum sun4i_usb_phy_type type;
    118	u32 disc_thresh;
    119	u32 hci_phy_ctl_clear;
    120	u8 phyctl_offset;
    121	bool dedicated_clocks;
    122	bool phy0_dual_route;
    123	int missing_phys;
    124};
    125
    126struct sun4i_usb_phy_data {
    127	void __iomem *base;
    128	const struct sun4i_usb_phy_cfg *cfg;
    129	enum usb_dr_mode dr_mode;
    130	spinlock_t reg_lock; /* guard access to phyctl reg */
    131	struct sun4i_usb_phy {
    132		struct phy *phy;
    133		void __iomem *pmu;
    134		struct regulator *vbus;
    135		struct reset_control *reset;
    136		struct clk *clk;
    137		struct clk *clk2;
    138		bool regulator_on;
    139		int index;
    140	} phys[MAX_PHYS];
    141	/* phy0 / otg related variables */
    142	struct extcon_dev *extcon;
    143	bool phy0_init;
    144	struct gpio_desc *id_det_gpio;
    145	struct gpio_desc *vbus_det_gpio;
    146	struct power_supply *vbus_power_supply;
    147	struct notifier_block vbus_power_nb;
    148	bool vbus_power_nb_registered;
    149	bool force_session_end;
    150	int id_det_irq;
    151	int vbus_det_irq;
    152	int id_det;
    153	int vbus_det;
    154	struct delayed_work detect;
    155};
    156
    157#define to_sun4i_usb_phy_data(phy) \
    158	container_of((phy), struct sun4i_usb_phy_data, phys[(phy)->index])
    159
    160static void sun4i_usb_phy0_update_iscr(struct phy *_phy, u32 clr, u32 set)
    161{
    162	struct sun4i_usb_phy *phy = phy_get_drvdata(_phy);
    163	struct sun4i_usb_phy_data *data = to_sun4i_usb_phy_data(phy);
    164	u32 iscr;
    165
    166	iscr = readl(data->base + REG_ISCR);
    167	iscr &= ~clr;
    168	iscr |= set;
    169	writel(iscr, data->base + REG_ISCR);
    170}
    171
    172static void sun4i_usb_phy0_set_id_detect(struct phy *phy, u32 val)
    173{
    174	if (val)
    175		val = ISCR_FORCE_ID_HIGH;
    176	else
    177		val = ISCR_FORCE_ID_LOW;
    178
    179	sun4i_usb_phy0_update_iscr(phy, ISCR_FORCE_ID_MASK, val);
    180}
    181
    182static void sun4i_usb_phy0_set_vbus_detect(struct phy *phy, u32 val)
    183{
    184	if (val)
    185		val = ISCR_FORCE_VBUS_HIGH;
    186	else
    187		val = ISCR_FORCE_VBUS_LOW;
    188
    189	sun4i_usb_phy0_update_iscr(phy, ISCR_FORCE_VBUS_MASK, val);
    190}
    191
    192static void sun4i_usb_phy_write(struct sun4i_usb_phy *phy, u32 addr, u32 data,
    193				int len)
    194{
    195	struct sun4i_usb_phy_data *phy_data = to_sun4i_usb_phy_data(phy);
    196	u32 temp, usbc_bit = BIT(phy->index * 2);
    197	void __iomem *phyctl = phy_data->base + phy_data->cfg->phyctl_offset;
    198	unsigned long flags;
    199	int i;
    200
    201	spin_lock_irqsave(&phy_data->reg_lock, flags);
    202
    203	if (phy_data->cfg->phyctl_offset == REG_PHYCTL_A33) {
    204		/* SoCs newer than A33 need us to set phyctl to 0 explicitly */
    205		writel(0, phyctl);
    206	}
    207
    208	for (i = 0; i < len; i++) {
    209		temp = readl(phyctl);
    210
    211		/* clear the address portion */
    212		temp &= ~(0xff << 8);
    213
    214		/* set the address */
    215		temp |= ((addr + i) << 8);
    216		writel(temp, phyctl);
    217
    218		/* set the data bit and clear usbc bit*/
    219		temp = readb(phyctl);
    220		if (data & 0x1)
    221			temp |= PHYCTL_DATA;
    222		else
    223			temp &= ~PHYCTL_DATA;
    224		temp &= ~usbc_bit;
    225		writeb(temp, phyctl);
    226
    227		/* pulse usbc_bit */
    228		temp = readb(phyctl);
    229		temp |= usbc_bit;
    230		writeb(temp, phyctl);
    231
    232		temp = readb(phyctl);
    233		temp &= ~usbc_bit;
    234		writeb(temp, phyctl);
    235
    236		data >>= 1;
    237	}
    238
    239	spin_unlock_irqrestore(&phy_data->reg_lock, flags);
    240}
    241
    242static void sun4i_usb_phy_passby(struct sun4i_usb_phy *phy, int enable)
    243{
    244	struct sun4i_usb_phy_data *phy_data = to_sun4i_usb_phy_data(phy);
    245	u32 bits, reg_value;
    246
    247	if (!phy->pmu)
    248		return;
    249
    250	bits = SUNXI_AHB_ICHR8_EN | SUNXI_AHB_INCR4_BURST_EN |
    251		SUNXI_AHB_INCRX_ALIGN_EN | SUNXI_ULPI_BYPASS_EN;
    252
    253	/* A83T USB2 is HSIC */
    254	if (phy_data->cfg->type == sun8i_a83t_phy && phy->index == 2)
    255		bits |= SUNXI_EHCI_HS_FORCE | SUNXI_HSIC_CONNECT_INT |
    256			SUNXI_HSIC;
    257
    258	reg_value = readl(phy->pmu);
    259
    260	if (enable)
    261		reg_value |= bits;
    262	else
    263		reg_value &= ~bits;
    264
    265	writel(reg_value, phy->pmu);
    266}
    267
    268static int sun4i_usb_phy_init(struct phy *_phy)
    269{
    270	struct sun4i_usb_phy *phy = phy_get_drvdata(_phy);
    271	struct sun4i_usb_phy_data *data = to_sun4i_usb_phy_data(phy);
    272	int ret;
    273	u32 val;
    274
    275	ret = clk_prepare_enable(phy->clk);
    276	if (ret)
    277		return ret;
    278
    279	ret = clk_prepare_enable(phy->clk2);
    280	if (ret) {
    281		clk_disable_unprepare(phy->clk);
    282		return ret;
    283	}
    284
    285	ret = reset_control_deassert(phy->reset);
    286	if (ret) {
    287		clk_disable_unprepare(phy->clk2);
    288		clk_disable_unprepare(phy->clk);
    289		return ret;
    290	}
    291
    292	if (phy->pmu && data->cfg->hci_phy_ctl_clear) {
    293		val = readl(phy->pmu + REG_HCI_PHY_CTL);
    294		val &= ~data->cfg->hci_phy_ctl_clear;
    295		writel(val, phy->pmu + REG_HCI_PHY_CTL);
    296	}
    297
    298	if (data->cfg->type == sun8i_a83t_phy ||
    299	    data->cfg->type == sun50i_h6_phy) {
    300		if (phy->index == 0) {
    301			val = readl(data->base + data->cfg->phyctl_offset);
    302			val |= PHY_CTL_VBUSVLDEXT;
    303			val &= ~PHY_CTL_SIDDQ;
    304			writel(val, data->base + data->cfg->phyctl_offset);
    305		}
    306	} else {
    307		/* Enable USB 45 Ohm resistor calibration */
    308		if (phy->index == 0)
    309			sun4i_usb_phy_write(phy, PHY_RES45_CAL_EN, 0x01, 1);
    310
    311		/* Adjust PHY's magnitude and rate */
    312		sun4i_usb_phy_write(phy, PHY_TX_AMPLITUDE_TUNE, 0x14, 5);
    313
    314		/* Disconnect threshold adjustment */
    315		sun4i_usb_phy_write(phy, PHY_DISCON_TH_SEL,
    316				    data->cfg->disc_thresh, 2);
    317	}
    318
    319	sun4i_usb_phy_passby(phy, 1);
    320
    321	if (phy->index == 0) {
    322		data->phy0_init = true;
    323
    324		/* Enable pull-ups */
    325		sun4i_usb_phy0_update_iscr(_phy, 0, ISCR_DPDM_PULLUP_EN);
    326		sun4i_usb_phy0_update_iscr(_phy, 0, ISCR_ID_PULLUP_EN);
    327
    328		/* Force ISCR and cable state updates */
    329		data->id_det = -1;
    330		data->vbus_det = -1;
    331		queue_delayed_work(system_wq, &data->detect, 0);
    332	}
    333
    334	return 0;
    335}
    336
    337static int sun4i_usb_phy_exit(struct phy *_phy)
    338{
    339	struct sun4i_usb_phy *phy = phy_get_drvdata(_phy);
    340	struct sun4i_usb_phy_data *data = to_sun4i_usb_phy_data(phy);
    341
    342	if (phy->index == 0) {
    343		if (data->cfg->type == sun8i_a83t_phy ||
    344		    data->cfg->type == sun50i_h6_phy) {
    345			void __iomem *phyctl = data->base +
    346				data->cfg->phyctl_offset;
    347
    348			writel(readl(phyctl) | PHY_CTL_SIDDQ, phyctl);
    349		}
    350
    351		/* Disable pull-ups */
    352		sun4i_usb_phy0_update_iscr(_phy, ISCR_DPDM_PULLUP_EN, 0);
    353		sun4i_usb_phy0_update_iscr(_phy, ISCR_ID_PULLUP_EN, 0);
    354		data->phy0_init = false;
    355	}
    356
    357	sun4i_usb_phy_passby(phy, 0);
    358	reset_control_assert(phy->reset);
    359	clk_disable_unprepare(phy->clk2);
    360	clk_disable_unprepare(phy->clk);
    361
    362	return 0;
    363}
    364
    365static int sun4i_usb_phy0_get_id_det(struct sun4i_usb_phy_data *data)
    366{
    367	switch (data->dr_mode) {
    368	case USB_DR_MODE_OTG:
    369		if (data->id_det_gpio)
    370			return gpiod_get_value_cansleep(data->id_det_gpio);
    371		else
    372			return 1; /* Fallback to peripheral mode */
    373	case USB_DR_MODE_HOST:
    374		return 0;
    375	case USB_DR_MODE_PERIPHERAL:
    376	default:
    377		return 1;
    378	}
    379}
    380
    381static int sun4i_usb_phy0_get_vbus_det(struct sun4i_usb_phy_data *data)
    382{
    383	if (data->vbus_det_gpio)
    384		return gpiod_get_value_cansleep(data->vbus_det_gpio);
    385
    386	if (data->vbus_power_supply) {
    387		union power_supply_propval val;
    388		int r;
    389
    390		r = power_supply_get_property(data->vbus_power_supply,
    391					      POWER_SUPPLY_PROP_PRESENT, &val);
    392		if (r == 0)
    393			return val.intval;
    394	}
    395
    396	/* Fallback: report vbus as high */
    397	return 1;
    398}
    399
    400static bool sun4i_usb_phy0_have_vbus_det(struct sun4i_usb_phy_data *data)
    401{
    402	return data->vbus_det_gpio || data->vbus_power_supply;
    403}
    404
    405static bool sun4i_usb_phy0_poll(struct sun4i_usb_phy_data *data)
    406{
    407	if ((data->id_det_gpio && data->id_det_irq <= 0) ||
    408	    (data->vbus_det_gpio && data->vbus_det_irq <= 0))
    409		return true;
    410
    411	/*
    412	 * The A31/A23/A33 companion pmics (AXP221/AXP223) do not
    413	 * generate vbus change interrupts when the board is driving
    414	 * vbus using the N_VBUSEN pin on the pmic, so we must poll
    415	 * when using the pmic for vbus-det _and_ we're driving vbus.
    416	 */
    417	if ((data->cfg->type == sun6i_a31_phy ||
    418	     data->cfg->type == sun8i_a33_phy) &&
    419	    data->vbus_power_supply && data->phys[0].regulator_on)
    420		return true;
    421
    422	return false;
    423}
    424
    425static int sun4i_usb_phy_power_on(struct phy *_phy)
    426{
    427	struct sun4i_usb_phy *phy = phy_get_drvdata(_phy);
    428	struct sun4i_usb_phy_data *data = to_sun4i_usb_phy_data(phy);
    429	int ret;
    430
    431	if (!phy->vbus || phy->regulator_on)
    432		return 0;
    433
    434	/* For phy0 only turn on Vbus if we don't have an ext. Vbus */
    435	if (phy->index == 0 && sun4i_usb_phy0_have_vbus_det(data) &&
    436				data->vbus_det) {
    437		dev_warn(&_phy->dev, "External vbus detected, not enabling our own vbus\n");
    438		return 0;
    439	}
    440
    441	ret = regulator_enable(phy->vbus);
    442	if (ret)
    443		return ret;
    444
    445	phy->regulator_on = true;
    446
    447	/* We must report Vbus high within OTG_TIME_A_WAIT_VRISE msec. */
    448	if (phy->index == 0 && sun4i_usb_phy0_poll(data))
    449		mod_delayed_work(system_wq, &data->detect, DEBOUNCE_TIME);
    450
    451	return 0;
    452}
    453
    454static int sun4i_usb_phy_power_off(struct phy *_phy)
    455{
    456	struct sun4i_usb_phy *phy = phy_get_drvdata(_phy);
    457	struct sun4i_usb_phy_data *data = to_sun4i_usb_phy_data(phy);
    458
    459	if (!phy->vbus || !phy->regulator_on)
    460		return 0;
    461
    462	regulator_disable(phy->vbus);
    463	phy->regulator_on = false;
    464
    465	/*
    466	 * phy0 vbus typically slowly discharges, sometimes this causes the
    467	 * Vbus gpio to not trigger an edge irq on Vbus off, so force a rescan.
    468	 */
    469	if (phy->index == 0 && !sun4i_usb_phy0_poll(data))
    470		mod_delayed_work(system_wq, &data->detect, POLL_TIME);
    471
    472	return 0;
    473}
    474
    475static int sun4i_usb_phy_set_mode(struct phy *_phy,
    476				  enum phy_mode mode, int submode)
    477{
    478	struct sun4i_usb_phy *phy = phy_get_drvdata(_phy);
    479	struct sun4i_usb_phy_data *data = to_sun4i_usb_phy_data(phy);
    480	int new_mode;
    481
    482	if (phy->index != 0) {
    483		if (mode == PHY_MODE_USB_HOST)
    484			return 0;
    485		return -EINVAL;
    486	}
    487
    488	switch (mode) {
    489	case PHY_MODE_USB_HOST:
    490		new_mode = USB_DR_MODE_HOST;
    491		break;
    492	case PHY_MODE_USB_DEVICE:
    493		new_mode = USB_DR_MODE_PERIPHERAL;
    494		break;
    495	case PHY_MODE_USB_OTG:
    496		new_mode = USB_DR_MODE_OTG;
    497		break;
    498	default:
    499		return -EINVAL;
    500	}
    501
    502	if (new_mode != data->dr_mode) {
    503		dev_info(&_phy->dev, "Changing dr_mode to %d\n", new_mode);
    504		data->dr_mode = new_mode;
    505	}
    506
    507	data->id_det = -1; /* Force reprocessing of id */
    508	data->force_session_end = true;
    509	queue_delayed_work(system_wq, &data->detect, 0);
    510
    511	return 0;
    512}
    513
    514void sun4i_usb_phy_set_squelch_detect(struct phy *_phy, bool enabled)
    515{
    516	struct sun4i_usb_phy *phy = phy_get_drvdata(_phy);
    517
    518	sun4i_usb_phy_write(phy, PHY_SQUELCH_DETECT, enabled ? 0 : 2, 2);
    519}
    520EXPORT_SYMBOL_GPL(sun4i_usb_phy_set_squelch_detect);
    521
    522static const struct phy_ops sun4i_usb_phy_ops = {
    523	.init		= sun4i_usb_phy_init,
    524	.exit		= sun4i_usb_phy_exit,
    525	.power_on	= sun4i_usb_phy_power_on,
    526	.power_off	= sun4i_usb_phy_power_off,
    527	.set_mode	= sun4i_usb_phy_set_mode,
    528	.owner		= THIS_MODULE,
    529};
    530
    531static void sun4i_usb_phy0_reroute(struct sun4i_usb_phy_data *data, int id_det)
    532{
    533	u32 regval;
    534
    535	regval = readl(data->base + REG_PHY_OTGCTL);
    536	if (id_det == 0) {
    537		/* Host mode. Route phy0 to EHCI/OHCI */
    538		regval &= ~OTGCTL_ROUTE_MUSB;
    539	} else {
    540		/* Peripheral mode. Route phy0 to MUSB */
    541		regval |= OTGCTL_ROUTE_MUSB;
    542	}
    543	writel(regval, data->base + REG_PHY_OTGCTL);
    544}
    545
    546static void sun4i_usb_phy0_id_vbus_det_scan(struct work_struct *work)
    547{
    548	struct sun4i_usb_phy_data *data =
    549		container_of(work, struct sun4i_usb_phy_data, detect.work);
    550	struct phy *phy0 = data->phys[0].phy;
    551	struct sun4i_usb_phy *phy;
    552	bool force_session_end, id_notify = false, vbus_notify = false;
    553	int id_det, vbus_det;
    554
    555	if (!phy0)
    556		return;
    557
    558	phy = phy_get_drvdata(phy0);
    559	id_det = sun4i_usb_phy0_get_id_det(data);
    560	vbus_det = sun4i_usb_phy0_get_vbus_det(data);
    561
    562	mutex_lock(&phy0->mutex);
    563
    564	if (!data->phy0_init) {
    565		mutex_unlock(&phy0->mutex);
    566		return;
    567	}
    568
    569	force_session_end = data->force_session_end;
    570	data->force_session_end = false;
    571
    572	if (id_det != data->id_det) {
    573		/* id-change, force session end if we've no vbus detection */
    574		if (data->dr_mode == USB_DR_MODE_OTG &&
    575		    !sun4i_usb_phy0_have_vbus_det(data))
    576			force_session_end = true;
    577
    578		/* When entering host mode (id = 0) force end the session now */
    579		if (force_session_end && id_det == 0) {
    580			sun4i_usb_phy0_set_vbus_detect(phy0, 0);
    581			msleep(200);
    582			sun4i_usb_phy0_set_vbus_detect(phy0, 1);
    583		}
    584		sun4i_usb_phy0_set_id_detect(phy0, id_det);
    585		data->id_det = id_det;
    586		id_notify = true;
    587	}
    588
    589	if (vbus_det != data->vbus_det) {
    590		sun4i_usb_phy0_set_vbus_detect(phy0, vbus_det);
    591		data->vbus_det = vbus_det;
    592		vbus_notify = true;
    593	}
    594
    595	mutex_unlock(&phy0->mutex);
    596
    597	if (id_notify) {
    598		extcon_set_state_sync(data->extcon, EXTCON_USB_HOST,
    599					!id_det);
    600		/* When leaving host mode force end the session here */
    601		if (force_session_end && id_det == 1) {
    602			mutex_lock(&phy0->mutex);
    603			sun4i_usb_phy0_set_vbus_detect(phy0, 0);
    604			msleep(1000);
    605			sun4i_usb_phy0_set_vbus_detect(phy0, 1);
    606			mutex_unlock(&phy0->mutex);
    607		}
    608
    609		/* Enable PHY0 passby for host mode only. */
    610		sun4i_usb_phy_passby(phy, !id_det);
    611
    612		/* Re-route PHY0 if necessary */
    613		if (data->cfg->phy0_dual_route)
    614			sun4i_usb_phy0_reroute(data, id_det);
    615	}
    616
    617	if (vbus_notify)
    618		extcon_set_state_sync(data->extcon, EXTCON_USB, vbus_det);
    619
    620	if (sun4i_usb_phy0_poll(data))
    621		queue_delayed_work(system_wq, &data->detect, POLL_TIME);
    622}
    623
    624static irqreturn_t sun4i_usb_phy0_id_vbus_det_irq(int irq, void *dev_id)
    625{
    626	struct sun4i_usb_phy_data *data = dev_id;
    627
    628	/* vbus or id changed, let the pins settle and then scan them */
    629	mod_delayed_work(system_wq, &data->detect, DEBOUNCE_TIME);
    630
    631	return IRQ_HANDLED;
    632}
    633
    634static int sun4i_usb_phy0_vbus_notify(struct notifier_block *nb,
    635				      unsigned long val, void *v)
    636{
    637	struct sun4i_usb_phy_data *data =
    638		container_of(nb, struct sun4i_usb_phy_data, vbus_power_nb);
    639	struct power_supply *psy = v;
    640
    641	/* Properties on the vbus_power_supply changed, scan vbus_det */
    642	if (val == PSY_EVENT_PROP_CHANGED && psy == data->vbus_power_supply)
    643		mod_delayed_work(system_wq, &data->detect, DEBOUNCE_TIME);
    644
    645	return NOTIFY_OK;
    646}
    647
    648static struct phy *sun4i_usb_phy_xlate(struct device *dev,
    649					struct of_phandle_args *args)
    650{
    651	struct sun4i_usb_phy_data *data = dev_get_drvdata(dev);
    652
    653	if (args->args[0] >= data->cfg->num_phys)
    654		return ERR_PTR(-ENODEV);
    655
    656	if (data->cfg->missing_phys & BIT(args->args[0]))
    657		return ERR_PTR(-ENODEV);
    658
    659	return data->phys[args->args[0]].phy;
    660}
    661
    662static int sun4i_usb_phy_remove(struct platform_device *pdev)
    663{
    664	struct device *dev = &pdev->dev;
    665	struct sun4i_usb_phy_data *data = dev_get_drvdata(dev);
    666
    667	if (data->vbus_power_nb_registered)
    668		power_supply_unreg_notifier(&data->vbus_power_nb);
    669	if (data->id_det_irq > 0)
    670		devm_free_irq(dev, data->id_det_irq, data);
    671	if (data->vbus_det_irq > 0)
    672		devm_free_irq(dev, data->vbus_det_irq, data);
    673
    674	cancel_delayed_work_sync(&data->detect);
    675
    676	return 0;
    677}
    678
    679static const unsigned int sun4i_usb_phy0_cable[] = {
    680	EXTCON_USB,
    681	EXTCON_USB_HOST,
    682	EXTCON_NONE,
    683};
    684
    685static int sun4i_usb_phy_probe(struct platform_device *pdev)
    686{
    687	struct sun4i_usb_phy_data *data;
    688	struct device *dev = &pdev->dev;
    689	struct device_node *np = dev->of_node;
    690	struct phy_provider *phy_provider;
    691	int i, ret;
    692
    693	data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
    694	if (!data)
    695		return -ENOMEM;
    696
    697	spin_lock_init(&data->reg_lock);
    698	INIT_DELAYED_WORK(&data->detect, sun4i_usb_phy0_id_vbus_det_scan);
    699	dev_set_drvdata(dev, data);
    700	data->cfg = of_device_get_match_data(dev);
    701	if (!data->cfg)
    702		return -EINVAL;
    703
    704	data->base = devm_platform_ioremap_resource_byname(pdev, "phy_ctrl");
    705	if (IS_ERR(data->base))
    706		return PTR_ERR(data->base);
    707
    708	data->id_det_gpio = devm_gpiod_get_optional(dev, "usb0_id_det",
    709						    GPIOD_IN);
    710	if (IS_ERR(data->id_det_gpio)) {
    711		dev_err(dev, "Couldn't request ID GPIO\n");
    712		return PTR_ERR(data->id_det_gpio);
    713	}
    714
    715	data->vbus_det_gpio = devm_gpiod_get_optional(dev, "usb0_vbus_det",
    716						      GPIOD_IN);
    717	if (IS_ERR(data->vbus_det_gpio)) {
    718		dev_err(dev, "Couldn't request VBUS detect GPIO\n");
    719		return PTR_ERR(data->vbus_det_gpio);
    720	}
    721
    722	if (of_find_property(np, "usb0_vbus_power-supply", NULL)) {
    723		data->vbus_power_supply = devm_power_supply_get_by_phandle(dev,
    724						     "usb0_vbus_power-supply");
    725		if (IS_ERR(data->vbus_power_supply)) {
    726			dev_err(dev, "Couldn't get the VBUS power supply\n");
    727			return PTR_ERR(data->vbus_power_supply);
    728		}
    729
    730		if (!data->vbus_power_supply)
    731			return -EPROBE_DEFER;
    732	}
    733
    734	data->dr_mode = of_usb_get_dr_mode_by_phy(np, 0);
    735
    736	data->extcon = devm_extcon_dev_allocate(dev, sun4i_usb_phy0_cable);
    737	if (IS_ERR(data->extcon)) {
    738		dev_err(dev, "Couldn't allocate our extcon device\n");
    739		return PTR_ERR(data->extcon);
    740	}
    741
    742	ret = devm_extcon_dev_register(dev, data->extcon);
    743	if (ret) {
    744		dev_err(dev, "failed to register extcon: %d\n", ret);
    745		return ret;
    746	}
    747
    748	for (i = 0; i < data->cfg->num_phys; i++) {
    749		struct sun4i_usb_phy *phy = data->phys + i;
    750		char name[16];
    751
    752		if (data->cfg->missing_phys & BIT(i))
    753			continue;
    754
    755		snprintf(name, sizeof(name), "usb%d_vbus", i);
    756		phy->vbus = devm_regulator_get_optional(dev, name);
    757		if (IS_ERR(phy->vbus)) {
    758			if (PTR_ERR(phy->vbus) == -EPROBE_DEFER) {
    759				dev_err(dev,
    760					"Couldn't get regulator %s... Deferring probe\n",
    761					name);
    762				return -EPROBE_DEFER;
    763			}
    764
    765			phy->vbus = NULL;
    766		}
    767
    768		if (data->cfg->dedicated_clocks)
    769			snprintf(name, sizeof(name), "usb%d_phy", i);
    770		else
    771			strlcpy(name, "usb_phy", sizeof(name));
    772
    773		phy->clk = devm_clk_get(dev, name);
    774		if (IS_ERR(phy->clk)) {
    775			dev_err(dev, "failed to get clock %s\n", name);
    776			return PTR_ERR(phy->clk);
    777		}
    778
    779		/* The first PHY is always tied to OTG, and never HSIC */
    780		if (data->cfg->hsic_index && i == data->cfg->hsic_index) {
    781			/* HSIC needs secondary clock */
    782			snprintf(name, sizeof(name), "usb%d_hsic_12M", i);
    783			phy->clk2 = devm_clk_get(dev, name);
    784			if (IS_ERR(phy->clk2)) {
    785				dev_err(dev, "failed to get clock %s\n", name);
    786				return PTR_ERR(phy->clk2);
    787			}
    788		}
    789
    790		snprintf(name, sizeof(name), "usb%d_reset", i);
    791		phy->reset = devm_reset_control_get(dev, name);
    792		if (IS_ERR(phy->reset)) {
    793			dev_err(dev, "failed to get reset %s\n", name);
    794			return PTR_ERR(phy->reset);
    795		}
    796
    797		if (i || data->cfg->phy0_dual_route) { /* No pmu for musb */
    798			snprintf(name, sizeof(name), "pmu%d", i);
    799			phy->pmu = devm_platform_ioremap_resource_byname(pdev, name);
    800			if (IS_ERR(phy->pmu))
    801				return PTR_ERR(phy->pmu);
    802		}
    803
    804		phy->phy = devm_phy_create(dev, NULL, &sun4i_usb_phy_ops);
    805		if (IS_ERR(phy->phy)) {
    806			dev_err(dev, "failed to create PHY %d\n", i);
    807			return PTR_ERR(phy->phy);
    808		}
    809
    810		phy->index = i;
    811		phy_set_drvdata(phy->phy, &data->phys[i]);
    812	}
    813
    814	data->id_det_irq = gpiod_to_irq(data->id_det_gpio);
    815	if (data->id_det_irq > 0) {
    816		ret = devm_request_irq(dev, data->id_det_irq,
    817				sun4i_usb_phy0_id_vbus_det_irq,
    818				IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
    819				"usb0-id-det", data);
    820		if (ret) {
    821			dev_err(dev, "Err requesting id-det-irq: %d\n", ret);
    822			return ret;
    823		}
    824	}
    825
    826	data->vbus_det_irq = gpiod_to_irq(data->vbus_det_gpio);
    827	if (data->vbus_det_irq > 0) {
    828		ret = devm_request_irq(dev, data->vbus_det_irq,
    829				sun4i_usb_phy0_id_vbus_det_irq,
    830				IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
    831				"usb0-vbus-det", data);
    832		if (ret) {
    833			dev_err(dev, "Err requesting vbus-det-irq: %d\n", ret);
    834			data->vbus_det_irq = -1;
    835			sun4i_usb_phy_remove(pdev); /* Stop detect work */
    836			return ret;
    837		}
    838	}
    839
    840	if (data->vbus_power_supply) {
    841		data->vbus_power_nb.notifier_call = sun4i_usb_phy0_vbus_notify;
    842		data->vbus_power_nb.priority = 0;
    843		ret = power_supply_reg_notifier(&data->vbus_power_nb);
    844		if (ret) {
    845			sun4i_usb_phy_remove(pdev); /* Stop detect work */
    846			return ret;
    847		}
    848		data->vbus_power_nb_registered = true;
    849	}
    850
    851	phy_provider = devm_of_phy_provider_register(dev, sun4i_usb_phy_xlate);
    852	if (IS_ERR(phy_provider)) {
    853		sun4i_usb_phy_remove(pdev); /* Stop detect work */
    854		return PTR_ERR(phy_provider);
    855	}
    856
    857	dev_dbg(dev, "successfully loaded\n");
    858
    859	return 0;
    860}
    861
    862static const struct sun4i_usb_phy_cfg sun4i_a10_cfg = {
    863	.num_phys = 3,
    864	.type = sun4i_a10_phy,
    865	.disc_thresh = 3,
    866	.phyctl_offset = REG_PHYCTL_A10,
    867	.dedicated_clocks = false,
    868};
    869
    870static const struct sun4i_usb_phy_cfg sun5i_a13_cfg = {
    871	.num_phys = 2,
    872	.type = sun4i_a10_phy,
    873	.disc_thresh = 2,
    874	.phyctl_offset = REG_PHYCTL_A10,
    875	.dedicated_clocks = false,
    876};
    877
    878static const struct sun4i_usb_phy_cfg sun6i_a31_cfg = {
    879	.num_phys = 3,
    880	.type = sun6i_a31_phy,
    881	.disc_thresh = 3,
    882	.phyctl_offset = REG_PHYCTL_A10,
    883	.dedicated_clocks = true,
    884};
    885
    886static const struct sun4i_usb_phy_cfg sun7i_a20_cfg = {
    887	.num_phys = 3,
    888	.type = sun4i_a10_phy,
    889	.disc_thresh = 2,
    890	.phyctl_offset = REG_PHYCTL_A10,
    891	.dedicated_clocks = false,
    892};
    893
    894static const struct sun4i_usb_phy_cfg sun8i_a23_cfg = {
    895	.num_phys = 2,
    896	.type = sun6i_a31_phy,
    897	.disc_thresh = 3,
    898	.phyctl_offset = REG_PHYCTL_A10,
    899	.dedicated_clocks = true,
    900};
    901
    902static const struct sun4i_usb_phy_cfg sun8i_a33_cfg = {
    903	.num_phys = 2,
    904	.type = sun8i_a33_phy,
    905	.disc_thresh = 3,
    906	.phyctl_offset = REG_PHYCTL_A33,
    907	.dedicated_clocks = true,
    908};
    909
    910static const struct sun4i_usb_phy_cfg sun8i_a83t_cfg = {
    911	.num_phys = 3,
    912	.hsic_index = 2,
    913	.type = sun8i_a83t_phy,
    914	.phyctl_offset = REG_PHYCTL_A33,
    915	.dedicated_clocks = true,
    916};
    917
    918static const struct sun4i_usb_phy_cfg sun8i_h3_cfg = {
    919	.num_phys = 4,
    920	.type = sun8i_h3_phy,
    921	.disc_thresh = 3,
    922	.phyctl_offset = REG_PHYCTL_A33,
    923	.dedicated_clocks = true,
    924	.hci_phy_ctl_clear = PHY_CTL_H3_SIDDQ,
    925	.phy0_dual_route = true,
    926};
    927
    928static const struct sun4i_usb_phy_cfg sun8i_r40_cfg = {
    929	.num_phys = 3,
    930	.type = sun8i_r40_phy,
    931	.disc_thresh = 3,
    932	.phyctl_offset = REG_PHYCTL_A33,
    933	.dedicated_clocks = true,
    934	.hci_phy_ctl_clear = PHY_CTL_H3_SIDDQ,
    935	.phy0_dual_route = true,
    936};
    937
    938static const struct sun4i_usb_phy_cfg sun8i_v3s_cfg = {
    939	.num_phys = 1,
    940	.type = sun8i_v3s_phy,
    941	.disc_thresh = 3,
    942	.phyctl_offset = REG_PHYCTL_A33,
    943	.dedicated_clocks = true,
    944	.hci_phy_ctl_clear = PHY_CTL_H3_SIDDQ,
    945	.phy0_dual_route = true,
    946};
    947
    948static const struct sun4i_usb_phy_cfg sun20i_d1_cfg = {
    949	.num_phys = 2,
    950	.type = sun50i_h6_phy,
    951	.phyctl_offset = REG_PHYCTL_A33,
    952	.dedicated_clocks = true,
    953	.hci_phy_ctl_clear = PHY_CTL_SIDDQ,
    954	.phy0_dual_route = true,
    955};
    956
    957static const struct sun4i_usb_phy_cfg sun50i_a64_cfg = {
    958	.num_phys = 2,
    959	.type = sun50i_a64_phy,
    960	.disc_thresh = 3,
    961	.phyctl_offset = REG_PHYCTL_A33,
    962	.dedicated_clocks = true,
    963	.hci_phy_ctl_clear = PHY_CTL_H3_SIDDQ,
    964	.phy0_dual_route = true,
    965};
    966
    967static const struct sun4i_usb_phy_cfg sun50i_h6_cfg = {
    968	.num_phys = 4,
    969	.type = sun50i_h6_phy,
    970	.phyctl_offset = REG_PHYCTL_A33,
    971	.dedicated_clocks = true,
    972	.phy0_dual_route = true,
    973	.missing_phys = BIT(1) | BIT(2),
    974};
    975
    976static const struct of_device_id sun4i_usb_phy_of_match[] = {
    977	{ .compatible = "allwinner,sun4i-a10-usb-phy", .data = &sun4i_a10_cfg },
    978	{ .compatible = "allwinner,sun5i-a13-usb-phy", .data = &sun5i_a13_cfg },
    979	{ .compatible = "allwinner,sun6i-a31-usb-phy", .data = &sun6i_a31_cfg },
    980	{ .compatible = "allwinner,sun7i-a20-usb-phy", .data = &sun7i_a20_cfg },
    981	{ .compatible = "allwinner,sun8i-a23-usb-phy", .data = &sun8i_a23_cfg },
    982	{ .compatible = "allwinner,sun8i-a33-usb-phy", .data = &sun8i_a33_cfg },
    983	{ .compatible = "allwinner,sun8i-a83t-usb-phy", .data = &sun8i_a83t_cfg },
    984	{ .compatible = "allwinner,sun8i-h3-usb-phy", .data = &sun8i_h3_cfg },
    985	{ .compatible = "allwinner,sun8i-r40-usb-phy", .data = &sun8i_r40_cfg },
    986	{ .compatible = "allwinner,sun8i-v3s-usb-phy", .data = &sun8i_v3s_cfg },
    987	{ .compatible = "allwinner,sun20i-d1-usb-phy", .data = &sun20i_d1_cfg },
    988	{ .compatible = "allwinner,sun50i-a64-usb-phy",
    989	  .data = &sun50i_a64_cfg},
    990	{ .compatible = "allwinner,sun50i-h6-usb-phy", .data = &sun50i_h6_cfg },
    991	{ },
    992};
    993MODULE_DEVICE_TABLE(of, sun4i_usb_phy_of_match);
    994
    995static struct platform_driver sun4i_usb_phy_driver = {
    996	.probe	= sun4i_usb_phy_probe,
    997	.remove	= sun4i_usb_phy_remove,
    998	.driver = {
    999		.of_match_table	= sun4i_usb_phy_of_match,
   1000		.name  = "sun4i-usb-phy",
   1001	}
   1002};
   1003module_platform_driver(sun4i_usb_phy_driver);
   1004
   1005MODULE_DESCRIPTION("Allwinner sun4i USB phy driver");
   1006MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
   1007MODULE_LICENSE("GPL v2");