linux/drivers/phy/samsung/phy-exynos5-usbdrd.c

// SPDX-License-Identifier: GPL-2.0-only
/*
 * Samsung Exynos5 SoC series USB DRD PHY driver
 *
 * Phy provider for USB 3.0 DRD controller on Exynos5 SoC series
 *
 * Copyright (C) 2014 Samsung Electronics Co., Ltd.
 * Author: Vivek Gautam <[email protected]>
 */

#include <linux/bitfield.h>
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/iopoll.h>
#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/mutex.h>
#include <linux/mfd/syscon.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
#include <linux/soc/samsung/exynos-regs-pmu.h>

/* Exynos USB PHY registers */
#define EXYNOS5_FSEL_9MHZ6
#define EXYNOS5_FSEL_10MHZ
#define EXYNOS5_FSEL_12MHZ
#define EXYNOS5_FSEL_19MHZ2
#define EXYNOS5_FSEL_20MHZ
#define EXYNOS5_FSEL_24MHZ
#define EXYNOS5_FSEL_26MHZ
#define EXYNOS5_FSEL_50MHZ

/* Exynos5: USB 3.0 DRD PHY registers */
#define EXYNOS5_DRD_LINKSYSTEM
#define LINKSYSTEM_XHCI_VERSION_CONTROL
#define LINKSYSTEM_FLADJ_MASK
#define LINKSYSTEM_FLADJ(_x)

#define EXYNOS5_DRD_PHYUTMI
#define PHYUTMI_OTGDISABLE
#define PHYUTMI_FORCESUSPEND
#define PHYUTMI_FORCESLEEP

#define EXYNOS5_DRD_PHYPIPE

#define EXYNOS5_DRD_PHYCLKRST
#define PHYCLKRST_EN_UTMISUSPEND
#define PHYCLKRST_SSC_REFCLKSEL_MASK
#define PHYCLKRST_SSC_REFCLKSEL(_x)
#define PHYCLKRST_SSC_RANGE_MASK
#define PHYCLKRST_SSC_RANGE(_x)
#define PHYCLKRST_SSC_EN
#define PHYCLKRST_REF_SSP_EN
#define PHYCLKRST_REF_CLKDIV2
#define PHYCLKRST_MPLL_MULTIPLIER_MASK
#define PHYCLKRST_MPLL_MULTIPLIER_100MHZ_REF
#define PHYCLKRST_MPLL_MULTIPLIER_50M_REF
#define PHYCLKRST_MPLL_MULTIPLIER_24MHZ_REF
#define PHYCLKRST_MPLL_MULTIPLIER_20MHZ_REF
#define PHYCLKRST_MPLL_MULTIPLIER_19200KHZ_REF
#define PHYCLKRST_FSEL_PIPE_MASK
#define PHYCLKRST_FSEL_UTMI_MASK
#define PHYCLKRST_FSEL(_x)
#define PHYCLKRST_FSEL_PAD_100MHZ
#define PHYCLKRST_FSEL_PAD_24MHZ
#define PHYCLKRST_FSEL_PAD_20MHZ
#define PHYCLKRST_FSEL_PAD_19_2MHZ
#define PHYCLKRST_RETENABLEN
#define PHYCLKRST_REFCLKSEL_MASK
#define PHYCLKRST_REFCLKSEL_PAD_REFCLK
#define PHYCLKRST_REFCLKSEL_EXT_REFCLK
#define PHYCLKRST_PORTRESET
#define PHYCLKRST_COMMONONN

#define EXYNOS5_DRD_PHYREG0
#define PHYREG0_SSC_REF_CLK_SEL
#define PHYREG0_SSC_RANGE
#define PHYREG0_CR_WRITE
#define PHYREG0_CR_READ
#define PHYREG0_CR_DATA_IN(_x)
#define PHYREG0_CR_CAP_DATA
#define PHYREG0_CR_CAP_ADDR

#define EXYNOS5_DRD_PHYREG1
#define PHYREG1_CR_DATA_OUT(_x)
#define PHYREG1_CR_ACK

#define EXYNOS5_DRD_PHYPARAM0
#define PHYPARAM0_REF_USE_PAD
#define PHYPARAM0_REF_LOSLEVEL_MASK
#define PHYPARAM0_REF_LOSLEVEL

#define EXYNOS5_DRD_PHYPARAM1
#define PHYPARAM1_PCS_TXDEEMPH_MASK
#define PHYPARAM1_PCS_TXDEEMPH

