[PATCH v3 4/5] phy: Add ARTPEC-8 PCIe PHY driver
Wangseok Lee
wangseok.lee at samsung.com
Wed Jul 6 01:10:36 PDT 2022
On 05-07-22, 15:30, Vinod Koul wrote:
> On 14-06-22, 10:34, Wangseok Lee wrote:
>> Add support Axis, ARTPEC-8 SoC.
>> ARTPEC-8 is the SoC platform of Axis Communications.
>> This is based on arm64 and support GEN4 & 2lane.
>> This driver provides PHY interface for ARTPEC-8 SoC PCIe controller,
>> based on Samsung PCIe PHY IP.
>>
>> Signed-off-by: Wangseok Lee <wangseok.lee at samsung.com>
>> Signed-off-by: Jaeho Cho <jaeho79.cho at samsung.com>
>> ---
>> v2->v3 :
>> -remove unnecessary indentation
>> -redefine local struct to statis const
>> -add static const to struct that requires static const definition
>> -remove wrappers on writel and readl
>>
>> v1->v2 :
>> -change folder name of phy driver to axis from artpec
>> ---
>> drivers/phy/Kconfig | 1 +
>> drivers/phy/Makefile | 1 +
>> drivers/phy/axis/Kconfig | 9 +
>> drivers/phy/axis/Makefile | 2 +
>> drivers/phy/axis/phy-artpec8-pcie.c | 776 ++++++++++++++++++++++++++++++++++++
>> 5 files changed, 789 insertions(+)
>> create mode 100644 drivers/phy/axis/Kconfig
>> create mode 100644 drivers/phy/axis/Makefile
>> create mode 100644 drivers/phy/axis/phy-artpec8-pcie.c
>>
>> diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
>> index 300b0f2..92b8232 100644
>> --- a/drivers/phy/Kconfig
>> +++ b/drivers/phy/Kconfig
>> @@ -73,6 +73,7 @@ config PHY_CAN_TRANSCEIVER
>>
>> source "drivers/phy/allwinner/Kconfig"
>> source "drivers/phy/amlogic/Kconfig"
>> +source "drivers/phy/axis/Kconfig"
>> source "drivers/phy/broadcom/Kconfig"
>> source "drivers/phy/cadence/Kconfig"
>> source "drivers/phy/freescale/Kconfig"
>> diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
>> index 01e9eff..808c055e 100644
>> --- a/drivers/phy/Makefile
>> +++ b/drivers/phy/Makefile
>> @@ -12,6 +12,7 @@ obj-$(CONFIG_PHY_PISTACHIO_USB) += phy-pistachio-usb.o
>> obj-$(CONFIG_USB_LGM_PHY) += phy-lgm-usb.o
>> obj-y += allwinner/ \
>> amlogic/ \
>> + axis/ \
>> broadcom/ \
>> cadence/ \
>> freescale/ \
>> diff --git a/drivers/phy/axis/Kconfig b/drivers/phy/axis/Kconfig
>> new file mode 100644
>> index 0000000..7198b93
>> --- /dev/null
>> +++ b/drivers/phy/axis/Kconfig
>> @@ -0,0 +1,9 @@
>> +config PHY_ARTPEC8_PCIE
>> + bool "ARTPEC-8 PCIe PHY driver"
>> + depends on OF && (ARCH_ARTPEC8 || COMPILE_TEST)
>> + select GENERIC_PHY
>> + help
>> + Enable PCIe PHY support for ARTPEC-8 SoC.
>> + This driver provides PHY interface for ARTPEC-8 SoC
>> + PCIe controller.
>> + This is based on Samsung PCIe PHY IP.
>
> How different is it from SS IP and why should it not be under
> phy/samsung/ then?
>
SoC platform is completely different from exynos platform and different
from exynos PCIe PHY. So the overall sysreg configuration is different
and register map is also different. The reset method and type of PHY for
initialization are different. This is not a driver that supports Samsung
SoC platform, but this PHY driver that supports only Axis, Artpec-8
platforms, so it is not added to phy/samsung.
>> diff --git a/drivers/phy/axis/Makefile b/drivers/phy/axis/Makefile
>> new file mode 100644
>> index 0000000..45d853c
>> --- /dev/null
>> +++ b/drivers/phy/axis/Makefile
>> @@ -0,0 +1,2 @@
>> +# SPDX-License-Identifier: GPL-2.0
>> +obj-$(CONFIG_PHY_ARTPEC8_PCIE) += phy-artpec8-pcie.o
>> diff --git a/drivers/phy/axis/phy-artpec8-pcie.c b/drivers/phy/axis/phy-artpec8-pcie.c
>> new file mode 100644
>> index 0000000..d21867b
>> --- /dev/null
>> +++ b/drivers/phy/axis/phy-artpec8-pcie.c
>> @@ -0,0 +1,776 @@
>> +// SPDX-License-Identifier: GPL-2.0-only
>> +/*
>> + * PHY provider for ARTPEC-8 PCIe controller
>> + *
>> + * Copyright (C) 2019 Samsung Electronics Co., Ltd.
>> + * http://www.samsung.com
>> + *
>> + * Author: Jaeho Cho <jaeho79.cho at samsung.com>
>> + */
>> +
>> +#include <linux/clk.h>
>> +#include <linux/io.h>
>> +#include <linux/init.h>
>> +#include <linux/mfd/syscon.h>
>> +#include <linux/module.h>
>> +#include <linux/of.h>
>> +#include <linux/of_address.h>
>> +#include <linux/of_platform.h>
>> +#include <linux/platform_device.h>
>> +#include <linux/phy/phy.h>
>> +#include <linux/regmap.h>
>> +#include <linux/debugfs.h>
>> +
>> +/* ARTPEC-8 PCIe PHY registers */
>> +/* CMN registers */
>> +#define PCIE_PHY_CMN_REG004 0x10
>> +#define PCIE_PHY_CMN_REG00B 0x2C
>> +#define PCIE_PHY_CMN_REG016 0x58
>> +#define PCIE_PHY_CMN_REG01C 0x70
>> +#define PCIE_PHY_CMN_REG021 0x84
>> +#define PCIE_PHY_CMN_REG024 0x90
>> +#define PCIE_PHY_CMN_REG025 0x94
>> +#define PCIE_PHY_CMN_REG0E6 0x398
>> +#define PCIE_PHY_CMN_REG0E7 0x39C
>> +#define PCIE_PHY_CMN_REG0E8 0x3A0
>> +#define PCIE_PHY_CMN_REG0E9 0x3A4
>> +#define PCIE_PHY_CMN_REG0EA 0x3A8
>> +#define PCIE_PHY_CMN_REG0EB 0x3AC
>> +#define PCIE_PHY_CMN_REG0EC 0x3B0
>> +#define PCIE_PHY_CMN_REG0EE 0x3B8
>> +#define PCIE_PHY_CMN_REG0EF 0x3BC
>> +#define PCIE_PHY_CMN_REG0F1 0x3C4
>> +#define PCIE_PHY_CMN_REG0F3 0x3CC
>> +#define PCIE_PHY_CMN_REG0F4 0x3D0
>> +
>> +#define PCIE_PHY_CMN_REG101 0x404
>> +#define OV_I_CMN_RSTN BIT(4)
>> +#define OV_I_INIT_RSTN BIT(6)
>> +
>> +#define PCIE_PHY_CMN_REG131 0x4C4
>> +#define PCIE_PHY_CMN_REG17B 0x5EC
>> +#define PCIE_PHY_CMN_REG17D 0x5F4
>> +#define PCIE_PHY_CMN_REG190 0x640
>> +#define PCIE_PHY_CMN_REG191 0x644
>> +#define PCIE_PHY_CMN_REG192 0x648
>> +#define PCIE_PHY_CMN_REG1C7 0x71C
>> +#define PCIE_PHY_CMN_REG1DF 0x77C
>> +#define PCIE_PHY_CMN_REG1E0 0x780
>> +
>> +#define PCIE_PHY_CMN_REG0B1 0x2C4
>> +#define ANA_ROPLL_REF_DIG_CLK_SEL BIT(2)
>> +
>> +/* External clock */
>> +#define PCIE_PHY_CMN_REG14D 0x534
>> +#define PCIE_AUX_RX_MODE_EXTEND BIT(7)
>> +
>> +#define PCIE_PHY_CMN_REG0D9 0x364
>> +#define ANA_AUX_EXT_REF_CLK_SEL BIT(4)
>> +
>> +#define PCIE_PHY_CMN_REG10F 0x43C
>> +#define AUX_PLL_EN_EXTEND BIT(4)
>> +
>> +#define PCIE_PHY_CMN_REG11E 0x478
>> +#define AUX2_PLL_EN_EXTEND BIT(3)
>> +
>> +#define PCIE_PHY_CMN_REG0D4 0x350
>> +#define OV_S_ANA_AUX_EN BIT(3)
>> +#define OV_I_ANA_AUX_EN BIT(2)
>> +
>> +/* LANE registers */
>> +#define PCIE_PHY_TRSV_REG22D 0x8B4
>> +#define PCIE_PHY_TRSV_REG23E 0x8F8
>> +#define PCIE_PHY_TRSV_REG2A5 0xA94
>> +#define PCIE_PHY_TRSV_REG3E3 0xF8C
>> +#define PCIE_PHY_TRSV_REG3ED 0xFB4
>> +#define PCIE_PHY_TRSV_REG20B 0x82C
>> +#define PCIE_PHY_TRSV_REG20C 0x830
>> +#define PCIE_PHY_TRSV_REG234 0x8D0
>> +#define PCIE_PHY_TRSV_REG235 0x8D4
>> +#define PCIE_PHY_TRSV_REG237 0x8DC
>> +#define PCIE_PHY_TRSV_REG239 0x8E4
>> +#define PCIE_PHY_TRSV_REG23A 0x8E8
>> +#define PCIE_PHY_TRSV_REG23B 0x8EC
>> +#define PCIE_PHY_TRSV_REG24B 0x92C
>> +#define PCIE_PHY_TRSV_REG25D 0x974
>> +#define PCIE_PHY_TRSV_REG262 0x988
>> +#define PCIE_PHY_TRSV_REG271 0x9C4
>> +#define PCIE_PHY_TRSV_REG272 0x9C8
>> +#define PCIE_PHY_TRSV_REG27C 0x9F0
>> +#define PCIE_PHY_TRSV_REG27D 0x9F4
>> +#define PCIE_PHY_TRSV_REG27E 0x9F8
>> +#define PCIE_PHY_TRSV_REG284 0xA10
>> +#define PCIE_PHY_TRSV_REG289 0xA24
>> +#define PCIE_PHY_TRSV_REG28A 0xA28
>> +#define PCIE_PHY_TRSV_REG28B 0xA2C
>> +#define PCIE_PHY_TRSV_REG28C 0xA30
>> +#define PCIE_PHY_TRSV_REG28E 0xA38
>> +#define PCIE_PHY_TRSV_REG28F 0xA3C
>> +#define PCIE_PHY_TRSV_REG290 0xA40
>> +#define PCIE_PHY_TRSV_REG291 0xA44
>> +#define PCIE_PHY_TRSV_REG292 0xA48
>> +#define PCIE_PHY_TRSV_REG294 0xA50
>> +#define PCIE_PHY_TRSV_REG295 0xA54
>> +#define PCIE_PHY_TRSV_REG296 0xA58
>> +#define PCIE_PHY_TRSV_REG297 0xA5C
>> +#define PCIE_PHY_TRSV_REG298 0xA60
>> +#define PCIE_PHY_TRSV_REG29B 0xA6C
>> +#define PCIE_PHY_TRSV_REG29C 0xA70
>> +#define PCIE_PHY_TRSV_REG29D 0xA74
>> +#define PCIE_PHY_TRSV_REG29E 0xA78
>> +#define PCIE_PHY_TRSV_REG2AA 0xAA8
>> +#define PCIE_PHY_TRSV_REG2AE 0xAB8
>> +#define PCIE_PHY_TRSV_REG2C2 0xB08
>> +#define PCIE_PHY_TRSV_REG2C6 0xB18
>> +#define PCIE_PHY_TRSV_REG2C7 0xB1C
>> +#define PCIE_PHY_TRSV_REG2CB 0xB2C
>> +#define PCIE_PHY_TRSV_REG2CC 0xB30
>> +#define PCIE_PHY_TRSV_REG2CD 0xB34
>> +#define PCIE_PHY_TRSV_REG2CE 0xB38
>> +#define PCIE_PHY_TRSV_REG2D0 0xB40
>> +#define PCIE_PHY_TRSV_REG2CF 0xB3C
>> +#define PCIE_PHY_TRSV_REG2E0 0xB80
>> +#define PCIE_PHY_TRSV_REG2E9 0xBA4
>> +#define PCIE_PHY_TRSV_REG2EA 0xBA8
>> +#define PCIE_PHY_TRSV_REG2EB 0xBAC
>> +#define PCIE_PHY_TRSV_REG315 0xC54
>> +#define PCIE_PHY_TRSV_REG317 0xC5C
>> +#define PCIE_PHY_TRSV_REG319 0xC64
>> +#define PCIE_PHY_TRSV_REG364 0xD90
>> +#define PCIE_PHY_TRSV_REG36C 0xDB0
>> +#define PCIE_PHY_TRSV_REG36D 0xDB4
>> +#define PCIE_PHY_TRSV_REG37E 0xDF8
>> +#define PCIE_PHY_TRSV_REG37F 0xDFC
>> +#define PCIE_PHY_TRSV_REG38F 0xE3C
>> +#define PCIE_PHY_TRSV_REG391 0xE44
>> +#define PCIE_PHY_TRSV_REG39C 0xE70
>> +#define PCIE_PHY_TRSV_REG3A8 0xEA0
>> +#define PCIE_PHY_TRSV_REG3E0 0xF80
>> +#define PCIE_PHY_TRSV_REG3E1 0xF84
>> +#define PCIE_PHY_TRSV_REG3E7 0xF9C
>> +#define PCIE_PHY_TRSV_REG3E9 0xFA4
>> +#define PCIE_PHY_TRSV_REG3EA 0xFA8
>> +#define PCIE_PHY_TRSV_REG3EE 0xFB8
>> +#define PCIE_PHY_TRSV_REG3EF 0xFBC
>> +#define PCIE_PHY_TRSV_REG3F0 0xFC0
>> +
>> +#define PCIE_PHY_TRSV_REG2C0 0xB00
>> +#define LN_EQ_CTRL_RX_DATA_HOLD BIT(5)
>> +
>> +/* RX Preset registers */
>> +#define PCIE_PHY_CMN_REG17E 0x5F8
>> +#define PCIE_PHY_CMN_REG180 0x600
>> +#define PCIE_PHY_CMN_REG181 0x604
>> +#define PCIE_PHY_CMN_REG182 0x608
>> +#define PCIE_PHY_CMN_REG183 0x60C
>> +#define PCIE_PHY_CMN_REG184 0x610
>> +#define PCIE_PHY_CMN_REG185 0x614
>> +#define PCIE_PHY_CMN_REG186 0x618
>> +#define PCIE_PHY_CMN_REG187 0x61C
>> +
>> +
>> +/* ARTPEC-8 PCIe PCS registers */
>> +#define PCIE_PCS_OUT_VEC_4 0x154
>> +#define B1_DYNAMIC BIT(3)
>> +
>> +/* ARTPEC-8 SYS REG registers */
>> +#define FSYS_PCIE_CON 0x424
>> +#define PCIE_PHY_LCPLL_REFCLK_SEL 0x3
>> +#define PCIE_PHY_ROPLL_REFCLK_SEL (0x3UL << 2)
>> +#define ROPLL_REFCLK_NOT_AVAILABLE (0x2UL << 2)
>
> Pls use GENMASK for this
>
Ok, i will fix it.
>> +#define PCIE_PHY_LN0_REFCLK_PAD_EN BIT(10)
>> +#define PCIE_PHY_LN1_REFCLK_PAD_EN BIT(11)
>> +#define PCIE_PHY_PWR_OFF BIT(7)
>> +
>> +/* ARTPEC-8 Sub Controller registers */
>> +#define SFR_INIT_RSTN 0x1404
>> +#define SFR_CMN_RSTN 0x1408
>> +
>> +#define PCIE_PHY_LN0_REG_START 0x800
>> +#define PCIE_PHY_LN0_REG_END 0xFCC
>> +#define OFFSET_PER_LANE 0x800
>> +
>> +enum artpec8_pcie_phy_num_lanes {
>> + LANE0 = 0,
>> + LANE1,
>> + LANE_MAX
>> +};
>> +
>> +struct artpec8_pcie_phy_data {
>> + const struct phy_ops *ops;
>> +};
>> +
>> +struct artpec8_pcie_phy {
>> + const struct artpec8_pcie_phy_data *drv_data;
>> + void __iomem *phy_base;
>> + void __iomem *pcs_base;
>> + void __iomem *elbi_base;
>> + struct clk *soc_pll_clk;
>> + struct regmap *sysreg;
>> + u32 lcpll_ref_clk;
>> + const char *mode;
>> + u32 num_lanes;
>> +};
>> +
>> +enum artpec8_pcie_ref_clk {
>> + REF_CLK_FROM_XO = 0,
>> + REF_CLK_FROM_IO,
>> + REF_CLK_RESERVED,
>> + REF_CLK_FROM_SOC_PLL,
>> + REF_CLK_MAX
>> +};
>> +
>> +struct artpec8_pcie_phy_tune_reg {
>> + u32 offset;
>> + u32 val;
>> +};
>> +
>> +/* ARTPEC-8 PCIe Gen4 x2 PHY CMN register settings */
>> +static const struct artpec8_pcie_phy_tune_reg cmn_regs[] = {
>> + {PCIE_PHY_CMN_REG004, 0x65},
>> + {PCIE_PHY_CMN_REG00B, 0x18},
>> + {PCIE_PHY_CMN_REG016, 0x0E},
>> + {PCIE_PHY_CMN_REG01C, 0x4F},
>> + {PCIE_PHY_CMN_REG021, 0x01},
>> + {PCIE_PHY_CMN_REG024, 0x58},
>> + {PCIE_PHY_CMN_REG025, 0x98},
>> + {PCIE_PHY_CMN_REG0E6, 0x00},
>> + {PCIE_PHY_CMN_REG0E7, 0x00},
>> + {PCIE_PHY_CMN_REG0E8, 0x3F},
>> + {PCIE_PHY_CMN_REG0E9, 0x3F},
>> + {PCIE_PHY_CMN_REG0EA, 0xFF},
>> + {PCIE_PHY_CMN_REG0EB, 0xFF},
>> + {PCIE_PHY_CMN_REG0EC, 0x42},
>> + {PCIE_PHY_CMN_REG0EE, 0x3F},
>> + {PCIE_PHY_CMN_REG0EF, 0x7F},
>> + {PCIE_PHY_CMN_REG0F1, 0x02},
>> + {PCIE_PHY_CMN_REG0F3, 0xFF},
>> + {PCIE_PHY_CMN_REG0F4, 0xFF},
>> + {PCIE_PHY_CMN_REG131, 0x01},
>> + {PCIE_PHY_CMN_REG17B, 0xC0},
>> + {PCIE_PHY_CMN_REG17D, 0xAF},
>> + {PCIE_PHY_CMN_REG190, 0x27},
>> + {PCIE_PHY_CMN_REG191, 0x0F},
>> + {PCIE_PHY_CMN_REG192, 0x3F},
>> + {PCIE_PHY_CMN_REG1C7, 0x05},
>> + {PCIE_PHY_CMN_REG1DF, 0x28},
>> + {PCIE_PHY_CMN_REG1E0, 0x28},
>> +};
>> +
>> +/* ARTPEC-8 PCIe Gen4 x2 PHY lane register settings */
>> +static const struct artpec8_pcie_phy_tune_reg lane_regs[] = {
>> + {PCIE_PHY_TRSV_REG22D, 0x00},
>> + {PCIE_PHY_TRSV_REG23E, 0x00},
>> + {PCIE_PHY_TRSV_REG2A5, 0x73},
>> + {PCIE_PHY_TRSV_REG3E3, 0x7B},
>> + {PCIE_PHY_TRSV_REG3ED, 0x4B},
>> + {PCIE_PHY_TRSV_REG20B, 0x02},
>> + {PCIE_PHY_TRSV_REG20C, 0xEA},
>> + {PCIE_PHY_TRSV_REG234, 0x7A},
>> + {PCIE_PHY_TRSV_REG235, 0x1C},
>> + {PCIE_PHY_TRSV_REG237, 0x10},
>> + {PCIE_PHY_TRSV_REG239, 0x68},
>> + {PCIE_PHY_TRSV_REG23A, 0xC0},
>> + {PCIE_PHY_TRSV_REG23B, 0x0B},
>> + {PCIE_PHY_TRSV_REG24B, 0x00},
>> + {PCIE_PHY_TRSV_REG25D, 0x07},
>> + {PCIE_PHY_TRSV_REG262, 0x07},
>> + {PCIE_PHY_TRSV_REG271, 0x23},
>> + {PCIE_PHY_TRSV_REG272, 0x5E},
>> + {PCIE_PHY_TRSV_REG27C, 0x8C},
>> + {PCIE_PHY_TRSV_REG27D, 0x5B},
>> + {PCIE_PHY_TRSV_REG27E, 0x2C},
>> + {PCIE_PHY_TRSV_REG284, 0x33},
>> + {PCIE_PHY_TRSV_REG289, 0xD4},
>> + {PCIE_PHY_TRSV_REG28A, 0xCC},
>> + {PCIE_PHY_TRSV_REG28B, 0xD9},
>> + {PCIE_PHY_TRSV_REG28C, 0xDC},
>> + {PCIE_PHY_TRSV_REG28E, 0xC6},
>> + {PCIE_PHY_TRSV_REG28F, 0x90},
>> + {PCIE_PHY_TRSV_REG290, 0x4D},
>> + {PCIE_PHY_TRSV_REG291, 0x19},
>> + {PCIE_PHY_TRSV_REG292, 0x1C},
>> + {PCIE_PHY_TRSV_REG294, 0x05},
>> + {PCIE_PHY_TRSV_REG295, 0x10},
>> + {PCIE_PHY_TRSV_REG296, 0x0C},
>> + {PCIE_PHY_TRSV_REG297, 0x19},
>> + {PCIE_PHY_TRSV_REG298, 0x04},
>> + {PCIE_PHY_TRSV_REG29B, 0x03},
>> + {PCIE_PHY_TRSV_REG29C, 0x1B},
>> + {PCIE_PHY_TRSV_REG29D, 0x1B},
>> + {PCIE_PHY_TRSV_REG29E, 0x1F},
>> + {PCIE_PHY_TRSV_REG2AA, 0x00},
>> + {PCIE_PHY_TRSV_REG2AE, 0x1F},
>> + {PCIE_PHY_TRSV_REG2C2, 0x25},
>> + {PCIE_PHY_TRSV_REG2C6, 0x10},
>> + {PCIE_PHY_TRSV_REG2C7, 0x06},
>> + {PCIE_PHY_TRSV_REG2CB, 0x10},
>> + {PCIE_PHY_TRSV_REG2CC, 0x06},
>> + {PCIE_PHY_TRSV_REG2CD, 0x20},
>> + {PCIE_PHY_TRSV_REG2CE, 0x27},
>> + {PCIE_PHY_TRSV_REG2D0, 0x10},
>> + {PCIE_PHY_TRSV_REG2CF, 0x0A},
>> + {PCIE_PHY_TRSV_REG2E0, 0x01},
>> + {PCIE_PHY_TRSV_REG2E9, 0x11},
>> + {PCIE_PHY_TRSV_REG2EA, 0x05},
>> + {PCIE_PHY_TRSV_REG2EB, 0x4C},
>> + {PCIE_PHY_TRSV_REG315, 0x18},
>> + {PCIE_PHY_TRSV_REG317, 0x86},
>> + {PCIE_PHY_TRSV_REG319, 0x8E},
>> + {PCIE_PHY_TRSV_REG364, 0x00},
>> + {PCIE_PHY_TRSV_REG36C, 0x03},
>> + {PCIE_PHY_TRSV_REG36D, 0x04},
>> + {PCIE_PHY_TRSV_REG37E, 0x06},
>> + {PCIE_PHY_TRSV_REG37F, 0x04},
>> + {PCIE_PHY_TRSV_REG38F, 0x40},
>> + {PCIE_PHY_TRSV_REG391, 0x8B},
>> + {PCIE_PHY_TRSV_REG39C, 0xFF},
>> + {PCIE_PHY_TRSV_REG3A8, 0x02},
>> + {PCIE_PHY_TRSV_REG3E0, 0x93},
>> + {PCIE_PHY_TRSV_REG3E1, 0x79},
>> + {PCIE_PHY_TRSV_REG3E7, 0xF5},
>> + {PCIE_PHY_TRSV_REG3E9, 0x75},
>> + {PCIE_PHY_TRSV_REG3EA, 0x0D},
>> + {PCIE_PHY_TRSV_REG3EE, 0xE2},
>> + {PCIE_PHY_TRSV_REG3EF, 0x6F},
>> + {PCIE_PHY_TRSV_REG3F0, 0x3D}
>> +};
>> +
>> +static const struct artpec8_pcie_phy_tune_reg rx_preset_regs[] = {
>> + /* 0 */
>> + {PCIE_PHY_CMN_REG17E, 0x00},
>> + {PCIE_PHY_CMN_REG180, 0x23},
>> + {PCIE_PHY_CMN_REG181, 0x44},
>> + {PCIE_PHY_CMN_REG182, 0x61},
>> + {PCIE_PHY_CMN_REG183, 0x55},
>> + {PCIE_PHY_CMN_REG184, 0x14},
>> + {PCIE_PHY_CMN_REG185, 0x23},
>> + {PCIE_PHY_CMN_REG186, 0x1A},
>> + {PCIE_PHY_CMN_REG187, 0x04},
>> + {PCIE_PHY_CMN_REG17E, 0x04},
>> + {PCIE_PHY_CMN_REG17E, 0x00},
>> + /* 1 */
>> + {PCIE_PHY_CMN_REG17E, 0x08},
>> + {PCIE_PHY_CMN_REG181, 0x42},
>> + {PCIE_PHY_CMN_REG17E, 0x0C},
>> + {PCIE_PHY_CMN_REG17E, 0x08},
>> + /* 2 */
>> + {PCIE_PHY_CMN_REG17E, 0x10},
>> + {PCIE_PHY_CMN_REG181, 0x40},
>> + {PCIE_PHY_CMN_REG17E, 0x14},
>> + {PCIE_PHY_CMN_REG17E, 0x10},
>> + /* 3 */
>> + {PCIE_PHY_CMN_REG17E, 0x18},
>> + {PCIE_PHY_CMN_REG181, 0x45},
>> + {PCIE_PHY_CMN_REG17E, 0x1C},
>> + {PCIE_PHY_CMN_REG17E, 0x18},
>> + /* 4 */
>> + {PCIE_PHY_CMN_REG17E, 0x20},
>> + {PCIE_PHY_CMN_REG181, 0x46},
>> + {PCIE_PHY_CMN_REG17E, 0x24},
>> + {PCIE_PHY_CMN_REG17E, 0x20},
>> + /* 5 */
>> + {PCIE_PHY_CMN_REG17E, 0x28},
>> + {PCIE_PHY_CMN_REG181, 0x48},
>> + {PCIE_PHY_CMN_REG17E, 0x2C},
>> + {PCIE_PHY_CMN_REG17E, 0x28},
>> + /* 6 */
>> + {PCIE_PHY_CMN_REG17E, 0x30},
>> + {PCIE_PHY_CMN_REG181, 0x4A},
>> + {PCIE_PHY_CMN_REG17E, 0x34},
>> + {PCIE_PHY_CMN_REG17E, 0x30},
>> + /* 7 */
>> + {PCIE_PHY_CMN_REG17E, 0x38},
>> + {PCIE_PHY_CMN_REG181, 0x4C},
>> + {PCIE_PHY_CMN_REG17E, 0x3C},
>> + {PCIE_PHY_CMN_REG17E, 0x38},
>> + /* 8 */
>> + {PCIE_PHY_CMN_REG17E, 0x40},
>> + {PCIE_PHY_CMN_REG180, 0x20},
>> + {PCIE_PHY_CMN_REG181, 0x20},
>> + {PCIE_PHY_CMN_REG182, 0x01},
>> + {PCIE_PHY_CMN_REG17E, 0x44},
>> + {PCIE_PHY_CMN_REG17E, 0x40},
>> + /* 9 */
>> + {PCIE_PHY_CMN_REG17E, 0x48},
>> + {PCIE_PHY_CMN_REG180, 0x20},
>> + {PCIE_PHY_CMN_REG181, 0x21},
>> + {PCIE_PHY_CMN_REG182, 0x01},
>> + {PCIE_PHY_CMN_REG17E, 0x4C},
>> + {PCIE_PHY_CMN_REG17E, 0x48},
>> + /* 10 */
>> + {PCIE_PHY_CMN_REG17E, 0x50},
>> + {PCIE_PHY_CMN_REG180, 0x24},
>> + {PCIE_PHY_CMN_REG181, 0x80},
>> + {PCIE_PHY_CMN_REG182, 0x41},
>> + {PCIE_PHY_CMN_REG183, 0xAF},
>> + {PCIE_PHY_CMN_REG184, 0x26},
>> + {PCIE_PHY_CMN_REG185, 0x34},
>> + {PCIE_PHY_CMN_REG186, 0x24},
>> + {PCIE_PHY_CMN_REG187, 0x06},
>> + {PCIE_PHY_CMN_REG17E, 0x54},
>> + {PCIE_PHY_CMN_REG17E, 0x50},
>> + /* 11 */
>> + {PCIE_PHY_CMN_REG17E, 0x58},
>> + {PCIE_PHY_CMN_REG181, 0x81},
>> + {PCIE_PHY_CMN_REG17E, 0x5C},
>> + {PCIE_PHY_CMN_REG17E, 0x58},
>> + /* 12 */
>> + {PCIE_PHY_CMN_REG17E, 0x60},
>> + {PCIE_PHY_CMN_REG181, 0x82},
>> + {PCIE_PHY_CMN_REG17E, 0x64},
>> + {PCIE_PHY_CMN_REG17E, 0x60},
>> + /* 13 */
>> + {PCIE_PHY_CMN_REG17E, 0x68},
>> + {PCIE_PHY_CMN_REG181, 0x83},
>> + {PCIE_PHY_CMN_REG17E, 0x6C},
>> + {PCIE_PHY_CMN_REG17E, 0x68},
>> + /* 14 */
>> + {PCIE_PHY_CMN_REG17E, 0x70},
>> + {PCIE_PHY_CMN_REG181, 0x84},
>> + {PCIE_PHY_CMN_REG17E, 0x74},
>> + {PCIE_PHY_CMN_REG17E, 0x70},
>> + /* 15 */
>> + {PCIE_PHY_CMN_REG17E, 0x78},
>> + {PCIE_PHY_CMN_REG180, 0x24},
>> + {PCIE_PHY_CMN_REG181, 0x85},
>> + {PCIE_PHY_CMN_REG182, 0x80},
>> + {PCIE_PHY_CMN_REG183, 0x7F},
>> + {PCIE_PHY_CMN_REG184, 0x2D},
>> + {PCIE_PHY_CMN_REG185, 0x34},
>> + {PCIE_PHY_CMN_REG186, 0x24},
>> + {PCIE_PHY_CMN_REG187, 0x05},
>> + {PCIE_PHY_CMN_REG17E, 0x7C},
>> + {PCIE_PHY_CMN_REG17E, 0x78},
>> + /* 16 */
>> + {PCIE_PHY_CMN_REG17E, 0x80},
>> + {PCIE_PHY_CMN_REG181, 0x86},
>> + {PCIE_PHY_CMN_REG17E, 0x84},
>> + {PCIE_PHY_CMN_REG17E, 0x80},
>> + /* 17 */
>> + {PCIE_PHY_CMN_REG17E, 0x88},
>> + {PCIE_PHY_CMN_REG181, 0x87},
>> + {PCIE_PHY_CMN_REG17E, 0x8C},
>> + {PCIE_PHY_CMN_REG17E, 0x88},
>> + /* 18 */
>> + {PCIE_PHY_CMN_REG17E, 0x90},
>> + {PCIE_PHY_CMN_REG181, 0x88},
>> + {PCIE_PHY_CMN_REG17E, 0x94},
>> + {PCIE_PHY_CMN_REG17E, 0x90},
>> + /* 19 */
>> + {PCIE_PHY_CMN_REG17E, 0x98},
>> + {PCIE_PHY_CMN_REG181, 0x89},
>> + {PCIE_PHY_CMN_REG17E, 0x9C},
>> + {PCIE_PHY_CMN_REG17E, 0x98},
>> +};
>> +
>> +static void artpec8_pcie_phy_reg_update(void __iomem *base, u32 mask,
>> + u32 update, u32 reg)
>> +{
>> + u32 val;
>> +
>> + val = readl(base + reg);
>> + val &= ~(mask);
>> + val |= update;
>> + writel(val, base + reg);
>> +};
>> +
>> +static void artpec8_pcie_enable_ref_clk_from_xo(struct artpec8_pcie_phy
>> + *pciephy)
>
> pls use consistent formatting for second lines, this and previous
> function _do_not_ match. Hint, checkpatch recommends aligning to
> previous line open brace (--strict option will check that for you)
I will fix it, thank you for information.
>> +{
>> + regmap_update_bits(pciephy->>sysreg, FSYS_PCIE_CON,
>> + PCIE_PHY_LCPLL_REFCLK_SEL,
>> + REF_CLK_FROM_XO);
>> + regmap_update_bits(pciephy->>sysreg, FSYS_PCIE_CON,
>> + PCIE_PHY_ROPLL_REFCLK_SEL,
>> + ROPLL_REFCLK_NOT_AVAILABLE);
>> +};
>> +
>> +static void artpec8_pcie_enable_ref_clk_from_io(struct artpec8_pcie_phy
>> + *pciephy)
>> +{
>> + artpec8_pcie_phy_reg_update(pciephy->>phy_base,
>> + PCIE_AUX_RX_MODE_EXTEND, 0,
>> + PCIE_PHY_CMN_REG14D);
>> + artpec8_pcie_phy_reg_update(pciephy->>phy_base,
>> + ANA_AUX_EXT_REF_CLK_SEL, 0,
>> + PCIE_PHY_CMN_REG0D9);
>> + artpec8_pcie_phy_reg_update(pciephy->>phy_base,
>> + AUX_PLL_EN_EXTEND, 0,
>> + PCIE_PHY_CMN_REG10F);
>> + artpec8_pcie_phy_reg_update(pciephy->>phy_base,
>> + AUX2_PLL_EN_EXTEND, 0,
>> + PCIE_PHY_CMN_REG11E);
>> + artpec8_pcie_phy_reg_update(pciephy->>phy_base,
>> + OV_S_ANA_AUX_EN, OV_S_ANA_AUX_EN,
>> + PCIE_PHY_CMN_REG0D4);
>> + artpec8_pcie_phy_reg_update(pciephy->>phy_base,
>> + OV_I_ANA_AUX_EN, OV_I_ANA_AUX_EN,
>> + PCIE_PHY_CMN_REG0D4);
>> +
>> + regmap_update_bits(pciephy->>sysreg, FSYS_PCIE_CON,
>> + PCIE_PHY_LCPLL_REFCLK_SEL,
>> + REF_CLK_FROM_IO);
>> + regmap_update_bits(pciephy->>sysreg, FSYS_PCIE_CON,
>> + PCIE_PHY_ROPLL_REFCLK_SEL,
>> + ROPLL_REFCLK_NOT_AVAILABLE);
>> + regmap_update_bits(pciephy->>sysreg, FSYS_PCIE_CON,
>> + PCIE_PHY_LN0_REFCLK_PAD_EN,
>> + PCIE_PHY_LN0_REFCLK_PAD_EN);
>> + regmap_update_bits(pciephy->>sysreg, FSYS_PCIE_CON,
>> + PCIE_PHY_LN1_REFCLK_PAD_EN,
>> + PCIE_PHY_LN1_REFCLK_PAD_EN);
>> +}
>> +
>> +static void artpec8_pcie_enable_ref_clk_from_soc_pll(struct artpec8_pcie_phy
>> + *pciephy)
>> +{
>> + regmap_update_bits(pciephy->>sysreg, FSYS_PCIE_CON,
>> + PCIE_PHY_LCPLL_REFCLK_SEL,
>> + REF_CLK_FROM_SOC_PLL);
>> + regmap_update_bits(pciephy->>sysreg, FSYS_PCIE_CON,
>> + PCIE_PHY_ROPLL_REFCLK_SEL,
>> + ROPLL_REFCLK_NOT_AVAILABLE);
>> +}
>> +
>> +static void artpec8_pcie_lane_control(struct phy *phy, u32 lane0_reg, u32 mask,
>> + u32 val)
>> +{
>> + struct artpec8_pcie_phy *pciephy = phy_get_drvdata(phy);
>> + u32 lanex_reg = lane0_reg;
>> + int i;
>> +
>> + if (lane0_reg < PCIE_PHY_LN0_REG_START ||
>> + lane0_reg >> PCIE_PHY_LN0_REG_END) {
>> + return;
>> + }
>> +
>> + for (i = 0; i < pciephy->>num_lanes; i++) {
>> + lanex_reg += OFFSET_PER_LANE * i;
>> + artpec8_pcie_phy_reg_update(pciephy->>phy_base, mask, val,
>> + lanex_reg);
>> + }
>> +}
>> +
>> +static void artpec8_pcie_phy_tune(struct artpec8_pcie_phy *pciephy)
>> +{
>> + int i, count;
>> +
>> + /* init cmn registers */
>> + count = ARRAY_SIZE(cmn_regs);
>> + for (i = 0; i < count; i++)
>> + writel(cmn_regs[i].val, pciephy->>phy_base + cmn_regs[i].offset);
>> +
>> + /* init lane registers */
>> + count = ARRAY_SIZE(lane_regs);
>> + for (i = 0; i < count; i++) {
>> + writel(lane_regs[i].val, pciephy->>phy_base + lane_regs[i].offset);
>> + writel(lane_regs[i].val, pciephy->>phy_base + lane_regs[i].offset +
>> + OFFSET_PER_LANE);
>> + }
>> +
>> + /* rx preset registers */
>> + count = ARRAY_SIZE(rx_preset_regs);
>> + for (i = 0; i < count; i++)
>> + writel(rx_preset_regs[i].val, pciephy->>phy_base + rx_preset_regs[i].offset);
>> +}
>> +
>> +static int artpec8_pcie_phy_init(struct phy *phy)
>> +{
>> + struct artpec8_pcie_phy *pciephy = phy_get_drvdata(phy);
>> +
>> + /* reset init_rstn and cmn_rstn */
>> + artpec8_pcie_phy_reg_update(pciephy->>phy_base,
>> + OV_I_CMN_RSTN | OV_I_INIT_RSTN, 0, PCIE_PHY_CMN_REG101);
>> +
>> + /* reference clock selection */
>> + switch (pciephy->>lcpll_ref_clk) {
>> + case REF_CLK_FROM_XO:
>> + artpec8_pcie_enable_ref_clk_from_xo(pciephy);
>> + break;
>> + case REF_CLK_FROM_IO:
>> + artpec8_pcie_enable_ref_clk_from_io(pciephy);
>> + break;
>> + case REF_CLK_FROM_SOC_PLL:
>> + artpec8_pcie_enable_ref_clk_from_soc_pll(pciephy);
>> + break;
>> + default:
>> + break;
>> + }
>> +
>> + /* release i_init_rstn */
>> + artpec8_pcie_phy_reg_update(pciephy->>phy_base, OV_I_INIT_RSTN,
>> + OV_I_INIT_RSTN, PCIE_PHY_CMN_REG101);
>> +
>> + /* phy initial settings */
>> + artpec8_pcie_phy_tune(pciephy);
>> +
>> + /* pll_en should be set to off when PM_STATE is P1.CPM */
>> + if (!strncmp(pciephy->>mode, "pcie_ep", strlen("pcie_ep"))) {
>> + artpec8_pcie_phy_reg_update(pciephy->>pcs_base, B1_DYNAMIC,
>> + B1_DYNAMIC, PCIE_PCS_OUT_VEC_4);
>> + }
>> +
>> + /* disable lane eq ctrl rx data hold */
>> + artpec8_pcie_lane_control(phy, PCIE_PHY_TRSV_REG2C0,
>> + LN_EQ_CTRL_RX_DATA_HOLD, 0);
>> +
>> + return 0;
>> +}
>> +
>> +static int artpec8_pcie_phy_exit(struct phy *phy)
>> +{
>> + return 0;
>> +}
>> +
>> +static int artpec8_pcie_phy_reset(struct phy *phy)
>> +{
>> + struct artpec8_pcie_phy *pciephy = phy_get_drvdata(phy);
>> +
>> + artpec8_pcie_phy_reg_update(pciephy->>phy_base, OV_I_CMN_RSTN,
>> + 0, PCIE_PHY_CMN_REG101);
>> + udelay(10);
>> + artpec8_pcie_phy_reg_update(pciephy->>phy_base, OV_I_CMN_RSTN,
>> + OV_I_CMN_RSTN, PCIE_PHY_CMN_REG101);
>> +
>> + return 0;
>> +}
>> +
>> +static int artpec8_pcie_phy_power_on(struct phy *phy)
>> +{
>> + struct artpec8_pcie_phy *pciephy = phy_get_drvdata(phy);
>> +
>> + regmap_update_bits(pciephy->>sysreg, FSYS_PCIE_CON,
>> + PCIE_PHY_PWR_OFF, 0);
>> +
>> + return 0;
>> +}
>> +
>> +static int artpec8_pcie_phy_power_off(struct phy *phy)
>> +{
>> + struct artpec8_pcie_phy *pciephy = phy_get_drvdata(phy);
>> +
>> + regmap_update_bits(pciephy->>sysreg, FSYS_PCIE_CON,
>> + PCIE_PHY_PWR_OFF, PCIE_PHY_PWR_OFF);
>> +
>> + return 0;
>> +}
>> +
>> +static int artpec8_pcie_phy_probe(struct platform_device *pdev)
>> +{
>> + struct device *dev = &pdev->>dev;
>> + struct artpec8_pcie_phy *artpec8_phy;
>> + struct phy *generic_phy;
>> + struct phy_provider *phy_provider;
>> + const struct artpec8_pcie_phy_data *drv_data;
>> +
>> + drv_data = of_device_get_match_data(dev);
>> + if (!drv_data)
>> + return -ENODEV;
>> +
>> + artpec8_phy = devm_kzalloc(dev, sizeof(*artpec8_phy), GFP_KERNEL);
>> + if (!artpec8_phy)
>> + return -ENOMEM;
>> +
>> + /* reference clock */
>> + if (of_property_read_u32(dev->>of_node, "lcpll-ref-clk",
>> + &artpec8_phy->>lcpll_ref_clk)) {
>> + return -EINVAL;
>> + }
>> + /* PLL SOC reference clock */
>> + if (artpec8_phy->>lcpll_ref_clk == REF_CLK_FROM_SOC_PLL) {
>> + artpec8_phy->>soc_pll_clk = devm_clk_get(dev, "ref_clk");
>> + if (IS_ERR(artpec8_phy->>soc_pll_clk))
>> + return -EINVAL;
>> + clk_prepare_enable(artpec8_phy->>soc_pll_clk);
>> + }
>> +
>> + /* link mode */
>> + if (of_property_read_string(dev->>of_node, "mode", &artpec8_phy->>mode))
>> + return -EINVAL;
>> +
>> + /* number of lanes */
>> + if (of_property_read_u32(dev->>of_node, "num-lanes",
>> + &artpec8_phy->>num_lanes))
>> + return -EINVAL;
>> +
>> + if (artpec8_phy->>num_lanes >> LANE_MAX)
>> + return -EINVAL;
>> +
>> + /* PHY base register */
>> + artpec8_phy->>phy_base = devm_platform_ioremap_resource_byname(pdev, "phy");
>> + if (IS_ERR(artpec8_phy->>phy_base))
>> + return PTR_ERR(artpec8_phy->>phy_base);
>> +
>> + /* PCS base register */
>> + artpec8_phy->>pcs_base = devm_platform_ioremap_resource_byname(pdev, "pcs");
>> + if (IS_ERR(artpec8_phy->>pcs_base))
>> + return PTR_ERR(artpec8_phy->>pcs_base);
>> +
>> + /* sysreg regmap handle, need to change using smc */
>> + artpec8_phy->>sysreg =
>> + syscon_regmap_lookup_by_phandle(dev->>of_node,
>> + "samsung,fsys-sysreg");
>> + if (IS_ERR(artpec8_phy->>sysreg))
>> + return PTR_ERR(artpec8_phy->>sysreg);
>> +
>> + artpec8_phy->>drv_data = drv_data;
>> +
>> + generic_phy = devm_phy_create(dev, dev->>of_node, drv_data->>ops);
>> + if (IS_ERR(generic_phy))
>> + return PTR_ERR(generic_phy);
>> +
>> + phy_set_drvdata(generic_phy, artpec8_phy);
>> + phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
>> +
>> + if (IS_ERR(phy_provider))
>> + return PTR_ERR(phy_provider);
>> +
>> + return 0;
>> +}
>> +
>> +static int __exit artpec8_pcie_remove(struct platform_device *pdev)
>> +{
>> + struct artpec8_pcie_phy *artpec8_phy = platform_get_drvdata(pdev);
>> +
>> + if (artpec8_phy->>soc_pll_clk)
>> + clk_disable_unprepare(artpec8_phy->>soc_pll_clk);
>> +
>> + return 0;
>> +}
>> +
>> +static const struct phy_ops artpec8_phy_ops = {
>> + .init = artpec8_pcie_phy_init,
>> + .exit = artpec8_pcie_phy_exit,
>> + .reset = artpec8_pcie_phy_reset,
>> + .power_on = artpec8_pcie_phy_power_on,
>> + .power_off = artpec8_pcie_phy_power_off,
>> + .owner = THIS_MODULE,
>> +};
>> +
>> +static const struct artpec8_pcie_phy_data artpec8_pcie_phy_data = {
>> + .ops = &artpec8_phy_ops,
>> +};
>
> you have only _one_ ops, so why add driver data for this?
>
Maybe i made it in case data is added in the future, but I will delete it.
>> +
>> +static const struct of_device_id artpec8_pcie_phy_match[] = {
>> + {
>> + .compatible = "axis,artpec8-pcie-phy",
>> + .data = &artpec8_pcie_phy_data,
>> + },
>> + {},
>> +};
>> +MODULE_DEVICE_TABLE(of, artpec8_pcie_phy_match);
>> +
>> +static struct platform_driver artpec8_pcie_phy_driver = {
>> + .probe = artpec8_pcie_phy_probe,
>> + .remove = __exit_p(artpec8_pcie_phy_remove),
>> + .driver = {
>> + .of_match_table = artpec8_pcie_phy_match,
>> + .name = "artpec8_pcie_phy",
>> + }
>> +};
>> +
>> +module_platform_driver(artpec8_pcie_phy_driver);
>> +
>> +MODULE_LICENSE("GPL");
>> +MODULE_AUTHOR("Jaeho Cho <jaeho79.cho at samsung.com>>");
>> --
>> 2.9.5
>
> --
> ~Vinod
Thank you for kindness reivew.
Best regards,
Wangseok Lee
More information about the linux-phy
mailing list