linux/drivers/phy/phy-xgene.c

// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * AppliedMicro X-Gene Multi-purpose PHY driver
 *
 * Copyright (c) 2014, Applied Micro Circuits Corporation
 * Author: Loc Ho <[email protected]>
 *         Tuan Phan <[email protected]>
 *         Suman Tripathi <[email protected]>
 *
 * The APM X-Gene PHY consists of two PLL clock macro's (CMU) and lanes.
 * The first PLL clock macro is used for internal reference clock. The second
 * PLL clock macro is used to generate the clock for the PHY. This driver
 * configures the first PLL CMU, the second PLL CMU, and programs the PHY to
 * operate according to the mode of operation. The first PLL CMU is only
 * required if internal clock is enabled.
 *
 * Logical Layer Out Of HW module units:
 *
 * -----------------
 * | Internal      |    |------|
 * | Ref PLL CMU   |----|      |     -------------    ---------
 * ------------ ----    | MUX  |-----|PHY PLL CMU|----| Serdes|
 *                      |      |     |           |    ---------
 * External Clock ------|      |     -------------
 *                      |------|
 *
 * The Ref PLL CMU CSR (Configuration System Registers) is accessed
 * indirectly from the SDS offset at 0x2000. It is only required for
 * internal reference clock.
 * The PHY PLL CMU CSR is accessed indirectly from the SDS offset at 0x0000.
 * The Serdes CSR is accessed indirectly from the SDS offset at 0x0400.
 *
 * The Ref PLL CMU can be located within the same PHY IP or outside the PHY IP
 * due to shared Ref PLL CMU. For PHY with Ref PLL CMU shared with another IP,
 * it is located outside the PHY IP. This is the case for the PHY located
 * at 0x1f23a000 (SATA Port 4/5). For such PHY, another resource is required
 * to located the SDS/Ref PLL CMU module and its clock for that IP enabled.
 *
 * Currently, this driver only supports Gen3 SATA mode with external clock.
 */
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/delay.h>
#include <linux/phy/phy.h>
#include <linux/clk.h>

/* Max 2 lanes per a PHY unit */
#define MAX_LANE

/* Register offset inside the PHY */
#define SERDES_PLL_INDIRECT_OFFSET
#define SERDES_PLL_REF_INDIRECT_OFFSET
#define SERDES_INDIRECT_OFFSET
#define SERDES_LANE_STRIDE

/* Some default Serdes parameters */
#define DEFAULT_SATA_TXBOOST_GAIN
#define DEFAULT_SATA_TXEYEDIRECTION
#define DEFAULT_SATA_TXEYETUNING
#define DEFAULT_SATA_SPD_SEL
#define DEFAULT_SATA_TXAMP
#define DEFAULT_SATA_TXCN1
#define DEFAULT_SATA_TXCN2
#define DEFAULT_SATA_TXCP1

#define SATA_SPD_SEL_GEN3
#define SATA_SPD_SEL_GEN2
#define SATA_SPD_SEL_GEN1

#define SSC_DISABLE
#define SSC_ENABLE

#define FBDIV_VAL_50M
#define REFDIV_VAL_50M
#define FBDIV_VAL_100M
#define REFDIV_VAL_100M

/* SATA Clock/Reset CSR */
#define SATACLKENREG
#define SATA0_CORE_CLKEN
#define SATA1_CORE_CLKEN
#define SATASRESETREG
#define SATA_MEM_RESET_MASK
#define SATA_MEM_RESET_RD(src)
#define SATA_SDS_RESET_MASK
#define SATA_CSR_RESET_MASK
#define SATA_CORE_RESET_MASK
#define SATA_PMCLK_RESET_MASK
#define SATA_PCLK_RESET_MASK

