Linux Audio

Check our new training course

Linux BSP development engineering services

Need help to port Linux and bootloaders to your hardware?
Loading...
v6.2
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*
   3 * Rockchip USB2.0 PHY with Innosilicon IP block driver
   4 *
   5 * Copyright (C) 2016 Fuzhou Rockchip Electronics Co., Ltd
   6 */
   7
   8#include <linux/clk.h>
   9#include <linux/clk-provider.h>
  10#include <linux/delay.h>
  11#include <linux/extcon-provider.h>
  12#include <linux/interrupt.h>
  13#include <linux/io.h>
  14#include <linux/gpio/consumer.h>
  15#include <linux/jiffies.h>
  16#include <linux/kernel.h>
  17#include <linux/module.h>
  18#include <linux/mutex.h>
  19#include <linux/of.h>
  20#include <linux/of_address.h>
  21#include <linux/of_irq.h>
  22#include <linux/of_platform.h>
  23#include <linux/phy/phy.h>
  24#include <linux/platform_device.h>
  25#include <linux/power_supply.h>
  26#include <linux/regmap.h>
 
  27#include <linux/mfd/syscon.h>
  28#include <linux/usb/of.h>
  29#include <linux/usb/otg.h>
  30
  31#define BIT_WRITEABLE_SHIFT	16
  32#define SCHEDULE_DELAY		(60 * HZ)
  33#define OTG_SCHEDULE_DELAY	(2 * HZ)
  34
 
 
  35enum rockchip_usb2phy_port_id {
  36	USB2PHY_PORT_OTG,
  37	USB2PHY_PORT_HOST,
  38	USB2PHY_NUM_PORTS,
  39};
  40
  41enum rockchip_usb2phy_host_state {
  42	PHY_STATE_HS_ONLINE	= 0,
  43	PHY_STATE_DISCONNECT	= 1,
  44	PHY_STATE_CONNECT	= 2,
  45	PHY_STATE_FS_LS_ONLINE	= 4,
  46};
  47
  48/**
  49 * enum usb_chg_state - Different states involved in USB charger detection.
  50 * @USB_CHG_STATE_UNDEFINED:	USB charger is not connected or detection
  51 *				process is not yet started.
  52 * @USB_CHG_STATE_WAIT_FOR_DCD:	Waiting for Data pins contact.
  53 * @USB_CHG_STATE_DCD_DONE:	Data pin contact is detected.
  54 * @USB_CHG_STATE_PRIMARY_DONE:	Primary detection is completed (Detects
  55 *				between SDP and DCP/CDP).
  56 * @USB_CHG_STATE_SECONDARY_DONE: Secondary detection is completed (Detects
  57 *				  between DCP and CDP).
  58 * @USB_CHG_STATE_DETECTED:	USB charger type is determined.
  59 */
  60enum usb_chg_state {
  61	USB_CHG_STATE_UNDEFINED = 0,
  62	USB_CHG_STATE_WAIT_FOR_DCD,
  63	USB_CHG_STATE_DCD_DONE,
  64	USB_CHG_STATE_PRIMARY_DONE,
  65	USB_CHG_STATE_SECONDARY_DONE,
  66	USB_CHG_STATE_DETECTED,
  67};
  68
  69static const unsigned int rockchip_usb2phy_extcon_cable[] = {
  70	EXTCON_USB,
  71	EXTCON_USB_HOST,
  72	EXTCON_CHG_USB_SDP,
  73	EXTCON_CHG_USB_CDP,
  74	EXTCON_CHG_USB_DCP,
  75	EXTCON_CHG_USB_SLOW,
  76	EXTCON_NONE,
  77};
  78
  79struct usb2phy_reg {
  80	unsigned int	offset;
  81	unsigned int	bitend;
  82	unsigned int	bitstart;
  83	unsigned int	disable;
  84	unsigned int	enable;
  85};
  86
  87/**
  88 * struct rockchip_chg_det_reg - usb charger detect registers
  89 * @cp_det: charging port detected successfully.
  90 * @dcp_det: dedicated charging port detected successfully.
  91 * @dp_det: assert data pin connect successfully.
  92 * @idm_sink_en: open dm sink curren.
  93 * @idp_sink_en: open dp sink current.
  94 * @idp_src_en: open dm source current.
  95 * @rdm_pdwn_en: open dm pull down resistor.
  96 * @vdm_src_en: open dm voltage source.
  97 * @vdp_src_en: open dp voltage source.
  98 * @opmode: utmi operational mode.
  99 */
 100struct rockchip_chg_det_reg {
 101	struct usb2phy_reg	cp_det;
 102	struct usb2phy_reg	dcp_det;
 103	struct usb2phy_reg	dp_det;
 104	struct usb2phy_reg	idm_sink_en;
 105	struct usb2phy_reg	idp_sink_en;
 106	struct usb2phy_reg	idp_src_en;
 107	struct usb2phy_reg	rdm_pdwn_en;
 108	struct usb2phy_reg	vdm_src_en;
 109	struct usb2phy_reg	vdp_src_en;
 110	struct usb2phy_reg	opmode;
 111};
 112
 113/**
 114 * struct rockchip_usb2phy_port_cfg - usb-phy port configuration.
 115 * @phy_sus: phy suspend register.
 116 * @bvalid_det_en: vbus valid rise detection enable register.
 117 * @bvalid_det_st: vbus valid rise detection status register.
 118 * @bvalid_det_clr: vbus valid rise detection clear register.
 119 * @id_det_en: id detection enable register.
 120 * @id_det_st: id detection state register.
 121 * @id_det_clr: id detection clear register.
 
 
 
 
 
 
 
 
 
 122 * @ls_det_en: linestate detection enable register.
 123 * @ls_det_st: linestate detection state register.
 124 * @ls_det_clr: linestate detection clear register.
 125 * @utmi_avalid: utmi vbus avalid status register.
 126 * @utmi_bvalid: utmi vbus bvalid status register.
 127 * @utmi_id: utmi id state register.
 128 * @utmi_ls: utmi linestate state register.
 129 * @utmi_hstdet: utmi host disconnect register.
 130 */
 131struct rockchip_usb2phy_port_cfg {
 132	struct usb2phy_reg	phy_sus;
 133	struct usb2phy_reg	bvalid_det_en;
 134	struct usb2phy_reg	bvalid_det_st;
 135	struct usb2phy_reg	bvalid_det_clr;
 136	struct usb2phy_reg	id_det_en;
 137	struct usb2phy_reg	id_det_st;
 138	struct usb2phy_reg	id_det_clr;
 
 
 
 
 
 
 
 
 
 139	struct usb2phy_reg	ls_det_en;
 140	struct usb2phy_reg	ls_det_st;
 141	struct usb2phy_reg	ls_det_clr;
 142	struct usb2phy_reg	utmi_avalid;
 143	struct usb2phy_reg	utmi_bvalid;
 144	struct usb2phy_reg	utmi_id;
 145	struct usb2phy_reg	utmi_ls;
 146	struct usb2phy_reg	utmi_hstdet;
 147};
 148
 149/**
 150 * struct rockchip_usb2phy_cfg - usb-phy configuration.
 151 * @reg: the address offset of grf for usb-phy config.
 152 * @num_ports: specify how many ports that the phy has.
 
 153 * @clkout_ctl: keep on/turn off output clk of phy.
 154 * @port_cfgs: usb-phy port configurations.
 155 * @chg_det: charger detection registers.
 156 */
 157struct rockchip_usb2phy_cfg {
 158	unsigned int	reg;
 159	unsigned int	num_ports;
 
 160	struct usb2phy_reg	clkout_ctl;
 161	const struct rockchip_usb2phy_port_cfg	port_cfgs[USB2PHY_NUM_PORTS];
 162	const struct rockchip_chg_det_reg	chg_det;
 163};
 164
 165/**
 166 * struct rockchip_usb2phy_port - usb-phy port data.
 167 * @phy: generic phy.
 168 * @port_id: flag for otg port or host port.
 169 * @suspended: phy suspended flag.
 170 * @vbus_attached: otg device vbus status.
 
 171 * @bvalid_irq: IRQ number assigned for vbus valid rise detection.
 172 * @id_irq: IRQ number assigned for ID pin detection.
 173 * @ls_irq: IRQ number assigned for linestate detection.
 174 * @otg_mux_irq: IRQ number which multiplex otg-id/otg-bvalid/linestate
 175 *		 irqs to one irq in otg-port.
 176 * @mutex: for register updating in sm_work.
 177 * @chg_work: charge detect work.
 178 * @otg_sm_work: OTG state machine work.
 179 * @sm_work: HOST state machine work.
 180 * @port_cfg: port register configuration, assigned by driver data.
 181 * @event_nb: hold event notification callback.
 182 * @state: define OTG enumeration states before device reset.
 183 * @mode: the dr_mode of the controller.
 184 */
 185struct rockchip_usb2phy_port {
 186	struct phy	*phy;
 187	unsigned int	port_id;
 188	bool		suspended;
 189	bool		vbus_attached;
 
 190	int		bvalid_irq;
 191	int		id_irq;
 192	int		ls_irq;
 193	int		otg_mux_irq;
 194	struct mutex	mutex;
 195	struct		delayed_work chg_work;
 196	struct		delayed_work otg_sm_work;
 197	struct		delayed_work sm_work;
 198	const struct	rockchip_usb2phy_port_cfg *port_cfg;
 199	struct notifier_block	event_nb;
 200	enum usb_otg_state	state;
 201	enum usb_dr_mode	mode;
 202};
 203
 204/**
 205 * struct rockchip_usb2phy - usb2.0 phy driver data.
 206 * @dev: pointer to device.
 207 * @grf: General Register Files regmap.
 208 * @usbgrf: USB General Register Files regmap.
 209 * @clk: clock struct of phy input clk.
 210 * @clk480m: clock struct of phy output clk.
 211 * @clk480m_hw: clock struct of phy output clk management.
 
 
 212 * @chg_state: states involved in USB charger detection.
 213 * @chg_type: USB charger types.
 214 * @dcd_retries: The retry count used to track Data contact
 215 *		 detection process.
 216 * @edev: extcon device for notification registration
 217 * @irq: muxed interrupt for single irq configuration
 218 * @phy_cfg: phy register configuration, assigned by driver data.
 219 * @ports: phy port instance.
 220 */
 221struct rockchip_usb2phy {
 222	struct device	*dev;
 223	struct regmap	*grf;
 224	struct regmap	*usbgrf;
 225	struct clk	*clk;
 226	struct clk	*clk480m;
 227	struct clk_hw	clk480m_hw;
 
 
 228	enum usb_chg_state	chg_state;
 229	enum power_supply_type	chg_type;
 230	u8			dcd_retries;
 231	struct extcon_dev	*edev;
 232	int			irq;
 233	const struct rockchip_usb2phy_cfg	*phy_cfg;
 234	struct rockchip_usb2phy_port	ports[USB2PHY_NUM_PORTS];
 235};
 236
 237static inline struct regmap *get_reg_base(struct rockchip_usb2phy *rphy)
 238{
 239	return rphy->usbgrf == NULL ? rphy->grf : rphy->usbgrf;
 240}
 241
 242static inline int property_enable(struct regmap *base,
 243				  const struct usb2phy_reg *reg, bool en)
 244{
 245	unsigned int val, mask, tmp;
 246
 247	tmp = en ? reg->enable : reg->disable;
 248	mask = GENMASK(reg->bitend, reg->bitstart);
 249	val = (tmp << reg->bitstart) | (mask << BIT_WRITEABLE_SHIFT);
 250
 251	return regmap_write(base, reg->offset, val);
 252}
 253
 254static inline bool property_enabled(struct regmap *base,
 255				    const struct usb2phy_reg *reg)
 256{
 257	int ret;
 258	unsigned int tmp, orig;
 259	unsigned int mask = GENMASK(reg->bitend, reg->bitstart);
 260
 261	ret = regmap_read(base, reg->offset, &orig);
 262	if (ret)
 263		return false;
 264
 265	tmp = (orig & mask) >> reg->bitstart;
 266	return tmp != reg->disable;
 267}
 268
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 269static int rockchip_usb2phy_clk480m_prepare(struct clk_hw *hw)
 270{
 271	struct rockchip_usb2phy *rphy =
 272		container_of(hw, struct rockchip_usb2phy, clk480m_hw);
 273	struct regmap *base = get_reg_base(rphy);
 274	int ret;
 275
 276	/* turn on 480m clk output if it is off */
 277	if (!property_enabled(base, &rphy->phy_cfg->clkout_ctl)) {
 278		ret = property_enable(base, &rphy->phy_cfg->clkout_ctl, true);
 279		if (ret)
 280			return ret;
 281
 282		/* waiting for the clk become stable */
 283		usleep_range(1200, 1300);
 284	}
 285
 286	return 0;
 287}
 288
 289static void rockchip_usb2phy_clk480m_unprepare(struct clk_hw *hw)
 290{
 291	struct rockchip_usb2phy *rphy =
 292		container_of(hw, struct rockchip_usb2phy, clk480m_hw);
 293	struct regmap *base = get_reg_base(rphy);
 294
 295	/* turn off 480m clk output */
 296	property_enable(base, &rphy->phy_cfg->clkout_ctl, false);
 297}
 298
 299static int rockchip_usb2phy_clk480m_prepared(struct clk_hw *hw)
 300{
 301	struct rockchip_usb2phy *rphy =
 302		container_of(hw, struct rockchip_usb2phy, clk480m_hw);
 303	struct regmap *base = get_reg_base(rphy);
 304
 305	return property_enabled(base, &rphy->phy_cfg->clkout_ctl);
 306}
 307
 308static unsigned long
 309rockchip_usb2phy_clk480m_recalc_rate(struct clk_hw *hw,
 310				     unsigned long parent_rate)
 311{
 312	return 480000000;
 313}
 314
 315static const struct clk_ops rockchip_usb2phy_clkout_ops = {
 316	.prepare = rockchip_usb2phy_clk480m_prepare,
 317	.unprepare = rockchip_usb2phy_clk480m_unprepare,
 318	.is_prepared = rockchip_usb2phy_clk480m_prepared,
 319	.recalc_rate = rockchip_usb2phy_clk480m_recalc_rate,
 320};
 321
 322static void rockchip_usb2phy_clk480m_unregister(void *data)
 323{
 324	struct rockchip_usb2phy *rphy = data;
 325
 326	of_clk_del_provider(rphy->dev->of_node);
 327	clk_unregister(rphy->clk480m);
 328}
 329
 330static int
 331rockchip_usb2phy_clk480m_register(struct rockchip_usb2phy *rphy)
 332{
 333	struct device_node *node = rphy->dev->of_node;
 334	struct clk_init_data init;
 
 335	const char *clk_name;
 
 336	int ret = 0;
 337
 338	init.flags = 0;
 339	init.name = "clk_usbphy_480m";
 340	init.ops = &rockchip_usb2phy_clkout_ops;
 341
 342	/* optional override of the clockname */
 343	of_property_read_string(node, "clock-output-names", &init.name);
 344
 345	if (rphy->clk) {
 346		clk_name = __clk_get_name(rphy->clk);
 
 
 
 
 
 
 
 347		init.parent_names = &clk_name;
 348		init.num_parents = 1;
 349	} else {
 350		init.parent_names = NULL;
 351		init.num_parents = 0;
 352	}
 353
 354	rphy->clk480m_hw.init = &init;
 355
 356	/* register the clock */
 357	rphy->clk480m = clk_register(rphy->dev, &rphy->clk480m_hw);
 358	if (IS_ERR(rphy->clk480m)) {
 359		ret = PTR_ERR(rphy->clk480m);
 360		goto err_ret;
 361	}
 362
 363	ret = of_clk_add_provider(node, of_clk_src_simple_get, rphy->clk480m);
 364	if (ret < 0)
 365		goto err_clk_provider;
 366
 367	return devm_add_action_or_reset(rphy->dev, rockchip_usb2phy_clk480m_unregister, rphy);
 368
 369err_clk_provider:
 370	clk_unregister(rphy->clk480m);
 371err_ret:
 372	return ret;
 373}
 374
 375static int rockchip_usb2phy_extcon_register(struct rockchip_usb2phy *rphy)
 376{
 377	int ret;
 378	struct device_node *node = rphy->dev->of_node;
 379	struct extcon_dev *edev;
 
 380
 381	if (of_property_read_bool(node, "extcon")) {
 382		edev = extcon_get_edev_by_phandle(rphy->dev, 0);
 383		if (IS_ERR(edev)) {
 384			if (PTR_ERR(edev) != -EPROBE_DEFER)
 385				dev_err(rphy->dev, "Invalid or missing extcon\n");
 386			return PTR_ERR(edev);
 387		}
 388	} else {
 389		/* Initialize extcon device */
 390		edev = devm_extcon_dev_allocate(rphy->dev,
 391						rockchip_usb2phy_extcon_cable);
 392
 393		if (IS_ERR(edev))
 394			return -ENOMEM;
 
 395
 396		ret = devm_extcon_dev_register(rphy->dev, edev);
 397		if (ret) {
 398			dev_err(rphy->dev, "failed to register extcon device\n");
 399			return ret;
 400		}
 401	}
 402
 403	rphy->edev = edev;
 404
 405	return 0;
 406}
 407
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 408static int rockchip_usb2phy_init(struct phy *phy)
 409{
 410	struct rockchip_usb2phy_port *rport = phy_get_drvdata(phy);
 411	struct rockchip_usb2phy *rphy = dev_get_drvdata(phy->dev.parent);
 412	int ret = 0;
 413
 414	mutex_lock(&rport->mutex);
 415
 416	if (rport->port_id == USB2PHY_PORT_OTG) {
 417		if (rport->mode != USB_DR_MODE_HOST &&
 418		    rport->mode != USB_DR_MODE_UNKNOWN) {
 419			/* clear bvalid status and enable bvalid detect irq */
 420			ret = property_enable(rphy->grf,
 421					      &rport->port_cfg->bvalid_det_clr,
 422					      true);
 423			if (ret)
 424				goto out;
 425
 426			ret = property_enable(rphy->grf,
 427					      &rport->port_cfg->bvalid_det_en,
 428					      true);
 429			if (ret)
 430				goto out;
 431
 432			/* clear id status and enable id detect irq */
 
 
 
 
 
 
 433			ret = property_enable(rphy->grf,
 434					      &rport->port_cfg->id_det_clr,
 435					      true);
 436			if (ret)
 437				goto out;
 438
 439			ret = property_enable(rphy->grf,
 440					      &rport->port_cfg->id_det_en,
 
 
 
 
 
 
 441					      true);
 442			if (ret)
 443				goto out;
 444
 445			schedule_delayed_work(&rport->otg_sm_work,
 446					      OTG_SCHEDULE_DELAY * 3);
 447		} else {
 448			/* If OTG works in host only mode, do nothing. */
 449			dev_dbg(&rport->phy->dev, "mode %d\n", rport->mode);
 450		}
 451	} else if (rport->port_id == USB2PHY_PORT_HOST) {
 
 
 
 
 
 
 
 
 
 452		/* clear linestate and enable linestate detect irq */
 453		ret = property_enable(rphy->grf,
 454				      &rport->port_cfg->ls_det_clr, true);
 455		if (ret)
 456			goto out;
 457
 458		ret = property_enable(rphy->grf,
 459				      &rport->port_cfg->ls_det_en, true);
 460		if (ret)
 461			goto out;
 462
 463		schedule_delayed_work(&rport->sm_work, SCHEDULE_DELAY);
 464	}
 465
 466out:
 467	mutex_unlock(&rport->mutex);
 468	return ret;
 469}
 470
 471static int rockchip_usb2phy_power_on(struct phy *phy)
 472{
 473	struct rockchip_usb2phy_port *rport = phy_get_drvdata(phy);
 474	struct rockchip_usb2phy *rphy = dev_get_drvdata(phy->dev.parent);
 475	struct regmap *base = get_reg_base(rphy);
 476	int ret;
 477
 478	dev_dbg(&rport->phy->dev, "port power on\n");
 479
 480	if (!rport->suspended)
 481		return 0;
 482
 483	ret = clk_prepare_enable(rphy->clk480m);
 484	if (ret)
 485		return ret;
 486
 487	ret = property_enable(base, &rport->port_cfg->phy_sus, false);
 488	if (ret) {
 489		clk_disable_unprepare(rphy->clk480m);
 490		return ret;
 491	}
 492
 
 
 
 
 
 
 
 
 
 
 
 
 493	/* waiting for the utmi_clk to become stable */
 494	usleep_range(1500, 2000);
 495
 496	rport->suspended = false;
 497	return 0;
 498}
 499
 500static int rockchip_usb2phy_power_off(struct phy *phy)
 501{
 502	struct rockchip_usb2phy_port *rport = phy_get_drvdata(phy);
 503	struct rockchip_usb2phy *rphy = dev_get_drvdata(phy->dev.parent);
 504	struct regmap *base = get_reg_base(rphy);
 505	int ret;
 506
 507	dev_dbg(&rport->phy->dev, "port power off\n");
 508
 509	if (rport->suspended)
 510		return 0;
 511
 512	ret = property_enable(base, &rport->port_cfg->phy_sus, true);
 513	if (ret)
 514		return ret;
 515
 516	rport->suspended = true;
 517	clk_disable_unprepare(rphy->clk480m);
 518
 519	return 0;
 520}
 521
 522static int rockchip_usb2phy_exit(struct phy *phy)
 523{
 524	struct rockchip_usb2phy_port *rport = phy_get_drvdata(phy);
 525
 526	if (rport->port_id == USB2PHY_PORT_OTG &&
 527	    rport->mode != USB_DR_MODE_HOST &&
 528	    rport->mode != USB_DR_MODE_UNKNOWN) {
 529		cancel_delayed_work_sync(&rport->otg_sm_work);
 530		cancel_delayed_work_sync(&rport->chg_work);
 531	} else if (rport->port_id == USB2PHY_PORT_HOST)
 532		cancel_delayed_work_sync(&rport->sm_work);
 533
 534	return 0;
 535}
 536
 537static const struct phy_ops rockchip_usb2phy_ops = {
 538	.init		= rockchip_usb2phy_init,
 539	.exit		= rockchip_usb2phy_exit,
 540	.power_on	= rockchip_usb2phy_power_on,
 541	.power_off	= rockchip_usb2phy_power_off,
 542	.owner		= THIS_MODULE,
 543};
 544
 545static void rockchip_usb2phy_otg_sm_work(struct work_struct *work)
 546{
 547	struct rockchip_usb2phy_port *rport =
 548		container_of(work, struct rockchip_usb2phy_port,
 549			     otg_sm_work.work);
 550	struct rockchip_usb2phy *rphy = dev_get_drvdata(rport->phy->dev.parent);
 551	static unsigned int cable;
 552	unsigned long delay;
 553	bool vbus_attach, sch_work, notify_charger;
 554
 555	vbus_attach = property_enabled(rphy->grf,
 556				       &rport->port_cfg->utmi_bvalid);
 557
 558	sch_work = false;
 559	notify_charger = false;
 560	delay = OTG_SCHEDULE_DELAY;
 561	dev_dbg(&rport->phy->dev, "%s otg sm work\n",
 562		usb_otg_state_string(rport->state));
 563
 564	switch (rport->state) {
 565	case OTG_STATE_UNDEFINED:
 566		rport->state = OTG_STATE_B_IDLE;
 567		if (!vbus_attach)
 568			rockchip_usb2phy_power_off(rport->phy);
 569		fallthrough;
 570	case OTG_STATE_B_IDLE:
 571		if (extcon_get_state(rphy->edev, EXTCON_USB_HOST) > 0) {
 572			dev_dbg(&rport->phy->dev, "usb otg host connect\n");
 573			rport->state = OTG_STATE_A_HOST;
 574			rockchip_usb2phy_power_on(rport->phy);
 575			return;
 576		} else if (vbus_attach) {
 577			dev_dbg(&rport->phy->dev, "vbus_attach\n");
 578			switch (rphy->chg_state) {
 579			case USB_CHG_STATE_UNDEFINED:
 580				schedule_delayed_work(&rport->chg_work, 0);
 581				return;
 582			case USB_CHG_STATE_DETECTED:
 583				switch (rphy->chg_type) {
 584				case POWER_SUPPLY_TYPE_USB:
 585					dev_dbg(&rport->phy->dev, "sdp cable is connected\n");
 586					rockchip_usb2phy_power_on(rport->phy);
 587					rport->state = OTG_STATE_B_PERIPHERAL;
 588					notify_charger = true;
 589					sch_work = true;
 590					cable = EXTCON_CHG_USB_SDP;
 591					break;
 592				case POWER_SUPPLY_TYPE_USB_DCP:
 593					dev_dbg(&rport->phy->dev, "dcp cable is connected\n");
 594					rockchip_usb2phy_power_off(rport->phy);
 595					notify_charger = true;
 596					sch_work = true;
 597					cable = EXTCON_CHG_USB_DCP;
 598					break;
 599				case POWER_SUPPLY_TYPE_USB_CDP:
 600					dev_dbg(&rport->phy->dev, "cdp cable is connected\n");
 601					rockchip_usb2phy_power_on(rport->phy);
 602					rport->state = OTG_STATE_B_PERIPHERAL;
 603					notify_charger = true;
 604					sch_work = true;
 605					cable = EXTCON_CHG_USB_CDP;
 606					break;
 607				default:
 608					break;
 609				}
 610				break;
 611			default:
 612				break;
 613			}
 614		} else {
 615			notify_charger = true;
 616			rphy->chg_state = USB_CHG_STATE_UNDEFINED;
 617			rphy->chg_type = POWER_SUPPLY_TYPE_UNKNOWN;
 618		}
 619
 620		if (rport->vbus_attached != vbus_attach) {
 621			rport->vbus_attached = vbus_attach;
 622
 623			if (notify_charger && rphy->edev) {
 624				extcon_set_state_sync(rphy->edev,
 625							cable, vbus_attach);
 626				if (cable == EXTCON_CHG_USB_SDP)
 627					extcon_set_state_sync(rphy->edev,
 628							      EXTCON_USB,
 629							      vbus_attach);
 630			}
 631		}
 632		break;
 633	case OTG_STATE_B_PERIPHERAL:
 634		if (!vbus_attach) {
 635			dev_dbg(&rport->phy->dev, "usb disconnect\n");
 636			rphy->chg_state = USB_CHG_STATE_UNDEFINED;
 637			rphy->chg_type = POWER_SUPPLY_TYPE_UNKNOWN;
 638			rport->state = OTG_STATE_B_IDLE;
 639			delay = 0;
 640			rockchip_usb2phy_power_off(rport->phy);
 641		}
 642		sch_work = true;
 643		break;
 644	case OTG_STATE_A_HOST:
 645		if (extcon_get_state(rphy->edev, EXTCON_USB_HOST) == 0) {
 646			dev_dbg(&rport->phy->dev, "usb otg host disconnect\n");
 647			rport->state = OTG_STATE_B_IDLE;
 648			rockchip_usb2phy_power_off(rport->phy);
 649		}
 650		break;
 651	default:
 652		break;
 653	}
 654
 655	if (sch_work)
 656		schedule_delayed_work(&rport->otg_sm_work, delay);
 657}
 658
 659static const char *chg_to_string(enum power_supply_type chg_type)
 660{
 661	switch (chg_type) {
 662	case POWER_SUPPLY_TYPE_USB:
 663		return "USB_SDP_CHARGER";
 664	case POWER_SUPPLY_TYPE_USB_DCP:
 665		return "USB_DCP_CHARGER";
 666	case POWER_SUPPLY_TYPE_USB_CDP:
 667		return "USB_CDP_CHARGER";
 668	default:
 669		return "INVALID_CHARGER";
 670	}
 671}
 672
 673static void rockchip_chg_enable_dcd(struct rockchip_usb2phy *rphy,
 674				    bool en)
 675{
 676	struct regmap *base = get_reg_base(rphy);
 677
 678	property_enable(base, &rphy->phy_cfg->chg_det.rdm_pdwn_en, en);
 679	property_enable(base, &rphy->phy_cfg->chg_det.idp_src_en, en);
 680}
 681
 682static void rockchip_chg_enable_primary_det(struct rockchip_usb2phy *rphy,
 683					    bool en)
 684{
 685	struct regmap *base = get_reg_base(rphy);
 686
 687	property_enable(base, &rphy->phy_cfg->chg_det.vdp_src_en, en);
 688	property_enable(base, &rphy->phy_cfg->chg_det.idm_sink_en, en);
 689}
 690
 691static void rockchip_chg_enable_secondary_det(struct rockchip_usb2phy *rphy,
 692					      bool en)
 693{
 694	struct regmap *base = get_reg_base(rphy);
 695
 696	property_enable(base, &rphy->phy_cfg->chg_det.vdm_src_en, en);
 697	property_enable(base, &rphy->phy_cfg->chg_det.idp_sink_en, en);
 698}
 699
 700#define CHG_DCD_POLL_TIME	(100 * HZ / 1000)
 701#define CHG_DCD_MAX_RETRIES	6
 702#define CHG_PRIMARY_DET_TIME	(40 * HZ / 1000)
 703#define CHG_SECONDARY_DET_TIME	(40 * HZ / 1000)
 704static void rockchip_chg_detect_work(struct work_struct *work)
 705{
 706	struct rockchip_usb2phy_port *rport =
 707		container_of(work, struct rockchip_usb2phy_port, chg_work.work);
 708	struct rockchip_usb2phy *rphy = dev_get_drvdata(rport->phy->dev.parent);
 709	struct regmap *base = get_reg_base(rphy);
 710	bool is_dcd, tmout, vout;
 711	unsigned long delay;
 712
 713	dev_dbg(&rport->phy->dev, "chg detection work state = %d\n",
 714		rphy->chg_state);
 715	switch (rphy->chg_state) {
 716	case USB_CHG_STATE_UNDEFINED:
 717		if (!rport->suspended)
 718			rockchip_usb2phy_power_off(rport->phy);
 719		/* put the controller in non-driving mode */
 720		property_enable(base, &rphy->phy_cfg->chg_det.opmode, false);
 721		/* Start DCD processing stage 1 */
 722		rockchip_chg_enable_dcd(rphy, true);
 723		rphy->chg_state = USB_CHG_STATE_WAIT_FOR_DCD;
 724		rphy->dcd_retries = 0;
 725		delay = CHG_DCD_POLL_TIME;
 726		break;
 727	case USB_CHG_STATE_WAIT_FOR_DCD:
 728		/* get data contact detection status */
 729		is_dcd = property_enabled(rphy->grf,
 730					  &rphy->phy_cfg->chg_det.dp_det);
 731		tmout = ++rphy->dcd_retries == CHG_DCD_MAX_RETRIES;
 732		/* stage 2 */
 733		if (is_dcd || tmout) {
 734			/* stage 4 */
 735			/* Turn off DCD circuitry */
 736			rockchip_chg_enable_dcd(rphy, false);
 737			/* Voltage Source on DP, Probe on DM */
 738			rockchip_chg_enable_primary_det(rphy, true);
 739			delay = CHG_PRIMARY_DET_TIME;
 740			rphy->chg_state = USB_CHG_STATE_DCD_DONE;
 741		} else {
 742			/* stage 3 */
 743			delay = CHG_DCD_POLL_TIME;
 744		}
 745		break;
 746	case USB_CHG_STATE_DCD_DONE:
 747		vout = property_enabled(rphy->grf,
 748					&rphy->phy_cfg->chg_det.cp_det);
 749		rockchip_chg_enable_primary_det(rphy, false);
 750		if (vout) {
 751			/* Voltage Source on DM, Probe on DP  */
 752			rockchip_chg_enable_secondary_det(rphy, true);
 753			delay = CHG_SECONDARY_DET_TIME;
 754			rphy->chg_state = USB_CHG_STATE_PRIMARY_DONE;
 755		} else {
 756			if (rphy->dcd_retries == CHG_DCD_MAX_RETRIES) {
 757				/* floating charger found */
 758				rphy->chg_type = POWER_SUPPLY_TYPE_USB_DCP;
 759				rphy->chg_state = USB_CHG_STATE_DETECTED;
 760				delay = 0;
 761			} else {
 762				rphy->chg_type = POWER_SUPPLY_TYPE_USB;
 763				rphy->chg_state = USB_CHG_STATE_DETECTED;
 764				delay = 0;
 765			}
 766		}
 767		break;
 768	case USB_CHG_STATE_PRIMARY_DONE:
 769		vout = property_enabled(rphy->grf,
 770					&rphy->phy_cfg->chg_det.dcp_det);
 771		/* Turn off voltage source */
 772		rockchip_chg_enable_secondary_det(rphy, false);
 773		if (vout)
 774			rphy->chg_type = POWER_SUPPLY_TYPE_USB_DCP;
 775		else
 776			rphy->chg_type = POWER_SUPPLY_TYPE_USB_CDP;
 777		fallthrough;
 778	case USB_CHG_STATE_SECONDARY_DONE:
 779		rphy->chg_state = USB_CHG_STATE_DETECTED;
 780		fallthrough;
 781	case USB_CHG_STATE_DETECTED:
 782		/* put the controller in normal mode */
 783		property_enable(base, &rphy->phy_cfg->chg_det.opmode, true);
 784		rockchip_usb2phy_otg_sm_work(&rport->otg_sm_work.work);
 785		dev_dbg(&rport->phy->dev, "charger = %s\n",
 786			 chg_to_string(rphy->chg_type));
 787		return;
 788	default:
 789		return;
 790	}
 791
 792	schedule_delayed_work(&rport->chg_work, delay);
 793}
 794
 795/*
 796 * The function manage host-phy port state and suspend/resume phy port
 797 * to save power.
 798 *
 799 * we rely on utmi_linestate and utmi_hostdisconnect to identify whether
 800 * devices is disconnect or not. Besides, we do not need care it is FS/LS
 801 * disconnected or HS disconnected, actually, we just only need get the
 802 * device is disconnected at last through rearm the delayed work,
 803 * to suspend the phy port in _PHY_STATE_DISCONNECT_ case.
 804 *
 805 * NOTE: It may invoke *phy_powr_off or *phy_power_on which will invoke
 806 * some clk related APIs, so do not invoke it from interrupt context directly.
 807 */
 808static void rockchip_usb2phy_sm_work(struct work_struct *work)
 809{
 810	struct rockchip_usb2phy_port *rport =
 811		container_of(work, struct rockchip_usb2phy_port, sm_work.work);
 812	struct rockchip_usb2phy *rphy = dev_get_drvdata(rport->phy->dev.parent);
 813	unsigned int sh = rport->port_cfg->utmi_hstdet.bitend -
 814			  rport->port_cfg->utmi_hstdet.bitstart + 1;
 815	unsigned int ul, uhd, state;
 816	unsigned int ul_mask, uhd_mask;
 817	int ret;
 818
 819	mutex_lock(&rport->mutex);
 820
 821	ret = regmap_read(rphy->grf, rport->port_cfg->utmi_ls.offset, &ul);
 822	if (ret < 0)
 823		goto next_schedule;
 824
 825	ret = regmap_read(rphy->grf, rport->port_cfg->utmi_hstdet.offset, &uhd);
 826	if (ret < 0)
 827		goto next_schedule;
 828
 829	uhd_mask = GENMASK(rport->port_cfg->utmi_hstdet.bitend,
 830			   rport->port_cfg->utmi_hstdet.bitstart);
 831	ul_mask = GENMASK(rport->port_cfg->utmi_ls.bitend,
 832			  rport->port_cfg->utmi_ls.bitstart);
 833
 834	/* stitch on utmi_ls and utmi_hstdet as phy state */
 835	state = ((uhd & uhd_mask) >> rport->port_cfg->utmi_hstdet.bitstart) |
 836		(((ul & ul_mask) >> rport->port_cfg->utmi_ls.bitstart) << sh);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 837
 838	switch (state) {
 839	case PHY_STATE_HS_ONLINE:
 840		dev_dbg(&rport->phy->dev, "HS online\n");
 841		break;
 842	case PHY_STATE_FS_LS_ONLINE:
 843		/*
 844		 * For FS/LS device, the online state share with connect state
 845		 * from utmi_ls and utmi_hstdet register, so we distinguish
 846		 * them via suspended flag.
 847		 *
 848		 * Plus, there are two cases, one is D- Line pull-up, and D+
 849		 * line pull-down, the state is 4; another is D+ line pull-up,
 850		 * and D- line pull-down, the state is 2.
 851		 */
 852		if (!rport->suspended) {
 853			/* D- line pull-up, D+ line pull-down */
 854			dev_dbg(&rport->phy->dev, "FS/LS online\n");
 855			break;
 856		}
 857		fallthrough;
 858	case PHY_STATE_CONNECT:
 859		if (rport->suspended) {
 860			dev_dbg(&rport->phy->dev, "Connected\n");
 861			rockchip_usb2phy_power_on(rport->phy);
 862			rport->suspended = false;
 863		} else {
 864			/* D+ line pull-up, D- line pull-down */
 865			dev_dbg(&rport->phy->dev, "FS/LS online\n");
 866		}
 867		break;
 868	case PHY_STATE_DISCONNECT:
 869		if (!rport->suspended) {
 870			dev_dbg(&rport->phy->dev, "Disconnected\n");
 871			rockchip_usb2phy_power_off(rport->phy);
 872			rport->suspended = true;
 873		}
 874
 875		/*
 876		 * activate the linestate detection to get the next device
 877		 * plug-in irq.
 878		 */
 879		property_enable(rphy->grf, &rport->port_cfg->ls_det_clr, true);
 880		property_enable(rphy->grf, &rport->port_cfg->ls_det_en, true);
 881
 882		/*
 883		 * we don't need to rearm the delayed work when the phy port
 884		 * is suspended.
 885		 */
 886		mutex_unlock(&rport->mutex);
 887		return;
 888	default:
 889		dev_dbg(&rport->phy->dev, "unknown phy state\n");
 890		break;
 891	}
 892
 893next_schedule:
 894	mutex_unlock(&rport->mutex);
 895	schedule_delayed_work(&rport->sm_work, SCHEDULE_DELAY);
 896}
 897
 898static irqreturn_t rockchip_usb2phy_linestate_irq(int irq, void *data)
 899{
 900	struct rockchip_usb2phy_port *rport = data;
 901	struct rockchip_usb2phy *rphy = dev_get_drvdata(rport->phy->dev.parent);
 902
 903	if (!property_enabled(rphy->grf, &rport->port_cfg->ls_det_st))
 904		return IRQ_NONE;
 905
 906	mutex_lock(&rport->mutex);
 907
 908	/* disable linestate detect irq and clear its status */
 909	property_enable(rphy->grf, &rport->port_cfg->ls_det_en, false);
 910	property_enable(rphy->grf, &rport->port_cfg->ls_det_clr, true);
 911
 912	mutex_unlock(&rport->mutex);
 913
 914	/*
 915	 * In this case for host phy port, a new device is plugged in,
 916	 * meanwhile, if the phy port is suspended, we need rearm the work to
 917	 * resume it and mange its states; otherwise, we do nothing about that.
 918	 */
 919	if (rport->suspended && rport->port_id == USB2PHY_PORT_HOST)
 920		rockchip_usb2phy_sm_work(&rport->sm_work.work);
 921
 922	return IRQ_HANDLED;
 923}
 924
 925static irqreturn_t rockchip_usb2phy_bvalid_irq(int irq, void *data)
 926{
 927	struct rockchip_usb2phy_port *rport = data;
 928	struct rockchip_usb2phy *rphy = dev_get_drvdata(rport->phy->dev.parent);
 929
 930	if (!property_enabled(rphy->grf, &rport->port_cfg->bvalid_det_st))
 931		return IRQ_NONE;
 932
 933	/* clear bvalid detect irq pending status */
 934	property_enable(rphy->grf, &rport->port_cfg->bvalid_det_clr, true);
 935
 936	rockchip_usb2phy_otg_sm_work(&rport->otg_sm_work.work);
 937
 938	return IRQ_HANDLED;
 939}
 940
 941static irqreturn_t rockchip_usb2phy_id_irq(int irq, void *data)
 942{
 943	struct rockchip_usb2phy_port *rport = data;
 944	struct rockchip_usb2phy *rphy = dev_get_drvdata(rport->phy->dev.parent);
 945	bool id;
 946
 947	if (!property_enabled(rphy->grf, &rport->port_cfg->id_det_st))
 
 948		return IRQ_NONE;
 949
 950	/* clear id detect irq pending status */
 951	property_enable(rphy->grf, &rport->port_cfg->id_det_clr, true);
 
 
 
 
 952
 953	id = property_enabled(rphy->grf, &rport->port_cfg->utmi_id);
 954	extcon_set_state_sync(rphy->edev, EXTCON_USB_HOST, !id);
 955
 956	return IRQ_HANDLED;
 957}
 958
 959static irqreturn_t rockchip_usb2phy_otg_mux_irq(int irq, void *data)
 960{
 961	irqreturn_t ret = IRQ_NONE;
 962
 963	ret |= rockchip_usb2phy_bvalid_irq(irq, data);
 964	ret |= rockchip_usb2phy_id_irq(irq, data);
 965
 966	return ret;
 967}
 968
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 969static irqreturn_t rockchip_usb2phy_irq(int irq, void *data)
 970{
 971	struct rockchip_usb2phy *rphy = data;
 972	struct rockchip_usb2phy_port *rport;
 973	irqreturn_t ret = IRQ_NONE;
 974	unsigned int index;
 975
 976	for (index = 0; index < rphy->phy_cfg->num_ports; index++) {
 977		rport = &rphy->ports[index];
 978		if (!rport->phy)
 979			continue;
 980
 
 
 
 
 981		switch (rport->port_id) {
 982		case USB2PHY_PORT_OTG:
 983			if (rport->mode != USB_DR_MODE_HOST &&
 984			    rport->mode != USB_DR_MODE_UNKNOWN)
 985				ret |= rockchip_usb2phy_otg_mux_irq(irq, rport);
 986			break;
 987		case USB2PHY_PORT_HOST:
 988			ret |= rockchip_usb2phy_linestate_irq(irq, rport);
 989			break;
 990		}
 991	}
 992
 993	return ret;
 994}
 995
 996static int rockchip_usb2phy_port_irq_init(struct rockchip_usb2phy *rphy,
 997					  struct rockchip_usb2phy_port *rport,
 998					  struct device_node *child_np)
 999{
1000	int ret;
1001
1002	/*
1003	 * If the usb2 phy used combined irq for otg and host port,
1004	 * don't need to init otg and host port irq separately.
1005	 */
1006	if (rphy->irq > 0)
1007		return 0;
1008
1009	switch (rport->port_id) {
1010	case USB2PHY_PORT_HOST:
1011		rport->ls_irq = of_irq_get_byname(child_np, "linestate");
1012		if (rport->ls_irq < 0) {
1013			dev_err(rphy->dev, "no linestate irq provided\n");
1014			return rport->ls_irq;
1015		}
1016
1017		ret = devm_request_threaded_irq(rphy->dev, rport->ls_irq, NULL,
1018						rockchip_usb2phy_linestate_irq,
1019						IRQF_ONESHOT,
1020						"rockchip_usb2phy", rport);
1021		if (ret) {
1022			dev_err(rphy->dev, "failed to request linestate irq handle\n");
1023			return ret;
1024		}
1025		break;
1026	case USB2PHY_PORT_OTG:
1027		/*
1028		 * Some SoCs use one interrupt with otg-id/otg-bvalid/linestate
1029		 * interrupts muxed together, so probe the otg-mux interrupt first,
1030		 * if not found, then look for the regular interrupts one by one.
1031		 */
1032		rport->otg_mux_irq = of_irq_get_byname(child_np, "otg-mux");
1033		if (rport->otg_mux_irq > 0) {
1034			ret = devm_request_threaded_irq(rphy->dev, rport->otg_mux_irq,
1035							NULL,
1036							rockchip_usb2phy_otg_mux_irq,
1037							IRQF_ONESHOT,
1038							"rockchip_usb2phy_otg",
1039							rport);
1040			if (ret) {
1041				dev_err(rphy->dev,
1042					"failed to request otg-mux irq handle\n");
1043				return ret;
1044			}
1045		} else {
1046			rport->bvalid_irq = of_irq_get_byname(child_np, "otg-bvalid");
1047			if (rport->bvalid_irq < 0) {
1048				dev_err(rphy->dev, "no vbus valid irq provided\n");
1049				ret = rport->bvalid_irq;
1050				return ret;
1051			}
1052
1053			ret = devm_request_threaded_irq(rphy->dev, rport->bvalid_irq,
1054							NULL,
1055							rockchip_usb2phy_bvalid_irq,
1056							IRQF_ONESHOT,
1057							"rockchip_usb2phy_bvalid",
1058							rport);
1059			if (ret) {
1060				dev_err(rphy->dev,
1061					"failed to request otg-bvalid irq handle\n");
1062				return ret;
1063			}
1064
1065			rport->id_irq = of_irq_get_byname(child_np, "otg-id");
1066			if (rport->id_irq < 0) {
1067				dev_err(rphy->dev, "no otg-id irq provided\n");
1068				ret = rport->id_irq;
1069				return ret;
1070			}
1071
1072			ret = devm_request_threaded_irq(rphy->dev, rport->id_irq,
1073							NULL,
1074							rockchip_usb2phy_id_irq,
1075							IRQF_ONESHOT,
1076							"rockchip_usb2phy_id",
1077							rport);
1078			if (ret) {
1079				dev_err(rphy->dev,
1080					"failed to request otg-id irq handle\n");
1081				return ret;
1082			}
1083		}
1084		break;
1085	default:
1086		return -EINVAL;
1087	}
1088
1089	return 0;
1090}
1091
1092static int rockchip_usb2phy_host_port_init(struct rockchip_usb2phy *rphy,
1093					   struct rockchip_usb2phy_port *rport,
1094					   struct device_node *child_np)
1095{
1096	int ret;
1097
1098	rport->port_id = USB2PHY_PORT_HOST;
1099	rport->port_cfg = &rphy->phy_cfg->port_cfgs[USB2PHY_PORT_HOST];
1100	rport->suspended = true;
1101
1102	mutex_init(&rport->mutex);
1103	INIT_DELAYED_WORK(&rport->sm_work, rockchip_usb2phy_sm_work);
1104
1105	ret = rockchip_usb2phy_port_irq_init(rphy, rport, child_np);
1106	if (ret) {
1107		dev_err(rphy->dev, "failed to setup host irq\n");
1108		return ret;
1109	}
1110
1111	return 0;
1112}
1113
1114static int rockchip_otg_event(struct notifier_block *nb,
1115			      unsigned long event, void *ptr)
1116{
1117	struct rockchip_usb2phy_port *rport =
1118		container_of(nb, struct rockchip_usb2phy_port, event_nb);
1119
1120	schedule_delayed_work(&rport->otg_sm_work, OTG_SCHEDULE_DELAY);
1121
1122	return NOTIFY_DONE;
1123}
1124
1125static int rockchip_usb2phy_otg_port_init(struct rockchip_usb2phy *rphy,
1126					  struct rockchip_usb2phy_port *rport,
1127					  struct device_node *child_np)
1128{
1129	int ret, id;
1130
1131	rport->port_id = USB2PHY_PORT_OTG;
1132	rport->port_cfg = &rphy->phy_cfg->port_cfgs[USB2PHY_PORT_OTG];
1133	rport->state = OTG_STATE_UNDEFINED;
1134
1135	/*
1136	 * set suspended flag to true, but actually don't
1137	 * put phy in suspend mode, it aims to enable usb
1138	 * phy and clock in power_on() called by usb controller
1139	 * driver during probe.
1140	 */
1141	rport->suspended = true;
1142	rport->vbus_attached = false;
1143
1144	mutex_init(&rport->mutex);
1145
1146	rport->mode = of_usb_get_dr_mode_by_phy(child_np, -1);
1147	if (rport->mode == USB_DR_MODE_HOST ||
1148	    rport->mode == USB_DR_MODE_UNKNOWN) {
1149		ret = 0;
1150		goto out;
1151	}
1152
1153	INIT_DELAYED_WORK(&rport->chg_work, rockchip_chg_detect_work);
1154	INIT_DELAYED_WORK(&rport->otg_sm_work, rockchip_usb2phy_otg_sm_work);
1155
1156	ret = rockchip_usb2phy_port_irq_init(rphy, rport, child_np);
1157	if (ret) {
1158		dev_err(rphy->dev, "failed to init irq for host port\n");
1159		goto out;
1160	}
1161
1162	if (!IS_ERR(rphy->edev)) {
1163		rport->event_nb.notifier_call = rockchip_otg_event;
1164
1165		ret = devm_extcon_register_notifier(rphy->dev, rphy->edev,
1166					EXTCON_USB_HOST, &rport->event_nb);
1167		if (ret) {
1168			dev_err(rphy->dev, "register USB HOST notifier failed\n");
1169			goto out;
1170		}
1171
1172		if (!of_property_read_bool(rphy->dev->of_node, "extcon")) {
1173			/* do initial sync of usb state */
1174			id = property_enabled(rphy->grf, &rport->port_cfg->utmi_id);
1175			extcon_set_state_sync(rphy->edev, EXTCON_USB_HOST, !id);
1176		}
1177	}
1178
1179out:
1180	return ret;
1181}
1182
1183static int rockchip_usb2phy_probe(struct platform_device *pdev)
1184{
1185	struct device *dev = &pdev->dev;
1186	struct device_node *np = dev->of_node;
1187	struct device_node *child_np;
1188	struct phy_provider *provider;
1189	struct rockchip_usb2phy *rphy;
1190	const struct rockchip_usb2phy_cfg *phy_cfgs;
1191	const struct of_device_id *match;
1192	unsigned int reg;
1193	int index, ret;
1194
1195	rphy = devm_kzalloc(dev, sizeof(*rphy), GFP_KERNEL);
1196	if (!rphy)
1197		return -ENOMEM;
1198
1199	match = of_match_device(dev->driver->of_match_table, dev);
1200	if (!match || !match->data) {
1201		dev_err(dev, "phy configs are not assigned!\n");
1202		return -EINVAL;
1203	}
1204
1205	if (!dev->parent || !dev->parent->of_node) {
1206		rphy->grf = syscon_regmap_lookup_by_phandle(np, "rockchip,usbgrf");
1207		if (IS_ERR(rphy->grf)) {
1208			dev_err(dev, "failed to locate usbgrf\n");
1209			return PTR_ERR(rphy->grf);
1210		}
1211	}
1212
1213	else {
1214		rphy->grf = syscon_node_to_regmap(dev->parent->of_node);
1215		if (IS_ERR(rphy->grf))
1216			return PTR_ERR(rphy->grf);
1217	}
1218
1219	if (of_device_is_compatible(np, "rockchip,rv1108-usb2phy")) {
1220		rphy->usbgrf =
1221			syscon_regmap_lookup_by_phandle(dev->of_node,
1222							"rockchip,usbgrf");
1223		if (IS_ERR(rphy->usbgrf))
1224			return PTR_ERR(rphy->usbgrf);
1225	} else {
1226		rphy->usbgrf = NULL;
1227	}
1228
1229	if (of_property_read_u32_index(np, "reg", 0, &reg)) {
1230		dev_err(dev, "the reg property is not assigned in %pOFn node\n",
1231			np);
1232		return -EINVAL;
1233	}
1234
1235	/* support address_cells=2 */
1236	if (reg == 0) {
1237		if (of_property_read_u32_index(np, "reg", 1, &reg)) {
1238			dev_err(dev, "the reg property is not assigned in %pOFn node\n",
1239				np);
1240			return -EINVAL;
1241		}
1242	}
1243
1244	rphy->dev = dev;
1245	phy_cfgs = match->data;
1246	rphy->chg_state = USB_CHG_STATE_UNDEFINED;
1247	rphy->chg_type = POWER_SUPPLY_TYPE_UNKNOWN;
1248	rphy->irq = platform_get_irq_optional(pdev, 0);
1249	platform_set_drvdata(pdev, rphy);
1250
 
 
 
1251	ret = rockchip_usb2phy_extcon_register(rphy);
1252	if (ret)
1253		return ret;
1254
1255	/* find out a proper config which can be matched with dt. */
1256	index = 0;
1257	while (phy_cfgs[index].reg) {
1258		if (phy_cfgs[index].reg == reg) {
1259			rphy->phy_cfg = &phy_cfgs[index];
1260			break;
1261		}
1262
1263		++index;
1264	}
1265
1266	if (!rphy->phy_cfg) {
1267		dev_err(dev, "no phy-config can be matched with %pOFn node\n",
1268			np);
1269		return -EINVAL;
1270	}
1271
1272	rphy->clk = of_clk_get_by_name(np, "phyclk");
1273	if (!IS_ERR(rphy->clk)) {
1274		clk_prepare_enable(rphy->clk);
1275	} else {
1276		dev_info(&pdev->dev, "no phyclk specified\n");
1277		rphy->clk = NULL;
1278	}
 
 
 
 
1279
1280	ret = rockchip_usb2phy_clk480m_register(rphy);
1281	if (ret) {
1282		dev_err(dev, "failed to register 480m output clock\n");
1283		goto disable_clks;
 
 
 
 
 
 
 
 
 
 
 
 
1284	}
1285
1286	index = 0;
1287	for_each_available_child_of_node(np, child_np) {
1288		struct rockchip_usb2phy_port *rport = &rphy->ports[index];
1289		struct phy *phy;
1290
1291		/* This driver aims to support both otg-port and host-port */
1292		if (!of_node_name_eq(child_np, "host-port") &&
1293		    !of_node_name_eq(child_np, "otg-port"))
1294			goto next_child;
1295
1296		phy = devm_phy_create(dev, child_np, &rockchip_usb2phy_ops);
1297		if (IS_ERR(phy)) {
1298			dev_err_probe(dev, PTR_ERR(phy), "failed to create phy\n");
1299			ret = PTR_ERR(phy);
1300			goto put_child;
1301		}
1302
1303		rport->phy = phy;
1304		phy_set_drvdata(rport->phy, rport);
1305
1306		/* initialize otg/host port separately */
1307		if (of_node_name_eq(child_np, "host-port")) {
1308			ret = rockchip_usb2phy_host_port_init(rphy, rport,
1309							      child_np);
1310			if (ret)
1311				goto put_child;
1312		} else {
1313			ret = rockchip_usb2phy_otg_port_init(rphy, rport,
1314							     child_np);
1315			if (ret)
1316				goto put_child;
1317		}
1318
1319next_child:
1320		/* to prevent out of boundary */
1321		if (++index >= rphy->phy_cfg->num_ports) {
1322			of_node_put(child_np);
1323			break;
1324		}
1325	}
1326
1327	provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
1328
1329	if (rphy->irq > 0) {
1330		ret = devm_request_threaded_irq(rphy->dev, rphy->irq, NULL,
1331						rockchip_usb2phy_irq,
1332						IRQF_ONESHOT,
1333						"rockchip_usb2phy",
1334						rphy);
1335		if (ret) {
1336			dev_err(rphy->dev,
1337				"failed to request usb2phy irq handle\n");
1338			goto put_child;
1339		}
1340	}
1341
1342	return PTR_ERR_OR_ZERO(provider);
1343
1344put_child:
1345	of_node_put(child_np);
1346disable_clks:
1347	if (rphy->clk) {
1348		clk_disable_unprepare(rphy->clk);
1349		clk_put(rphy->clk);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1350	}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1351	return ret;
1352}
1353
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1354static const struct rockchip_usb2phy_cfg rk3228_phy_cfgs[] = {
1355	{
1356		.reg = 0x760,
1357		.num_ports	= 2,
1358		.clkout_ctl	= { 0x0768, 4, 4, 1, 0 },
1359		.port_cfgs	= {
1360			[USB2PHY_PORT_OTG] = {
1361				.phy_sus	= { 0x0760, 15, 0, 0, 0x1d1 },
1362				.bvalid_det_en	= { 0x0680, 3, 3, 0, 1 },
1363				.bvalid_det_st	= { 0x0690, 3, 3, 0, 1 },
1364				.bvalid_det_clr	= { 0x06a0, 3, 3, 0, 1 },
1365				.id_det_en	= { 0x0680, 6, 5, 0, 3 },
1366				.id_det_st	= { 0x0690, 6, 5, 0, 3 },
1367				.id_det_clr	= { 0x06a0, 6, 5, 0, 3 },
 
 
 
1368				.ls_det_en	= { 0x0680, 2, 2, 0, 1 },
1369				.ls_det_st	= { 0x0690, 2, 2, 0, 1 },
1370				.ls_det_clr	= { 0x06a0, 2, 2, 0, 1 },
1371				.utmi_bvalid	= { 0x0480, 4, 4, 0, 1 },
1372				.utmi_id	= { 0x0480, 1, 1, 0, 1 },
1373				.utmi_ls	= { 0x0480, 3, 2, 0, 1 },
1374			},
1375			[USB2PHY_PORT_HOST] = {
1376				.phy_sus	= { 0x0764, 15, 0, 0, 0x1d1 },
1377				.ls_det_en	= { 0x0680, 4, 4, 0, 1 },
1378				.ls_det_st	= { 0x0690, 4, 4, 0, 1 },
1379				.ls_det_clr	= { 0x06a0, 4, 4, 0, 1 }
1380			}
1381		},
1382		.chg_det = {
1383			.opmode		= { 0x0760, 3, 0, 5, 1 },
1384			.cp_det		= { 0x0884, 4, 4, 0, 1 },
1385			.dcp_det	= { 0x0884, 3, 3, 0, 1 },
1386			.dp_det		= { 0x0884, 5, 5, 0, 1 },
1387			.idm_sink_en	= { 0x0768, 8, 8, 0, 1 },
1388			.idp_sink_en	= { 0x0768, 7, 7, 0, 1 },
1389			.idp_src_en	= { 0x0768, 9, 9, 0, 1 },
1390			.rdm_pdwn_en	= { 0x0768, 10, 10, 0, 1 },
1391			.vdm_src_en	= { 0x0768, 12, 12, 0, 1 },
1392			.vdp_src_en	= { 0x0768, 11, 11, 0, 1 },
1393		},
1394	},
1395	{
1396		.reg = 0x800,
1397		.num_ports	= 2,
1398		.clkout_ctl	= { 0x0808, 4, 4, 1, 0 },
1399		.port_cfgs	= {
1400			[USB2PHY_PORT_OTG] = {
1401				.phy_sus	= { 0x800, 15, 0, 0, 0x1d1 },
1402				.ls_det_en	= { 0x0684, 0, 0, 0, 1 },
1403				.ls_det_st	= { 0x0694, 0, 0, 0, 1 },
1404				.ls_det_clr	= { 0x06a4, 0, 0, 0, 1 }
1405			},
1406			[USB2PHY_PORT_HOST] = {
1407				.phy_sus	= { 0x804, 15, 0, 0, 0x1d1 },
1408				.ls_det_en	= { 0x0684, 1, 1, 0, 1 },
1409				.ls_det_st	= { 0x0694, 1, 1, 0, 1 },
1410				.ls_det_clr	= { 0x06a4, 1, 1, 0, 1 }
1411			}
1412		},
1413	},
1414	{ /* sentinel */ }
1415};
1416
1417static const struct rockchip_usb2phy_cfg rk3308_phy_cfgs[] = {
1418	{
1419		.reg = 0x100,
1420		.num_ports	= 2,
1421		.clkout_ctl	= { 0x108, 4, 4, 1, 0 },
1422		.port_cfgs	= {
1423			[USB2PHY_PORT_OTG] = {
1424				.phy_sus	= { 0x0100, 8, 0, 0, 0x1d1 },
1425				.bvalid_det_en	= { 0x3020, 3, 2, 0, 3 },
1426				.bvalid_det_st	= { 0x3024, 3, 2, 0, 3 },
1427				.bvalid_det_clr = { 0x3028, 3, 2, 0, 3 },
1428				.id_det_en	= { 0x3020, 5, 4, 0, 3 },
1429				.id_det_st	= { 0x3024, 5, 4, 0, 3 },
1430				.id_det_clr	= { 0x3028, 5, 4, 0, 3 },
 
 
 
1431				.ls_det_en	= { 0x3020, 0, 0, 0, 1 },
1432				.ls_det_st	= { 0x3024, 0, 0, 0, 1 },
1433				.ls_det_clr	= { 0x3028, 0, 0, 0, 1 },
1434				.utmi_avalid	= { 0x0120, 10, 10, 0, 1 },
1435				.utmi_bvalid	= { 0x0120, 9, 9, 0, 1 },
1436				.utmi_id	= { 0x0120, 6, 6, 0, 1 },
1437				.utmi_ls	= { 0x0120, 5, 4, 0, 1 },
1438			},
1439			[USB2PHY_PORT_HOST] = {
1440				.phy_sus	= { 0x0104, 8, 0, 0, 0x1d1 },
1441				.ls_det_en	= { 0x3020, 1, 1, 0, 1 },
1442				.ls_det_st	= { 0x3024, 1, 1, 0, 1 },
1443				.ls_det_clr	= { 0x3028, 1, 1, 0, 1 },
1444				.utmi_ls	= { 0x0120, 17, 16, 0, 1 },
1445				.utmi_hstdet	= { 0x0120, 19, 19, 0, 1 }
1446			}
1447		},
1448		.chg_det = {
1449			.opmode		= { 0x0100, 3, 0, 5, 1 },
1450			.cp_det		= { 0x0120, 24, 24, 0, 1 },
1451			.dcp_det	= { 0x0120, 23, 23, 0, 1 },
1452			.dp_det		= { 0x0120, 25, 25, 0, 1 },
1453			.idm_sink_en	= { 0x0108, 8, 8, 0, 1 },
1454			.idp_sink_en	= { 0x0108, 7, 7, 0, 1 },
1455			.idp_src_en	= { 0x0108, 9, 9, 0, 1 },
1456			.rdm_pdwn_en	= { 0x0108, 10, 10, 0, 1 },
1457			.vdm_src_en	= { 0x0108, 12, 12, 0, 1 },
1458			.vdp_src_en	= { 0x0108, 11, 11, 0, 1 },
1459		},
1460	},
1461	{ /* sentinel */ }
1462};
1463
1464static const struct rockchip_usb2phy_cfg rk3328_phy_cfgs[] = {
1465	{
1466		.reg = 0x100,
1467		.num_ports	= 2,
1468		.clkout_ctl	= { 0x108, 4, 4, 1, 0 },
1469		.port_cfgs	= {
1470			[USB2PHY_PORT_OTG] = {
1471				.phy_sus	= { 0x0100, 15, 0, 0, 0x1d1 },
1472				.bvalid_det_en	= { 0x0110, 3, 2, 0, 3 },
1473				.bvalid_det_st	= { 0x0114, 3, 2, 0, 3 },
1474				.bvalid_det_clr = { 0x0118, 3, 2, 0, 3 },
1475				.id_det_en	= { 0x0110, 5, 4, 0, 3 },
1476				.id_det_st	= { 0x0114, 5, 4, 0, 3 },
1477				.id_det_clr	= { 0x0118, 5, 4, 0, 3 },
 
 
 
1478				.ls_det_en	= { 0x0110, 0, 0, 0, 1 },
1479				.ls_det_st	= { 0x0114, 0, 0, 0, 1 },
1480				.ls_det_clr	= { 0x0118, 0, 0, 0, 1 },
1481				.utmi_avalid	= { 0x0120, 10, 10, 0, 1 },
1482				.utmi_bvalid	= { 0x0120, 9, 9, 0, 1 },
1483				.utmi_id	= { 0x0120, 6, 6, 0, 1 },
1484				.utmi_ls	= { 0x0120, 5, 4, 0, 1 },
1485			},
1486			[USB2PHY_PORT_HOST] = {
1487				.phy_sus	= { 0x104, 15, 0, 0, 0x1d1 },
1488				.ls_det_en	= { 0x110, 1, 1, 0, 1 },
1489				.ls_det_st	= { 0x114, 1, 1, 0, 1 },
1490				.ls_det_clr	= { 0x118, 1, 1, 0, 1 },
1491				.utmi_ls	= { 0x120, 17, 16, 0, 1 },
1492				.utmi_hstdet	= { 0x120, 19, 19, 0, 1 }
1493			}
1494		},
1495		.chg_det = {
1496			.opmode		= { 0x0100, 3, 0, 5, 1 },
1497			.cp_det		= { 0x0120, 24, 24, 0, 1 },
1498			.dcp_det	= { 0x0120, 23, 23, 0, 1 },
1499			.dp_det		= { 0x0120, 25, 25, 0, 1 },
1500			.idm_sink_en	= { 0x0108, 8, 8, 0, 1 },
1501			.idp_sink_en	= { 0x0108, 7, 7, 0, 1 },
1502			.idp_src_en	= { 0x0108, 9, 9, 0, 1 },
1503			.rdm_pdwn_en	= { 0x0108, 10, 10, 0, 1 },
1504			.vdm_src_en	= { 0x0108, 12, 12, 0, 1 },
1505			.vdp_src_en	= { 0x0108, 11, 11, 0, 1 },
1506		},
1507	},
1508	{ /* sentinel */ }
1509};
1510
1511static const struct rockchip_usb2phy_cfg rk3366_phy_cfgs[] = {
1512	{
1513		.reg = 0x700,
1514		.num_ports	= 2,
1515		.clkout_ctl	= { 0x0724, 15, 15, 1, 0 },
1516		.port_cfgs	= {
1517			[USB2PHY_PORT_HOST] = {
1518				.phy_sus	= { 0x0728, 15, 0, 0, 0x1d1 },
1519				.ls_det_en	= { 0x0680, 4, 4, 0, 1 },
1520				.ls_det_st	= { 0x0690, 4, 4, 0, 1 },
1521				.ls_det_clr	= { 0x06a0, 4, 4, 0, 1 },
1522				.utmi_ls	= { 0x049c, 14, 13, 0, 1 },
1523				.utmi_hstdet	= { 0x049c, 12, 12, 0, 1 }
1524			}
1525		},
1526	},
1527	{ /* sentinel */ }
1528};
1529
1530static const struct rockchip_usb2phy_cfg rk3399_phy_cfgs[] = {
1531	{
1532		.reg		= 0xe450,
1533		.num_ports	= 2,
1534		.clkout_ctl	= { 0xe450, 4, 4, 1, 0 },
1535		.port_cfgs	= {
1536			[USB2PHY_PORT_OTG] = {
1537				.phy_sus	= { 0xe454, 1, 0, 2, 1 },
1538				.bvalid_det_en	= { 0xe3c0, 3, 3, 0, 1 },
1539				.bvalid_det_st	= { 0xe3e0, 3, 3, 0, 1 },
1540				.bvalid_det_clr	= { 0xe3d0, 3, 3, 0, 1 },
1541				.id_det_en	= { 0xe3c0, 5, 4, 0, 3 },
1542				.id_det_st	= { 0xe3e0, 5, 4, 0, 3 },
1543				.id_det_clr	= { 0xe3d0, 5, 4, 0, 3 },
 
 
 
1544				.utmi_avalid	= { 0xe2ac, 7, 7, 0, 1 },
1545				.utmi_bvalid	= { 0xe2ac, 12, 12, 0, 1 },
1546				.utmi_id	= { 0xe2ac, 8, 8, 0, 1 },
1547			},
1548			[USB2PHY_PORT_HOST] = {
1549				.phy_sus	= { 0xe458, 1, 0, 0x2, 0x1 },
1550				.ls_det_en	= { 0xe3c0, 6, 6, 0, 1 },
1551				.ls_det_st	= { 0xe3e0, 6, 6, 0, 1 },
1552				.ls_det_clr	= { 0xe3d0, 6, 6, 0, 1 },
1553				.utmi_ls	= { 0xe2ac, 22, 21, 0, 1 },
1554				.utmi_hstdet	= { 0xe2ac, 23, 23, 0, 1 }
1555			}
1556		},
1557		.chg_det = {
1558			.opmode		= { 0xe454, 3, 0, 5, 1 },
1559			.cp_det		= { 0xe2ac, 2, 2, 0, 1 },
1560			.dcp_det	= { 0xe2ac, 1, 1, 0, 1 },
1561			.dp_det		= { 0xe2ac, 0, 0, 0, 1 },
1562			.idm_sink_en	= { 0xe450, 8, 8, 0, 1 },
1563			.idp_sink_en	= { 0xe450, 7, 7, 0, 1 },
1564			.idp_src_en	= { 0xe450, 9, 9, 0, 1 },
1565			.rdm_pdwn_en	= { 0xe450, 10, 10, 0, 1 },
1566			.vdm_src_en	= { 0xe450, 12, 12, 0, 1 },
1567			.vdp_src_en	= { 0xe450, 11, 11, 0, 1 },
1568		},
1569	},
1570	{
1571		.reg		= 0xe460,
1572		.num_ports	= 2,
1573		.clkout_ctl	= { 0xe460, 4, 4, 1, 0 },
1574		.port_cfgs	= {
1575			[USB2PHY_PORT_OTG] = {
1576				.phy_sus        = { 0xe464, 1, 0, 2, 1 },
1577				.bvalid_det_en  = { 0xe3c0, 8, 8, 0, 1 },
1578				.bvalid_det_st  = { 0xe3e0, 8, 8, 0, 1 },
1579				.bvalid_det_clr = { 0xe3d0, 8, 8, 0, 1 },
1580				.id_det_en	= { 0xe3c0, 10, 9, 0, 3 },
1581				.id_det_st	= { 0xe3e0, 10, 9, 0, 3 },
1582				.id_det_clr	= { 0xe3d0, 10, 9, 0, 3 },
 
 
 
1583				.utmi_avalid	= { 0xe2ac, 10, 10, 0, 1 },
1584				.utmi_bvalid    = { 0xe2ac, 16, 16, 0, 1 },
1585				.utmi_id	= { 0xe2ac, 11, 11, 0, 1 },
1586			},
1587			[USB2PHY_PORT_HOST] = {
1588				.phy_sus	= { 0xe468, 1, 0, 0x2, 0x1 },
1589				.ls_det_en	= { 0xe3c0, 11, 11, 0, 1 },
1590				.ls_det_st	= { 0xe3e0, 11, 11, 0, 1 },
1591				.ls_det_clr	= { 0xe3d0, 11, 11, 0, 1 },
1592				.utmi_ls	= { 0xe2ac, 26, 25, 0, 1 },
1593				.utmi_hstdet	= { 0xe2ac, 27, 27, 0, 1 }
1594			}
1595		},
1596	},
1597	{ /* sentinel */ }
1598};
1599
1600static const struct rockchip_usb2phy_cfg rk3568_phy_cfgs[] = {
1601	{
1602		.reg = 0xfe8a0000,
1603		.num_ports	= 2,
1604		.clkout_ctl	= { 0x0008, 4, 4, 1, 0 },
1605		.port_cfgs	= {
1606			[USB2PHY_PORT_OTG] = {
1607				.phy_sus	= { 0x0000, 8, 0, 0, 0x1d1 },
1608				.bvalid_det_en	= { 0x0080, 3, 2, 0, 3 },
1609				.bvalid_det_st	= { 0x0084, 3, 2, 0, 3 },
1610				.bvalid_det_clr = { 0x0088, 3, 2, 0, 3 },
1611				.id_det_en	= { 0x0080, 5, 4, 0, 3 },
1612				.id_det_st	= { 0x0084, 5, 4, 0, 3 },
1613				.id_det_clr	= { 0x0088, 5, 4, 0, 3 },
 
 
 
1614				.utmi_avalid	= { 0x00c0, 10, 10, 0, 1 },
1615				.utmi_bvalid	= { 0x00c0, 9, 9, 0, 1 },
1616				.utmi_id	= { 0x00c0, 6, 6, 0, 1 },
1617			},
1618			[USB2PHY_PORT_HOST] = {
1619				/* Select suspend control from controller */
1620				.phy_sus	= { 0x0004, 8, 0, 0x1d2, 0x1d2 },
1621				.ls_det_en	= { 0x0080, 1, 1, 0, 1 },
1622				.ls_det_st	= { 0x0084, 1, 1, 0, 1 },
1623				.ls_det_clr	= { 0x0088, 1, 1, 0, 1 },
1624				.utmi_ls	= { 0x00c0, 17, 16, 0, 1 },
1625				.utmi_hstdet	= { 0x00c0, 19, 19, 0, 1 }
1626			}
1627		},
1628		.chg_det = {
1629			.opmode		= { 0x0000, 3, 0, 5, 1 },
1630			.cp_det		= { 0x00c0, 24, 24, 0, 1 },
1631			.dcp_det	= { 0x00c0, 23, 23, 0, 1 },
1632			.dp_det		= { 0x00c0, 25, 25, 0, 1 },
1633			.idm_sink_en	= { 0x0008, 8, 8, 0, 1 },
1634			.idp_sink_en	= { 0x0008, 7, 7, 0, 1 },
1635			.idp_src_en	= { 0x0008, 9, 9, 0, 1 },
1636			.rdm_pdwn_en	= { 0x0008, 10, 10, 0, 1 },
1637			.vdm_src_en	= { 0x0008, 12, 12, 0, 1 },
1638			.vdp_src_en	= { 0x0008, 11, 11, 0, 1 },
1639		},
1640	},
1641	{
1642		.reg = 0xfe8b0000,
1643		.num_ports	= 2,
1644		.clkout_ctl	= { 0x0008, 4, 4, 1, 0 },
1645		.port_cfgs	= {
1646			[USB2PHY_PORT_OTG] = {
1647				.phy_sus	= { 0x0000, 8, 0, 0x1d2, 0x1d1 },
1648				.ls_det_en	= { 0x0080, 0, 0, 0, 1 },
1649				.ls_det_st	= { 0x0084, 0, 0, 0, 1 },
1650				.ls_det_clr	= { 0x0088, 0, 0, 0, 1 },
1651				.utmi_ls	= { 0x00c0, 5, 4, 0, 1 },
1652				.utmi_hstdet	= { 0x00c0, 7, 7, 0, 1 }
1653			},
1654			[USB2PHY_PORT_HOST] = {
1655				.phy_sus	= { 0x0004, 8, 0, 0x1d2, 0x1d1 },
1656				.ls_det_en	= { 0x0080, 1, 1, 0, 1 },
1657				.ls_det_st	= { 0x0084, 1, 1, 0, 1 },
1658				.ls_det_clr	= { 0x0088, 1, 1, 0, 1 },
1659				.utmi_ls	= { 0x00c0, 17, 16, 0, 1 },
1660				.utmi_hstdet	= { 0x00c0, 19, 19, 0, 1 }
1661			}
1662		},
1663	},
1664	{ /* sentinel */ }
1665};
1666
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1667static const struct rockchip_usb2phy_cfg rv1108_phy_cfgs[] = {
1668	{
1669		.reg = 0x100,
1670		.num_ports	= 2,
1671		.clkout_ctl	= { 0x108, 4, 4, 1, 0 },
1672		.port_cfgs	= {
1673			[USB2PHY_PORT_OTG] = {
1674				.phy_sus	= { 0x0100, 15, 0, 0, 0x1d1 },
1675				.bvalid_det_en	= { 0x0680, 3, 3, 0, 1 },
1676				.bvalid_det_st	= { 0x0690, 3, 3, 0, 1 },
1677				.bvalid_det_clr = { 0x06a0, 3, 3, 0, 1 },
1678				.ls_det_en	= { 0x0680, 2, 2, 0, 1 },
1679				.ls_det_st	= { 0x0690, 2, 2, 0, 1 },
1680				.ls_det_clr	= { 0x06a0, 2, 2, 0, 1 },
1681				.utmi_bvalid	= { 0x0804, 10, 10, 0, 1 },
1682				.utmi_ls	= { 0x0804, 13, 12, 0, 1 },
1683			},
1684			[USB2PHY_PORT_HOST] = {
1685				.phy_sus	= { 0x0104, 15, 0, 0, 0x1d1 },
1686				.ls_det_en	= { 0x0680, 4, 4, 0, 1 },
1687				.ls_det_st	= { 0x0690, 4, 4, 0, 1 },
1688				.ls_det_clr	= { 0x06a0, 4, 4, 0, 1 },
1689				.utmi_ls	= { 0x0804, 9, 8, 0, 1 },
1690				.utmi_hstdet	= { 0x0804, 7, 7, 0, 1 }
1691			}
1692		},
1693		.chg_det = {
1694			.opmode		= { 0x0100, 3, 0, 5, 1 },
1695			.cp_det		= { 0x0804, 1, 1, 0, 1 },
1696			.dcp_det	= { 0x0804, 0, 0, 0, 1 },
1697			.dp_det		= { 0x0804, 2, 2, 0, 1 },
1698			.idm_sink_en	= { 0x0108, 8, 8, 0, 1 },
1699			.idp_sink_en	= { 0x0108, 7, 7, 0, 1 },
1700			.idp_src_en	= { 0x0108, 9, 9, 0, 1 },
1701			.rdm_pdwn_en	= { 0x0108, 10, 10, 0, 1 },
1702			.vdm_src_en	= { 0x0108, 12, 12, 0, 1 },
1703			.vdp_src_en	= { 0x0108, 11, 11, 0, 1 },
1704		},
1705	},
1706	{ /* sentinel */ }
1707};
1708
1709static const struct of_device_id rockchip_usb2phy_dt_match[] = {
1710	{ .compatible = "rockchip,px30-usb2phy", .data = &rk3328_phy_cfgs },
 
1711	{ .compatible = "rockchip,rk3228-usb2phy", .data = &rk3228_phy_cfgs },
1712	{ .compatible = "rockchip,rk3308-usb2phy", .data = &rk3308_phy_cfgs },
1713	{ .compatible = "rockchip,rk3328-usb2phy", .data = &rk3328_phy_cfgs },
1714	{ .compatible = "rockchip,rk3366-usb2phy", .data = &rk3366_phy_cfgs },
1715	{ .compatible = "rockchip,rk3399-usb2phy", .data = &rk3399_phy_cfgs },
1716	{ .compatible = "rockchip,rk3568-usb2phy", .data = &rk3568_phy_cfgs },
 
 
1717	{ .compatible = "rockchip,rv1108-usb2phy", .data = &rv1108_phy_cfgs },
1718	{}
1719};
1720MODULE_DEVICE_TABLE(of, rockchip_usb2phy_dt_match);
1721
1722static struct platform_driver rockchip_usb2phy_driver = {
1723	.probe		= rockchip_usb2phy_probe,
1724	.driver		= {
1725		.name	= "rockchip-usb2phy",
1726		.of_match_table = rockchip_usb2phy_dt_match,
1727	},
1728};
1729module_platform_driver(rockchip_usb2phy_driver);
1730
1731MODULE_AUTHOR("Frank Wang <frank.wang@rock-chips.com>");
1732MODULE_DESCRIPTION("Rockchip USB2.0 PHY driver");
1733MODULE_LICENSE("GPL v2");
v6.13.7
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*
   3 * Rockchip USB2.0 PHY with Innosilicon IP block driver
   4 *
   5 * Copyright (C) 2016 Fuzhou Rockchip Electronics Co., Ltd
   6 */
   7
   8#include <linux/clk.h>
   9#include <linux/clk-provider.h>
  10#include <linux/delay.h>
  11#include <linux/extcon-provider.h>
  12#include <linux/interrupt.h>
  13#include <linux/io.h>
  14#include <linux/gpio/consumer.h>
  15#include <linux/jiffies.h>
  16#include <linux/kernel.h>
  17#include <linux/module.h>
  18#include <linux/mutex.h>
  19#include <linux/of.h>
 
  20#include <linux/of_irq.h>
 
  21#include <linux/phy/phy.h>
  22#include <linux/platform_device.h>
  23#include <linux/power_supply.h>
  24#include <linux/regmap.h>
  25#include <linux/reset.h>
  26#include <linux/mfd/syscon.h>
  27#include <linux/usb/of.h>
  28#include <linux/usb/otg.h>
  29
  30#define BIT_WRITEABLE_SHIFT	16
  31#define SCHEDULE_DELAY		(60 * HZ)
  32#define OTG_SCHEDULE_DELAY	(2 * HZ)
  33
  34struct rockchip_usb2phy;
  35
  36enum rockchip_usb2phy_port_id {
  37	USB2PHY_PORT_OTG,
  38	USB2PHY_PORT_HOST,
  39	USB2PHY_NUM_PORTS,
  40};
  41
  42enum rockchip_usb2phy_host_state {
  43	PHY_STATE_HS_ONLINE	= 0,
  44	PHY_STATE_DISCONNECT	= 1,
  45	PHY_STATE_CONNECT	= 2,
  46	PHY_STATE_FS_LS_ONLINE	= 4,
  47};
  48
  49/**
  50 * enum usb_chg_state - Different states involved in USB charger detection.
  51 * @USB_CHG_STATE_UNDEFINED:	USB charger is not connected or detection
  52 *				process is not yet started.
  53 * @USB_CHG_STATE_WAIT_FOR_DCD:	Waiting for Data pins contact.
  54 * @USB_CHG_STATE_DCD_DONE:	Data pin contact is detected.
  55 * @USB_CHG_STATE_PRIMARY_DONE:	Primary detection is completed (Detects
  56 *				between SDP and DCP/CDP).
  57 * @USB_CHG_STATE_SECONDARY_DONE: Secondary detection is completed (Detects
  58 *				  between DCP and CDP).
  59 * @USB_CHG_STATE_DETECTED:	USB charger type is determined.
  60 */
  61enum usb_chg_state {
  62	USB_CHG_STATE_UNDEFINED = 0,
  63	USB_CHG_STATE_WAIT_FOR_DCD,
  64	USB_CHG_STATE_DCD_DONE,
  65	USB_CHG_STATE_PRIMARY_DONE,
  66	USB_CHG_STATE_SECONDARY_DONE,
  67	USB_CHG_STATE_DETECTED,
  68};
  69
  70static const unsigned int rockchip_usb2phy_extcon_cable[] = {
  71	EXTCON_USB,
  72	EXTCON_USB_HOST,
  73	EXTCON_CHG_USB_SDP,
  74	EXTCON_CHG_USB_CDP,
  75	EXTCON_CHG_USB_DCP,
  76	EXTCON_CHG_USB_SLOW,
  77	EXTCON_NONE,
  78};
  79
  80struct usb2phy_reg {
  81	unsigned int	offset;
  82	unsigned int	bitend;
  83	unsigned int	bitstart;
  84	unsigned int	disable;
  85	unsigned int	enable;
  86};
  87
  88/**
  89 * struct rockchip_chg_det_reg - usb charger detect registers
  90 * @cp_det: charging port detected successfully.
  91 * @dcp_det: dedicated charging port detected successfully.
  92 * @dp_det: assert data pin connect successfully.
  93 * @idm_sink_en: open dm sink curren.
  94 * @idp_sink_en: open dp sink current.
  95 * @idp_src_en: open dm source current.
  96 * @rdm_pdwn_en: open dm pull down resistor.
  97 * @vdm_src_en: open dm voltage source.
  98 * @vdp_src_en: open dp voltage source.
  99 * @opmode: utmi operational mode.
 100 */
 101struct rockchip_chg_det_reg {
 102	struct usb2phy_reg	cp_det;
 103	struct usb2phy_reg	dcp_det;
 104	struct usb2phy_reg	dp_det;
 105	struct usb2phy_reg	idm_sink_en;
 106	struct usb2phy_reg	idp_sink_en;
 107	struct usb2phy_reg	idp_src_en;
 108	struct usb2phy_reg	rdm_pdwn_en;
 109	struct usb2phy_reg	vdm_src_en;
 110	struct usb2phy_reg	vdp_src_en;
 111	struct usb2phy_reg	opmode;
 112};
 113
 114/**
 115 * struct rockchip_usb2phy_port_cfg - usb-phy port configuration.
 116 * @phy_sus: phy suspend register.
 117 * @bvalid_det_en: vbus valid rise detection enable register.
 118 * @bvalid_det_st: vbus valid rise detection status register.
 119 * @bvalid_det_clr: vbus valid rise detection clear register.
 120 * @disfall_en: host disconnect fall edge detection enable.
 121 * @disfall_st: host disconnect fall edge detection state.
 122 * @disfall_clr: host disconnect fall edge detection clear.
 123 * @disrise_en: host disconnect rise edge detection enable.
 124 * @disrise_st: host disconnect rise edge detection state.
 125 * @disrise_clr: host disconnect rise edge detection clear.
 126 * @idfall_det_en: id detection enable register, falling edge
 127 * @idfall_det_st: id detection state register, falling edge
 128 * @idfall_det_clr: id detection clear register, falling edge
 129 * @idrise_det_en: id detection enable register, rising edge
 130 * @idrise_det_st: id detection state register, rising edge
 131 * @idrise_det_clr: id detection clear register, rising edge
 132 * @ls_det_en: linestate detection enable register.
 133 * @ls_det_st: linestate detection state register.
 134 * @ls_det_clr: linestate detection clear register.
 135 * @utmi_avalid: utmi vbus avalid status register.
 136 * @utmi_bvalid: utmi vbus bvalid status register.
 137 * @utmi_id: utmi id state register.
 138 * @utmi_ls: utmi linestate state register.
 139 * @utmi_hstdet: utmi host disconnect register.
 140 */
 141struct rockchip_usb2phy_port_cfg {
 142	struct usb2phy_reg	phy_sus;
 143	struct usb2phy_reg	bvalid_det_en;
 144	struct usb2phy_reg	bvalid_det_st;
 145	struct usb2phy_reg	bvalid_det_clr;
 146	struct usb2phy_reg      disfall_en;
 147	struct usb2phy_reg      disfall_st;
 148	struct usb2phy_reg      disfall_clr;
 149	struct usb2phy_reg      disrise_en;
 150	struct usb2phy_reg      disrise_st;
 151	struct usb2phy_reg      disrise_clr;
 152	struct usb2phy_reg	idfall_det_en;
 153	struct usb2phy_reg	idfall_det_st;
 154	struct usb2phy_reg	idfall_det_clr;
 155	struct usb2phy_reg	idrise_det_en;
 156	struct usb2phy_reg	idrise_det_st;
 157	struct usb2phy_reg	idrise_det_clr;
 158	struct usb2phy_reg	ls_det_en;
 159	struct usb2phy_reg	ls_det_st;
 160	struct usb2phy_reg	ls_det_clr;
 161	struct usb2phy_reg	utmi_avalid;
 162	struct usb2phy_reg	utmi_bvalid;
 163	struct usb2phy_reg	utmi_id;
 164	struct usb2phy_reg	utmi_ls;
 165	struct usb2phy_reg	utmi_hstdet;
 166};
 167
 168/**
 169 * struct rockchip_usb2phy_cfg - usb-phy configuration.
 170 * @reg: the address offset of grf for usb-phy config.
 171 * @num_ports: specify how many ports that the phy has.
 172 * @phy_tuning: phy default parameters tuning.
 173 * @clkout_ctl: keep on/turn off output clk of phy.
 174 * @port_cfgs: usb-phy port configurations.
 175 * @chg_det: charger detection registers.
 176 */
 177struct rockchip_usb2phy_cfg {
 178	unsigned int	reg;
 179	unsigned int	num_ports;
 180	int (*phy_tuning)(struct rockchip_usb2phy *rphy);
 181	struct usb2phy_reg	clkout_ctl;
 182	const struct rockchip_usb2phy_port_cfg	port_cfgs[USB2PHY_NUM_PORTS];
 183	const struct rockchip_chg_det_reg	chg_det;
 184};
 185
 186/**
 187 * struct rockchip_usb2phy_port - usb-phy port data.
 188 * @phy: generic phy.
 189 * @port_id: flag for otg port or host port.
 190 * @suspended: phy suspended flag.
 191 * @vbus_attached: otg device vbus status.
 192 * @host_disconnect: usb host disconnect status.
 193 * @bvalid_irq: IRQ number assigned for vbus valid rise detection.
 194 * @id_irq: IRQ number assigned for ID pin detection.
 195 * @ls_irq: IRQ number assigned for linestate detection.
 196 * @otg_mux_irq: IRQ number which multiplex otg-id/otg-bvalid/linestate
 197 *		 irqs to one irq in otg-port.
 198 * @mutex: for register updating in sm_work.
 199 * @chg_work: charge detect work.
 200 * @otg_sm_work: OTG state machine work.
 201 * @sm_work: HOST state machine work.
 202 * @port_cfg: port register configuration, assigned by driver data.
 203 * @event_nb: hold event notification callback.
 204 * @state: define OTG enumeration states before device reset.
 205 * @mode: the dr_mode of the controller.
 206 */
 207struct rockchip_usb2phy_port {
 208	struct phy	*phy;
 209	unsigned int	port_id;
 210	bool		suspended;
 211	bool		vbus_attached;
 212	bool            host_disconnect;
 213	int		bvalid_irq;
 214	int		id_irq;
 215	int		ls_irq;
 216	int		otg_mux_irq;
 217	struct mutex	mutex;
 218	struct		delayed_work chg_work;
 219	struct		delayed_work otg_sm_work;
 220	struct		delayed_work sm_work;
 221	const struct	rockchip_usb2phy_port_cfg *port_cfg;
 222	struct notifier_block	event_nb;
 223	enum usb_otg_state	state;
 224	enum usb_dr_mode	mode;
 225};
 226
 227/**
 228 * struct rockchip_usb2phy - usb2.0 phy driver data.
 229 * @dev: pointer to device.
 230 * @grf: General Register Files regmap.
 231 * @usbgrf: USB General Register Files regmap.
 232 * @clks: array of phy input clocks.
 233 * @clk480m: clock struct of phy output clk.
 234 * @clk480m_hw: clock struct of phy output clk management.
 235 * @num_clks: number of phy input clocks.
 236 * @phy_reset: phy reset control.
 237 * @chg_state: states involved in USB charger detection.
 238 * @chg_type: USB charger types.
 239 * @dcd_retries: The retry count used to track Data contact
 240 *		 detection process.
 241 * @edev: extcon device for notification registration
 242 * @irq: muxed interrupt for single irq configuration
 243 * @phy_cfg: phy register configuration, assigned by driver data.
 244 * @ports: phy port instance.
 245 */
 246struct rockchip_usb2phy {
 247	struct device	*dev;
 248	struct regmap	*grf;
 249	struct regmap	*usbgrf;
 250	struct clk_bulk_data	*clks;
 251	struct clk	*clk480m;
 252	struct clk_hw	clk480m_hw;
 253	int			num_clks;
 254	struct reset_control	*phy_reset;
 255	enum usb_chg_state	chg_state;
 256	enum power_supply_type	chg_type;
 257	u8			dcd_retries;
 258	struct extcon_dev	*edev;
 259	int			irq;
 260	const struct rockchip_usb2phy_cfg	*phy_cfg;
 261	struct rockchip_usb2phy_port	ports[USB2PHY_NUM_PORTS];
 262};
 263
 264static inline struct regmap *get_reg_base(struct rockchip_usb2phy *rphy)
 265{
 266	return rphy->usbgrf == NULL ? rphy->grf : rphy->usbgrf;
 267}
 268
 269static inline int property_enable(struct regmap *base,
 270				  const struct usb2phy_reg *reg, bool en)
 271{
 272	unsigned int val, mask, tmp;
 273
 274	tmp = en ? reg->enable : reg->disable;
 275	mask = GENMASK(reg->bitend, reg->bitstart);
 276	val = (tmp << reg->bitstart) | (mask << BIT_WRITEABLE_SHIFT);
 277
 278	return regmap_write(base, reg->offset, val);
 279}
 280
 281static inline bool property_enabled(struct regmap *base,
 282				    const struct usb2phy_reg *reg)
 283{
 284	int ret;
 285	unsigned int tmp, orig;
 286	unsigned int mask = GENMASK(reg->bitend, reg->bitstart);
 287
 288	ret = regmap_read(base, reg->offset, &orig);
 289	if (ret)
 290		return false;
 291
 292	tmp = (orig & mask) >> reg->bitstart;
 293	return tmp != reg->disable;
 294}
 295
 296static int rockchip_usb2phy_reset(struct rockchip_usb2phy *rphy)
 297{
 298	int ret;
 299
 300	ret = reset_control_assert(rphy->phy_reset);
 301	if (ret)
 302		return ret;
 303
 304	udelay(10);
 305
 306	ret = reset_control_deassert(rphy->phy_reset);
 307	if (ret)
 308		return ret;
 309
 310	usleep_range(100, 200);
 311
 312	return 0;
 313}
 314
 315static void rockchip_usb2phy_clk_bulk_disable(void *data)
 316{
 317	struct rockchip_usb2phy *rphy = data;
 318
 319	clk_bulk_disable_unprepare(rphy->num_clks, rphy->clks);
 320}
 321
 322static int rockchip_usb2phy_clk480m_prepare(struct clk_hw *hw)
 323{
 324	struct rockchip_usb2phy *rphy =
 325		container_of(hw, struct rockchip_usb2phy, clk480m_hw);
 326	struct regmap *base = get_reg_base(rphy);
 327	int ret;
 328
 329	/* turn on 480m clk output if it is off */
 330	if (!property_enabled(base, &rphy->phy_cfg->clkout_ctl)) {
 331		ret = property_enable(base, &rphy->phy_cfg->clkout_ctl, true);
 332		if (ret)
 333			return ret;
 334
 335		/* waiting for the clk become stable */
 336		usleep_range(1200, 1300);
 337	}
 338
 339	return 0;
 340}
 341
 342static void rockchip_usb2phy_clk480m_unprepare(struct clk_hw *hw)
 343{
 344	struct rockchip_usb2phy *rphy =
 345		container_of(hw, struct rockchip_usb2phy, clk480m_hw);
 346	struct regmap *base = get_reg_base(rphy);
 347
 348	/* turn off 480m clk output */
 349	property_enable(base, &rphy->phy_cfg->clkout_ctl, false);
 350}
 351
 352static int rockchip_usb2phy_clk480m_prepared(struct clk_hw *hw)
 353{
 354	struct rockchip_usb2phy *rphy =
 355		container_of(hw, struct rockchip_usb2phy, clk480m_hw);
 356	struct regmap *base = get_reg_base(rphy);
 357
 358	return property_enabled(base, &rphy->phy_cfg->clkout_ctl);
 359}
 360
 361static unsigned long
 362rockchip_usb2phy_clk480m_recalc_rate(struct clk_hw *hw,
 363				     unsigned long parent_rate)
 364{
 365	return 480000000;
 366}
 367
 368static const struct clk_ops rockchip_usb2phy_clkout_ops = {
 369	.prepare = rockchip_usb2phy_clk480m_prepare,
 370	.unprepare = rockchip_usb2phy_clk480m_unprepare,
 371	.is_prepared = rockchip_usb2phy_clk480m_prepared,
 372	.recalc_rate = rockchip_usb2phy_clk480m_recalc_rate,
 373};
 374
 375static void rockchip_usb2phy_clk480m_unregister(void *data)
 376{
 377	struct rockchip_usb2phy *rphy = data;
 378
 379	of_clk_del_provider(rphy->dev->of_node);
 380	clk_unregister(rphy->clk480m);
 381}
 382
 383static int
 384rockchip_usb2phy_clk480m_register(struct rockchip_usb2phy *rphy)
 385{
 386	struct device_node *node = rphy->dev->of_node;
 387	struct clk_init_data init;
 388	struct clk *refclk = NULL;
 389	const char *clk_name;
 390	int i;
 391	int ret = 0;
 392
 393	init.flags = 0;
 394	init.name = "clk_usbphy_480m";
 395	init.ops = &rockchip_usb2phy_clkout_ops;
 396
 397	/* optional override of the clockname */
 398	of_property_read_string(node, "clock-output-names", &init.name);
 399
 400	for (i = 0; i < rphy->num_clks; i++) {
 401		if (!strncmp(rphy->clks[i].id, "phyclk", 6)) {
 402			refclk = rphy->clks[i].clk;
 403			break;
 404		}
 405	}
 406
 407	if (!IS_ERR(refclk)) {
 408		clk_name = __clk_get_name(refclk);
 409		init.parent_names = &clk_name;
 410		init.num_parents = 1;
 411	} else {
 412		init.parent_names = NULL;
 413		init.num_parents = 0;
 414	}
 415
 416	rphy->clk480m_hw.init = &init;
 417
 418	/* register the clock */
 419	rphy->clk480m = clk_register(rphy->dev, &rphy->clk480m_hw);
 420	if (IS_ERR(rphy->clk480m)) {
 421		ret = PTR_ERR(rphy->clk480m);
 422		goto err_ret;
 423	}
 424
 425	ret = of_clk_add_provider(node, of_clk_src_simple_get, rphy->clk480m);
 426	if (ret < 0)
 427		goto err_clk_provider;
 428
 429	return devm_add_action_or_reset(rphy->dev, rockchip_usb2phy_clk480m_unregister, rphy);
 430
 431err_clk_provider:
 432	clk_unregister(rphy->clk480m);
 433err_ret:
 434	return ret;
 435}
 436
 437static int rockchip_usb2phy_extcon_register(struct rockchip_usb2phy *rphy)
 438{
 
 439	struct device_node *node = rphy->dev->of_node;
 440	struct extcon_dev *edev;
 441	int ret;
 442
 443	if (of_property_read_bool(node, "extcon")) {
 444		edev = extcon_get_edev_by_phandle(rphy->dev, 0);
 445		if (IS_ERR(edev))
 446			return dev_err_probe(rphy->dev, PTR_ERR(edev),
 447					     "invalid or missing extcon\n");
 
 
 448	} else {
 449		/* Initialize extcon device */
 450		edev = devm_extcon_dev_allocate(rphy->dev,
 451						rockchip_usb2phy_extcon_cable);
 452
 453		if (IS_ERR(edev))
 454			return dev_err_probe(rphy->dev, PTR_ERR(edev),
 455					     "failed to allocate extcon device\n");
 456
 457		ret = devm_extcon_dev_register(rphy->dev, edev);
 458		if (ret)
 459			return dev_err_probe(rphy->dev, ret,
 460					     "failed to register extcon device\n");
 
 461	}
 462
 463	rphy->edev = edev;
 464
 465	return 0;
 466}
 467
 468static int rockchip_usb2phy_enable_host_disc_irq(struct rockchip_usb2phy *rphy,
 469						 struct rockchip_usb2phy_port *rport,
 470						 bool en)
 471{
 472	int ret;
 473
 474	ret = property_enable(rphy->grf, &rport->port_cfg->disfall_clr, true);
 475	if (ret)
 476		return ret;
 477
 478	ret = property_enable(rphy->grf, &rport->port_cfg->disfall_en, en);
 479	if (ret)
 480		return ret;
 481
 482	ret = property_enable(rphy->grf, &rport->port_cfg->disrise_clr, true);
 483	if (ret)
 484		return ret;
 485
 486	return property_enable(rphy->grf, &rport->port_cfg->disrise_en, en);
 487}
 488
 489static int rockchip_usb2phy_init(struct phy *phy)
 490{
 491	struct rockchip_usb2phy_port *rport = phy_get_drvdata(phy);
 492	struct rockchip_usb2phy *rphy = dev_get_drvdata(phy->dev.parent);
 493	int ret = 0;
 494
 495	mutex_lock(&rport->mutex);
 496
 497	if (rport->port_id == USB2PHY_PORT_OTG) {
 498		if (rport->mode != USB_DR_MODE_HOST &&
 499		    rport->mode != USB_DR_MODE_UNKNOWN) {
 500			/* clear bvalid status and enable bvalid detect irq */
 501			ret = property_enable(rphy->grf,
 502					      &rport->port_cfg->bvalid_det_clr,
 503					      true);
 504			if (ret)
 505				goto out;
 506
 507			ret = property_enable(rphy->grf,
 508					      &rport->port_cfg->bvalid_det_en,
 509					      true);
 510			if (ret)
 511				goto out;
 512
 513			/* clear id status and enable id detect irqs */
 514			ret = property_enable(rphy->grf,
 515					      &rport->port_cfg->idfall_det_clr,
 516					      true);
 517			if (ret)
 518				goto out;
 519
 520			ret = property_enable(rphy->grf,
 521					      &rport->port_cfg->idrise_det_clr,
 522					      true);
 523			if (ret)
 524				goto out;
 525
 526			ret = property_enable(rphy->grf,
 527					      &rport->port_cfg->idfall_det_en,
 528					      true);
 529			if (ret)
 530				goto out;
 531
 532			ret = property_enable(rphy->grf,
 533					      &rport->port_cfg->idrise_det_en,
 534					      true);
 535			if (ret)
 536				goto out;
 537
 538			schedule_delayed_work(&rport->otg_sm_work,
 539					      OTG_SCHEDULE_DELAY * 3);
 540		} else {
 541			/* If OTG works in host only mode, do nothing. */
 542			dev_dbg(&rport->phy->dev, "mode %d\n", rport->mode);
 543		}
 544	} else if (rport->port_id == USB2PHY_PORT_HOST) {
 545		if (rport->port_cfg->disfall_en.offset) {
 546			rport->host_disconnect = true;
 547			ret = rockchip_usb2phy_enable_host_disc_irq(rphy, rport, true);
 548			if (ret) {
 549				dev_err(rphy->dev, "failed to enable disconnect irq\n");
 550				goto out;
 551			}
 552		}
 553
 554		/* clear linestate and enable linestate detect irq */
 555		ret = property_enable(rphy->grf,
 556				      &rport->port_cfg->ls_det_clr, true);
 557		if (ret)
 558			goto out;
 559
 560		ret = property_enable(rphy->grf,
 561				      &rport->port_cfg->ls_det_en, true);
 562		if (ret)
 563			goto out;
 564
 565		schedule_delayed_work(&rport->sm_work, SCHEDULE_DELAY);
 566	}
 567
 568out:
 569	mutex_unlock(&rport->mutex);
 570	return ret;
 571}
 572
 573static int rockchip_usb2phy_power_on(struct phy *phy)
 574{
 575	struct rockchip_usb2phy_port *rport = phy_get_drvdata(phy);
 576	struct rockchip_usb2phy *rphy = dev_get_drvdata(phy->dev.parent);
 577	struct regmap *base = get_reg_base(rphy);
 578	int ret;
 579
 580	dev_dbg(&rport->phy->dev, "port power on\n");
 581
 582	if (!rport->suspended)
 583		return 0;
 584
 585	ret = clk_prepare_enable(rphy->clk480m);
 586	if (ret)
 587		return ret;
 588
 589	ret = property_enable(base, &rport->port_cfg->phy_sus, false);
 590	if (ret) {
 591		clk_disable_unprepare(rphy->clk480m);
 592		return ret;
 593	}
 594
 595	/*
 596	 * For rk3588, it needs to reset phy when exit from
 597	 * suspend mode with common_on_n 1'b1(aka REFCLK_LOGIC,
 598	 * Bias, and PLL blocks are powered down) for lower
 599	 * power consumption. If you don't want to reset phy,
 600	 * please keep the common_on_n 1'b0 to set these blocks
 601	 * remain powered.
 602	 */
 603	ret = rockchip_usb2phy_reset(rphy);
 604	if (ret)
 605		return ret;
 606
 607	/* waiting for the utmi_clk to become stable */
 608	usleep_range(1500, 2000);
 609
 610	rport->suspended = false;
 611	return 0;
 612}
 613
 614static int rockchip_usb2phy_power_off(struct phy *phy)
 615{
 616	struct rockchip_usb2phy_port *rport = phy_get_drvdata(phy);
 617	struct rockchip_usb2phy *rphy = dev_get_drvdata(phy->dev.parent);
 618	struct regmap *base = get_reg_base(rphy);
 619	int ret;
 620
 621	dev_dbg(&rport->phy->dev, "port power off\n");
 622
 623	if (rport->suspended)
 624		return 0;
 625
 626	ret = property_enable(base, &rport->port_cfg->phy_sus, true);
 627	if (ret)
 628		return ret;
 629
 630	rport->suspended = true;
 631	clk_disable_unprepare(rphy->clk480m);
 632
 633	return 0;
 634}
 635
 636static int rockchip_usb2phy_exit(struct phy *phy)
 637{
 638	struct rockchip_usb2phy_port *rport = phy_get_drvdata(phy);
 639
 640	if (rport->port_id == USB2PHY_PORT_OTG &&
 641	    rport->mode != USB_DR_MODE_HOST &&
 642	    rport->mode != USB_DR_MODE_UNKNOWN) {
 643		cancel_delayed_work_sync(&rport->otg_sm_work);
 644		cancel_delayed_work_sync(&rport->chg_work);
 645	} else if (rport->port_id == USB2PHY_PORT_HOST)
 646		cancel_delayed_work_sync(&rport->sm_work);
 647
 648	return 0;
 649}
 650
 651static const struct phy_ops rockchip_usb2phy_ops = {
 652	.init		= rockchip_usb2phy_init,
 653	.exit		= rockchip_usb2phy_exit,
 654	.power_on	= rockchip_usb2phy_power_on,
 655	.power_off	= rockchip_usb2phy_power_off,
 656	.owner		= THIS_MODULE,
 657};
 658
 659static void rockchip_usb2phy_otg_sm_work(struct work_struct *work)
 660{
 661	struct rockchip_usb2phy_port *rport =
 662		container_of(work, struct rockchip_usb2phy_port,
 663			     otg_sm_work.work);
 664	struct rockchip_usb2phy *rphy = dev_get_drvdata(rport->phy->dev.parent);
 665	static unsigned int cable;
 666	unsigned long delay;
 667	bool vbus_attach, sch_work, notify_charger;
 668
 669	vbus_attach = property_enabled(rphy->grf,
 670				       &rport->port_cfg->utmi_bvalid);
 671
 672	sch_work = false;
 673	notify_charger = false;
 674	delay = OTG_SCHEDULE_DELAY;
 675	dev_dbg(&rport->phy->dev, "%s otg sm work\n",
 676		usb_otg_state_string(rport->state));
 677
 678	switch (rport->state) {
 679	case OTG_STATE_UNDEFINED:
 680		rport->state = OTG_STATE_B_IDLE;
 681		if (!vbus_attach)
 682			rockchip_usb2phy_power_off(rport->phy);
 683		fallthrough;
 684	case OTG_STATE_B_IDLE:
 685		if (extcon_get_state(rphy->edev, EXTCON_USB_HOST) > 0) {
 686			dev_dbg(&rport->phy->dev, "usb otg host connect\n");
 687			rport->state = OTG_STATE_A_HOST;
 688			rockchip_usb2phy_power_on(rport->phy);
 689			return;
 690		} else if (vbus_attach) {
 691			dev_dbg(&rport->phy->dev, "vbus_attach\n");
 692			switch (rphy->chg_state) {
 693			case USB_CHG_STATE_UNDEFINED:
 694				schedule_delayed_work(&rport->chg_work, 0);
 695				return;
 696			case USB_CHG_STATE_DETECTED:
 697				switch (rphy->chg_type) {
 698				case POWER_SUPPLY_TYPE_USB:
 699					dev_dbg(&rport->phy->dev, "sdp cable is connected\n");
 700					rockchip_usb2phy_power_on(rport->phy);
 701					rport->state = OTG_STATE_B_PERIPHERAL;
 702					notify_charger = true;
 703					sch_work = true;
 704					cable = EXTCON_CHG_USB_SDP;
 705					break;
 706				case POWER_SUPPLY_TYPE_USB_DCP:
 707					dev_dbg(&rport->phy->dev, "dcp cable is connected\n");
 708					rockchip_usb2phy_power_off(rport->phy);
 709					notify_charger = true;
 710					sch_work = true;
 711					cable = EXTCON_CHG_USB_DCP;
 712					break;
 713				case POWER_SUPPLY_TYPE_USB_CDP:
 714					dev_dbg(&rport->phy->dev, "cdp cable is connected\n");
 715					rockchip_usb2phy_power_on(rport->phy);
 716					rport->state = OTG_STATE_B_PERIPHERAL;
 717					notify_charger = true;
 718					sch_work = true;
 719					cable = EXTCON_CHG_USB_CDP;
 720					break;
 721				default:
 722					break;
 723				}
 724				break;
 725			default:
 726				break;
 727			}
 728		} else {
 729			notify_charger = true;
 730			rphy->chg_state = USB_CHG_STATE_UNDEFINED;
 731			rphy->chg_type = POWER_SUPPLY_TYPE_UNKNOWN;
 732		}
 733
 734		if (rport->vbus_attached != vbus_attach) {
 735			rport->vbus_attached = vbus_attach;
 736
 737			if (notify_charger && rphy->edev) {
 738				extcon_set_state_sync(rphy->edev,
 739							cable, vbus_attach);
 740				if (cable == EXTCON_CHG_USB_SDP)
 741					extcon_set_state_sync(rphy->edev,
 742							      EXTCON_USB,
 743							      vbus_attach);
 744			}
 745		}
 746		break;
 747	case OTG_STATE_B_PERIPHERAL:
 748		if (!vbus_attach) {
 749			dev_dbg(&rport->phy->dev, "usb disconnect\n");
 750			rphy->chg_state = USB_CHG_STATE_UNDEFINED;
 751			rphy->chg_type = POWER_SUPPLY_TYPE_UNKNOWN;
 752			rport->state = OTG_STATE_B_IDLE;
 753			delay = 0;
 754			rockchip_usb2phy_power_off(rport->phy);
 755		}
 756		sch_work = true;
 757		break;
 758	case OTG_STATE_A_HOST:
 759		if (extcon_get_state(rphy->edev, EXTCON_USB_HOST) == 0) {
 760			dev_dbg(&rport->phy->dev, "usb otg host disconnect\n");
 761			rport->state = OTG_STATE_B_IDLE;
 762			rockchip_usb2phy_power_off(rport->phy);
 763		}
 764		break;
 765	default:
 766		break;
 767	}
 768
 769	if (sch_work)
 770		schedule_delayed_work(&rport->otg_sm_work, delay);
 771}
 772
 773static const char *chg_to_string(enum power_supply_type chg_type)
 774{
 775	switch (chg_type) {
 776	case POWER_SUPPLY_TYPE_USB:
 777		return "USB_SDP_CHARGER";
 778	case POWER_SUPPLY_TYPE_USB_DCP:
 779		return "USB_DCP_CHARGER";
 780	case POWER_SUPPLY_TYPE_USB_CDP:
 781		return "USB_CDP_CHARGER";
 782	default:
 783		return "INVALID_CHARGER";
 784	}
 785}
 786
 787static void rockchip_chg_enable_dcd(struct rockchip_usb2phy *rphy,
 788				    bool en)
 789{
 790	struct regmap *base = get_reg_base(rphy);
 791
 792	property_enable(base, &rphy->phy_cfg->chg_det.rdm_pdwn_en, en);
 793	property_enable(base, &rphy->phy_cfg->chg_det.idp_src_en, en);
 794}
 795
 796static void rockchip_chg_enable_primary_det(struct rockchip_usb2phy *rphy,
 797					    bool en)
 798{
 799	struct regmap *base = get_reg_base(rphy);
 800
 801	property_enable(base, &rphy->phy_cfg->chg_det.vdp_src_en, en);
 802	property_enable(base, &rphy->phy_cfg->chg_det.idm_sink_en, en);
 803}
 804
 805static void rockchip_chg_enable_secondary_det(struct rockchip_usb2phy *rphy,
 806					      bool en)
 807{
 808	struct regmap *base = get_reg_base(rphy);
 809
 810	property_enable(base, &rphy->phy_cfg->chg_det.vdm_src_en, en);
 811	property_enable(base, &rphy->phy_cfg->chg_det.idp_sink_en, en);
 812}
 813
 814#define CHG_DCD_POLL_TIME	(100 * HZ / 1000)
 815#define CHG_DCD_MAX_RETRIES	6
 816#define CHG_PRIMARY_DET_TIME	(40 * HZ / 1000)
 817#define CHG_SECONDARY_DET_TIME	(40 * HZ / 1000)
 818static void rockchip_chg_detect_work(struct work_struct *work)
 819{
 820	struct rockchip_usb2phy_port *rport =
 821		container_of(work, struct rockchip_usb2phy_port, chg_work.work);
 822	struct rockchip_usb2phy *rphy = dev_get_drvdata(rport->phy->dev.parent);
 823	struct regmap *base = get_reg_base(rphy);
 824	bool is_dcd, tmout, vout;
 825	unsigned long delay;
 826
 827	dev_dbg(&rport->phy->dev, "chg detection work state = %d\n",
 828		rphy->chg_state);
 829	switch (rphy->chg_state) {
 830	case USB_CHG_STATE_UNDEFINED:
 831		if (!rport->suspended)
 832			rockchip_usb2phy_power_off(rport->phy);
 833		/* put the controller in non-driving mode */
 834		property_enable(base, &rphy->phy_cfg->chg_det.opmode, false);
 835		/* Start DCD processing stage 1 */
 836		rockchip_chg_enable_dcd(rphy, true);
 837		rphy->chg_state = USB_CHG_STATE_WAIT_FOR_DCD;
 838		rphy->dcd_retries = 0;
 839		delay = CHG_DCD_POLL_TIME;
 840		break;
 841	case USB_CHG_STATE_WAIT_FOR_DCD:
 842		/* get data contact detection status */
 843		is_dcd = property_enabled(rphy->grf,
 844					  &rphy->phy_cfg->chg_det.dp_det);
 845		tmout = ++rphy->dcd_retries == CHG_DCD_MAX_RETRIES;
 846		/* stage 2 */
 847		if (is_dcd || tmout) {
 848			/* stage 4 */
 849			/* Turn off DCD circuitry */
 850			rockchip_chg_enable_dcd(rphy, false);
 851			/* Voltage Source on DP, Probe on DM */
 852			rockchip_chg_enable_primary_det(rphy, true);
 853			delay = CHG_PRIMARY_DET_TIME;
 854			rphy->chg_state = USB_CHG_STATE_DCD_DONE;
 855		} else {
 856			/* stage 3 */
 857			delay = CHG_DCD_POLL_TIME;
 858		}
 859		break;
 860	case USB_CHG_STATE_DCD_DONE:
 861		vout = property_enabled(rphy->grf,
 862					&rphy->phy_cfg->chg_det.cp_det);
 863		rockchip_chg_enable_primary_det(rphy, false);
 864		if (vout) {
 865			/* Voltage Source on DM, Probe on DP  */
 866			rockchip_chg_enable_secondary_det(rphy, true);
 867			delay = CHG_SECONDARY_DET_TIME;
 868			rphy->chg_state = USB_CHG_STATE_PRIMARY_DONE;
 869		} else {
 870			if (rphy->dcd_retries == CHG_DCD_MAX_RETRIES) {
 871				/* floating charger found */
 872				rphy->chg_type = POWER_SUPPLY_TYPE_USB_DCP;
 873				rphy->chg_state = USB_CHG_STATE_DETECTED;
 874				delay = 0;
 875			} else {
 876				rphy->chg_type = POWER_SUPPLY_TYPE_USB;
 877				rphy->chg_state = USB_CHG_STATE_DETECTED;
 878				delay = 0;
 879			}
 880		}
 881		break;
 882	case USB_CHG_STATE_PRIMARY_DONE:
 883		vout = property_enabled(rphy->grf,
 884					&rphy->phy_cfg->chg_det.dcp_det);
 885		/* Turn off voltage source */
 886		rockchip_chg_enable_secondary_det(rphy, false);
 887		if (vout)
 888			rphy->chg_type = POWER_SUPPLY_TYPE_USB_DCP;
 889		else
 890			rphy->chg_type = POWER_SUPPLY_TYPE_USB_CDP;
 891		fallthrough;
 892	case USB_CHG_STATE_SECONDARY_DONE:
 893		rphy->chg_state = USB_CHG_STATE_DETECTED;
 894		fallthrough;
 895	case USB_CHG_STATE_DETECTED:
 896		/* put the controller in normal mode */
 897		property_enable(base, &rphy->phy_cfg->chg_det.opmode, true);
 898		rockchip_usb2phy_otg_sm_work(&rport->otg_sm_work.work);
 899		dev_dbg(&rport->phy->dev, "charger = %s\n",
 900			 chg_to_string(rphy->chg_type));
 901		return;
 902	default:
 903		return;
 904	}
 905
 906	schedule_delayed_work(&rport->chg_work, delay);
 907}
 908
 909/*
 910 * The function manage host-phy port state and suspend/resume phy port
 911 * to save power.
 912 *
 913 * we rely on utmi_linestate and utmi_hostdisconnect to identify whether
 914 * devices is disconnect or not. Besides, we do not need care it is FS/LS
 915 * disconnected or HS disconnected, actually, we just only need get the
 916 * device is disconnected at last through rearm the delayed work,
 917 * to suspend the phy port in _PHY_STATE_DISCONNECT_ case.
 918 *
 919 * NOTE: It may invoke *phy_powr_off or *phy_power_on which will invoke
 920 * some clk related APIs, so do not invoke it from interrupt context directly.
 921 */
 922static void rockchip_usb2phy_sm_work(struct work_struct *work)
 923{
 924	struct rockchip_usb2phy_port *rport =
 925		container_of(work, struct rockchip_usb2phy_port, sm_work.work);
 926	struct rockchip_usb2phy *rphy = dev_get_drvdata(rport->phy->dev.parent);
 927	unsigned int sh, ul, uhd, state;
 
 
 928	unsigned int ul_mask, uhd_mask;
 929	int ret;
 930
 931	mutex_lock(&rport->mutex);
 932
 933	ret = regmap_read(rphy->grf, rport->port_cfg->utmi_ls.offset, &ul);
 934	if (ret < 0)
 935		goto next_schedule;
 936
 
 
 
 
 
 
 937	ul_mask = GENMASK(rport->port_cfg->utmi_ls.bitend,
 938			  rport->port_cfg->utmi_ls.bitstart);
 939
 940	if (rport->port_cfg->utmi_hstdet.offset) {
 941		ret = regmap_read(rphy->grf, rport->port_cfg->utmi_hstdet.offset, &uhd);
 942		if (ret < 0)
 943			goto next_schedule;
 944
 945		uhd_mask = GENMASK(rport->port_cfg->utmi_hstdet.bitend,
 946				   rport->port_cfg->utmi_hstdet.bitstart);
 947
 948		sh = rport->port_cfg->utmi_hstdet.bitend -
 949		     rport->port_cfg->utmi_hstdet.bitstart + 1;
 950		/* stitch on utmi_ls and utmi_hstdet as phy state */
 951		state = ((uhd & uhd_mask) >> rport->port_cfg->utmi_hstdet.bitstart) |
 952			(((ul & ul_mask) >> rport->port_cfg->utmi_ls.bitstart) << sh);
 953	} else {
 954		state = ((ul & ul_mask) >> rport->port_cfg->utmi_ls.bitstart) << 1 |
 955			rport->host_disconnect;
 956	}
 957
 958	switch (state) {
 959	case PHY_STATE_HS_ONLINE:
 960		dev_dbg(&rport->phy->dev, "HS online\n");
 961		break;
 962	case PHY_STATE_FS_LS_ONLINE:
 963		/*
 964		 * For FS/LS device, the online state share with connect state
 965		 * from utmi_ls and utmi_hstdet register, so we distinguish
 966		 * them via suspended flag.
 967		 *
 968		 * Plus, there are two cases, one is D- Line pull-up, and D+
 969		 * line pull-down, the state is 4; another is D+ line pull-up,
 970		 * and D- line pull-down, the state is 2.
 971		 */
 972		if (!rport->suspended) {
 973			/* D- line pull-up, D+ line pull-down */
 974			dev_dbg(&rport->phy->dev, "FS/LS online\n");
 975			break;
 976		}
 977		fallthrough;
 978	case PHY_STATE_CONNECT:
 979		if (rport->suspended) {
 980			dev_dbg(&rport->phy->dev, "Connected\n");
 981			rockchip_usb2phy_power_on(rport->phy);
 982			rport->suspended = false;
 983		} else {
 984			/* D+ line pull-up, D- line pull-down */
 985			dev_dbg(&rport->phy->dev, "FS/LS online\n");
 986		}
 987		break;
 988	case PHY_STATE_DISCONNECT:
 989		if (!rport->suspended) {
 990			dev_dbg(&rport->phy->dev, "Disconnected\n");
 991			rockchip_usb2phy_power_off(rport->phy);
 992			rport->suspended = true;
 993		}
 994
 995		/*
 996		 * activate the linestate detection to get the next device
 997		 * plug-in irq.
 998		 */
 999		property_enable(rphy->grf, &rport->port_cfg->ls_det_clr, true);
1000		property_enable(rphy->grf, &rport->port_cfg->ls_det_en, true);
1001
1002		/*
1003		 * we don't need to rearm the delayed work when the phy port
1004		 * is suspended.
1005		 */
1006		mutex_unlock(&rport->mutex);
1007		return;
1008	default:
1009		dev_dbg(&rport->phy->dev, "unknown phy state\n");
1010		break;
1011	}
1012
1013next_schedule:
1014	mutex_unlock(&rport->mutex);
1015	schedule_delayed_work(&rport->sm_work, SCHEDULE_DELAY);
1016}
1017
1018static irqreturn_t rockchip_usb2phy_linestate_irq(int irq, void *data)
1019{
1020	struct rockchip_usb2phy_port *rport = data;
1021	struct rockchip_usb2phy *rphy = dev_get_drvdata(rport->phy->dev.parent);
1022
1023	if (!property_enabled(rphy->grf, &rport->port_cfg->ls_det_st))
1024		return IRQ_NONE;
1025
1026	mutex_lock(&rport->mutex);
1027
1028	/* disable linestate detect irq and clear its status */
1029	property_enable(rphy->grf, &rport->port_cfg->ls_det_en, false);
1030	property_enable(rphy->grf, &rport->port_cfg->ls_det_clr, true);
1031
1032	mutex_unlock(&rport->mutex);
1033
1034	/*
1035	 * In this case for host phy port, a new device is plugged in,
1036	 * meanwhile, if the phy port is suspended, we need rearm the work to
1037	 * resume it and mange its states; otherwise, we do nothing about that.
1038	 */
1039	if (rport->suspended && rport->port_id == USB2PHY_PORT_HOST)
1040		rockchip_usb2phy_sm_work(&rport->sm_work.work);
1041
1042	return IRQ_HANDLED;
1043}
1044
1045static irqreturn_t rockchip_usb2phy_bvalid_irq(int irq, void *data)
1046{
1047	struct rockchip_usb2phy_port *rport = data;
1048	struct rockchip_usb2phy *rphy = dev_get_drvdata(rport->phy->dev.parent);
1049
1050	if (!property_enabled(rphy->grf, &rport->port_cfg->bvalid_det_st))
1051		return IRQ_NONE;
1052
1053	/* clear bvalid detect irq pending status */
1054	property_enable(rphy->grf, &rport->port_cfg->bvalid_det_clr, true);
1055
1056	rockchip_usb2phy_otg_sm_work(&rport->otg_sm_work.work);
1057
1058	return IRQ_HANDLED;
1059}
1060
1061static irqreturn_t rockchip_usb2phy_id_irq(int irq, void *data)
1062{
1063	struct rockchip_usb2phy_port *rport = data;
1064	struct rockchip_usb2phy *rphy = dev_get_drvdata(rport->phy->dev.parent);
1065	bool id;
1066
1067	if (!property_enabled(rphy->grf, &rport->port_cfg->idfall_det_st) &&
1068	    !property_enabled(rphy->grf, &rport->port_cfg->idrise_det_st))
1069		return IRQ_NONE;
1070
1071	/* clear id detect irq pending status */
1072	if (property_enabled(rphy->grf, &rport->port_cfg->idfall_det_st))
1073		property_enable(rphy->grf, &rport->port_cfg->idfall_det_clr, true);
1074
1075	if (property_enabled(rphy->grf, &rport->port_cfg->idrise_det_st))
1076		property_enable(rphy->grf, &rport->port_cfg->idrise_det_clr, true);
1077
1078	id = property_enabled(rphy->grf, &rport->port_cfg->utmi_id);
1079	extcon_set_state_sync(rphy->edev, EXTCON_USB_HOST, !id);
1080
1081	return IRQ_HANDLED;
1082}
1083
1084static irqreturn_t rockchip_usb2phy_otg_mux_irq(int irq, void *data)
1085{
1086	irqreturn_t ret = IRQ_NONE;
1087
1088	ret |= rockchip_usb2phy_bvalid_irq(irq, data);
1089	ret |= rockchip_usb2phy_id_irq(irq, data);
1090
1091	return ret;
1092}
1093
1094static irqreturn_t rockchip_usb2phy_host_disc_irq(int irq, void *data)
1095{
1096	struct rockchip_usb2phy_port *rport = data;
1097	struct rockchip_usb2phy *rphy = dev_get_drvdata(rport->phy->dev.parent);
1098
1099	if (!property_enabled(rphy->grf, &rport->port_cfg->disfall_st) &&
1100	    !property_enabled(rphy->grf, &rport->port_cfg->disrise_st))
1101		return IRQ_NONE;
1102
1103	mutex_lock(&rport->mutex);
1104
1105	/* clear disconnect fall or rise detect irq pending status */
1106	if (property_enabled(rphy->grf, &rport->port_cfg->disfall_st)) {
1107		property_enable(rphy->grf, &rport->port_cfg->disfall_clr, true);
1108		rport->host_disconnect = false;
1109	} else if (property_enabled(rphy->grf, &rport->port_cfg->disrise_st)) {
1110		property_enable(rphy->grf, &rport->port_cfg->disrise_clr, true);
1111		rport->host_disconnect = true;
1112	}
1113
1114	mutex_unlock(&rport->mutex);
1115
1116	return IRQ_HANDLED;
1117}
1118
1119static irqreturn_t rockchip_usb2phy_irq(int irq, void *data)
1120{
1121	struct rockchip_usb2phy *rphy = data;
1122	struct rockchip_usb2phy_port *rport;
1123	irqreturn_t ret = IRQ_NONE;
1124	unsigned int index;
1125
1126	for (index = 0; index < rphy->phy_cfg->num_ports; index++) {
1127		rport = &rphy->ports[index];
1128		if (!rport->phy)
1129			continue;
1130
1131		if (rport->port_id == USB2PHY_PORT_HOST &&
1132		    rport->port_cfg->disfall_en.offset)
1133			ret |= rockchip_usb2phy_host_disc_irq(irq, rport);
1134
1135		switch (rport->port_id) {
1136		case USB2PHY_PORT_OTG:
1137			if (rport->mode != USB_DR_MODE_HOST &&
1138			    rport->mode != USB_DR_MODE_UNKNOWN)
1139				ret |= rockchip_usb2phy_otg_mux_irq(irq, rport);
1140			break;
1141		case USB2PHY_PORT_HOST:
1142			ret |= rockchip_usb2phy_linestate_irq(irq, rport);
1143			break;
1144		}
1145	}
1146
1147	return ret;
1148}
1149
1150static int rockchip_usb2phy_port_irq_init(struct rockchip_usb2phy *rphy,
1151					  struct rockchip_usb2phy_port *rport,
1152					  struct device_node *child_np)
1153{
1154	int ret;
1155
1156	/*
1157	 * If the usb2 phy used combined irq for otg and host port,
1158	 * don't need to init otg and host port irq separately.
1159	 */
1160	if (rphy->irq > 0)
1161		return 0;
1162
1163	switch (rport->port_id) {
1164	case USB2PHY_PORT_HOST:
1165		rport->ls_irq = of_irq_get_byname(child_np, "linestate");
1166		if (rport->ls_irq < 0) {
1167			dev_err(rphy->dev, "no linestate irq provided\n");
1168			return rport->ls_irq;
1169		}
1170
1171		ret = devm_request_threaded_irq(rphy->dev, rport->ls_irq, NULL,
1172						rockchip_usb2phy_linestate_irq,
1173						IRQF_ONESHOT,
1174						"rockchip_usb2phy", rport);
1175		if (ret) {
1176			dev_err(rphy->dev, "failed to request linestate irq handle\n");
1177			return ret;
1178		}
1179		break;
1180	case USB2PHY_PORT_OTG:
1181		/*
1182		 * Some SoCs use one interrupt with otg-id/otg-bvalid/linestate
1183		 * interrupts muxed together, so probe the otg-mux interrupt first,
1184		 * if not found, then look for the regular interrupts one by one.
1185		 */
1186		rport->otg_mux_irq = of_irq_get_byname(child_np, "otg-mux");
1187		if (rport->otg_mux_irq > 0) {
1188			ret = devm_request_threaded_irq(rphy->dev, rport->otg_mux_irq,
1189							NULL,
1190							rockchip_usb2phy_otg_mux_irq,
1191							IRQF_ONESHOT,
1192							"rockchip_usb2phy_otg",
1193							rport);
1194			if (ret) {
1195				dev_err(rphy->dev,
1196					"failed to request otg-mux irq handle\n");
1197				return ret;
1198			}
1199		} else {
1200			rport->bvalid_irq = of_irq_get_byname(child_np, "otg-bvalid");
1201			if (rport->bvalid_irq < 0) {
1202				dev_err(rphy->dev, "no vbus valid irq provided\n");
1203				ret = rport->bvalid_irq;
1204				return ret;
1205			}
1206
1207			ret = devm_request_threaded_irq(rphy->dev, rport->bvalid_irq,
1208							NULL,
1209							rockchip_usb2phy_bvalid_irq,
1210							IRQF_ONESHOT,
1211							"rockchip_usb2phy_bvalid",
1212							rport);
1213			if (ret) {
1214				dev_err(rphy->dev,
1215					"failed to request otg-bvalid irq handle\n");
1216				return ret;
1217			}
1218
1219			rport->id_irq = of_irq_get_byname(child_np, "otg-id");
1220			if (rport->id_irq < 0) {
1221				dev_err(rphy->dev, "no otg-id irq provided\n");
1222				ret = rport->id_irq;
1223				return ret;
1224			}
1225
1226			ret = devm_request_threaded_irq(rphy->dev, rport->id_irq,
1227							NULL,
1228							rockchip_usb2phy_id_irq,
1229							IRQF_ONESHOT,
1230							"rockchip_usb2phy_id",
1231							rport);
1232			if (ret) {
1233				dev_err(rphy->dev,
1234					"failed to request otg-id irq handle\n");
1235				return ret;
1236			}
1237		}
1238		break;
1239	default:
1240		return -EINVAL;
1241	}
1242
1243	return 0;
1244}
1245
1246static int rockchip_usb2phy_host_port_init(struct rockchip_usb2phy *rphy,
1247					   struct rockchip_usb2phy_port *rport,
1248					   struct device_node *child_np)
1249{
1250	int ret;
1251
1252	rport->port_id = USB2PHY_PORT_HOST;
1253	rport->port_cfg = &rphy->phy_cfg->port_cfgs[USB2PHY_PORT_HOST];
1254	rport->suspended = true;
1255
1256	mutex_init(&rport->mutex);
1257	INIT_DELAYED_WORK(&rport->sm_work, rockchip_usb2phy_sm_work);
1258
1259	ret = rockchip_usb2phy_port_irq_init(rphy, rport, child_np);
1260	if (ret) {
1261		dev_err(rphy->dev, "failed to setup host irq\n");
1262		return ret;
1263	}
1264
1265	return 0;
1266}
1267
1268static int rockchip_otg_event(struct notifier_block *nb,
1269			      unsigned long event, void *ptr)
1270{
1271	struct rockchip_usb2phy_port *rport =
1272		container_of(nb, struct rockchip_usb2phy_port, event_nb);
1273
1274	schedule_delayed_work(&rport->otg_sm_work, OTG_SCHEDULE_DELAY);
1275
1276	return NOTIFY_DONE;
1277}
1278
1279static int rockchip_usb2phy_otg_port_init(struct rockchip_usb2phy *rphy,
1280					  struct rockchip_usb2phy_port *rport,
1281					  struct device_node *child_np)
1282{
1283	int ret, id;
1284
1285	rport->port_id = USB2PHY_PORT_OTG;
1286	rport->port_cfg = &rphy->phy_cfg->port_cfgs[USB2PHY_PORT_OTG];
1287	rport->state = OTG_STATE_UNDEFINED;
1288
1289	/*
1290	 * set suspended flag to true, but actually don't
1291	 * put phy in suspend mode, it aims to enable usb
1292	 * phy and clock in power_on() called by usb controller
1293	 * driver during probe.
1294	 */
1295	rport->suspended = true;
1296	rport->vbus_attached = false;
1297
1298	mutex_init(&rport->mutex);
1299
1300	rport->mode = of_usb_get_dr_mode_by_phy(child_np, -1);
1301	if (rport->mode == USB_DR_MODE_HOST ||
1302	    rport->mode == USB_DR_MODE_UNKNOWN) {
1303		ret = 0;
1304		goto out;
1305	}
1306
1307	INIT_DELAYED_WORK(&rport->chg_work, rockchip_chg_detect_work);
1308	INIT_DELAYED_WORK(&rport->otg_sm_work, rockchip_usb2phy_otg_sm_work);
1309
1310	ret = rockchip_usb2phy_port_irq_init(rphy, rport, child_np);
1311	if (ret) {
1312		dev_err(rphy->dev, "failed to init irq for host port\n");
1313		goto out;
1314	}
1315
1316	if (!IS_ERR(rphy->edev)) {
1317		rport->event_nb.notifier_call = rockchip_otg_event;
1318
1319		ret = devm_extcon_register_notifier(rphy->dev, rphy->edev,
1320					EXTCON_USB_HOST, &rport->event_nb);
1321		if (ret) {
1322			dev_err(rphy->dev, "register USB HOST notifier failed\n");
1323			goto out;
1324		}
1325
1326		if (!of_property_read_bool(rphy->dev->of_node, "extcon")) {
1327			/* do initial sync of usb state */
1328			id = property_enabled(rphy->grf, &rport->port_cfg->utmi_id);
1329			extcon_set_state_sync(rphy->edev, EXTCON_USB_HOST, !id);
1330		}
1331	}
1332
1333out:
1334	return ret;
1335}
1336
1337static int rockchip_usb2phy_probe(struct platform_device *pdev)
1338{
1339	struct device *dev = &pdev->dev;
1340	struct device_node *np = dev->of_node;
1341	struct device_node *child_np;
1342	struct phy_provider *provider;
1343	struct rockchip_usb2phy *rphy;
1344	const struct rockchip_usb2phy_cfg *phy_cfgs;
 
1345	unsigned int reg;
1346	int index = 0, ret;
1347
1348	rphy = devm_kzalloc(dev, sizeof(*rphy), GFP_KERNEL);
1349	if (!rphy)
1350		return -ENOMEM;
1351
 
 
 
 
 
 
1352	if (!dev->parent || !dev->parent->of_node) {
1353		rphy->grf = syscon_regmap_lookup_by_phandle(np, "rockchip,usbgrf");
1354		if (IS_ERR(rphy->grf)) {
1355			dev_err(dev, "failed to locate usbgrf\n");
1356			return PTR_ERR(rphy->grf);
1357		}
1358	} else {
 
 
1359		rphy->grf = syscon_node_to_regmap(dev->parent->of_node);
1360		if (IS_ERR(rphy->grf))
1361			return PTR_ERR(rphy->grf);
1362	}
1363
1364	if (of_device_is_compatible(np, "rockchip,rv1108-usb2phy")) {
1365		rphy->usbgrf =
1366			syscon_regmap_lookup_by_phandle(dev->of_node,
1367							"rockchip,usbgrf");
1368		if (IS_ERR(rphy->usbgrf))
1369			return PTR_ERR(rphy->usbgrf);
1370	} else {
1371		rphy->usbgrf = NULL;
1372	}
1373
1374	if (of_property_read_u32_index(np, "reg", 0, &reg)) {
1375		dev_err(dev, "the reg property is not assigned in %pOFn node\n", np);
 
1376		return -EINVAL;
1377	}
1378
1379	/* support address_cells=2 */
1380	if (of_property_count_u32_elems(np, "reg") > 2 && reg == 0) {
1381		if (of_property_read_u32_index(np, "reg", 1, &reg)) {
1382			dev_err(dev, "the reg property is not assigned in %pOFn node\n", np);
 
1383			return -EINVAL;
1384		}
1385	}
1386
1387	rphy->dev = dev;
1388	phy_cfgs = device_get_match_data(dev);
1389	rphy->chg_state = USB_CHG_STATE_UNDEFINED;
1390	rphy->chg_type = POWER_SUPPLY_TYPE_UNKNOWN;
1391	rphy->irq = platform_get_irq_optional(pdev, 0);
1392	platform_set_drvdata(pdev, rphy);
1393
1394	if (!phy_cfgs)
1395		return dev_err_probe(dev, -EINVAL, "phy configs are not assigned!\n");
1396
1397	ret = rockchip_usb2phy_extcon_register(rphy);
1398	if (ret)
1399		return ret;
1400
1401	/* find a proper config that can be matched with the DT */
1402	do {
 
1403		if (phy_cfgs[index].reg == reg) {
1404			rphy->phy_cfg = &phy_cfgs[index];
1405			break;
1406		}
1407
1408		++index;
1409	} while (phy_cfgs[index].reg);
1410
1411	if (!rphy->phy_cfg) {
1412		dev_err(dev, "could not find phy config for reg=0x%08x\n", reg);
 
1413		return -EINVAL;
1414	}
1415
1416	rphy->phy_reset = devm_reset_control_get_optional(dev, "phy");
1417	if (IS_ERR(rphy->phy_reset))
1418		return PTR_ERR(rphy->phy_reset);
1419
1420	ret = devm_clk_bulk_get_all(dev, &rphy->clks);
1421	if (ret == -EPROBE_DEFER)
1422		return dev_err_probe(&pdev->dev, -EPROBE_DEFER,
1423				     "failed to get phy clock\n");
1424
1425	/* Clocks are optional */
1426	rphy->num_clks = ret < 0 ? 0 : ret;
1427
1428	ret = rockchip_usb2phy_clk480m_register(rphy);
1429	if (ret)
1430		return dev_err_probe(dev, ret, "failed to register 480m output clock\n");
1431
1432	ret = clk_bulk_prepare_enable(rphy->num_clks, rphy->clks);
1433	if (ret)
1434		return dev_err_probe(dev, ret, "failed to enable phy clock\n");
1435
1436	ret = devm_add_action_or_reset(dev, rockchip_usb2phy_clk_bulk_disable, rphy);
1437	if (ret)
1438		return ret;
1439
1440	if (rphy->phy_cfg->phy_tuning) {
1441		ret = rphy->phy_cfg->phy_tuning(rphy);
1442		if (ret)
1443			return ret;
1444	}
1445
1446	index = 0;
1447	for_each_available_child_of_node(np, child_np) {
1448		struct rockchip_usb2phy_port *rport = &rphy->ports[index];
1449		struct phy *phy;
1450
1451		/* This driver aims to support both otg-port and host-port */
1452		if (!of_node_name_eq(child_np, "host-port") &&
1453		    !of_node_name_eq(child_np, "otg-port"))
1454			goto next_child;
1455
1456		phy = devm_phy_create(dev, child_np, &rockchip_usb2phy_ops);
1457		if (IS_ERR(phy)) {
1458			ret = dev_err_probe(dev, PTR_ERR(phy), "failed to create phy\n");
 
1459			goto put_child;
1460		}
1461
1462		rport->phy = phy;
1463		phy_set_drvdata(rport->phy, rport);
1464
1465		/* initialize otg/host port separately */
1466		if (of_node_name_eq(child_np, "host-port")) {
1467			ret = rockchip_usb2phy_host_port_init(rphy, rport, child_np);
 
1468			if (ret)
1469				goto put_child;
1470		} else {
1471			ret = rockchip_usb2phy_otg_port_init(rphy, rport, child_np);
 
1472			if (ret)
1473				goto put_child;
1474		}
1475
1476next_child:
1477		/* to prevent out of boundary */
1478		if (++index >= rphy->phy_cfg->num_ports) {
1479			of_node_put(child_np);
1480			break;
1481		}
1482	}
1483
1484	provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
1485
1486	if (rphy->irq > 0) {
1487		ret = devm_request_threaded_irq(rphy->dev, rphy->irq, NULL,
1488						rockchip_usb2phy_irq,
1489						IRQF_ONESHOT,
1490						"rockchip_usb2phy",
1491						rphy);
1492		if (ret) {
1493			dev_err_probe(rphy->dev, ret, "failed to request usb2phy irq handle\n");
 
1494			goto put_child;
1495		}
1496	}
1497
1498	return PTR_ERR_OR_ZERO(provider);
1499
1500put_child:
1501	of_node_put(child_np);
1502	return ret;
1503}
1504
1505static int rk3128_usb2phy_tuning(struct rockchip_usb2phy *rphy)
1506{
1507	/* Turn off differential receiver in suspend mode */
1508	return regmap_write_bits(rphy->grf, 0x298,
1509				BIT(2) << BIT_WRITEABLE_SHIFT | BIT(2),
1510				BIT(2) << BIT_WRITEABLE_SHIFT | 0);
1511}
1512
1513static int rk3576_usb2phy_tuning(struct rockchip_usb2phy *rphy)
1514{
1515	int ret;
1516	u32 reg = rphy->phy_cfg->reg;
1517
1518	/* Deassert SIDDQ to power on analog block */
1519	ret = regmap_write(rphy->grf, reg + 0x0010, GENMASK(29, 29) | 0x0000);
1520	if (ret)
1521		return ret;
1522
1523	/* Do reset after exit IDDQ mode */
1524	ret = rockchip_usb2phy_reset(rphy);
1525	if (ret)
1526		return ret;
1527
1528	/* HS DC Voltage Level Adjustment 4'b1001 : +5.89% */
1529	ret |= regmap_write(rphy->grf, reg + 0x000c, GENMASK(27, 24) | 0x0900);
1530
1531	/* HS Transmitter Pre-Emphasis Current Control 2'b10 : 2x */
1532	ret |= regmap_write(rphy->grf, reg + 0x0010, GENMASK(20, 19) | 0x0010);
1533
1534	return ret;
1535}
1536
1537static int rk3588_usb2phy_tuning(struct rockchip_usb2phy *rphy)
1538{
1539	int ret;
1540	bool usb3otg = false;
1541	/*
1542	 * utmi_termselect = 1'b1 (en FS terminations)
1543	 * utmi_xcvrselect = 2'b01 (FS transceiver)
1544	 */
1545	int suspend_cfg = 0x14;
1546
1547	if (rphy->phy_cfg->reg == 0x0000 || rphy->phy_cfg->reg == 0x4000) {
1548		/* USB2 config for USB3_0 and USB3_1 */
1549		suspend_cfg |= 0x01; /* utmi_opmode = 2'b01 (no-driving) */
1550		usb3otg = true;
1551	} else if (rphy->phy_cfg->reg == 0x8000 || rphy->phy_cfg->reg == 0xc000) {
1552		/* USB2 config for USB2_0 and USB2_1 */
1553		suspend_cfg |= 0x00; /* utmi_opmode = 2'b00 (normal) */
1554	} else {
1555		return -EINVAL;
1556	}
1557
1558	/* Deassert SIDDQ to power on analog block */
1559	ret = regmap_write(rphy->grf, 0x0008, GENMASK(29, 29) | 0x0000);
1560	if (ret)
1561		return ret;
1562
1563	/* Do reset after exit IDDQ mode */
1564	ret = rockchip_usb2phy_reset(rphy);
1565	if (ret)
1566		return ret;
1567
1568	/* suspend configuration */
1569	ret |= regmap_write(rphy->grf, 0x000c, GENMASK(20, 16) | suspend_cfg);
1570
1571	/* HS DC Voltage Level Adjustment 4'b1001 : +5.89% */
1572	ret |= regmap_write(rphy->grf, 0x0004, GENMASK(27, 24) | 0x0900);
1573
1574	/* HS Transmitter Pre-Emphasis Current Control 2'b10 : 2x */
1575	ret |= regmap_write(rphy->grf, 0x0008, GENMASK(20, 19) | 0x0010);
1576
1577	if (!usb3otg)
1578		return ret;
1579
1580	/* Pullup iddig pin for USB3_0 OTG mode */
1581	ret |= regmap_write(rphy->grf, 0x0010, GENMASK(17, 16) | 0x0003);
1582
1583	return ret;
1584}
1585
1586static const struct rockchip_usb2phy_cfg rk3128_phy_cfgs[] = {
1587	{
1588		.reg = 0x17c,
1589		.num_ports	= 2,
1590		.phy_tuning	= rk3128_usb2phy_tuning,
1591		.clkout_ctl	= { 0x0190, 15, 15, 1, 0 },
1592		.port_cfgs	= {
1593			[USB2PHY_PORT_OTG] = {
1594				.phy_sus	= { 0x017c, 8, 0, 0, 0x1d1 },
1595				.bvalid_det_en	= { 0x017c, 14, 14, 0, 1 },
1596				.bvalid_det_st	= { 0x017c, 15, 15, 0, 1 },
1597				.bvalid_det_clr	= { 0x017c, 15, 15, 0, 1 },
1598				.idfall_det_en  = { 0x01a0, 2, 2, 0, 1 },
1599				.idfall_det_st  = { 0x01a0, 3, 3, 0, 1 },
1600				.idfall_det_clr = { 0x01a0, 3, 3, 0, 1 },
1601				.idrise_det_en  = { 0x01a0, 0, 0, 0, 1 },
1602				.idrise_det_st  = { 0x01a0, 1, 1, 0, 1 },
1603				.idrise_det_clr = { 0x01a0, 1, 1, 0, 1 },
1604				.ls_det_en	= { 0x017c, 12, 12, 0, 1 },
1605				.ls_det_st	= { 0x017c, 13, 13, 0, 1 },
1606				.ls_det_clr	= { 0x017c, 13, 13, 0, 1 },
1607				.utmi_bvalid	= { 0x014c, 5, 5, 0, 1 },
1608				.utmi_id	= { 0x014c, 8, 8, 0, 1 },
1609				.utmi_ls	= { 0x014c, 7, 6, 0, 1 },
1610			},
1611			[USB2PHY_PORT_HOST] = {
1612				.phy_sus	= { 0x0194, 8, 0, 0, 0x1d1 },
1613				.ls_det_en	= { 0x0194, 14, 14, 0, 1 },
1614				.ls_det_st	= { 0x0194, 15, 15, 0, 1 },
1615				.ls_det_clr	= { 0x0194, 15, 15, 0, 1 }
1616			}
1617		},
1618		.chg_det = {
1619			.opmode		= { 0x017c, 3, 0, 5, 1 },
1620			.cp_det		= { 0x02c0, 6, 6, 0, 1 },
1621			.dcp_det	= { 0x02c0, 5, 5, 0, 1 },
1622			.dp_det		= { 0x02c0, 7, 7, 0, 1 },
1623			.idm_sink_en	= { 0x0184, 8, 8, 0, 1 },
1624			.idp_sink_en	= { 0x0184, 7, 7, 0, 1 },
1625			.idp_src_en	= { 0x0184, 9, 9, 0, 1 },
1626			.rdm_pdwn_en	= { 0x0184, 10, 10, 0, 1 },
1627			.vdm_src_en	= { 0x0184, 12, 12, 0, 1 },
1628			.vdp_src_en	= { 0x0184, 11, 11, 0, 1 },
1629		},
1630	},
1631	{ /* sentinel */ }
1632};
1633
1634static const struct rockchip_usb2phy_cfg rk3228_phy_cfgs[] = {
1635	{
1636		.reg = 0x760,
1637		.num_ports	= 2,
1638		.clkout_ctl	= { 0x0768, 4, 4, 1, 0 },
1639		.port_cfgs	= {
1640			[USB2PHY_PORT_OTG] = {
1641				.phy_sus	= { 0x0760, 15, 0, 0, 0x1d1 },
1642				.bvalid_det_en	= { 0x0680, 3, 3, 0, 1 },
1643				.bvalid_det_st	= { 0x0690, 3, 3, 0, 1 },
1644				.bvalid_det_clr	= { 0x06a0, 3, 3, 0, 1 },
1645				.idfall_det_en	= { 0x0680, 6, 6, 0, 1 },
1646				.idfall_det_st	= { 0x0690, 6, 6, 0, 1 },
1647				.idfall_det_clr	= { 0x06a0, 6, 6, 0, 1 },
1648				.idrise_det_en	= { 0x0680, 5, 5, 0, 1 },
1649				.idrise_det_st	= { 0x0690, 5, 5, 0, 1 },
1650				.idrise_det_clr	= { 0x06a0, 5, 5, 0, 1 },
1651				.ls_det_en	= { 0x0680, 2, 2, 0, 1 },
1652				.ls_det_st	= { 0x0690, 2, 2, 0, 1 },
1653				.ls_det_clr	= { 0x06a0, 2, 2, 0, 1 },
1654				.utmi_bvalid	= { 0x0480, 4, 4, 0, 1 },
1655				.utmi_id	= { 0x0480, 1, 1, 0, 1 },
1656				.utmi_ls	= { 0x0480, 3, 2, 0, 1 },
1657			},
1658			[USB2PHY_PORT_HOST] = {
1659				.phy_sus	= { 0x0764, 15, 0, 0, 0x1d1 },
1660				.ls_det_en	= { 0x0680, 4, 4, 0, 1 },
1661				.ls_det_st	= { 0x0690, 4, 4, 0, 1 },
1662				.ls_det_clr	= { 0x06a0, 4, 4, 0, 1 }
1663			}
1664		},
1665		.chg_det = {
1666			.opmode		= { 0x0760, 3, 0, 5, 1 },
1667			.cp_det		= { 0x0884, 4, 4, 0, 1 },
1668			.dcp_det	= { 0x0884, 3, 3, 0, 1 },
1669			.dp_det		= { 0x0884, 5, 5, 0, 1 },
1670			.idm_sink_en	= { 0x0768, 8, 8, 0, 1 },
1671			.idp_sink_en	= { 0x0768, 7, 7, 0, 1 },
1672			.idp_src_en	= { 0x0768, 9, 9, 0, 1 },
1673			.rdm_pdwn_en	= { 0x0768, 10, 10, 0, 1 },
1674			.vdm_src_en	= { 0x0768, 12, 12, 0, 1 },
1675			.vdp_src_en	= { 0x0768, 11, 11, 0, 1 },
1676		},
1677	},
1678	{
1679		.reg = 0x800,
1680		.num_ports	= 2,
1681		.clkout_ctl	= { 0x0808, 4, 4, 1, 0 },
1682		.port_cfgs	= {
1683			[USB2PHY_PORT_OTG] = {
1684				.phy_sus	= { 0x800, 15, 0, 0, 0x1d1 },
1685				.ls_det_en	= { 0x0684, 0, 0, 0, 1 },
1686				.ls_det_st	= { 0x0694, 0, 0, 0, 1 },
1687				.ls_det_clr	= { 0x06a4, 0, 0, 0, 1 }
1688			},
1689			[USB2PHY_PORT_HOST] = {
1690				.phy_sus	= { 0x804, 15, 0, 0, 0x1d1 },
1691				.ls_det_en	= { 0x0684, 1, 1, 0, 1 },
1692				.ls_det_st	= { 0x0694, 1, 1, 0, 1 },
1693				.ls_det_clr	= { 0x06a4, 1, 1, 0, 1 }
1694			}
1695		},
1696	},
1697	{ /* sentinel */ }
1698};
1699
1700static const struct rockchip_usb2phy_cfg rk3308_phy_cfgs[] = {
1701	{
1702		.reg = 0x100,
1703		.num_ports	= 2,
1704		.clkout_ctl	= { 0x108, 4, 4, 1, 0 },
1705		.port_cfgs	= {
1706			[USB2PHY_PORT_OTG] = {
1707				.phy_sus	= { 0x0100, 8, 0, 0, 0x1d1 },
1708				.bvalid_det_en	= { 0x3020, 3, 2, 0, 3 },
1709				.bvalid_det_st	= { 0x3024, 3, 2, 0, 3 },
1710				.bvalid_det_clr = { 0x3028, 3, 2, 0, 3 },
1711				.idfall_det_en	= { 0x3020, 5, 5, 0, 1 },
1712				.idfall_det_st	= { 0x3024, 5, 5, 0, 1 },
1713				.idfall_det_clr = { 0x3028, 5, 5, 0, 1 },
1714				.idrise_det_en	= { 0x3020, 4, 4, 0, 1 },
1715				.idrise_det_st	= { 0x3024, 4, 4, 0, 1 },
1716				.idrise_det_clr = { 0x3028, 4, 4, 0, 1 },
1717				.ls_det_en	= { 0x3020, 0, 0, 0, 1 },
1718				.ls_det_st	= { 0x3024, 0, 0, 0, 1 },
1719				.ls_det_clr	= { 0x3028, 0, 0, 0, 1 },
1720				.utmi_avalid	= { 0x0120, 10, 10, 0, 1 },
1721				.utmi_bvalid	= { 0x0120, 9, 9, 0, 1 },
1722				.utmi_id	= { 0x0120, 6, 6, 0, 1 },
1723				.utmi_ls	= { 0x0120, 5, 4, 0, 1 },
1724			},
1725			[USB2PHY_PORT_HOST] = {
1726				.phy_sus	= { 0x0104, 8, 0, 0, 0x1d1 },
1727				.ls_det_en	= { 0x3020, 1, 1, 0, 1 },
1728				.ls_det_st	= { 0x3024, 1, 1, 0, 1 },
1729				.ls_det_clr	= { 0x3028, 1, 1, 0, 1 },
1730				.utmi_ls	= { 0x0120, 17, 16, 0, 1 },
1731				.utmi_hstdet	= { 0x0120, 19, 19, 0, 1 }
1732			}
1733		},
1734		.chg_det = {
1735			.opmode		= { 0x0100, 3, 0, 5, 1 },
1736			.cp_det		= { 0x0120, 24, 24, 0, 1 },
1737			.dcp_det	= { 0x0120, 23, 23, 0, 1 },
1738			.dp_det		= { 0x0120, 25, 25, 0, 1 },
1739			.idm_sink_en	= { 0x0108, 8, 8, 0, 1 },
1740			.idp_sink_en	= { 0x0108, 7, 7, 0, 1 },
1741			.idp_src_en	= { 0x0108, 9, 9, 0, 1 },
1742			.rdm_pdwn_en	= { 0x0108, 10, 10, 0, 1 },
1743			.vdm_src_en	= { 0x0108, 12, 12, 0, 1 },
1744			.vdp_src_en	= { 0x0108, 11, 11, 0, 1 },
1745		},
1746	},
1747	{ /* sentinel */ }
1748};
1749
1750static const struct rockchip_usb2phy_cfg rk3328_phy_cfgs[] = {
1751	{
1752		.reg = 0x100,
1753		.num_ports	= 2,
1754		.clkout_ctl	= { 0x108, 4, 4, 1, 0 },
1755		.port_cfgs	= {
1756			[USB2PHY_PORT_OTG] = {
1757				.phy_sus	= { 0x0100, 15, 0, 0, 0x1d1 },
1758				.bvalid_det_en	= { 0x0110, 3, 2, 0, 3 },
1759				.bvalid_det_st	= { 0x0114, 3, 2, 0, 3 },
1760				.bvalid_det_clr = { 0x0118, 3, 2, 0, 3 },
1761				.idfall_det_en	= { 0x0110, 5, 5, 0, 1 },
1762				.idfall_det_st	= { 0x0114, 5, 5, 0, 1 },
1763				.idfall_det_clr = { 0x0118, 5, 5, 0, 1 },
1764				.idrise_det_en	= { 0x0110, 4, 4, 0, 1 },
1765				.idrise_det_st	= { 0x0114, 4, 4, 0, 1 },
1766				.idrise_det_clr = { 0x0118, 4, 4, 0, 1 },
1767				.ls_det_en	= { 0x0110, 0, 0, 0, 1 },
1768				.ls_det_st	= { 0x0114, 0, 0, 0, 1 },
1769				.ls_det_clr	= { 0x0118, 0, 0, 0, 1 },
1770				.utmi_avalid	= { 0x0120, 10, 10, 0, 1 },
1771				.utmi_bvalid	= { 0x0120, 9, 9, 0, 1 },
1772				.utmi_id	= { 0x0120, 6, 6, 0, 1 },
1773				.utmi_ls	= { 0x0120, 5, 4, 0, 1 },
1774			},
1775			[USB2PHY_PORT_HOST] = {
1776				.phy_sus	= { 0x104, 15, 0, 0, 0x1d1 },
1777				.ls_det_en	= { 0x110, 1, 1, 0, 1 },
1778				.ls_det_st	= { 0x114, 1, 1, 0, 1 },
1779				.ls_det_clr	= { 0x118, 1, 1, 0, 1 },
1780				.utmi_ls	= { 0x120, 17, 16, 0, 1 },
1781				.utmi_hstdet	= { 0x120, 19, 19, 0, 1 }
1782			}
1783		},
1784		.chg_det = {
1785			.opmode		= { 0x0100, 3, 0, 5, 1 },
1786			.cp_det		= { 0x0120, 24, 24, 0, 1 },
1787			.dcp_det	= { 0x0120, 23, 23, 0, 1 },
1788			.dp_det		= { 0x0120, 25, 25, 0, 1 },
1789			.idm_sink_en	= { 0x0108, 8, 8, 0, 1 },
1790			.idp_sink_en	= { 0x0108, 7, 7, 0, 1 },
1791			.idp_src_en	= { 0x0108, 9, 9, 0, 1 },
1792			.rdm_pdwn_en	= { 0x0108, 10, 10, 0, 1 },
1793			.vdm_src_en	= { 0x0108, 12, 12, 0, 1 },
1794			.vdp_src_en	= { 0x0108, 11, 11, 0, 1 },
1795		},
1796	},
1797	{ /* sentinel */ }
1798};
1799
1800static const struct rockchip_usb2phy_cfg rk3366_phy_cfgs[] = {
1801	{
1802		.reg = 0x700,
1803		.num_ports	= 2,
1804		.clkout_ctl	= { 0x0724, 15, 15, 1, 0 },
1805		.port_cfgs	= {
1806			[USB2PHY_PORT_HOST] = {
1807				.phy_sus	= { 0x0728, 15, 0, 0, 0x1d1 },
1808				.ls_det_en	= { 0x0680, 4, 4, 0, 1 },
1809				.ls_det_st	= { 0x0690, 4, 4, 0, 1 },
1810				.ls_det_clr	= { 0x06a0, 4, 4, 0, 1 },
1811				.utmi_ls	= { 0x049c, 14, 13, 0, 1 },
1812				.utmi_hstdet	= { 0x049c, 12, 12, 0, 1 }
1813			}
1814		},
1815	},
1816	{ /* sentinel */ }
1817};
1818
1819static const struct rockchip_usb2phy_cfg rk3399_phy_cfgs[] = {
1820	{
1821		.reg		= 0xe450,
1822		.num_ports	= 2,
1823		.clkout_ctl	= { 0xe450, 4, 4, 1, 0 },
1824		.port_cfgs	= {
1825			[USB2PHY_PORT_OTG] = {
1826				.phy_sus	= { 0xe454, 1, 0, 2, 1 },
1827				.bvalid_det_en	= { 0xe3c0, 3, 3, 0, 1 },
1828				.bvalid_det_st	= { 0xe3e0, 3, 3, 0, 1 },
1829				.bvalid_det_clr	= { 0xe3d0, 3, 3, 0, 1 },
1830				.idfall_det_en	= { 0xe3c0, 5, 5, 0, 1 },
1831				.idfall_det_st	= { 0xe3e0, 5, 5, 0, 1 },
1832				.idfall_det_clr	= { 0xe3d0, 5, 5, 0, 1 },
1833				.idrise_det_en	= { 0xe3c0, 4, 4, 0, 1 },
1834				.idrise_det_st	= { 0xe3e0, 4, 4, 0, 1 },
1835				.idrise_det_clr	= { 0xe3d0, 4, 4, 0, 1 },
1836				.utmi_avalid	= { 0xe2ac, 7, 7, 0, 1 },
1837				.utmi_bvalid	= { 0xe2ac, 12, 12, 0, 1 },
1838				.utmi_id	= { 0xe2ac, 8, 8, 0, 1 },
1839			},
1840			[USB2PHY_PORT_HOST] = {
1841				.phy_sus	= { 0xe458, 1, 0, 0x2, 0x1 },
1842				.ls_det_en	= { 0xe3c0, 6, 6, 0, 1 },
1843				.ls_det_st	= { 0xe3e0, 6, 6, 0, 1 },
1844				.ls_det_clr	= { 0xe3d0, 6, 6, 0, 1 },
1845				.utmi_ls	= { 0xe2ac, 22, 21, 0, 1 },
1846				.utmi_hstdet	= { 0xe2ac, 23, 23, 0, 1 }
1847			}
1848		},
1849		.chg_det = {
1850			.opmode		= { 0xe454, 3, 0, 5, 1 },
1851			.cp_det		= { 0xe2ac, 2, 2, 0, 1 },
1852			.dcp_det	= { 0xe2ac, 1, 1, 0, 1 },
1853			.dp_det		= { 0xe2ac, 0, 0, 0, 1 },
1854			.idm_sink_en	= { 0xe450, 8, 8, 0, 1 },
1855			.idp_sink_en	= { 0xe450, 7, 7, 0, 1 },
1856			.idp_src_en	= { 0xe450, 9, 9, 0, 1 },
1857			.rdm_pdwn_en	= { 0xe450, 10, 10, 0, 1 },
1858			.vdm_src_en	= { 0xe450, 12, 12, 0, 1 },
1859			.vdp_src_en	= { 0xe450, 11, 11, 0, 1 },
1860		},
1861	},
1862	{
1863		.reg		= 0xe460,
1864		.num_ports	= 2,
1865		.clkout_ctl	= { 0xe460, 4, 4, 1, 0 },
1866		.port_cfgs	= {
1867			[USB2PHY_PORT_OTG] = {
1868				.phy_sus        = { 0xe464, 1, 0, 2, 1 },
1869				.bvalid_det_en  = { 0xe3c0, 8, 8, 0, 1 },
1870				.bvalid_det_st  = { 0xe3e0, 8, 8, 0, 1 },
1871				.bvalid_det_clr = { 0xe3d0, 8, 8, 0, 1 },
1872				.idfall_det_en	= { 0xe3c0, 10, 10, 0, 1 },
1873				.idfall_det_st	= { 0xe3e0, 10, 10, 0, 1 },
1874				.idfall_det_clr	= { 0xe3d0, 10, 10, 0, 1 },
1875				.idrise_det_en	= { 0xe3c0, 9, 9, 0, 1 },
1876				.idrise_det_st	= { 0xe3e0, 9, 9, 0, 1 },
1877				.idrise_det_clr	= { 0xe3d0, 9, 9, 0, 1 },
1878				.utmi_avalid	= { 0xe2ac, 10, 10, 0, 1 },
1879				.utmi_bvalid    = { 0xe2ac, 16, 16, 0, 1 },
1880				.utmi_id	= { 0xe2ac, 11, 11, 0, 1 },
1881			},
1882			[USB2PHY_PORT_HOST] = {
1883				.phy_sus	= { 0xe468, 1, 0, 0x2, 0x1 },
1884				.ls_det_en	= { 0xe3c0, 11, 11, 0, 1 },
1885				.ls_det_st	= { 0xe3e0, 11, 11, 0, 1 },
1886				.ls_det_clr	= { 0xe3d0, 11, 11, 0, 1 },
1887				.utmi_ls	= { 0xe2ac, 26, 25, 0, 1 },
1888				.utmi_hstdet	= { 0xe2ac, 27, 27, 0, 1 }
1889			}
1890		},
1891	},
1892	{ /* sentinel */ }
1893};
1894
1895static const struct rockchip_usb2phy_cfg rk3568_phy_cfgs[] = {
1896	{
1897		.reg = 0xfe8a0000,
1898		.num_ports	= 2,
1899		.clkout_ctl	= { 0x0008, 4, 4, 1, 0 },
1900		.port_cfgs	= {
1901			[USB2PHY_PORT_OTG] = {
1902				.phy_sus	= { 0x0000, 8, 0, 0, 0x1d1 },
1903				.bvalid_det_en	= { 0x0080, 3, 2, 0, 3 },
1904				.bvalid_det_st	= { 0x0084, 3, 2, 0, 3 },
1905				.bvalid_det_clr = { 0x0088, 3, 2, 0, 3 },
1906				.idfall_det_en	= { 0x0080, 5, 5, 0, 1 },
1907				.idfall_det_st	= { 0x0084, 5, 5, 0, 1 },
1908				.idfall_det_clr	= { 0x0088, 5, 5, 0, 1 },
1909				.idrise_det_en	= { 0x0080, 4, 4, 0, 1 },
1910				.idrise_det_st	= { 0x0084, 4, 4, 0, 1 },
1911				.idrise_det_clr	= { 0x0088, 4, 4, 0, 1 },
1912				.utmi_avalid	= { 0x00c0, 10, 10, 0, 1 },
1913				.utmi_bvalid	= { 0x00c0, 9, 9, 0, 1 },
1914				.utmi_id	= { 0x00c0, 6, 6, 0, 1 },
1915			},
1916			[USB2PHY_PORT_HOST] = {
1917				/* Select suspend control from controller */
1918				.phy_sus	= { 0x0004, 8, 0, 0x1d2, 0x1d2 },
1919				.ls_det_en	= { 0x0080, 1, 1, 0, 1 },
1920				.ls_det_st	= { 0x0084, 1, 1, 0, 1 },
1921				.ls_det_clr	= { 0x0088, 1, 1, 0, 1 },
1922				.utmi_ls	= { 0x00c0, 17, 16, 0, 1 },
1923				.utmi_hstdet	= { 0x00c0, 19, 19, 0, 1 }
1924			}
1925		},
1926		.chg_det = {
1927			.opmode		= { 0x0000, 3, 0, 5, 1 },
1928			.cp_det		= { 0x00c0, 24, 24, 0, 1 },
1929			.dcp_det	= { 0x00c0, 23, 23, 0, 1 },
1930			.dp_det		= { 0x00c0, 25, 25, 0, 1 },
1931			.idm_sink_en	= { 0x0008, 8, 8, 0, 1 },
1932			.idp_sink_en	= { 0x0008, 7, 7, 0, 1 },
1933			.idp_src_en	= { 0x0008, 9, 9, 0, 1 },
1934			.rdm_pdwn_en	= { 0x0008, 10, 10, 0, 1 },
1935			.vdm_src_en	= { 0x0008, 12, 12, 0, 1 },
1936			.vdp_src_en	= { 0x0008, 11, 11, 0, 1 },
1937		},
1938	},
1939	{
1940		.reg = 0xfe8b0000,
1941		.num_ports	= 2,
1942		.clkout_ctl	= { 0x0008, 4, 4, 1, 0 },
1943		.port_cfgs	= {
1944			[USB2PHY_PORT_OTG] = {
1945				.phy_sus	= { 0x0000, 8, 0, 0x1d2, 0x1d1 },
1946				.ls_det_en	= { 0x0080, 0, 0, 0, 1 },
1947				.ls_det_st	= { 0x0084, 0, 0, 0, 1 },
1948				.ls_det_clr	= { 0x0088, 0, 0, 0, 1 },
1949				.utmi_ls	= { 0x00c0, 5, 4, 0, 1 },
1950				.utmi_hstdet	= { 0x00c0, 7, 7, 0, 1 }
1951			},
1952			[USB2PHY_PORT_HOST] = {
1953				.phy_sus	= { 0x0004, 8, 0, 0x1d2, 0x1d1 },
1954				.ls_det_en	= { 0x0080, 1, 1, 0, 1 },
1955				.ls_det_st	= { 0x0084, 1, 1, 0, 1 },
1956				.ls_det_clr	= { 0x0088, 1, 1, 0, 1 },
1957				.utmi_ls	= { 0x00c0, 17, 16, 0, 1 },
1958				.utmi_hstdet	= { 0x00c0, 19, 19, 0, 1 }
1959			}
1960		},
1961	},
1962	{ /* sentinel */ }
1963};
1964
1965static const struct rockchip_usb2phy_cfg rk3576_phy_cfgs[] = {
1966	{
1967		.reg = 0x0,
1968		.num_ports	= 1,
1969		.phy_tuning	= rk3576_usb2phy_tuning,
1970		.clkout_ctl	= { 0x0008, 0, 0, 1, 0 },
1971		.port_cfgs	= {
1972			[USB2PHY_PORT_OTG] = {
1973				.phy_sus	= { 0x0000, 8, 0, 0, 0x1d1 },
1974				.bvalid_det_en	= { 0x00c0, 1, 1, 0, 1 },
1975				.bvalid_det_st	= { 0x00c4, 1, 1, 0, 1 },
1976				.bvalid_det_clr = { 0x00c8, 1, 1, 0, 1 },
1977				.ls_det_en	= { 0x00c0, 0, 0, 0, 1 },
1978				.ls_det_st	= { 0x00c4, 0, 0, 0, 1 },
1979				.ls_det_clr	= { 0x00c8, 0, 0, 0, 1 },
1980				.disfall_en	= { 0x00c0, 6, 6, 0, 1 },
1981				.disfall_st	= { 0x00c4, 6, 6, 0, 1 },
1982				.disfall_clr	= { 0x00c8, 6, 6, 0, 1 },
1983				.disrise_en	= { 0x00c0, 5, 5, 0, 1 },
1984				.disrise_st	= { 0x00c4, 5, 5, 0, 1 },
1985				.disrise_clr	= { 0x00c8, 5, 5, 0, 1 },
1986				.utmi_avalid	= { 0x0080, 1, 1, 0, 1 },
1987				.utmi_bvalid	= { 0x0080, 0, 0, 0, 1 },
1988				.utmi_ls	= { 0x0080, 5, 4, 0, 1 },
1989			}
1990		},
1991		.chg_det = {
1992			.cp_det		= { 0x0080, 8, 8, 0, 1 },
1993			.dcp_det	= { 0x0080, 8, 8, 0, 1 },
1994			.dp_det		= { 0x0080, 9, 9, 1, 0 },
1995			.idm_sink_en	= { 0x0010, 5, 5, 1, 0 },
1996			.idp_sink_en	= { 0x0010, 5, 5, 0, 1 },
1997			.idp_src_en	= { 0x0010, 14, 14, 0, 1 },
1998			.rdm_pdwn_en	= { 0x0010, 14, 14, 0, 1 },
1999			.vdm_src_en	= { 0x0010, 7, 6, 0, 3 },
2000			.vdp_src_en	= { 0x0010, 7, 6, 0, 3 },
2001		},
2002	},
2003	{
2004		.reg = 0x2000,
2005		.num_ports	= 1,
2006		.phy_tuning	= rk3576_usb2phy_tuning,
2007		.clkout_ctl	= { 0x2008, 0, 0, 1, 0 },
2008		.port_cfgs	= {
2009			[USB2PHY_PORT_OTG] = {
2010				.phy_sus	= { 0x2000, 8, 0, 0, 0x1d1 },
2011				.bvalid_det_en	= { 0x20c0, 1, 1, 0, 1 },
2012				.bvalid_det_st	= { 0x20c4, 1, 1, 0, 1 },
2013				.bvalid_det_clr = { 0x20c8, 1, 1, 0, 1 },
2014				.ls_det_en	= { 0x20c0, 0, 0, 0, 1 },
2015				.ls_det_st	= { 0x20c4, 0, 0, 0, 1 },
2016				.ls_det_clr	= { 0x20c8, 0, 0, 0, 1 },
2017				.disfall_en	= { 0x20c0, 6, 6, 0, 1 },
2018				.disfall_st	= { 0x20c4, 6, 6, 0, 1 },
2019				.disfall_clr	= { 0x20c8, 6, 6, 0, 1 },
2020				.disrise_en	= { 0x20c0, 5, 5, 0, 1 },
2021				.disrise_st	= { 0x20c4, 5, 5, 0, 1 },
2022				.disrise_clr	= { 0x20c8, 5, 5, 0, 1 },
2023				.utmi_avalid	= { 0x2080, 1, 1, 0, 1 },
2024				.utmi_bvalid	= { 0x2080, 0, 0, 0, 1 },
2025				.utmi_ls	= { 0x2080, 5, 4, 0, 1 },
2026			}
2027		},
2028		.chg_det = {
2029			.cp_det		= { 0x2080, 8, 8, 0, 1 },
2030			.dcp_det	= { 0x2080, 8, 8, 0, 1 },
2031			.dp_det		= { 0x2080, 9, 9, 1, 0 },
2032			.idm_sink_en	= { 0x2010, 5, 5, 1, 0 },
2033			.idp_sink_en	= { 0x2010, 5, 5, 0, 1 },
2034			.idp_src_en	= { 0x2010, 14, 14, 0, 1 },
2035			.rdm_pdwn_en	= { 0x2010, 14, 14, 0, 1 },
2036			.vdm_src_en	= { 0x2010, 7, 6, 0, 3 },
2037			.vdp_src_en	= { 0x2010, 7, 6, 0, 3 },
2038		},
2039	},
2040	{ /* sentinel */ }
2041};
2042
2043static const struct rockchip_usb2phy_cfg rk3588_phy_cfgs[] = {
2044	{
2045		.reg = 0x0000,
2046		.num_ports	= 1,
2047		.phy_tuning	= rk3588_usb2phy_tuning,
2048		.clkout_ctl	= { 0x0000, 0, 0, 1, 0 },
2049		.port_cfgs	= {
2050			[USB2PHY_PORT_OTG] = {
2051				.phy_sus	= { 0x000c, 11, 11, 0, 1 },
2052				.bvalid_det_en	= { 0x0080, 1, 1, 0, 1 },
2053				.bvalid_det_st	= { 0x0084, 1, 1, 0, 1 },
2054				.bvalid_det_clr = { 0x0088, 1, 1, 0, 1 },
2055				.ls_det_en	= { 0x0080, 0, 0, 0, 1 },
2056				.ls_det_st	= { 0x0084, 0, 0, 0, 1 },
2057				.ls_det_clr	= { 0x0088, 0, 0, 0, 1 },
2058				.disfall_en	= { 0x0080, 6, 6, 0, 1 },
2059				.disfall_st	= { 0x0084, 6, 6, 0, 1 },
2060				.disfall_clr	= { 0x0088, 6, 6, 0, 1 },
2061				.disrise_en	= { 0x0080, 5, 5, 0, 1 },
2062				.disrise_st	= { 0x0084, 5, 5, 0, 1 },
2063				.disrise_clr	= { 0x0088, 5, 5, 0, 1 },
2064				.utmi_avalid	= { 0x00c0, 7, 7, 0, 1 },
2065				.utmi_bvalid	= { 0x00c0, 6, 6, 0, 1 },
2066				.utmi_ls	= { 0x00c0, 10, 9, 0, 1 },
2067			}
2068		},
2069		.chg_det = {
2070			.cp_det		= { 0x00c0, 0, 0, 0, 1 },
2071			.dcp_det	= { 0x00c0, 0, 0, 0, 1 },
2072			.dp_det		= { 0x00c0, 1, 1, 1, 0 },
2073			.idm_sink_en	= { 0x0008, 5, 5, 1, 0 },
2074			.idp_sink_en	= { 0x0008, 5, 5, 0, 1 },
2075			.idp_src_en	= { 0x0008, 14, 14, 0, 1 },
2076			.rdm_pdwn_en	= { 0x0008, 14, 14, 0, 1 },
2077			.vdm_src_en	= { 0x0008, 7, 6, 0, 3 },
2078			.vdp_src_en	= { 0x0008, 7, 6, 0, 3 },
2079		},
2080	},
2081	{
2082		.reg = 0x4000,
2083		.num_ports	= 1,
2084		.phy_tuning	= rk3588_usb2phy_tuning,
2085		.clkout_ctl	= { 0x0000, 0, 0, 1, 0 },
2086		.port_cfgs	= {
2087			[USB2PHY_PORT_OTG] = {
2088				.phy_sus	= { 0x000c, 11, 11, 0, 1 },
2089				.bvalid_det_en	= { 0x0080, 1, 1, 0, 1 },
2090				.bvalid_det_st	= { 0x0084, 1, 1, 0, 1 },
2091				.bvalid_det_clr = { 0x0088, 1, 1, 0, 1 },
2092				.ls_det_en	= { 0x0080, 0, 0, 0, 1 },
2093				.ls_det_st	= { 0x0084, 0, 0, 0, 1 },
2094				.ls_det_clr	= { 0x0088, 0, 0, 0, 1 },
2095				.disfall_en	= { 0x0080, 6, 6, 0, 1 },
2096				.disfall_st	= { 0x0084, 6, 6, 0, 1 },
2097				.disfall_clr	= { 0x0088, 6, 6, 0, 1 },
2098				.disrise_en	= { 0x0080, 5, 5, 0, 1 },
2099				.disrise_st	= { 0x0084, 5, 5, 0, 1 },
2100				.disrise_clr	= { 0x0088, 5, 5, 0, 1 },
2101				.utmi_avalid	= { 0x00c0, 7, 7, 0, 1 },
2102				.utmi_bvalid	= { 0x00c0, 6, 6, 0, 1 },
2103				.utmi_ls	= { 0x00c0, 10, 9, 0, 1 },
2104			}
2105		},
2106		.chg_det = {
2107			.cp_det		= { 0x00c0, 0, 0, 0, 1 },
2108			.dcp_det	= { 0x00c0, 0, 0, 0, 1 },
2109			.dp_det		= { 0x00c0, 1, 1, 1, 0 },
2110			.idm_sink_en	= { 0x0008, 5, 5, 1, 0 },
2111			.idp_sink_en	= { 0x0008, 5, 5, 0, 1 },
2112			.idp_src_en	= { 0x0008, 14, 14, 0, 1 },
2113			.rdm_pdwn_en	= { 0x0008, 14, 14, 0, 1 },
2114			.vdm_src_en	= { 0x0008, 7, 6, 0, 3 },
2115			.vdp_src_en	= { 0x0008, 7, 6, 0, 3 },
2116		},
2117	},
2118	{
2119		.reg = 0x8000,
2120		.num_ports	= 1,
2121		.phy_tuning	= rk3588_usb2phy_tuning,
2122		.clkout_ctl	= { 0x0000, 0, 0, 1, 0 },
2123		.port_cfgs	= {
2124			[USB2PHY_PORT_HOST] = {
2125				.phy_sus	= { 0x0008, 2, 2, 0, 1 },
2126				.ls_det_en	= { 0x0080, 0, 0, 0, 1 },
2127				.ls_det_st	= { 0x0084, 0, 0, 0, 1 },
2128				.ls_det_clr	= { 0x0088, 0, 0, 0, 1 },
2129				.disfall_en	= { 0x0080, 6, 6, 0, 1 },
2130				.disfall_st	= { 0x0084, 6, 6, 0, 1 },
2131				.disfall_clr	= { 0x0088, 6, 6, 0, 1 },
2132				.disrise_en	= { 0x0080, 5, 5, 0, 1 },
2133				.disrise_st	= { 0x0084, 5, 5, 0, 1 },
2134				.disrise_clr	= { 0x0088, 5, 5, 0, 1 },
2135				.utmi_ls	= { 0x00c0, 10, 9, 0, 1 },
2136			}
2137		},
2138	},
2139	{
2140		.reg = 0xc000,
2141		.num_ports	= 1,
2142		.phy_tuning	= rk3588_usb2phy_tuning,
2143		.clkout_ctl	= { 0x0000, 0, 0, 1, 0 },
2144		.port_cfgs	= {
2145			[USB2PHY_PORT_HOST] = {
2146				.phy_sus	= { 0x0008, 2, 2, 0, 1 },
2147				.ls_det_en	= { 0x0080, 0, 0, 0, 1 },
2148				.ls_det_st	= { 0x0084, 0, 0, 0, 1 },
2149				.ls_det_clr	= { 0x0088, 0, 0, 0, 1 },
2150				.disfall_en	= { 0x0080, 6, 6, 0, 1 },
2151				.disfall_st	= { 0x0084, 6, 6, 0, 1 },
2152				.disfall_clr	= { 0x0088, 6, 6, 0, 1 },
2153				.disrise_en	= { 0x0080, 5, 5, 0, 1 },
2154				.disrise_st	= { 0x0084, 5, 5, 0, 1 },
2155				.disrise_clr	= { 0x0088, 5, 5, 0, 1 },
2156				.utmi_ls	= { 0x00c0, 10, 9, 0, 1 },
2157			}
2158		},
2159	},
2160	{ /* sentinel */ }
2161};
2162
2163static const struct rockchip_usb2phy_cfg rv1108_phy_cfgs[] = {
2164	{
2165		.reg = 0x100,
2166		.num_ports	= 2,
2167		.clkout_ctl	= { 0x108, 4, 4, 1, 0 },
2168		.port_cfgs	= {
2169			[USB2PHY_PORT_OTG] = {
2170				.phy_sus	= { 0x0100, 15, 0, 0, 0x1d1 },
2171				.bvalid_det_en	= { 0x0680, 3, 3, 0, 1 },
2172				.bvalid_det_st	= { 0x0690, 3, 3, 0, 1 },
2173				.bvalid_det_clr = { 0x06a0, 3, 3, 0, 1 },
2174				.ls_det_en	= { 0x0680, 2, 2, 0, 1 },
2175				.ls_det_st	= { 0x0690, 2, 2, 0, 1 },
2176				.ls_det_clr	= { 0x06a0, 2, 2, 0, 1 },
2177				.utmi_bvalid	= { 0x0804, 10, 10, 0, 1 },
2178				.utmi_ls	= { 0x0804, 13, 12, 0, 1 },
2179			},
2180			[USB2PHY_PORT_HOST] = {
2181				.phy_sus	= { 0x0104, 15, 0, 0, 0x1d1 },
2182				.ls_det_en	= { 0x0680, 4, 4, 0, 1 },
2183				.ls_det_st	= { 0x0690, 4, 4, 0, 1 },
2184				.ls_det_clr	= { 0x06a0, 4, 4, 0, 1 },
2185				.utmi_ls	= { 0x0804, 9, 8, 0, 1 },
2186				.utmi_hstdet	= { 0x0804, 7, 7, 0, 1 }
2187			}
2188		},
2189		.chg_det = {
2190			.opmode		= { 0x0100, 3, 0, 5, 1 },
2191			.cp_det		= { 0x0804, 1, 1, 0, 1 },
2192			.dcp_det	= { 0x0804, 0, 0, 0, 1 },
2193			.dp_det		= { 0x0804, 2, 2, 0, 1 },
2194			.idm_sink_en	= { 0x0108, 8, 8, 0, 1 },
2195			.idp_sink_en	= { 0x0108, 7, 7, 0, 1 },
2196			.idp_src_en	= { 0x0108, 9, 9, 0, 1 },
2197			.rdm_pdwn_en	= { 0x0108, 10, 10, 0, 1 },
2198			.vdm_src_en	= { 0x0108, 12, 12, 0, 1 },
2199			.vdp_src_en	= { 0x0108, 11, 11, 0, 1 },
2200		},
2201	},
2202	{ /* sentinel */ }
2203};
2204
2205static const struct of_device_id rockchip_usb2phy_dt_match[] = {
2206	{ .compatible = "rockchip,px30-usb2phy", .data = &rk3328_phy_cfgs },
2207	{ .compatible = "rockchip,rk3128-usb2phy", .data = &rk3128_phy_cfgs },
2208	{ .compatible = "rockchip,rk3228-usb2phy", .data = &rk3228_phy_cfgs },
2209	{ .compatible = "rockchip,rk3308-usb2phy", .data = &rk3308_phy_cfgs },
2210	{ .compatible = "rockchip,rk3328-usb2phy", .data = &rk3328_phy_cfgs },
2211	{ .compatible = "rockchip,rk3366-usb2phy", .data = &rk3366_phy_cfgs },
2212	{ .compatible = "rockchip,rk3399-usb2phy", .data = &rk3399_phy_cfgs },
2213	{ .compatible = "rockchip,rk3568-usb2phy", .data = &rk3568_phy_cfgs },
2214	{ .compatible = "rockchip,rk3576-usb2phy", .data = &rk3576_phy_cfgs },
2215	{ .compatible = "rockchip,rk3588-usb2phy", .data = &rk3588_phy_cfgs },
2216	{ .compatible = "rockchip,rv1108-usb2phy", .data = &rv1108_phy_cfgs },
2217	{}
2218};
2219MODULE_DEVICE_TABLE(of, rockchip_usb2phy_dt_match);
2220
2221static struct platform_driver rockchip_usb2phy_driver = {
2222	.probe		= rockchip_usb2phy_probe,
2223	.driver		= {
2224		.name	= "rockchip-usb2phy",
2225		.of_match_table = rockchip_usb2phy_dt_match,
2226	},
2227};
2228module_platform_driver(rockchip_usb2phy_driver);
2229
2230MODULE_AUTHOR("Frank Wang <frank.wang@rock-chips.com>");
2231MODULE_DESCRIPTION("Rockchip USB2.0 PHY driver");
2232MODULE_LICENSE("GPL v2");