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

emac-sgmii-fsm9900.c (7588B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
      3 */
      4
      5/* Qualcomm Technologies, Inc. FSM9900 EMAC SGMII Controller driver.
      6 */
      7
      8#include <linux/iopoll.h>
      9#include "emac.h"
     10
     11/* EMAC_QSERDES register offsets */
     12#define EMAC_QSERDES_COM_SYS_CLK_CTRL		0x0000
     13#define EMAC_QSERDES_COM_PLL_CNTRL		0x0014
     14#define EMAC_QSERDES_COM_PLL_IP_SETI		0x0018
     15#define EMAC_QSERDES_COM_PLL_CP_SETI		0x0024
     16#define EMAC_QSERDES_COM_PLL_IP_SETP		0x0028
     17#define EMAC_QSERDES_COM_PLL_CP_SETP		0x002c
     18#define EMAC_QSERDES_COM_SYSCLK_EN_SEL		0x0038
     19#define EMAC_QSERDES_COM_RESETSM_CNTRL		0x0040
     20#define EMAC_QSERDES_COM_PLLLOCK_CMP1		0x0044
     21#define EMAC_QSERDES_COM_PLLLOCK_CMP2		0x0048
     22#define EMAC_QSERDES_COM_PLLLOCK_CMP3		0x004c
     23#define EMAC_QSERDES_COM_PLLLOCK_CMP_EN		0x0050
     24#define EMAC_QSERDES_COM_DEC_START1		0x0064
     25#define EMAC_QSERDES_COM_DIV_FRAC_START1	0x0098
     26#define EMAC_QSERDES_COM_DIV_FRAC_START2	0x009c
     27#define EMAC_QSERDES_COM_DIV_FRAC_START3	0x00a0
     28#define EMAC_QSERDES_COM_DEC_START2		0x00a4
     29#define EMAC_QSERDES_COM_PLL_CRCTRL		0x00ac
     30#define EMAC_QSERDES_COM_RESET_SM		0x00bc
     31#define EMAC_QSERDES_TX_BIST_MODE_LANENO	0x0100
     32#define EMAC_QSERDES_TX_TX_EMP_POST1_LVL	0x0108
     33#define EMAC_QSERDES_TX_TX_DRV_LVL		0x010c
     34#define EMAC_QSERDES_TX_LANE_MODE		0x0150
     35#define EMAC_QSERDES_TX_TRAN_DRVR_EMP_EN	0x0170
     36#define EMAC_QSERDES_RX_CDR_CONTROL		0x0200
     37#define EMAC_QSERDES_RX_CDR_CONTROL2		0x0210
     38#define EMAC_QSERDES_RX_RX_EQ_GAIN12		0x0230
     39
     40/* EMAC_SGMII register offsets */
     41#define EMAC_SGMII_PHY_SERDES_START		0x0000
     42#define EMAC_SGMII_PHY_CMN_PWR_CTRL		0x0004
     43#define EMAC_SGMII_PHY_RX_PWR_CTRL		0x0008
     44#define EMAC_SGMII_PHY_TX_PWR_CTRL		0x000C
     45#define EMAC_SGMII_PHY_LANE_CTRL1		0x0018
     46#define EMAC_SGMII_PHY_CDR_CTRL0		0x0058
     47#define EMAC_SGMII_PHY_POW_DWN_CTRL0		0x0080
     48#define EMAC_SGMII_PHY_INTERRUPT_MASK		0x00b4
     49
     50#define PLL_IPSETI(x)				((x) & 0x3f)
     51
     52#define PLL_CPSETI(x)				((x) & 0xff)
     53
     54#define PLL_IPSETP(x)				((x) & 0x3f)
     55
     56#define PLL_CPSETP(x)				((x) & 0x1f)
     57
     58#define PLL_RCTRL(x)				(((x) & 0xf) << 4)
     59#define PLL_CCTRL(x)				((x) & 0xf)
     60
     61#define LANE_MODE(x)				((x) & 0x1f)
     62
     63#define SYSCLK_CM				BIT(4)
     64#define SYSCLK_AC_COUPLE			BIT(3)
     65
     66#define OCP_EN					BIT(5)
     67#define PLL_DIV_FFEN				BIT(2)
     68#define PLL_DIV_ORD				BIT(1)
     69
     70#define SYSCLK_SEL_CMOS				BIT(3)
     71
     72#define FRQ_TUNE_MODE				BIT(4)
     73
     74#define PLLLOCK_CMP_EN				BIT(0)
     75
     76#define DEC_START1_MUX				BIT(7)
     77#define DEC_START1(x)				((x) & 0x7f)
     78
     79#define DIV_FRAC_START_MUX			BIT(7)
     80#define DIV_FRAC_START(x)			((x) & 0x7f)
     81
     82#define DIV_FRAC_START3_MUX			BIT(4)
     83#define DIV_FRAC_START3(x)			((x) & 0xf)
     84
     85#define DEC_START2_MUX				BIT(1)
     86#define DEC_START2				BIT(0)
     87
     88#define READY					BIT(5)
     89
     90#define TX_EMP_POST1_LVL_MUX			BIT(5)
     91#define TX_EMP_POST1_LVL(x)			((x) & 0x1f)
     92
     93#define TX_DRV_LVL_MUX				BIT(4)
     94#define TX_DRV_LVL(x)				((x) & 0xf)
     95
     96#define EMP_EN_MUX				BIT(1)
     97#define EMP_EN					BIT(0)
     98
     99#define SECONDORDERENABLE			BIT(6)
    100#define FIRSTORDER_THRESH(x)			(((x) & 0x7) << 3)
    101#define SECONDORDERGAIN(x)			((x) & 0x7)
    102
    103#define RX_EQ_GAIN2(x)				(((x) & 0xf) << 4)
    104#define RX_EQ_GAIN1(x)				((x) & 0xf)
    105
    106#define SERDES_START				BIT(0)
    107
    108#define BIAS_EN					BIT(6)
    109#define PLL_EN					BIT(5)
    110#define SYSCLK_EN				BIT(4)
    111#define CLKBUF_L_EN				BIT(3)
    112#define PLL_TXCLK_EN				BIT(1)
    113#define PLL_RXCLK_EN				BIT(0)
    114
    115#define L0_RX_SIGDET_EN				BIT(7)
    116#define L0_RX_TERM_MODE(x)			(((x) & 3) << 4)
    117#define L0_RX_I_EN				BIT(1)
    118
    119#define L0_TX_EN				BIT(5)
    120#define L0_CLKBUF_EN				BIT(4)
    121#define L0_TRAN_BIAS_EN				BIT(1)
    122
    123#define L0_RX_EQUALIZE_ENABLE			BIT(6)
    124#define L0_RESET_TSYNC_EN			BIT(4)
    125#define L0_DRV_LVL(x)				((x) & 0xf)
    126
    127#define PWRDN_B					BIT(0)
    128#define CDR_MAX_CNT(x)				((x) & 0xff)
    129
    130#define PLLLOCK_CMP(x)				((x) & 0xff)
    131
    132#define SERDES_START_WAIT_TIMES			100
    133
    134struct emac_reg_write {
    135	unsigned int offset;
    136	u32 val;
    137};
    138
    139static void emac_reg_write_all(void __iomem *base,
    140			       const struct emac_reg_write *itr, size_t size)
    141{
    142	size_t i;
    143
    144	for (i = 0; i < size; ++itr, ++i)
    145		writel(itr->val, base + itr->offset);
    146}
    147
    148static const struct emac_reg_write physical_coding_sublayer_programming[] = {
    149	{EMAC_SGMII_PHY_CDR_CTRL0, CDR_MAX_CNT(15)},
    150	{EMAC_SGMII_PHY_POW_DWN_CTRL0, PWRDN_B},
    151	{EMAC_SGMII_PHY_CMN_PWR_CTRL,
    152		BIAS_EN | SYSCLK_EN | CLKBUF_L_EN | PLL_TXCLK_EN | PLL_RXCLK_EN},
    153	{EMAC_SGMII_PHY_TX_PWR_CTRL, L0_TX_EN | L0_CLKBUF_EN | L0_TRAN_BIAS_EN},
    154	{EMAC_SGMII_PHY_RX_PWR_CTRL,
    155		L0_RX_SIGDET_EN | L0_RX_TERM_MODE(1) | L0_RX_I_EN},
    156	{EMAC_SGMII_PHY_CMN_PWR_CTRL,
    157		BIAS_EN | PLL_EN | SYSCLK_EN | CLKBUF_L_EN | PLL_TXCLK_EN |
    158		PLL_RXCLK_EN},
    159	{EMAC_SGMII_PHY_LANE_CTRL1,
    160		L0_RX_EQUALIZE_ENABLE | L0_RESET_TSYNC_EN | L0_DRV_LVL(15)},
    161};
    162
    163static const struct emac_reg_write sysclk_refclk_setting[] = {
    164	{EMAC_QSERDES_COM_SYSCLK_EN_SEL, SYSCLK_SEL_CMOS},
    165	{EMAC_QSERDES_COM_SYS_CLK_CTRL,	SYSCLK_CM | SYSCLK_AC_COUPLE},
    166};
    167
    168static const struct emac_reg_write pll_setting[] = {
    169	{EMAC_QSERDES_COM_PLL_IP_SETI, PLL_IPSETI(1)},
    170	{EMAC_QSERDES_COM_PLL_CP_SETI, PLL_CPSETI(59)},
    171	{EMAC_QSERDES_COM_PLL_IP_SETP, PLL_IPSETP(10)},
    172	{EMAC_QSERDES_COM_PLL_CP_SETP, PLL_CPSETP(9)},
    173	{EMAC_QSERDES_COM_PLL_CRCTRL, PLL_RCTRL(15) | PLL_CCTRL(11)},
    174	{EMAC_QSERDES_COM_PLL_CNTRL, OCP_EN | PLL_DIV_FFEN | PLL_DIV_ORD},
    175	{EMAC_QSERDES_COM_DEC_START1, DEC_START1_MUX | DEC_START1(2)},
    176	{EMAC_QSERDES_COM_DEC_START2, DEC_START2_MUX | DEC_START2},
    177	{EMAC_QSERDES_COM_DIV_FRAC_START1,
    178		DIV_FRAC_START_MUX | DIV_FRAC_START(85)},
    179	{EMAC_QSERDES_COM_DIV_FRAC_START2,
    180		DIV_FRAC_START_MUX | DIV_FRAC_START(42)},
    181	{EMAC_QSERDES_COM_DIV_FRAC_START3,
    182		DIV_FRAC_START3_MUX | DIV_FRAC_START3(3)},
    183	{EMAC_QSERDES_COM_PLLLOCK_CMP1, PLLLOCK_CMP(43)},
    184	{EMAC_QSERDES_COM_PLLLOCK_CMP2, PLLLOCK_CMP(104)},
    185	{EMAC_QSERDES_COM_PLLLOCK_CMP3, PLLLOCK_CMP(0)},
    186	{EMAC_QSERDES_COM_PLLLOCK_CMP_EN, PLLLOCK_CMP_EN},
    187	{EMAC_QSERDES_COM_RESETSM_CNTRL, FRQ_TUNE_MODE},
    188};
    189
    190static const struct emac_reg_write cdr_setting[] = {
    191	{EMAC_QSERDES_RX_CDR_CONTROL,
    192		SECONDORDERENABLE | FIRSTORDER_THRESH(3) | SECONDORDERGAIN(2)},
    193	{EMAC_QSERDES_RX_CDR_CONTROL2,
    194		SECONDORDERENABLE | FIRSTORDER_THRESH(3) | SECONDORDERGAIN(4)},
    195};
    196
    197static const struct emac_reg_write tx_rx_setting[] = {
    198	{EMAC_QSERDES_TX_BIST_MODE_LANENO, 0},
    199	{EMAC_QSERDES_TX_TX_DRV_LVL, TX_DRV_LVL_MUX | TX_DRV_LVL(15)},
    200	{EMAC_QSERDES_TX_TRAN_DRVR_EMP_EN, EMP_EN_MUX | EMP_EN},
    201	{EMAC_QSERDES_TX_TX_EMP_POST1_LVL,
    202		TX_EMP_POST1_LVL_MUX | TX_EMP_POST1_LVL(1)},
    203	{EMAC_QSERDES_RX_RX_EQ_GAIN12, RX_EQ_GAIN2(15) | RX_EQ_GAIN1(15)},
    204	{EMAC_QSERDES_TX_LANE_MODE, LANE_MODE(8)},
    205};
    206
    207int emac_sgmii_init_fsm9900(struct emac_adapter *adpt)
    208{
    209	struct emac_sgmii *phy = &adpt->phy;
    210	unsigned int i;
    211
    212	emac_reg_write_all(phy->base, physical_coding_sublayer_programming,
    213			   ARRAY_SIZE(physical_coding_sublayer_programming));
    214	emac_reg_write_all(phy->base, sysclk_refclk_setting,
    215			   ARRAY_SIZE(sysclk_refclk_setting));
    216	emac_reg_write_all(phy->base, pll_setting, ARRAY_SIZE(pll_setting));
    217	emac_reg_write_all(phy->base, cdr_setting, ARRAY_SIZE(cdr_setting));
    218	emac_reg_write_all(phy->base, tx_rx_setting, ARRAY_SIZE(tx_rx_setting));
    219
    220	/* Power up the Ser/Des engine */
    221	writel(SERDES_START, phy->base + EMAC_SGMII_PHY_SERDES_START);
    222
    223	for (i = 0; i < SERDES_START_WAIT_TIMES; i++) {
    224		if (readl(phy->base + EMAC_QSERDES_COM_RESET_SM) & READY)
    225			break;
    226		usleep_range(100, 200);
    227	}
    228
    229	if (i == SERDES_START_WAIT_TIMES) {
    230		netdev_err(adpt->netdev, "error: ser/des failed to start\n");
    231		return -EIO;
    232	}
    233	/* Mask out all the SGMII Interrupt */
    234	writel(0, phy->base + EMAC_SGMII_PHY_INTERRUPT_MASK);
    235
    236	return 0;
    237}