/* SDS CSR used for PHY Indirect access */
#define SATA_ENET_SDS_PCS_CTL0
#define REGSPEC_CFG_I_TX_WORDMODE0_SET(dst, src)
#define REGSPEC_CFG_I_RX_WORDMODE0_SET(dst, src)
#define SATA_ENET_SDS_CTL0
#define REGSPEC_CFG_I_CUSTOMER_PIN_MODE0_SET(dst, src)
#define SATA_ENET_SDS_CTL1
#define CFG_I_SPD_SEL_CDR_OVR1_SET(dst, src)
#define SATA_ENET_SDS_RST_CTL
#define SATA_ENET_SDS_IND_CMD_REG
#define CFG_IND_WR_CMD_MASK
#define CFG_IND_RD_CMD_MASK
#define CFG_IND_CMD_DONE_MASK
#define CFG_IND_ADDR_SET(dst, src)
#define SATA_ENET_SDS_IND_RDATA_REG
#define SATA_ENET_SDS_IND_WDATA_REG
#define SATA_ENET_CLK_MACRO_REG
#define I_RESET_B_SET(dst, src)
#define I_PLL_FBDIV_SET(dst, src)
#define I_CUSTOMEROV_SET(dst, src)
#define O_PLL_LOCK_RD(src)
#define O_PLL_READY_RD(src)

/* PLL Clock Macro Unit (CMU) CSR accessing from SDS indirectly */
#define CMU_REG0
#define CMU_REG0_PLL_REF_SEL_MASK
#define CMU_REG0_PLL_REF_SEL_SET(dst, src)
#define CMU_REG0_PDOWN_MASK
#define CMU_REG0_CAL_COUNT_RESOL_SET(dst, src)
#define CMU_REG1
#define CMU_REG1_PLL_CP_SET(dst, src)
#define CMU_REG1_PLL_MANUALCAL_SET(dst, src)
#define CMU_REG1_PLL_CP_SEL_SET(dst, src)
#define CMU_REG1_REFCLK_CMOS_SEL_MASK
#define CMU_REG1_REFCLK_CMOS_SEL_SET(dst, src)
#define CMU_REG2
#define CMU_REG2_PLL_REFDIV_SET(dst, src)
#define CMU_REG2_PLL_LFRES_SET(dst, src)
#define CMU_REG2_PLL_FBDIV_SET(dst, src)
#define CMU_REG3
#define CMU_REG3_VCOVARSEL_SET(dst, src)
#define CMU_REG3_VCO_MOMSEL_INIT_SET(dst, src)
#define CMU_REG3_VCO_MANMOMSEL_SET(dst, src)
#define CMU_REG4
#define CMU_REG5
#define CMU_REG5_PLL_LFSMCAP_SET(dst, src)
#define CMU_REG5_PLL_LOCK_RESOLUTION_SET(dst, src)
#define CMU_REG5_PLL_LFCAP_SET(dst, src)
#define CMU_REG5_PLL_RESETB_MASK
#define CMU_REG6
#define CMU_REG6_PLL_VREGTRIM_SET(dst, src)
#define CMU_REG6_MAN_PVT_CAL_SET(dst, src)
#define CMU_REG7
#define CMU_REG7_PLL_CALIB_DONE_RD(src)
#define CMU_REG7_VCO_CAL_FAIL_RD(src)
#define CMU_REG8
#define CMU_REG9
#define CMU_REG9_WORD_LEN_8BIT
#define CMU_REG9_WORD_LEN_10BIT
#define CMU_REG9_WORD_LEN_16BIT
#define CMU_REG9_WORD_LEN_20BIT
#define CMU_REG9_WORD_LEN_32BIT
#define CMU_REG9_WORD_LEN_40BIT
#define CMU_REG9_WORD_LEN_64BIT
#define CMU_REG9_WORD_LEN_66BIT
#define CMU_REG9_TX_WORD_MODE_CH1_SET(dst, src)
#define CMU_REG9_TX_WORD_MODE_CH0_SET(dst, src)
#define CMU_REG9_PLL_POST_DIVBY2_SET(dst, src)
#define CMU_REG9_VBG_BYPASSB_SET(dst, src)
#define CMU_REG9_IGEN_BYPASS_SET(dst, src)
#define CMU_REG10
#define CMU_REG10_VREG_REFSEL_SET(dst, src)
#define CMU_REG11
#define CMU_REG12
#define CMU_REG12_STATE_DELAY9_SET(dst, src)
#define CMU_REG13
#define CMU_REG14
#define CMU_REG15
#define CMU_REG16
#define CMU_REG16_PVT_DN_MAN_ENA_MASK
#define CMU_REG16_PVT_UP_MAN_ENA_MASK
#define CMU_REG16_VCOCAL_WAIT_BTW_CODE_SET(dst, src)
#define CMU_REG16_CALIBRATION_DONE_OVERRIDE_SET(dst, src)
#define CMU_REG16_BYPASS_PLL_LOCK_SET(dst, src)
#define CMU_REG17
#define CMU_REG17_PVT_CODE_R2A_SET(dst, src)
#define CMU_REG17_RESERVED_7_SET(dst, src)
#define CMU_REG17_PVT_TERM_MAN_ENA_MASK
#define CMU_REG18
#define CMU_REG19
#define CMU_REG20
#define CMU_REG21
#define CMU_REG22
#define CMU_REG23
#define CMU_REG24
#define CMU_REG25
#define CMU_REG26
#define CMU_REG26_FORCE_PLL_LOCK_SET(dst, src)
#define CMU_REG27
#define CMU_REG28
#define CMU_REG29
#define CMU_REG30
#define CMU_REG30_LOCK_COUNT_SET(dst, src)
#define CMU_REG30_PCIE_MODE_SET(dst, src)
#define CMU_REG31
#define CMU_REG32
#define CMU_REG32_FORCE_VCOCAL_START_MASK
#define CMU_REG32_PVT_CAL_WAIT_SEL_SET(dst, src)
#define CMU_REG32_IREF_ADJ_SET(dst, src)
#define CMU_REG33
#define CMU_REG34
#define CMU_REG34_VCO_CAL_VTH_LO_MAX_SET(dst, src)
#define CMU_REG34_VCO_CAL_VTH_HI_MAX_SET(dst, src)
#define CMU_REG34_VCO_CAL_VTH_LO_MIN_SET(dst, src)
#define CMU_REG34_VCO_CAL_VTH_HI_MIN_SET(dst, src)
#define CMU_REG35
#define CMU_REG35_PLL_SSC_MOD_SET(dst, src)
#define CMU_REG36
#define CMU_REG36_PLL_SSC_EN_SET(dst, src)
#define CMU_REG36_PLL_SSC_VSTEP_SET(dst, src)
#define CMU_REG36_PLL_SSC_DSMSEL_SET(dst, src)
#define CMU_REG37
#define CMU_REG38
#define CMU_REG39

