18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Copyright (C) 2014-2017 Broadcom
48c2ecf20Sopenharmony_ci */
58c2ecf20Sopenharmony_ci
68c2ecf20Sopenharmony_ci#ifndef _USB_BRCM_COMMON_INIT_H
78c2ecf20Sopenharmony_ci#define _USB_BRCM_COMMON_INIT_H
88c2ecf20Sopenharmony_ci
98c2ecf20Sopenharmony_ci#include <linux/regmap.h>
108c2ecf20Sopenharmony_ci
118c2ecf20Sopenharmony_ci#define USB_CTLR_MODE_HOST 0
128c2ecf20Sopenharmony_ci#define USB_CTLR_MODE_DEVICE 1
138c2ecf20Sopenharmony_ci#define USB_CTLR_MODE_DRD 2
148c2ecf20Sopenharmony_ci#define USB_CTLR_MODE_TYPEC_PD 3
158c2ecf20Sopenharmony_ci
168c2ecf20Sopenharmony_cienum brcmusb_reg_sel {
178c2ecf20Sopenharmony_ci	BRCM_REGS_CTRL = 0,
188c2ecf20Sopenharmony_ci	BRCM_REGS_XHCI_EC,
198c2ecf20Sopenharmony_ci	BRCM_REGS_XHCI_GBL,
208c2ecf20Sopenharmony_ci	BRCM_REGS_USB_PHY,
218c2ecf20Sopenharmony_ci	BRCM_REGS_USB_MDIO,
228c2ecf20Sopenharmony_ci	BRCM_REGS_BDC_EC,
238c2ecf20Sopenharmony_ci	BRCM_REGS_MAX
248c2ecf20Sopenharmony_ci};
258c2ecf20Sopenharmony_ci
268c2ecf20Sopenharmony_ci#define USB_CTRL_REG(base, reg)	((void __iomem *)base + USB_CTRL_##reg)
278c2ecf20Sopenharmony_ci#define USB_XHCI_EC_REG(base, reg) ((void __iomem *)base + USB_XHCI_EC_##reg)
288c2ecf20Sopenharmony_ci#define USB_CTRL_MASK(reg, field) \
298c2ecf20Sopenharmony_ci	USB_CTRL_##reg##_##field##_MASK
308c2ecf20Sopenharmony_ci#define USB_CTRL_SET(base, reg, field)	\
318c2ecf20Sopenharmony_ci	brcm_usb_ctrl_set(USB_CTRL_REG(base, reg),	\
328c2ecf20Sopenharmony_ci			  USB_CTRL_##reg##_##field##_MASK)
338c2ecf20Sopenharmony_ci#define USB_CTRL_UNSET(base, reg, field)	\
348c2ecf20Sopenharmony_ci	brcm_usb_ctrl_unset(USB_CTRL_REG(base, reg),		\
358c2ecf20Sopenharmony_ci			    USB_CTRL_##reg##_##field##_MASK)
368c2ecf20Sopenharmony_ci
378c2ecf20Sopenharmony_cistruct  brcm_usb_init_params;
388c2ecf20Sopenharmony_ci
398c2ecf20Sopenharmony_cistruct brcm_usb_init_ops {
408c2ecf20Sopenharmony_ci	void (*init_ipp)(struct brcm_usb_init_params *params);
418c2ecf20Sopenharmony_ci	void (*init_common)(struct brcm_usb_init_params *params);
428c2ecf20Sopenharmony_ci	void (*init_eohci)(struct brcm_usb_init_params *params);
438c2ecf20Sopenharmony_ci	void (*init_xhci)(struct brcm_usb_init_params *params);
448c2ecf20Sopenharmony_ci	void (*uninit_common)(struct brcm_usb_init_params *params);
458c2ecf20Sopenharmony_ci	void (*uninit_eohci)(struct brcm_usb_init_params *params);
468c2ecf20Sopenharmony_ci	void (*uninit_xhci)(struct brcm_usb_init_params *params);
478c2ecf20Sopenharmony_ci	int  (*get_dual_select)(struct brcm_usb_init_params *params);
488c2ecf20Sopenharmony_ci	void (*set_dual_select)(struct brcm_usb_init_params *params, int mode);
498c2ecf20Sopenharmony_ci};
508c2ecf20Sopenharmony_ci
518c2ecf20Sopenharmony_cistruct  brcm_usb_init_params {
528c2ecf20Sopenharmony_ci	void __iomem *regs[BRCM_REGS_MAX];
538c2ecf20Sopenharmony_ci	int ioc;
548c2ecf20Sopenharmony_ci	int ipp;
558c2ecf20Sopenharmony_ci	int mode;
568c2ecf20Sopenharmony_ci	u32 family_id;
578c2ecf20Sopenharmony_ci	u32 product_id;
588c2ecf20Sopenharmony_ci	int selected_family;
598c2ecf20Sopenharmony_ci	const char *family_name;
608c2ecf20Sopenharmony_ci	const u32 *usb_reg_bits_map;
618c2ecf20Sopenharmony_ci	const struct brcm_usb_init_ops *ops;
628c2ecf20Sopenharmony_ci	struct regmap *syscon_piarbctl;
638c2ecf20Sopenharmony_ci	bool wake_enabled;
648c2ecf20Sopenharmony_ci	bool suspend_with_clocks;
658c2ecf20Sopenharmony_ci};
668c2ecf20Sopenharmony_ci
678c2ecf20Sopenharmony_civoid brcm_usb_dvr_init_7445(struct brcm_usb_init_params *params);
688c2ecf20Sopenharmony_civoid brcm_usb_dvr_init_7216(struct brcm_usb_init_params *params);
698c2ecf20Sopenharmony_civoid brcm_usb_dvr_init_7211b0(struct brcm_usb_init_params *params);
708c2ecf20Sopenharmony_ci
718c2ecf20Sopenharmony_cistatic inline u32 brcm_usb_readl(void __iomem *addr)
728c2ecf20Sopenharmony_ci{
738c2ecf20Sopenharmony_ci	/*
748c2ecf20Sopenharmony_ci	 * MIPS endianness is configured by boot strap, which also reverses all
758c2ecf20Sopenharmony_ci	 * bus endianness (i.e., big-endian CPU + big endian bus ==> native
768c2ecf20Sopenharmony_ci	 * endian I/O).
778c2ecf20Sopenharmony_ci	 *
788c2ecf20Sopenharmony_ci	 * Other architectures (e.g., ARM) either do not support big endian, or
798c2ecf20Sopenharmony_ci	 * else leave I/O in little endian mode.
808c2ecf20Sopenharmony_ci	 */
818c2ecf20Sopenharmony_ci	if (IS_ENABLED(CONFIG_MIPS) && IS_ENABLED(CONFIG_CPU_BIG_ENDIAN))
828c2ecf20Sopenharmony_ci		return __raw_readl(addr);
838c2ecf20Sopenharmony_ci	else
848c2ecf20Sopenharmony_ci		return readl_relaxed(addr);
858c2ecf20Sopenharmony_ci}
868c2ecf20Sopenharmony_ci
878c2ecf20Sopenharmony_cistatic inline void brcm_usb_writel(u32 val, void __iomem *addr)
888c2ecf20Sopenharmony_ci{
898c2ecf20Sopenharmony_ci	/* See brcmnand_readl() comments */
908c2ecf20Sopenharmony_ci	if (IS_ENABLED(CONFIG_MIPS) && IS_ENABLED(CONFIG_CPU_BIG_ENDIAN))
918c2ecf20Sopenharmony_ci		__raw_writel(val, addr);
928c2ecf20Sopenharmony_ci	else
938c2ecf20Sopenharmony_ci		writel_relaxed(val, addr);
948c2ecf20Sopenharmony_ci}
958c2ecf20Sopenharmony_ci
968c2ecf20Sopenharmony_cistatic inline void brcm_usb_ctrl_unset(void __iomem *reg, u32 mask)
978c2ecf20Sopenharmony_ci{
988c2ecf20Sopenharmony_ci	brcm_usb_writel(brcm_usb_readl(reg) & ~(mask), reg);
998c2ecf20Sopenharmony_ci};
1008c2ecf20Sopenharmony_ci
1018c2ecf20Sopenharmony_cistatic inline void brcm_usb_ctrl_set(void __iomem *reg, u32 mask)
1028c2ecf20Sopenharmony_ci{
1038c2ecf20Sopenharmony_ci	brcm_usb_writel(brcm_usb_readl(reg) | (mask), reg);
1048c2ecf20Sopenharmony_ci};
1058c2ecf20Sopenharmony_ci
1068c2ecf20Sopenharmony_cistatic inline void brcm_usb_init_ipp(struct brcm_usb_init_params *ini)
1078c2ecf20Sopenharmony_ci{
1088c2ecf20Sopenharmony_ci	if (ini->ops->init_ipp)
1098c2ecf20Sopenharmony_ci		ini->ops->init_ipp(ini);
1108c2ecf20Sopenharmony_ci}
1118c2ecf20Sopenharmony_ci
1128c2ecf20Sopenharmony_cistatic inline void brcm_usb_init_common(struct brcm_usb_init_params *ini)
1138c2ecf20Sopenharmony_ci{
1148c2ecf20Sopenharmony_ci	if (ini->ops->init_common)
1158c2ecf20Sopenharmony_ci		ini->ops->init_common(ini);
1168c2ecf20Sopenharmony_ci}
1178c2ecf20Sopenharmony_ci
1188c2ecf20Sopenharmony_cistatic inline void brcm_usb_init_eohci(struct brcm_usb_init_params *ini)
1198c2ecf20Sopenharmony_ci{
1208c2ecf20Sopenharmony_ci	if (ini->ops->init_eohci)
1218c2ecf20Sopenharmony_ci		ini->ops->init_eohci(ini);
1228c2ecf20Sopenharmony_ci}
1238c2ecf20Sopenharmony_ci
1248c2ecf20Sopenharmony_cistatic inline void brcm_usb_init_xhci(struct brcm_usb_init_params *ini)
1258c2ecf20Sopenharmony_ci{
1268c2ecf20Sopenharmony_ci	if (ini->ops->init_xhci)
1278c2ecf20Sopenharmony_ci		ini->ops->init_xhci(ini);
1288c2ecf20Sopenharmony_ci}
1298c2ecf20Sopenharmony_ci
1308c2ecf20Sopenharmony_cistatic inline void brcm_usb_uninit_common(struct brcm_usb_init_params *ini)
1318c2ecf20Sopenharmony_ci{
1328c2ecf20Sopenharmony_ci	if (ini->ops->uninit_common)
1338c2ecf20Sopenharmony_ci		ini->ops->uninit_common(ini);
1348c2ecf20Sopenharmony_ci}
1358c2ecf20Sopenharmony_ci
1368c2ecf20Sopenharmony_cistatic inline void brcm_usb_uninit_eohci(struct brcm_usb_init_params *ini)
1378c2ecf20Sopenharmony_ci{
1388c2ecf20Sopenharmony_ci	if (ini->ops->uninit_eohci)
1398c2ecf20Sopenharmony_ci		ini->ops->uninit_eohci(ini);
1408c2ecf20Sopenharmony_ci}
1418c2ecf20Sopenharmony_ci
1428c2ecf20Sopenharmony_cistatic inline void brcm_usb_uninit_xhci(struct brcm_usb_init_params *ini)
1438c2ecf20Sopenharmony_ci{
1448c2ecf20Sopenharmony_ci	if (ini->ops->uninit_xhci)
1458c2ecf20Sopenharmony_ci		ini->ops->uninit_xhci(ini);
1468c2ecf20Sopenharmony_ci}
1478c2ecf20Sopenharmony_ci
1488c2ecf20Sopenharmony_cistatic inline int brcm_usb_get_dual_select(struct brcm_usb_init_params *ini)
1498c2ecf20Sopenharmony_ci{
1508c2ecf20Sopenharmony_ci	if (ini->ops->get_dual_select)
1518c2ecf20Sopenharmony_ci		return ini->ops->get_dual_select(ini);
1528c2ecf20Sopenharmony_ci	return 0;
1538c2ecf20Sopenharmony_ci}
1548c2ecf20Sopenharmony_ci
1558c2ecf20Sopenharmony_cistatic inline void brcm_usb_set_dual_select(struct brcm_usb_init_params *ini,
1568c2ecf20Sopenharmony_ci	int mode)
1578c2ecf20Sopenharmony_ci{
1588c2ecf20Sopenharmony_ci	if (ini->ops->set_dual_select)
1598c2ecf20Sopenharmony_ci		ini->ops->set_dual_select(ini, mode);
1608c2ecf20Sopenharmony_ci}
1618c2ecf20Sopenharmony_ci
1628c2ecf20Sopenharmony_ci#endif /* _USB_BRCM_COMMON_INIT_H */
163