cachepc-linux

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

phy-brcm-usb-init-synopsys.c (13245B)


      1// SPDX-License-Identifier: GPL-2.0
      2/* Copyright (c) 2018, Broadcom */
      3
      4/*
      5 * This module contains USB PHY initialization for power up and S3 resume
      6 * for newer Synopsys based USB hardware first used on the bcm7216.
      7 */
      8
      9#include <linux/delay.h>
     10#include <linux/io.h>
     11
     12#include <linux/soc/brcmstb/brcmstb.h>
     13#include "phy-brcm-usb-init.h"
     14
     15#define PHY_LOCK_TIMEOUT_MS 200
     16
     17/* Register definitions for syscon piarbctl registers */
     18#define PIARBCTL_CAM			0x00
     19#define PIARBCTL_SPLITTER		0x04
     20#define PIARBCTL_MISC			0x08
     21#define   PIARBCTL_MISC_SECURE_MASK			0x80000000
     22#define   PIARBCTL_MISC_USB_SELECT_MASK			0x40000000
     23#define   PIARBCTL_MISC_USB_4G_SDRAM_MASK		0x20000000
     24#define   PIARBCTL_MISC_USB_PRIORITY_MASK		0x000f0000
     25#define   PIARBCTL_MISC_USB_MEM_PAGE_MASK		0x0000f000
     26#define   PIARBCTL_MISC_CAM1_MEM_PAGE_MASK		0x00000f00
     27#define   PIARBCTL_MISC_CAM0_MEM_PAGE_MASK		0x000000f0
     28#define   PIARBCTL_MISC_SATA_PRIORITY_MASK		0x0000000f
     29
     30#define PIARBCTL_MISC_USB_ONLY_MASK		\
     31	(PIARBCTL_MISC_USB_SELECT_MASK |	\
     32	 PIARBCTL_MISC_USB_4G_SDRAM_MASK |	\
     33	 PIARBCTL_MISC_USB_PRIORITY_MASK |	\
     34	 PIARBCTL_MISC_USB_MEM_PAGE_MASK)
     35
     36/* Register definitions for the USB CTRL block */
     37#define USB_CTRL_SETUP			0x00
     38#define   USB_CTRL_SETUP_STRAP_IPP_SEL_MASK		0x02000000
     39#define   USB_CTRL_SETUP_SCB2_EN_MASK			0x00008000
     40#define   USB_CTRL_SETUP_tca_drv_sel_MASK		0x01000000
     41#define   USB_CTRL_SETUP_SCB1_EN_MASK			0x00004000
     42#define   USB_CTRL_SETUP_SOFT_SHUTDOWN_MASK		0x00000200
     43#define   USB_CTRL_SETUP_IPP_MASK			0x00000020
     44#define   USB_CTRL_SETUP_IOC_MASK			0x00000010
     45#define USB_CTRL_USB_PM			0x04
     46#define   USB_CTRL_USB_PM_USB_PWRDN_MASK		0x80000000
     47#define   USB_CTRL_USB_PM_SOFT_RESET_MASK		0x40000000
     48#define   USB_CTRL_USB_PM_BDC_SOFT_RESETB_MASK		0x00800000
     49#define   USB_CTRL_USB_PM_XHC_SOFT_RESETB_MASK		0x00400000
     50#define   USB_CTRL_USB_PM_XHC_PME_EN_MASK		0x00000010
     51#define   USB_CTRL_USB_PM_XHC_S2_CLK_SWITCH_EN_MASK	0x00000008
     52#define USB_CTRL_USB_PM_STATUS		0x08
     53#define USB_CTRL_USB_DEVICE_CTL1	0x10
     54#define   USB_CTRL_USB_DEVICE_CTL1_PORT_MODE_MASK	0x00000003
     55#define USB_CTRL_TEST_PORT_CTL		0x30
     56#define   USB_CTRL_TEST_PORT_CTL_TPOUT_SEL_MASK	0x000000ff
     57#define   USB_CTRL_TEST_PORT_CTL_TPOUT_SEL_PME_GEN_MASK	0x0000002e
     58#define USB_CTRL_TP_DIAG1		0x34
     59#define   USB_CTLR_TP_DIAG1_wake_MASK	0x00000002
     60#define USB_CTRL_CTLR_CSHCR		0x50
     61#define   USB_CTRL_CTLR_CSHCR_ctl_pme_en_MASK	0x00040000
     62
     63/* Register definitions for the USB_PHY block in 7211b0 */
     64#define USB_PHY_PLL_CTL			0x00
     65#define   USB_PHY_PLL_CTL_PLL_RESETB_MASK		0x40000000
     66#define USB_PHY_PLL_LDO_CTL		0x08
     67#define   USB_PHY_PLL_LDO_CTL_AFE_CORERDY_MASK		0x00000004
     68#define   USB_PHY_PLL_LDO_CTL_AFE_LDO_PWRDWNB_MASK	0x00000002
     69#define   USB_PHY_PLL_LDO_CTL_AFE_BG_PWRDWNB_MASK	0x00000001
     70#define USB_PHY_UTMI_CTL_1		0x04
     71#define   USB_PHY_UTMI_CTL_1_POWER_UP_FSM_EN_MASK	0x00000800
     72#define   USB_PHY_UTMI_CTL_1_PHY_MODE_MASK		0x0000000c
     73#define   USB_PHY_UTMI_CTL_1_PHY_MODE_SHIFT		2
     74#define USB_PHY_IDDQ			0x1c
     75#define   USB_PHY_IDDQ_phy_iddq_MASK			0x00000001
     76#define USB_PHY_STATUS			0x20
     77#define   USB_PHY_STATUS_pll_lock_MASK			0x00000001
     78
     79/* Register definitions for the MDIO registers in the DWC2 block of
     80 * the 7211b0.
     81 * NOTE: The PHY's MDIO registers are only accessible through the
     82 * legacy DesignWare USB controller even though it's not being used.
     83 */
     84#define USB_GMDIOCSR	0
     85#define USB_GMDIOGEN	4
     86
     87/* Register definitions for the BDC EC block in 7211b0 */
     88#define BDC_EC_AXIRDA			0x0c
     89#define   BDC_EC_AXIRDA_RTS_MASK			0xf0000000
     90#define   BDC_EC_AXIRDA_RTS_SHIFT			28
     91
     92
     93static void usb_mdio_write_7211b0(struct brcm_usb_init_params *params,
     94				  uint8_t addr, uint16_t data)
     95{
     96	void __iomem *usb_mdio = params->regs[BRCM_REGS_USB_MDIO];
     97
     98	addr &= 0x1f; /* 5-bit address */
     99	brcm_usb_writel(0xffffffff, usb_mdio + USB_GMDIOGEN);
    100	while (brcm_usb_readl(usb_mdio + USB_GMDIOCSR) & (1<<31))
    101		;
    102	brcm_usb_writel(0x59020000 | (addr << 18) | data,
    103			usb_mdio + USB_GMDIOGEN);
    104	while (brcm_usb_readl(usb_mdio + USB_GMDIOCSR) & (1<<31))
    105		;
    106	brcm_usb_writel(0x00000000, usb_mdio + USB_GMDIOGEN);
    107	while (brcm_usb_readl(usb_mdio + USB_GMDIOCSR) & (1<<31))
    108		;
    109}
    110
    111static uint16_t __maybe_unused usb_mdio_read_7211b0(
    112	struct brcm_usb_init_params *params, uint8_t addr)
    113{
    114	void __iomem *usb_mdio = params->regs[BRCM_REGS_USB_MDIO];
    115
    116	addr &= 0x1f; /* 5-bit address */
    117	brcm_usb_writel(0xffffffff, usb_mdio + USB_GMDIOGEN);
    118	while (brcm_usb_readl(usb_mdio + USB_GMDIOCSR) & (1<<31))
    119		;
    120	brcm_usb_writel(0x69020000 | (addr << 18), usb_mdio + USB_GMDIOGEN);
    121	while (brcm_usb_readl(usb_mdio + USB_GMDIOCSR) & (1<<31))
    122		;
    123	brcm_usb_writel(0x00000000, usb_mdio + USB_GMDIOGEN);
    124	while (brcm_usb_readl(usb_mdio + USB_GMDIOCSR) & (1<<31))
    125		;
    126	return brcm_usb_readl(usb_mdio + USB_GMDIOCSR) & 0xffff;
    127}
    128
    129static void usb2_eye_fix_7211b0(struct brcm_usb_init_params *params)
    130{
    131	/* select bank */
    132	usb_mdio_write_7211b0(params, 0x1f, 0x80a0);
    133
    134	/* Set the eye */
    135	usb_mdio_write_7211b0(params, 0x0a, 0xc6a0);
    136}
    137
    138static void xhci_soft_reset(struct brcm_usb_init_params *params,
    139			int on_off)
    140{
    141	void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
    142
    143	/* Assert reset */
    144	if (on_off)
    145		USB_CTRL_UNSET(ctrl, USB_PM, XHC_SOFT_RESETB);
    146	/* De-assert reset */
    147	else
    148		USB_CTRL_SET(ctrl, USB_PM, XHC_SOFT_RESETB);
    149}
    150
    151static void usb_init_ipp(struct brcm_usb_init_params *params)
    152{
    153	void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
    154	u32 reg;
    155	u32 orig_reg;
    156
    157	pr_debug("%s\n", __func__);
    158
    159	orig_reg = reg = brcm_usb_readl(USB_CTRL_REG(ctrl, SETUP));
    160	if (params->ipp != 2)
    161		/* override ipp strap pin (if it exits) */
    162		reg &= ~(USB_CTRL_MASK(SETUP, STRAP_IPP_SEL));
    163
    164	/* Override the default OC and PP polarity */
    165	reg &= ~(USB_CTRL_MASK(SETUP, IPP) | USB_CTRL_MASK(SETUP, IOC));
    166	if (params->ioc)
    167		reg |= USB_CTRL_MASK(SETUP, IOC);
    168	if (params->ipp == 1)
    169		reg |= USB_CTRL_MASK(SETUP, IPP);
    170	brcm_usb_writel(reg, USB_CTRL_REG(ctrl, SETUP));
    171
    172	/*
    173	 * If we're changing IPP, make sure power is off long enough
    174	 * to turn off any connected devices.
    175	 */
    176	if ((reg ^ orig_reg) & USB_CTRL_MASK(SETUP, IPP))
    177		msleep(50);
    178}
    179
    180static void syscon_piarbctl_init(struct regmap *rmap)
    181{
    182	/* Switch from legacy USB OTG controller to new STB USB controller */
    183	regmap_update_bits(rmap, PIARBCTL_MISC, PIARBCTL_MISC_USB_ONLY_MASK,
    184			   PIARBCTL_MISC_USB_SELECT_MASK |
    185			   PIARBCTL_MISC_USB_4G_SDRAM_MASK);
    186}
    187
    188static void usb_init_common(struct brcm_usb_init_params *params)
    189{
    190	u32 reg;
    191	void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
    192
    193	pr_debug("%s\n", __func__);
    194
    195	if (USB_CTRL_MASK(USB_DEVICE_CTL1, PORT_MODE)) {
    196		reg = brcm_usb_readl(USB_CTRL_REG(ctrl, USB_DEVICE_CTL1));
    197		reg &= ~USB_CTRL_MASK(USB_DEVICE_CTL1, PORT_MODE);
    198		reg |= params->mode;
    199		brcm_usb_writel(reg, USB_CTRL_REG(ctrl, USB_DEVICE_CTL1));
    200	}
    201	switch (params->mode) {
    202	case USB_CTLR_MODE_HOST:
    203		USB_CTRL_UNSET(ctrl, USB_PM, BDC_SOFT_RESETB);
    204		break;
    205	default:
    206		USB_CTRL_UNSET(ctrl, USB_PM, BDC_SOFT_RESETB);
    207		USB_CTRL_SET(ctrl, USB_PM, BDC_SOFT_RESETB);
    208		break;
    209	}
    210}
    211
    212static void usb_wake_enable_7211b0(struct brcm_usb_init_params *params,
    213				   bool enable)
    214{
    215	void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
    216
    217	if (enable)
    218		USB_CTRL_SET(ctrl, CTLR_CSHCR, ctl_pme_en);
    219	else
    220		USB_CTRL_UNSET(ctrl, CTLR_CSHCR, ctl_pme_en);
    221}
    222
    223static void usb_wake_enable_7216(struct brcm_usb_init_params *params,
    224				 bool enable)
    225{
    226	void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
    227
    228	if (enable)
    229		USB_CTRL_SET(ctrl, USB_PM, XHC_PME_EN);
    230	else
    231		USB_CTRL_UNSET(ctrl, USB_PM, XHC_PME_EN);
    232}
    233
    234static void usb_init_common_7211b0(struct brcm_usb_init_params *params)
    235{
    236	void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
    237	void __iomem *usb_phy = params->regs[BRCM_REGS_USB_PHY];
    238	void __iomem *bdc_ec = params->regs[BRCM_REGS_BDC_EC];
    239	int timeout_ms = PHY_LOCK_TIMEOUT_MS;
    240	u32 reg;
    241
    242	if (params->syscon_piarbctl)
    243		syscon_piarbctl_init(params->syscon_piarbctl);
    244
    245	USB_CTRL_UNSET(ctrl, USB_PM, USB_PWRDN);
    246
    247	usb_wake_enable_7211b0(params, false);
    248	if (!params->wake_enabled) {
    249
    250		/* undo possible suspend settings */
    251		brcm_usb_writel(0, usb_phy + USB_PHY_IDDQ);
    252		reg = brcm_usb_readl(usb_phy + USB_PHY_PLL_CTL);
    253		reg |= USB_PHY_PLL_CTL_PLL_RESETB_MASK;
    254		brcm_usb_writel(reg, usb_phy + USB_PHY_PLL_CTL);
    255
    256		/* temporarily enable FSM so PHY comes up properly */
    257		reg = brcm_usb_readl(usb_phy + USB_PHY_UTMI_CTL_1);
    258		reg |= USB_PHY_UTMI_CTL_1_POWER_UP_FSM_EN_MASK;
    259		brcm_usb_writel(reg, usb_phy + USB_PHY_UTMI_CTL_1);
    260	}
    261
    262	/* Init the PHY */
    263	reg = USB_PHY_PLL_LDO_CTL_AFE_CORERDY_MASK |
    264		USB_PHY_PLL_LDO_CTL_AFE_LDO_PWRDWNB_MASK |
    265		USB_PHY_PLL_LDO_CTL_AFE_BG_PWRDWNB_MASK;
    266	brcm_usb_writel(reg, usb_phy + USB_PHY_PLL_LDO_CTL);
    267
    268	/* wait for lock */
    269	while (timeout_ms-- > 0) {
    270		reg = brcm_usb_readl(usb_phy + USB_PHY_STATUS);
    271		if (reg & USB_PHY_STATUS_pll_lock_MASK)
    272			break;
    273		usleep_range(1000, 2000);
    274	}
    275
    276	/* Set the PHY_MODE */
    277	reg = brcm_usb_readl(usb_phy + USB_PHY_UTMI_CTL_1);
    278	reg &= ~USB_PHY_UTMI_CTL_1_PHY_MODE_MASK;
    279	reg |= params->mode << USB_PHY_UTMI_CTL_1_PHY_MODE_SHIFT;
    280	brcm_usb_writel(reg, usb_phy + USB_PHY_UTMI_CTL_1);
    281
    282	usb_init_common(params);
    283
    284	/*
    285	 * The BDC controller will get occasional failures with
    286	 * the default "Read Transaction Size" of 6 (1024 bytes).
    287	 * Set it to 4 (256 bytes).
    288	 */
    289	if ((params->mode != USB_CTLR_MODE_HOST) && bdc_ec) {
    290		reg = brcm_usb_readl(bdc_ec + BDC_EC_AXIRDA);
    291		reg &= ~BDC_EC_AXIRDA_RTS_MASK;
    292		reg |= (0x4 << BDC_EC_AXIRDA_RTS_SHIFT);
    293		brcm_usb_writel(reg, bdc_ec + BDC_EC_AXIRDA);
    294	}
    295
    296	/*
    297	 * Disable FSM, otherwise the PHY will auto suspend when no
    298	 * device is connected and will be reset on resume.
    299	 */
    300	reg = brcm_usb_readl(usb_phy + USB_PHY_UTMI_CTL_1);
    301	reg &= ~USB_PHY_UTMI_CTL_1_POWER_UP_FSM_EN_MASK;
    302	brcm_usb_writel(reg, usb_phy + USB_PHY_UTMI_CTL_1);
    303
    304	usb2_eye_fix_7211b0(params);
    305}
    306
    307static void usb_init_common_7216(struct brcm_usb_init_params *params)
    308{
    309	void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
    310
    311	USB_CTRL_UNSET(ctrl, USB_PM, XHC_S2_CLK_SWITCH_EN);
    312	USB_CTRL_UNSET(ctrl, USB_PM, USB_PWRDN);
    313
    314	/* 1 millisecond - for USB clocks to settle down */
    315	usleep_range(1000, 2000);
    316
    317	usb_wake_enable_7216(params, false);
    318	usb_init_common(params);
    319}
    320
    321static void usb_init_xhci(struct brcm_usb_init_params *params)
    322{
    323	pr_debug("%s\n", __func__);
    324
    325	xhci_soft_reset(params, 0);
    326}
    327
    328static void usb_uninit_common_7216(struct brcm_usb_init_params *params)
    329{
    330	void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
    331
    332	pr_debug("%s\n", __func__);
    333
    334	if (!params->wake_enabled) {
    335		USB_CTRL_SET(ctrl, USB_PM, USB_PWRDN);
    336
    337		/* Switch to using slower clock during suspend to save power */
    338		USB_CTRL_SET(ctrl, USB_PM, XHC_S2_CLK_SWITCH_EN);
    339	} else {
    340		usb_wake_enable_7216(params, true);
    341	}
    342}
    343
    344static void usb_uninit_common_7211b0(struct brcm_usb_init_params *params)
    345{
    346	void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
    347	void __iomem *usb_phy = params->regs[BRCM_REGS_USB_PHY];
    348	u32 reg;
    349
    350	pr_debug("%s\n", __func__);
    351
    352	if (params->wake_enabled) {
    353		USB_CTRL_SET(ctrl, TEST_PORT_CTL, TPOUT_SEL_PME_GEN);
    354		usb_wake_enable_7211b0(params, true);
    355	} else {
    356		USB_CTRL_SET(ctrl, USB_PM, USB_PWRDN);
    357		brcm_usb_writel(0, usb_phy + USB_PHY_PLL_LDO_CTL);
    358		reg = brcm_usb_readl(usb_phy + USB_PHY_PLL_CTL);
    359		reg &= ~USB_PHY_PLL_CTL_PLL_RESETB_MASK;
    360		brcm_usb_writel(reg, usb_phy + USB_PHY_PLL_CTL);
    361		brcm_usb_writel(USB_PHY_IDDQ_phy_iddq_MASK,
    362				usb_phy + USB_PHY_IDDQ);
    363	}
    364
    365}
    366
    367static void usb_uninit_xhci(struct brcm_usb_init_params *params)
    368{
    369
    370	pr_debug("%s\n", __func__);
    371
    372	if (!params->wake_enabled)
    373		xhci_soft_reset(params, 1);
    374}
    375
    376static int usb_get_dual_select(struct brcm_usb_init_params *params)
    377{
    378	void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
    379	u32 reg = 0;
    380
    381	pr_debug("%s\n", __func__);
    382
    383	reg = brcm_usb_readl(USB_CTRL_REG(ctrl, USB_DEVICE_CTL1));
    384	reg &= USB_CTRL_MASK(USB_DEVICE_CTL1, PORT_MODE);
    385	return reg;
    386}
    387
    388static void usb_set_dual_select(struct brcm_usb_init_params *params, int mode)
    389{
    390	void __iomem *ctrl = params->regs[BRCM_REGS_CTRL];
    391	u32 reg;
    392
    393	pr_debug("%s\n", __func__);
    394
    395	reg = brcm_usb_readl(USB_CTRL_REG(ctrl, USB_DEVICE_CTL1));
    396	reg &= ~USB_CTRL_MASK(USB_DEVICE_CTL1, PORT_MODE);
    397	reg |= mode;
    398	brcm_usb_writel(reg, USB_CTRL_REG(ctrl, USB_DEVICE_CTL1));
    399}
    400
    401static const struct brcm_usb_init_ops bcm7216_ops = {
    402	.init_ipp = usb_init_ipp,
    403	.init_common = usb_init_common_7216,
    404	.init_xhci = usb_init_xhci,
    405	.uninit_common = usb_uninit_common_7216,
    406	.uninit_xhci = usb_uninit_xhci,
    407	.get_dual_select = usb_get_dual_select,
    408	.set_dual_select = usb_set_dual_select,
    409};
    410
    411static const struct brcm_usb_init_ops bcm7211b0_ops = {
    412	.init_ipp = usb_init_ipp,
    413	.init_common = usb_init_common_7211b0,
    414	.init_xhci = usb_init_xhci,
    415	.uninit_common = usb_uninit_common_7211b0,
    416	.uninit_xhci = usb_uninit_xhci,
    417	.get_dual_select = usb_get_dual_select,
    418	.set_dual_select = usb_set_dual_select,
    419};
    420
    421void brcm_usb_dvr_init_7216(struct brcm_usb_init_params *params)
    422{
    423
    424	pr_debug("%s\n", __func__);
    425
    426	params->family_name = "7216";
    427	params->ops = &bcm7216_ops;
    428	params->suspend_with_clocks = true;
    429}
    430
    431void brcm_usb_dvr_init_7211b0(struct brcm_usb_init_params *params)
    432{
    433
    434	pr_debug("%s\n", __func__);
    435
    436	params->family_name = "7211";
    437	params->ops = &bcm7211b0_ops;
    438	params->suspend_with_clocks = true;
    439}