/* PHY lane CSR accessing from SDS indirectly */
#define RXTX_REG0
#define RXTX_REG0_CTLE_EQ_HR_SET(dst, src)
#define RXTX_REG0_CTLE_EQ_QR_SET(dst, src)
#define RXTX_REG0_CTLE_EQ_FR_SET(dst, src)
#define RXTX_REG1
#define RXTX_REG1_RXACVCM_SET(dst, src)
#define RXTX_REG1_CTLE_EQ_SET(dst, src)
#define RXTX_REG1_RXVREG1_SET(dst, src)
#define RXTX_REG1_RXIREF_ADJ_SET(dst, src)
#define RXTX_REG2
#define RXTX_REG2_VTT_ENA_SET(dst, src)
#define RXTX_REG2_TX_FIFO_ENA_SET(dst, src)
#define RXTX_REG2_VTT_SEL_SET(dst, src)
#define RXTX_REG4
#define RXTX_REG4_TX_LOOPBACK_BUF_EN_MASK
#define RXTX_REG4_TX_DATA_RATE_SET(dst, src)
#define RXTX_REG4_TX_WORD_MODE_SET(dst, src)
#define RXTX_REG5
#define RXTX_REG5_TX_CN1_SET(dst, src)
#define RXTX_REG5_TX_CP1_SET(dst, src)
#define RXTX_REG5_TX_CN2_SET(dst, src)
#define RXTX_REG6
#define RXTX_REG6_TXAMP_CNTL_SET(dst, src)
#define RXTX_REG6_TXAMP_ENA_SET(dst, src)
#define RXTX_REG6_RX_BIST_ERRCNT_RD_SET(dst, src)
#define RXTX_REG6_TX_IDLE_SET(dst, src)
#define RXTX_REG6_RX_BIST_RESYNC_SET(dst, src)
#define RXTX_REG7
#define RXTX_REG7_RESETB_RXD_MASK
#define RXTX_REG7_RESETB_RXA_MASK
#define RXTX_REG7_BIST_ENA_RX_SET(dst, src)
#define RXTX_REG7_RX_WORD_MODE_SET(dst, src)
#define RXTX_REG8
#define RXTX_REG8_CDR_LOOP_ENA_SET(dst, src)
#define RXTX_REG8_CDR_BYPASS_RXLOS_SET(dst, src)
#define RXTX_REG8_SSC_ENABLE_SET(dst, src)
#define RXTX_REG8_SD_VREF_SET(dst, src)
#define RXTX_REG8_SD_DISABLE_SET(dst, src)
#define RXTX_REG7
#define RXTX_REG7_RESETB_RXD_SET(dst, src)
#define RXTX_REG7_RESETB_RXA_SET(dst, src)
#define RXTX_REG7_LOOP_BACK_ENA_CTLE_MASK
#define RXTX_REG7_LOOP_BACK_ENA_CTLE_SET(dst, src)
#define RXTX_REG11
#define RXTX_REG11_PHASE_ADJUST_LIMIT_SET(dst, src)
#define RXTX_REG12
#define RXTX_REG12_LATCH_OFF_ENA_SET(dst, src)
#define RXTX_REG12_SUMOS_ENABLE_SET(dst, src)
#define RXTX_REG12_RX_DET_TERM_ENABLE_MASK
#define RXTX_REG12_RX_DET_TERM_ENABLE_SET(dst, src)
#define RXTX_REG13
#define RXTX_REG14
#define RXTX_REG14_CLTE_LATCAL_MAN_PROG_SET(dst, src)
#define RXTX_REG14_CTLE_LATCAL_MAN_ENA_SET(dst, src)
#define RXTX_REG26
#define RXTX_REG26_PERIOD_ERROR_LATCH_SET(dst, src)
#define RXTX_REG26_BLWC_ENA_SET(dst, src)
#define RXTX_REG21
#define RXTX_REG21_DO_LATCH_CALOUT_RD(src)
#define RXTX_REG21_XO_LATCH_CALOUT_RD(src)
#define RXTX_REG21_LATCH_CAL_FAIL_ODD_RD(src)
#define RXTX_REG22
#define RXTX_REG22_SO_LATCH_CALOUT_RD(src)
#define RXTX_REG22_EO_LATCH_CALOUT_RD(src)
#define RXTX_REG22_LATCH_CAL_FAIL_EVEN_RD(src)
#define RXTX_REG23
#define RXTX_REG23_DE_LATCH_CALOUT_RD(src)
#define RXTX_REG23_XE_LATCH_CALOUT_RD(src)
#define RXTX_REG24
#define RXTX_REG24_EE_LATCH_CALOUT_RD(src)
#define RXTX_REG24_SE_LATCH_CALOUT_RD(src)
#define RXTX_REG27
#define RXTX_REG28
#define RXTX_REG31
#define RXTX_REG38
#define RXTX_REG38_CUSTOMER_PINMODE_INV_SET(dst, src)
#define RXTX_REG39
#define RXTX_REG40
#define RXTX_REG41
#define RXTX_REG42
#define RXTX_REG43
#define RXTX_REG44
#define RXTX_REG45
#define RXTX_REG46
#define RXTX_REG47
#define RXTX_REG48
#define RXTX_REG49
#define RXTX_REG50
#define RXTX_REG51
#define RXTX_REG52
#define RXTX_REG53
#define RXTX_REG54
#define RXTX_REG55
#define RXTX_REG61
#define RXTX_REG61_ISCAN_INBERT_SET(dst, src)
#define RXTX_REG61_LOADFREQ_SHIFT_SET(dst, src)
#define RXTX_REG61_EYE_COUNT_WIDTH_SEL_SET(dst, src)
#define RXTX_REG61_SPD_SEL_CDR_SET(dst, src)
#define RXTX_REG62
#define RXTX_REG62_PERIOD_H1_QLATCH_SET(dst, src)
#define RXTX_REG81
#define RXTX_REG89_MU_TH7_SET(dst, src)
#define RXTX_REG89_MU_TH8_SET(dst, src)
#define RXTX_REG89_MU_TH9_SET(dst, src)
#define RXTX_REG96
#define RXTX_REG96_MU_FREQ1_SET(dst, src)
#define RXTX_REG96_MU_FREQ2_SET(dst, src)
#define RXTX_REG96_MU_FREQ3_SET(dst, src)
#define RXTX_REG99
#define RXTX_REG99_MU_PHASE1_SET(dst, src)
#define RXTX_REG99_MU_PHASE2_SET(dst, src)
#define RXTX_REG99_MU_PHASE3_SET(dst, src)
#define RXTX_REG102
#define RXTX_REG102_FREQLOOP_LIMIT_SET(dst, src)
#define RXTX_REG114
#define RXTX_REG121
#define RXTX_REG121_SUMOS_CAL_CODE_RD(src)
#define RXTX_REG125
#define RXTX_REG125_PQ_REG_SET(dst, src)
#define RXTX_REG125_SIGN_PQ_SET(dst, src)
#define RXTX_REG125_SIGN_PQ_2C_SET(dst, src)
#define RXTX_REG125_PHZ_MANUALCODE_SET(dst, src)
#define RXTX_REG125_PHZ_MANUAL_SET(dst, src)
#define RXTX_REG127
#define RXTX_REG127_FORCE_SUM_CAL_START_MASK
#define RXTX_REG127_FORCE_LAT_CAL_START_MASK
#define RXTX_REG127_FORCE_SUM_CAL_START_SET(dst, src)
#define RXTX_REG127_FORCE_LAT_CAL_START_SET(dst, src)
#define RXTX_REG127_LATCH_MAN_CAL_ENA_SET(dst, src)
#define RXTX_REG127_DO_LATCH_MANCAL_SET(dst, src)
#define RXTX_REG127_XO_LATCH_MANCAL_SET(dst, src)
#define RXTX_REG128
#define RXTX_REG128_LATCH_CAL_WAIT_SEL_SET(dst, src)
#define RXTX_REG128_EO_LATCH_MANCAL_SET(dst, src)
#define RXTX_REG128_SO_LATCH_MANCAL_SET(dst, src)
#define RXTX_REG129
#define RXTX_REG129_DE_LATCH_MANCAL_SET(dst, src)
#define RXTX_REG129_XE_LATCH_MANCAL_SET(dst, src)
#define RXTX_REG130
#define RXTX_REG130_EE_LATCH_MANCAL_SET(dst, src)
#define RXTX_REG130_SE_LATCH_MANCAL_SET(dst, src)
#define RXTX_REG145
#define RXTX_REG145_TX_IDLE_SATA_SET(dst, src)
#define RXTX_REG145_RXES_ENA_SET(dst, src)
#define RXTX_REG145_RXDFE_CONFIG_SET(dst, src)
#define RXTX_REG145_RXVWES_LATENA_SET(dst, src)
#define RXTX_REG147
#define RXTX_REG148