#define EXYNOS5_DRD_PHYTERM

#define EXYNOS5_DRD_PHYTEST
#define PHYTEST_POWERDOWN_SSP
#define PHYTEST_POWERDOWN_HSP

#define EXYNOS5_DRD_PHYADP

#define EXYNOS5_DRD_PHYUTMICLKSEL
#define PHYUTMICLKSEL_UTMI_CLKSEL

#define EXYNOS5_DRD_PHYRESUME

#define EXYNOS5_DRD_LINKPORT

/* USB 3.0 DRD PHY SS Function Control Reg; accessed by CR_PORT */
#define EXYNOS5_DRD_PHYSS_LOSLEVEL_OVRD_IN
#define LOSLEVEL_OVRD_IN_LOS_BIAS_5420
#define LOSLEVEL_OVRD_IN_LOS_BIAS_DEFAULT
#define LOSLEVEL_OVRD_IN_EN
#define LOSLEVEL_OVRD_IN_LOS_LEVEL_DEFAULT

#define EXYNOS5_DRD_PHYSS_TX_VBOOSTLEVEL_OVRD_IN
#define TX_VBOOSTLEVEL_OVRD_IN_VBOOST_5420
#define TX_VBOOSTLEVEL_OVRD_IN_VBOOST_DEFAULT

#define EXYNOS5_DRD_PHYSS_LANE0_TX_DEBUG
#define LANE0_TX_DEBUG_RXDET_MEAS_TIME_19M2_20M
#define LANE0_TX_DEBUG_RXDET_MEAS_TIME_24M
#define LANE0_TX_DEBUG_RXDET_MEAS_TIME_25M_26M
#define LANE0_TX_DEBUG_RXDET_MEAS_TIME_48M_50M_52M
#define LANE0_TX_DEBUG_RXDET_MEAS_TIME_62M5
#define LANE0_TX_DEBUG_RXDET_MEAS_TIME_96M_100M

/* Exynos850: USB DRD PHY registers */
#define EXYNOS850_DRD_LINKCTRL
#define LINKCTRL_FORCE_RXELECIDLE
#define LINKCTRL_FORCE_PHYSTATUS
#define LINKCTRL_FORCE_PIPE_EN
#define LINKCTRL_FORCE_QACT
#define LINKCTRL_BUS_FILTER_BYPASS(_x)

#define EXYNOS850_DRD_LINKPORT
#define LINKPORT_HOST_NUM_U3
#define LINKPORT_HOST_NUM_U2

#define EXYNOS850_DRD_CLKRST
/*
 * On versions without SS ports (like E850), bit 3 is for the 2.0 phy (HS),
 * while on versions with (like gs101), bits 2 and 3 are for the 3.0 phy (SS)
 * and bits 12 & 13 for the 2.0 phy.
 */
#define CLKRST_PHY20_SW_POR
#define CLKRST_PHY20_SW_POR_SEL
#define CLKRST_LINK_PCLK_SEL
#define CLKRST_PHY_SW_RST
#define CLKRST_PHY_RESET_SEL
#define CLKRST_PORT_RST
#define CLKRST_LINK_SW_RST

#define EXYNOS850_DRD_SSPPLLCTL
#define SSPPLLCTL_FSEL

#define EXYNOS850_DRD_UTMI
#define UTMI_FORCE_VBUSVALID
#define UTMI_FORCE_BVALID
#define UTMI_DP_PULLDOWN
#define UTMI_DM_PULLDOWN
#define UTMI_FORCE_SUSPEND
#define UTMI_FORCE_SLEEP

#define EXYNOS850_DRD_HSP
#define HSP_FSV_OUT_EN
#define HSP_VBUSVLDEXTSEL
#define HSP_VBUSVLDEXT
#define HSP_EN_UTMISUSPEND
#define HSP_COMMONONN

#define EXYNOS850_DRD_HSPPARACON
#define HSPPARACON_TXVREF
#define HSPPARACON_TXRISE
#define HSPPARACON_TXRES
#define HSPPARACON_TXPREEMPPULSE
#define HSPPARACON_TXPREEMPAMP
#define HSPPARACON_TXHSXV
#define HSPPARACON_TXFSLS
#define HSPPARACON_SQRX
#define HSPPARACON_OTG
#define HSPPARACON_COMPDIS

#define EXYNOS850_DRD_HSP_TEST
#define HSP_TEST_SIDDQ

