^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /* SPDX-License-Identifier: GPL-2.0-only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (C) 2014-2017 Broadcom
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #ifndef _USB_BRCM_COMMON_INIT_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #define _USB_BRCM_COMMON_INIT_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/regmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #define USB_CTLR_MODE_HOST 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #define USB_CTLR_MODE_DEVICE 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #define USB_CTLR_MODE_DRD 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #define USB_CTLR_MODE_TYPEC_PD 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) enum brcmusb_reg_sel {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) BRCM_REGS_CTRL = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) BRCM_REGS_XHCI_EC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) BRCM_REGS_XHCI_GBL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) BRCM_REGS_USB_PHY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) BRCM_REGS_USB_MDIO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) BRCM_REGS_BDC_EC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) BRCM_REGS_MAX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define USB_CTRL_REG(base, reg) ((void __iomem *)base + USB_CTRL_##reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define USB_XHCI_EC_REG(base, reg) ((void __iomem *)base + USB_XHCI_EC_##reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define USB_CTRL_MASK(reg, field) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) USB_CTRL_##reg##_##field##_MASK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define USB_CTRL_SET(base, reg, field) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) brcm_usb_ctrl_set(USB_CTRL_REG(base, reg), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) USB_CTRL_##reg##_##field##_MASK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define USB_CTRL_UNSET(base, reg, field) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) brcm_usb_ctrl_unset(USB_CTRL_REG(base, reg), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) USB_CTRL_##reg##_##field##_MASK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) struct brcm_usb_init_params;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) struct brcm_usb_init_ops {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) void (*init_ipp)(struct brcm_usb_init_params *params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) void (*init_common)(struct brcm_usb_init_params *params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) void (*init_eohci)(struct brcm_usb_init_params *params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) void (*init_xhci)(struct brcm_usb_init_params *params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) void (*uninit_common)(struct brcm_usb_init_params *params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) void (*uninit_eohci)(struct brcm_usb_init_params *params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) void (*uninit_xhci)(struct brcm_usb_init_params *params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) int (*get_dual_select)(struct brcm_usb_init_params *params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) void (*set_dual_select)(struct brcm_usb_init_params *params, int mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) struct brcm_usb_init_params {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) void __iomem *regs[BRCM_REGS_MAX];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) int ioc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) int ipp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) int mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) u32 family_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) u32 product_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) int selected_family;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) const char *family_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) const u32 *usb_reg_bits_map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) const struct brcm_usb_init_ops *ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) struct regmap *syscon_piarbctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) bool wake_enabled;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) bool suspend_with_clocks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) void brcm_usb_dvr_init_7445(struct brcm_usb_init_params *params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) void brcm_usb_dvr_init_7216(struct brcm_usb_init_params *params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) void brcm_usb_dvr_init_7211b0(struct brcm_usb_init_params *params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) static inline u32 brcm_usb_readl(void __iomem *addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) * MIPS endianness is configured by boot strap, which also reverses all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) * bus endianness (i.e., big-endian CPU + big endian bus ==> native
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) * endian I/O).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) * Other architectures (e.g., ARM) either do not support big endian, or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) * else leave I/O in little endian mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) if (IS_ENABLED(CONFIG_MIPS) && IS_ENABLED(CONFIG_CPU_BIG_ENDIAN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) return __raw_readl(addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) return readl_relaxed(addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) static inline void brcm_usb_writel(u32 val, void __iomem *addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) /* See brcmnand_readl() comments */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) if (IS_ENABLED(CONFIG_MIPS) && IS_ENABLED(CONFIG_CPU_BIG_ENDIAN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) __raw_writel(val, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) writel_relaxed(val, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) static inline void brcm_usb_ctrl_unset(void __iomem *reg, u32 mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) brcm_usb_writel(brcm_usb_readl(reg) & ~(mask), reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) static inline void brcm_usb_ctrl_set(void __iomem *reg, u32 mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) brcm_usb_writel(brcm_usb_readl(reg) | (mask), reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) static inline void brcm_usb_init_ipp(struct brcm_usb_init_params *ini)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) if (ini->ops->init_ipp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) ini->ops->init_ipp(ini);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) static inline void brcm_usb_init_common(struct brcm_usb_init_params *ini)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) if (ini->ops->init_common)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) ini->ops->init_common(ini);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) static inline void brcm_usb_init_eohci(struct brcm_usb_init_params *ini)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) if (ini->ops->init_eohci)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) ini->ops->init_eohci(ini);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) static inline void brcm_usb_init_xhci(struct brcm_usb_init_params *ini)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) if (ini->ops->init_xhci)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) ini->ops->init_xhci(ini);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) static inline void brcm_usb_uninit_common(struct brcm_usb_init_params *ini)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) if (ini->ops->uninit_common)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) ini->ops->uninit_common(ini);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) static inline void brcm_usb_uninit_eohci(struct brcm_usb_init_params *ini)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) if (ini->ops->uninit_eohci)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) ini->ops->uninit_eohci(ini);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) static inline void brcm_usb_uninit_xhci(struct brcm_usb_init_params *ini)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) if (ini->ops->uninit_xhci)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) ini->ops->uninit_xhci(ini);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) static inline int brcm_usb_get_dual_select(struct brcm_usb_init_params *ini)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) if (ini->ops->get_dual_select)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) return ini->ops->get_dual_select(ini);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) static inline void brcm_usb_set_dual_select(struct brcm_usb_init_params *ini,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) int mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) if (ini->ops->set_dual_select)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) ini->ops->set_dual_select(ini, mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) #endif /* _USB_BRCM_COMMON_INIT_H */