/* Clock macro type */
enum cmu_type_t {};

enum mux_type_t {};

enum clk_type_t {};

enum xgene_phy_mode {};

struct xgene_sata_override_param {};

struct xgene_phy_ctx {};

/*
 * For chip earlier than A3 version, enable this flag.
 * To enable, pass boot argument phy_xgene.preA3Chip=1
 */
static int preA3Chip;
MODULE_PARM_DESC();
module_param_named(preA3Chip, preA3Chip, int, 0444);

static void sds_wr(void __iomem *csr_base, u32 indirect_cmd_reg,
		   u32 indirect_data_reg, u32 addr, u32 data)
{}

static void sds_rd(void __iomem *csr_base, u32 indirect_cmd_reg,
		   u32 indirect_data_reg, u32 addr, u32 *data)
{}

static void cmu_wr(struct xgene_phy_ctx *ctx, enum cmu_type_t cmu_type,
		   u32 reg, u32 data)
{}

static void cmu_rd(struct xgene_phy_ctx *ctx, enum cmu_type_t cmu_type,
		   u32 reg, u32 *data)
{}

static void cmu_toggle1to0(struct xgene_phy_ctx *ctx, enum cmu_type_t cmu_type,
			   u32 reg, u32 bits)
{}

static void cmu_clrbits(struct xgene_phy_ctx *ctx, enum cmu_type_t cmu_type,
			u32 reg, u32 bits)
{}