/* Exynos9 - GS101 */
#define EXYNOS850_DRD_SECPMACTL
#define SECPMACTL_PMA_ROPLL_REF_CLK_SEL
#define SECPMACTL_PMA_LCPLL_REF_CLK_SEL
#define SECPMACTL_PMA_REF_FREQ_SEL
#define SECPMACTL_PMA_LOW_PWR
#define SECPMACTL_PMA_TRSV_SW_RST
#define SECPMACTL_PMA_CMN_SW_RST
#define SECPMACTL_PMA_INIT_SW_RST
#define SECPMACTL_PMA_APB_SW_RST

/* PMA registers */
#define EXYNOS9_PMA_USBDP_CMN_REG0008
#define CMN_REG0008_OVRD_AUX_EN
#define CMN_REG0008_AUX_EN

#define EXYNOS9_PMA_USBDP_CMN_REG00B8
#define CMN_REG00B8_LANE_MUX_SEL_DP

#define EXYNOS9_PMA_USBDP_CMN_REG01C0
#define CMN_REG01C0_ANA_LCPLL_LOCK_DONE
#define CMN_REG01C0_ANA_LCPLL_AFC_DONE

/* these have similar register layout, for lanes 0 and 2 */
#define EXYNOS9_PMA_USBDP_TRSV_REG03C3
#define EXYNOS9_PMA_USBDP_TRSV_REG07C3
#define TRSV_REG03C3_LN0_MON_RX_CDR_AFC_DONE
#define TRSV_REG03C3_LN0_MON_RX_CDR_CAL_DONE
#define TRSV_REG03C3_LN0_MON_RX_CDR_FLD_PLL_MODE_DONE
#define TRSV_REG03C3_LN0_MON_RX_CDR_LOCK_DONE

/* TRSV_REG0413 and TRSV_REG0813 have similar register layout */
#define EXYNOS9_PMA_USBDP_TRSV_REG0413
#define TRSV_REG0413_OVRD_LN1_TX_RXD_COMP_EN
#define TRSV_REG0413_OVRD_LN1_TX_RXD_EN

#define EXYNOS9_PMA_USBDP_TRSV_REG0813
#define TRSV_REG0813_OVRD_LN3_TX_RXD_COMP_EN
#define TRSV_REG0813_OVRD_LN3_TX_RXD_EN

/* PCS registers */
#define EXYNOS9_PCS_NS_VEC_PS1_N1
#define EXYNOS9_PCS_NS_VEC_PS2_N0
#define EXYNOS9_PCS_NS_VEC_PS3_N0
#define NS_VEC_NS_REQ
#define NS_VEC_ENABLE_TIMER
#define NS_VEC_SEL_TIMEOUT
#define NS_VEC_INV_MASK
#define NS_VEC_COND_MASK
#define NS_VEC_EXP_COND

#define EXYNOS9_PCS_OUT_VEC_2
#define EXYNOS9_PCS_OUT_VEC_3
#define PCS_OUT_VEC_B9_DYNAMIC
#define PCS_OUT_VEC_B9_SEL_OUT
#define PCS_OUT_VEC_B8_DYNAMIC
#define PCS_OUT_VEC_B8_SEL_OUT
#define PCS_OUT_VEC_B7_DYNAMIC
#define PCS_OUT_VEC_B7_SEL_OUT
#define PCS_OUT_VEC_B6_DYNAMIC
#define PCS_OUT_VEC_B6_SEL_OUT
#define PCS_OUT_VEC_B5_DYNAMIC
#define PCS_OUT_VEC_B5_SEL_OUT
#define PCS_OUT_VEC_B4_DYNAMIC
#define PCS_OUT_VEC_B4_SEL_OUT
#define PCS_OUT_VEC_B3_DYNAMIC
#define PCS_OUT_VEC_B3_SEL_OUT
#define PCS_OUT_VEC_B2_DYNAMIC
#define PCS_OUT_VEC_B2_SEL_OUT
#define PCS_OUT_VEC_B1_DYNAMIC
#define PCS_OUT_VEC_B1_SEL_OUT
#define PCS_OUT_VEC_B0_DYNAMIC
#define PCS_OUT_VEC_B0_SEL_OUT

#define EXYNOS9_PCS_TIMEOUT_0

#define EXYNOS9_PCS_TIMEOUT_3

#define EXYNOS9_PCS_EBUF_PARAM
#define EBUF_PARAM_SKP_REMOVE_TH_EMPTY_MODE

