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-cadence-salvo.c (10043B)


      1// SPDX-License-Identifier: GPL-2.0+
      2/*
      3 * Salvo PHY is a 28nm PHY, it is a legacy PHY, and only
      4 * for USB3 and USB2.
      5 *
      6 * Copyright (c) 2019-2020 NXP
      7 */
      8
      9#include <linux/clk.h>
     10#include <linux/io.h>
     11#include <linux/module.h>
     12#include <linux/phy/phy.h>
     13#include <linux/platform_device.h>
     14#include <linux/delay.h>
     15#include <linux/of.h>
     16#include <linux/of_platform.h>
     17
     18/* PHY register definition */
     19#define PHY_PMA_CMN_CTRL1			0xC800
     20#define TB_ADDR_CMN_DIAG_HSCLK_SEL		0x01e0
     21#define TB_ADDR_CMN_PLL0_VCOCAL_INIT_TMR	0x0084
     22#define TB_ADDR_CMN_PLL0_VCOCAL_ITER_TMR	0x0085
     23#define TB_ADDR_CMN_PLL0_INTDIV	                0x0094
     24#define TB_ADDR_CMN_PLL0_FRACDIV		0x0095
     25#define TB_ADDR_CMN_PLL0_HIGH_THR		0x0096
     26#define TB_ADDR_CMN_PLL0_SS_CTRL1		0x0098
     27#define TB_ADDR_CMN_PLL0_SS_CTRL2		0x0099
     28#define TB_ADDR_CMN_PLL0_DSM_DIAG		0x0097
     29#define TB_ADDR_CMN_DIAG_PLL0_OVRD		0x01c2
     30#define TB_ADDR_CMN_DIAG_PLL0_FBH_OVRD		0x01c0
     31#define TB_ADDR_CMN_DIAG_PLL0_FBL_OVRD		0x01c1
     32#define TB_ADDR_CMN_DIAG_PLL0_V2I_TUNE          0x01C5
     33#define TB_ADDR_CMN_DIAG_PLL0_CP_TUNE           0x01C6
     34#define TB_ADDR_CMN_DIAG_PLL0_LF_PROG           0x01C7
     35#define TB_ADDR_CMN_DIAG_PLL0_TEST_MODE		0x01c4
     36#define TB_ADDR_CMN_PSM_CLK_CTRL		0x0061
     37#define TB_ADDR_XCVR_DIAG_RX_LANE_CAL_RST_TMR	0x40ea
     38#define TB_ADDR_XCVR_PSM_RCTRL	                0x4001
     39#define TB_ADDR_TX_PSC_A0		        0x4100
     40#define TB_ADDR_TX_PSC_A1		        0x4101
     41#define TB_ADDR_TX_PSC_A2		        0x4102
     42#define TB_ADDR_TX_PSC_A3		        0x4103
     43#define TB_ADDR_TX_DIAG_ECTRL_OVRD		0x41f5
     44#define TB_ADDR_TX_PSC_CAL		        0x4106
     45#define TB_ADDR_TX_PSC_RDY		        0x4107
     46#define TB_ADDR_RX_PSC_A0	                0x8000
     47#define TB_ADDR_RX_PSC_A1	                0x8001
     48#define TB_ADDR_RX_PSC_A2	                0x8002
     49#define TB_ADDR_RX_PSC_A3	                0x8003
     50#define TB_ADDR_RX_PSC_CAL	                0x8006
     51#define TB_ADDR_RX_PSC_RDY	                0x8007
     52#define TB_ADDR_TX_TXCC_MGNLS_MULT_000		0x4058
     53#define TB_ADDR_TX_DIAG_BGREF_PREDRV_DELAY	0x41e7
     54#define TB_ADDR_RX_SLC_CU_ITER_TMR		0x80e3
     55#define TB_ADDR_RX_SIGDET_HL_FILT_TMR		0x8090
     56#define TB_ADDR_RX_SAMP_DAC_CTRL		0x8058
     57#define TB_ADDR_RX_DIAG_SIGDET_TUNE		0x81dc
     58#define TB_ADDR_RX_DIAG_LFPSDET_TUNE2		0x81df
     59#define TB_ADDR_RX_DIAG_BS_TM	                0x81f5
     60#define TB_ADDR_RX_DIAG_DFE_CTRL1		0x81d3
     61#define TB_ADDR_RX_DIAG_ILL_IQE_TRIM4		0x81c7
     62#define TB_ADDR_RX_DIAG_ILL_E_TRIM0		0x81c2
     63#define TB_ADDR_RX_DIAG_ILL_IQ_TRIM0		0x81c1
     64#define TB_ADDR_RX_DIAG_ILL_IQE_TRIM6		0x81c9
     65#define TB_ADDR_RX_DIAG_RXFE_TM3		0x81f8
     66#define TB_ADDR_RX_DIAG_RXFE_TM4		0x81f9
     67#define TB_ADDR_RX_DIAG_LFPSDET_TUNE		0x81dd
     68#define TB_ADDR_RX_DIAG_DFE_CTRL3		0x81d5
     69#define TB_ADDR_RX_DIAG_SC2C_DELAY		0x81e1
     70#define TB_ADDR_RX_REE_VGA_GAIN_NODFE		0x81bf
     71#define TB_ADDR_XCVR_PSM_CAL_TMR		0x4002
     72#define TB_ADDR_XCVR_PSM_A0BYP_TMR		0x4004
     73#define TB_ADDR_XCVR_PSM_A0IN_TMR		0x4003
     74#define TB_ADDR_XCVR_PSM_A1IN_TMR		0x4005
     75#define TB_ADDR_XCVR_PSM_A2IN_TMR		0x4006
     76#define TB_ADDR_XCVR_PSM_A3IN_TMR		0x4007
     77#define TB_ADDR_XCVR_PSM_A4IN_TMR		0x4008
     78#define TB_ADDR_XCVR_PSM_A5IN_TMR		0x4009
     79#define TB_ADDR_XCVR_PSM_A0OUT_TMR		0x400a
     80#define TB_ADDR_XCVR_PSM_A1OUT_TMR		0x400b
     81#define TB_ADDR_XCVR_PSM_A2OUT_TMR		0x400c
     82#define TB_ADDR_XCVR_PSM_A3OUT_TMR		0x400d
     83#define TB_ADDR_XCVR_PSM_A4OUT_TMR		0x400e
     84#define TB_ADDR_XCVR_PSM_A5OUT_TMR		0x400f
     85#define TB_ADDR_TX_RCVDET_EN_TMR	        0x4122
     86#define TB_ADDR_TX_RCVDET_ST_TMR	        0x4123
     87#define TB_ADDR_XCVR_DIAG_LANE_FCM_EN_MGN_TMR	0x40f2
     88#define TB_ADDR_TX_RCVDETSC_CTRL	        0x4124
     89
     90/* TB_ADDR_TX_RCVDETSC_CTRL */
     91#define RXDET_IN_P3_32KHZ			BIT(0)
     92
     93struct cdns_reg_pairs {
     94	u16 val;
     95	u32 off;
     96};
     97
     98struct cdns_salvo_data {
     99	u8 reg_offset_shift;
    100	const struct cdns_reg_pairs *init_sequence_val;
    101	u8 init_sequence_length;
    102};
    103
    104struct cdns_salvo_phy {
    105	struct phy *phy;
    106	struct clk *clk;
    107	void __iomem *base;
    108	struct cdns_salvo_data *data;
    109};
    110
    111static const struct of_device_id cdns_salvo_phy_of_match[];
    112static u16 cdns_salvo_read(struct cdns_salvo_phy *salvo_phy, u32 reg)
    113{
    114	return (u16)readl(salvo_phy->base +
    115		reg * (1 << salvo_phy->data->reg_offset_shift));
    116}
    117
    118static void cdns_salvo_write(struct cdns_salvo_phy *salvo_phy,
    119			     u32 reg, u16 val)
    120{
    121	writel(val, salvo_phy->base +
    122		reg * (1 << salvo_phy->data->reg_offset_shift));
    123}
    124
    125/*
    126 * Below bringup sequence pair are from Cadence PHY's User Guide
    127 * and NXP platform tuning results.
    128 */
    129static const struct cdns_reg_pairs cdns_nxp_sequence_pair[] = {
    130	{0x0830, PHY_PMA_CMN_CTRL1},
    131	{0x0010, TB_ADDR_CMN_DIAG_HSCLK_SEL},
    132	{0x00f0, TB_ADDR_CMN_PLL0_VCOCAL_INIT_TMR},
    133	{0x0018, TB_ADDR_CMN_PLL0_VCOCAL_ITER_TMR},
    134	{0x00d0, TB_ADDR_CMN_PLL0_INTDIV},
    135	{0x4aaa, TB_ADDR_CMN_PLL0_FRACDIV},
    136	{0x0034, TB_ADDR_CMN_PLL0_HIGH_THR},
    137	{0x01ee, TB_ADDR_CMN_PLL0_SS_CTRL1},
    138	{0x7f03, TB_ADDR_CMN_PLL0_SS_CTRL2},
    139	{0x0020, TB_ADDR_CMN_PLL0_DSM_DIAG},
    140	{0x0000, TB_ADDR_CMN_DIAG_PLL0_OVRD},
    141	{0x0000, TB_ADDR_CMN_DIAG_PLL0_FBH_OVRD},
    142	{0x0000, TB_ADDR_CMN_DIAG_PLL0_FBL_OVRD},
    143	{0x0007, TB_ADDR_CMN_DIAG_PLL0_V2I_TUNE},
    144	{0x0027, TB_ADDR_CMN_DIAG_PLL0_CP_TUNE},
    145	{0x0008, TB_ADDR_CMN_DIAG_PLL0_LF_PROG},
    146	{0x0022, TB_ADDR_CMN_DIAG_PLL0_TEST_MODE},
    147	{0x000a, TB_ADDR_CMN_PSM_CLK_CTRL},
    148	{0x0139, TB_ADDR_XCVR_DIAG_RX_LANE_CAL_RST_TMR},
    149	{0xbefc, TB_ADDR_XCVR_PSM_RCTRL},
    150
    151	{0x7799, TB_ADDR_TX_PSC_A0},
    152	{0x7798, TB_ADDR_TX_PSC_A1},
    153	{0x509b, TB_ADDR_TX_PSC_A2},
    154	{0x0003, TB_ADDR_TX_DIAG_ECTRL_OVRD},
    155	{0x509b, TB_ADDR_TX_PSC_A3},
    156	{0x2090, TB_ADDR_TX_PSC_CAL},
    157	{0x2090, TB_ADDR_TX_PSC_RDY},
    158
    159	{0xA6FD, TB_ADDR_RX_PSC_A0},
    160	{0xA6FD, TB_ADDR_RX_PSC_A1},
    161	{0xA410, TB_ADDR_RX_PSC_A2},
    162	{0x2410, TB_ADDR_RX_PSC_A3},
    163
    164	{0x23FF, TB_ADDR_RX_PSC_CAL},
    165	{0x2010, TB_ADDR_RX_PSC_RDY},
    166
    167	{0x0020, TB_ADDR_TX_TXCC_MGNLS_MULT_000},
    168	{0x00ff, TB_ADDR_TX_DIAG_BGREF_PREDRV_DELAY},
    169	{0x0002, TB_ADDR_RX_SLC_CU_ITER_TMR},
    170	{0x0013, TB_ADDR_RX_SIGDET_HL_FILT_TMR},
    171	{0x0000, TB_ADDR_RX_SAMP_DAC_CTRL},
    172	{0x1004, TB_ADDR_RX_DIAG_SIGDET_TUNE},
    173	{0x4041, TB_ADDR_RX_DIAG_LFPSDET_TUNE2},
    174	{0x0480, TB_ADDR_RX_DIAG_BS_TM},
    175	{0x8006, TB_ADDR_RX_DIAG_DFE_CTRL1},
    176	{0x003f, TB_ADDR_RX_DIAG_ILL_IQE_TRIM4},
    177	{0x543f, TB_ADDR_RX_DIAG_ILL_E_TRIM0},
    178	{0x543f, TB_ADDR_RX_DIAG_ILL_IQ_TRIM0},
    179	{0x0000, TB_ADDR_RX_DIAG_ILL_IQE_TRIM6},
    180	{0x8000, TB_ADDR_RX_DIAG_RXFE_TM3},
    181	{0x0003, TB_ADDR_RX_DIAG_RXFE_TM4},
    182	{0x2408, TB_ADDR_RX_DIAG_LFPSDET_TUNE},
    183	{0x05ca, TB_ADDR_RX_DIAG_DFE_CTRL3},
    184	{0x0258, TB_ADDR_RX_DIAG_SC2C_DELAY},
    185	{0x1fff, TB_ADDR_RX_REE_VGA_GAIN_NODFE},
    186
    187	{0x02c6, TB_ADDR_XCVR_PSM_CAL_TMR},
    188	{0x0002, TB_ADDR_XCVR_PSM_A0BYP_TMR},
    189	{0x02c6, TB_ADDR_XCVR_PSM_A0IN_TMR},
    190	{0x0010, TB_ADDR_XCVR_PSM_A1IN_TMR},
    191	{0x0010, TB_ADDR_XCVR_PSM_A2IN_TMR},
    192	{0x0010, TB_ADDR_XCVR_PSM_A3IN_TMR},
    193	{0x0010, TB_ADDR_XCVR_PSM_A4IN_TMR},
    194	{0x0010, TB_ADDR_XCVR_PSM_A5IN_TMR},
    195
    196	{0x0002, TB_ADDR_XCVR_PSM_A0OUT_TMR},
    197	{0x0002, TB_ADDR_XCVR_PSM_A1OUT_TMR},
    198	{0x0002, TB_ADDR_XCVR_PSM_A2OUT_TMR},
    199	{0x0002, TB_ADDR_XCVR_PSM_A3OUT_TMR},
    200	{0x0002, TB_ADDR_XCVR_PSM_A4OUT_TMR},
    201	{0x0002, TB_ADDR_XCVR_PSM_A5OUT_TMR},
    202	/* Change rx detect parameter */
    203	{0x0960, TB_ADDR_TX_RCVDET_EN_TMR},
    204	{0x01e0, TB_ADDR_TX_RCVDET_ST_TMR},
    205	{0x0090, TB_ADDR_XCVR_DIAG_LANE_FCM_EN_MGN_TMR},
    206};
    207
    208static int cdns_salvo_phy_init(struct phy *phy)
    209{
    210	struct cdns_salvo_phy *salvo_phy = phy_get_drvdata(phy);
    211	struct cdns_salvo_data *data = salvo_phy->data;
    212	int ret, i;
    213	u16 value;
    214
    215	ret = clk_prepare_enable(salvo_phy->clk);
    216	if (ret)
    217		return ret;
    218
    219	for (i = 0; i < data->init_sequence_length; i++) {
    220		const struct cdns_reg_pairs *reg_pair = data->init_sequence_val + i;
    221
    222		cdns_salvo_write(salvo_phy, reg_pair->off, reg_pair->val);
    223	}
    224
    225	/* RXDET_IN_P3_32KHZ, Receiver detect slow clock enable */
    226	value = cdns_salvo_read(salvo_phy, TB_ADDR_TX_RCVDETSC_CTRL);
    227	value |= RXDET_IN_P3_32KHZ;
    228	cdns_salvo_write(salvo_phy, TB_ADDR_TX_RCVDETSC_CTRL,
    229			 RXDET_IN_P3_32KHZ);
    230
    231	udelay(10);
    232
    233	clk_disable_unprepare(salvo_phy->clk);
    234
    235	return ret;
    236}
    237
    238static int cdns_salvo_phy_power_on(struct phy *phy)
    239{
    240	struct cdns_salvo_phy *salvo_phy = phy_get_drvdata(phy);
    241
    242	return clk_prepare_enable(salvo_phy->clk);
    243}
    244
    245static int cdns_salvo_phy_power_off(struct phy *phy)
    246{
    247	struct cdns_salvo_phy *salvo_phy = phy_get_drvdata(phy);
    248
    249	clk_disable_unprepare(salvo_phy->clk);
    250
    251	return 0;
    252}
    253
    254static const struct phy_ops cdns_salvo_phy_ops = {
    255	.init		= cdns_salvo_phy_init,
    256	.power_on	= cdns_salvo_phy_power_on,
    257	.power_off	= cdns_salvo_phy_power_off,
    258	.owner		= THIS_MODULE,
    259};
    260
    261static int cdns_salvo_phy_probe(struct platform_device *pdev)
    262{
    263	struct phy_provider *phy_provider;
    264	struct device *dev = &pdev->dev;
    265	struct cdns_salvo_phy *salvo_phy;
    266	struct cdns_salvo_data *data;
    267
    268	data = (struct cdns_salvo_data *)of_device_get_match_data(dev);
    269	salvo_phy = devm_kzalloc(dev, sizeof(*salvo_phy), GFP_KERNEL);
    270	if (!salvo_phy)
    271		return -ENOMEM;
    272
    273	salvo_phy->data = data;
    274	salvo_phy->clk = devm_clk_get_optional(dev, "salvo_phy_clk");
    275	if (IS_ERR(salvo_phy->clk))
    276		return PTR_ERR(salvo_phy->clk);
    277
    278	salvo_phy->base = devm_platform_ioremap_resource(pdev, 0);
    279	if (IS_ERR(salvo_phy->base))
    280		return PTR_ERR(salvo_phy->base);
    281
    282	salvo_phy->phy = devm_phy_create(dev, NULL, &cdns_salvo_phy_ops);
    283	if (IS_ERR(salvo_phy->phy))
    284		return PTR_ERR(salvo_phy->phy);
    285
    286	phy_set_drvdata(salvo_phy->phy, salvo_phy);
    287
    288	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
    289	return PTR_ERR_OR_ZERO(phy_provider);
    290}
    291
    292static const struct cdns_salvo_data cdns_nxp_salvo_data = {
    293	2,
    294	cdns_nxp_sequence_pair,
    295	ARRAY_SIZE(cdns_nxp_sequence_pair),
    296};
    297
    298static const struct of_device_id cdns_salvo_phy_of_match[] = {
    299	{
    300		.compatible = "nxp,salvo-phy",
    301		.data = &cdns_nxp_salvo_data,
    302	},
    303	{}
    304};
    305MODULE_DEVICE_TABLE(of, cdns_salvo_phy_of_match);
    306
    307static struct platform_driver cdns_salvo_phy_driver = {
    308	.probe	= cdns_salvo_phy_probe,
    309	.driver = {
    310		.name	= "cdns-salvo-phy",
    311		.of_match_table	= cdns_salvo_phy_of_match,
    312	}
    313};
    314module_platform_driver(cdns_salvo_phy_driver);
    315
    316MODULE_AUTHOR("Peter Chen <peter.chen@nxp.com>");
    317MODULE_LICENSE("GPL v2");
    318MODULE_DESCRIPTION("Cadence SALVO PHY Driver");