static void cmu_setbits(struct xgene_phy_ctx *ctx, enum cmu_type_t cmu_type,
			u32 reg, u32 bits)
{}

static void serdes_wr(struct xgene_phy_ctx *ctx, int lane, u32 reg, u32 data)
{}

static void serdes_rd(struct xgene_phy_ctx *ctx, int lane, u32 reg, u32 *data)
{}

static void serdes_clrbits(struct xgene_phy_ctx *ctx, int lane, u32 reg,
			   u32 bits)
{}

static void serdes_setbits(struct xgene_phy_ctx *ctx, int lane, u32 reg,
			   u32 bits)
{}

static void xgene_phy_cfg_cmu_clk_type(struct xgene_phy_ctx *ctx,
				       enum cmu_type_t cmu_type,
				       enum clk_type_t clk_type)
{}

static void xgene_phy_sata_cfg_cmu_core(struct xgene_phy_ctx *ctx,
					enum cmu_type_t cmu_type,
					enum clk_type_t clk_type)
{}

static void xgene_phy_ssc_enable(struct xgene_phy_ctx *ctx,
				 enum cmu_type_t cmu_type)
{}

static void xgene_phy_sata_cfg_lanes(struct xgene_phy_ctx *ctx)
{}

static int xgene_phy_cal_rdy_chk(struct xgene_phy_ctx *ctx,
				 enum cmu_type_t cmu_type,
				 enum clk_type_t clk_type)
{}