#define EXYNOS9_PCS_BACK_END_MODE_VEC
#define BACK_END_MODE_VEC_FORCE_EBUF_EMPTY_MODE
#define BACK_END_MODE_VEC_DISABLE_DATA_MASK

#define EXYNOS9_PCS_RX_CONTROL
#define RX_CONTROL_EN_BLOCK_ALIGNER_TYPE_B

#define EXYNOS9_PCS_RX_CONTROL_DEBUG
#define RX_CONTROL_DEBUG_EN_TS_CHECK
#define RX_CONTROL_DEBUG_NUM_COM_FOUND

#define EXYNOS9_PCS_LOCAL_COEF
#define LOCAL_COEF_PMA_CENTER_COEF
#define LOCAL_COEF_LF
#define LOCAL_COEF_FS

#define EXYNOS9_PCS_HS_TX_COEF_MAP_0
#define HS_TX_COEF_MAP_0_SSTX_DEEMP
#define HS_TX_COEF_MAP_0_SSTX_LEVEL
#define HS_TX_COEF_MAP_0_SSTX_PRE_SHOOT


#define KHZ
#define MHZ

#define PHY_TUNING_ENTRY_PHY(o, m, v)

#define PHY_TUNING_ENTRY_PCS(o, m, v)

#define PHY_TUNING_ENTRY_PMA(o, m, v)

#define PHY_TUNING_ENTRY_LAST

#define for_each_phy_tune(tune)

struct exynos5_usbdrd_phy_tuning {};

enum exynos5_usbdrd_phy_tuning_state {};

enum exynos5_usbdrd_phy_id {};

struct phy_usb_instance;
struct exynos5_usbdrd_phy;

struct exynos5_usbdrd_phy_config {};

struct exynos5_usbdrd_phy_drvdata {};

/**
 * struct exynos5_usbdrd_phy - driver data for USB 3.0 PHY
 * @dev: pointer to device instance of this platform device
 * @reg_phy: usb phy controller register memory base
 * @reg_pcs: usb phy physical coding sublayer register memory base
 * @reg_pma: usb phy physical media attachment register memory base
 * @clks: clocks for register access
 * @core_clks: core clocks for phy (ref, pipe3, utmi+, ITP, etc. as required)
 * @drv_data: pointer to SoC level driver data structure
 * @phys: array for 'EXYNOS5_DRDPHYS_NUM' number of PHY
 *	    instances each with its 'phy' and 'phy_cfg'.
 * @extrefclk: frequency select settings when using 'separate
 *	       reference clocks' for SS and HS operations
 * @regulators: regulators for phy
 */
struct exynos5_usbdrd_phy {};

static inline
struct exynos5_usbdrd_phy *to_usbdrd_phy(struct phy_usb_instance *inst)
{}

/*
 * exynos5_rate_to_clk() converts the supplied clock rate to the value that
 * can be written to the phy register.
 */
static unsigned int exynos5_rate_to_clk(unsigned long rate, u32 *reg)
{}

static void exynos5_usbdrd_phy_isol(struct phy_usb_instance *inst,
				    bool isolate)
{}

/*
 * Sets the pipe3 phy's clk as EXTREFCLK (XXTI) which is internal clock
 * from clock core. Further sets multiplier values and spread spectrum
 * clock settings for SuperSpeed operations.
 */
static unsigned int
exynos5_usbdrd_pipe3_set_refclk(struct phy_usb_instance *inst)
{}

/*
 * Sets the utmi phy's clk as EXTREFCLK (XXTI) which is internal clock
 * from clock core. Further sets the FSEL values for HighSpeed operations.
 */
static unsigned int
exynos5_usbdrd_utmi_set_refclk(struct phy_usb_instance *inst)
{}

static void
exynos5_usbdrd_apply_phy_tunes(struct exynos5_usbdrd_phy *phy_drd,
			       enum exynos5_usbdrd_phy_tuning_state state)
{}

static void exynos5_usbdrd_pipe3_init(struct exynos5_usbdrd_phy *phy_drd)
{}

static void
exynos5_usbdrd_usbdp_g2_v4_ctrl_pma_ready(struct exynos5_usbdrd_phy *phy_drd)
{}

static void
exynos5_usbdrd_usbdp_g2_v4_pma_lane_mux_sel(struct exynos5_usbdrd_phy *phy_drd)
{}