static void xgene_phy_pdwn_force_vco(struct xgene_phy_ctx *ctx,
				     enum cmu_type_t cmu_type,
				     enum clk_type_t clk_type)
{}

static int xgene_phy_hw_init_sata(struct xgene_phy_ctx *ctx,
				  enum clk_type_t clk_type, int ssc_enable)
{}

static int xgene_phy_hw_initialize(struct xgene_phy_ctx *ctx,
				   enum clk_type_t clk_type,
				   int ssc_enable)
{}

/*
 * Receiver Offset Calibration:
 *
 * Calibrate the receiver signal path offset in two steps - summar and
 * latch calibrations
 */
static void xgene_phy_force_lat_summer_cal(struct xgene_phy_ctx *ctx, int lane)
{}

static void xgene_phy_reset_rxd(struct xgene_phy_ctx *ctx, int lane)
{}

static int xgene_phy_get_avg(int accum, int samples)
{}

static void xgene_phy_gen_avg_val(struct xgene_phy_ctx *ctx, int lane)
{}

static int xgene_phy_hw_init(struct phy *phy)
{}

static const struct phy_ops xgene_phy_ops =;

static struct phy *xgene_phy_xlate(struct device *dev,
				   const struct of_phandle_args *args)
{}

static void xgene_phy_get_param(struct platform_device *pdev,
				const char *name, u32 *buffer,
				int count, u32 *default_val,
				u32 conv_factor)
{}

static int xgene_phy_probe(struct platform_device *pdev)
{}

static const struct of_device_id xgene_phy_of_match[] =;
MODULE_DEVICE_TABLE(of, xgene_phy_of_match);

static struct platform_driver xgene_phy_driver =;
module_platform_driver();

MODULE_DESCRIPTION();
MODULE_AUTHOR();
MODULE_LICENSE();
MODULE_VERSION();