static int
exynos5_usbdrd_usbdp_g2_v4_pma_check_pll_lock(struct exynos5_usbdrd_phy *phy_drd)
{}

static void
exynos5_usbdrd_usbdp_g2_v4_pma_check_cdr_lock(struct exynos5_usbdrd_phy *phy_drd)
{}

static void exynos5_usbdrd_utmi_init(struct exynos5_usbdrd_phy *phy_drd)
{}

static int exynos5_usbdrd_phy_init(struct phy *phy)
{}

static int exynos5_usbdrd_phy_exit(struct phy *phy)
{}

static int exynos5_usbdrd_phy_power_on(struct phy *phy)
{}

static int exynos5_usbdrd_phy_power_off(struct phy *phy)
{}

static int crport_handshake(struct exynos5_usbdrd_phy *phy_drd,
			    u32 val, u32 cmd)
{}

static int crport_ctrl_write(struct exynos5_usbdrd_phy *phy_drd,
			     u32 addr, u32 data)
{}

/*
 * Calibrate few PHY parameters using CR_PORT register to meet
 * SuperSpeed requirements on Exynos5420 and Exynos5800 systems,
 * which have 28nm USB 3.0 DRD PHY.
 */
static int exynos5420_usbdrd_phy_calibrate(struct exynos5_usbdrd_phy *phy_drd)
{}

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

static int exynos5_usbdrd_phy_calibrate(struct phy *phy)
{}

static const struct phy_ops exynos5_usbdrd_phy_ops =;

static void
exynos5_usbdrd_usb_v3p1_pipe_override(struct exynos5_usbdrd_phy *phy_drd)
{}

static void exynos850_usbdrd_utmi_init(struct exynos5_usbdrd_phy *phy_drd)
{}

static int exynos850_usbdrd_phy_init(struct phy *phy)
{}

static int exynos850_usbdrd_phy_exit(struct phy *phy)
{}

static const struct phy_ops exynos850_usbdrd_phy_ops =;

static void exynos5_usbdrd_gs101_pipe3_init(struct exynos5_usbdrd_phy *phy_drd)
{}

static int exynos5_usbdrd_gs101_phy_init(struct phy *phy)
{}

static int exynos5_usbdrd_gs101_phy_exit(struct phy *phy)
{}

static const struct phy_ops gs101_usbdrd_phy_ops =;

static int exynos5_usbdrd_phy_clk_handle(struct exynos5_usbdrd_phy *phy_drd)
{}

static const struct exynos5_usbdrd_phy_config phy_cfg_exynos5[] =;

static const struct exynos5_usbdrd_phy_config phy_cfg_exynos850[] =;

static const char * const exynos5_clk_names[] =;

static const char * const exynos5_core_clk_names[] =;

static const char * const exynos5433_core_clk_names[] =;

static const char * const exynos5_regulator_names[] =;

static const struct exynos5_usbdrd_phy_drvdata exynos5420_usbdrd_phy =;

static const struct exynos5_usbdrd_phy_drvdata exynos5250_usbdrd_phy =;

static const struct exynos5_usbdrd_phy_drvdata exynos5433_usbdrd_phy =;

static const struct exynos5_usbdrd_phy_drvdata exynos7_usbdrd_phy =;

static const struct exynos5_usbdrd_phy_drvdata exynos850_usbdrd_phy =;

static const struct exynos5_usbdrd_phy_config phy_cfg_gs101[] =;

static const struct exynos5_usbdrd_phy_tuning gs101_tunes_utmi_postinit[] =;

static const struct exynos5_usbdrd_phy_tuning gs101_tunes_pipe3_preinit[] =;

static const struct exynos5_usbdrd_phy_tuning gs101_tunes_pipe3_init[] =;

static const struct exynos5_usbdrd_phy_tuning gs101_tunes_pipe3_postlock[] =;

static const struct exynos5_usbdrd_phy_tuning *gs101_tunes[PTS_MAX] =;

static const char * const gs101_clk_names[] =;

static const char * const gs101_regulator_names[] =;

static const struct exynos5_usbdrd_phy_drvdata gs101_usbd31rd_phy =;

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

static int exynos5_usbdrd_phy_probe(struct platform_device *pdev)
{}

static struct platform_driver exynos5_usb3drd_phy =;

module_platform_driver();
MODULE_DESCRIPTION();
MODULE_AUTHOR();
MODULE_LICENSE();
MODULE_ALIAS();