1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Copyright (c) 2022 MediaTek Inc. 4 * Author: Jianjun Wang <jianjun.wang@mediatek.com> 5 */ 6 7#include <linux/bitfield.h> 8#include <linux/module.h> 9#include <linux/nvmem-consumer.h> 10#include <linux/of.h> 11#include <linux/phy/phy.h> 12#include <linux/platform_device.h> 13#include <linux/slab.h> 14 15#include "phy-mtk-io.h" 16 17#define PEXTP_ANA_GLB_00_REG 0x9000 18/* Internal Resistor Selection of TX Bias Current */ 19#define EFUSE_GLB_INTR_SEL GENMASK(28, 24) 20 21#define PEXTP_ANA_LN0_TRX_REG 0xa000 22 23#define PEXTP_ANA_TX_REG 0x04 24/* TX PMOS impedance selection */ 25#define EFUSE_LN_TX_PMOS_SEL GENMASK(5, 2) 26/* TX NMOS impedance selection */ 27#define EFUSE_LN_TX_NMOS_SEL GENMASK(11, 8) 28 29#define PEXTP_ANA_RX_REG 0x3c 30/* RX impedance selection */ 31#define EFUSE_LN_RX_SEL GENMASK(3, 0) 32 33#define PEXTP_ANA_LANE_OFFSET 0x100 34 35/** 36 * struct mtk_pcie_lane_efuse - eFuse data for each lane 37 * @tx_pmos: TX PMOS impedance selection data 38 * @tx_nmos: TX NMOS impedance selection data 39 * @rx_data: RX impedance selection data 40 * @lane_efuse_supported: software eFuse data is supported for this lane 41 */ 42struct mtk_pcie_lane_efuse { 43 u32 tx_pmos; 44 u32 tx_nmos; 45 u32 rx_data; 46 bool lane_efuse_supported; 47}; 48 49/** 50 * struct mtk_pcie_phy_data - phy data for each SoC 51 * @num_lanes: supported lane numbers 52 * @sw_efuse_supported: support software to load eFuse data 53 */ 54struct mtk_pcie_phy_data { 55 int num_lanes; 56 bool sw_efuse_supported; 57}; 58 59/** 60 * struct mtk_pcie_phy - PCIe phy driver main structure 61 * @dev: pointer to device 62 * @phy: pointer to generic phy 63 * @sif_base: IO mapped register base address of system interface 64 * @data: pointer to SoC dependent data 65 * @sw_efuse_en: software eFuse enable status 66 * @efuse_glb_intr: internal resistor selection of TX bias current data 67 * @efuse: pointer to eFuse data for each lane 68 */ 69struct mtk_pcie_phy { 70 struct device *dev; 71 struct phy *phy; 72 void __iomem *sif_base; 73 const struct mtk_pcie_phy_data *data; 74 75 bool sw_efuse_en; 76 u32 efuse_glb_intr; 77 struct mtk_pcie_lane_efuse *efuse; 78}; 79 80static void mtk_pcie_efuse_set_lane(struct mtk_pcie_phy *pcie_phy, 81 unsigned int lane) 82{ 83 struct mtk_pcie_lane_efuse *data = &pcie_phy->efuse[lane]; 84 void __iomem *addr; 85 86 if (!data->lane_efuse_supported) 87 return; 88 89 addr = pcie_phy->sif_base + PEXTP_ANA_LN0_TRX_REG + 90 lane * PEXTP_ANA_LANE_OFFSET; 91 92 mtk_phy_update_field(addr + PEXTP_ANA_TX_REG, EFUSE_LN_TX_PMOS_SEL, 93 data->tx_pmos); 94 95 mtk_phy_update_field(addr + PEXTP_ANA_TX_REG, EFUSE_LN_TX_NMOS_SEL, 96 data->tx_nmos); 97 98 mtk_phy_update_field(addr + PEXTP_ANA_RX_REG, EFUSE_LN_RX_SEL, 99 data->rx_data); 100} 101 102/** 103 * mtk_pcie_phy_init() - Initialize the phy 104 * @phy: the phy to be initialized 105 * 106 * Initialize the phy by setting the efuse data. 107 * The hardware settings will be reset during suspend, it should be 108 * reinitialized when the consumer calls phy_init() again on resume. 109 */ 110static int mtk_pcie_phy_init(struct phy *phy) 111{ 112 struct mtk_pcie_phy *pcie_phy = phy_get_drvdata(phy); 113 int i; 114 115 if (!pcie_phy->sw_efuse_en) 116 return 0; 117 118 /* Set global data */ 119 mtk_phy_update_field(pcie_phy->sif_base + PEXTP_ANA_GLB_00_REG, 120 EFUSE_GLB_INTR_SEL, pcie_phy->efuse_glb_intr); 121 122 for (i = 0; i < pcie_phy->data->num_lanes; i++) 123 mtk_pcie_efuse_set_lane(pcie_phy, i); 124 125 return 0; 126} 127 128static const struct phy_ops mtk_pcie_phy_ops = { 129 .init = mtk_pcie_phy_init, 130 .owner = THIS_MODULE, 131}; 132 133static int mtk_pcie_efuse_read_for_lane(struct mtk_pcie_phy *pcie_phy, 134 unsigned int lane) 135{ 136 struct mtk_pcie_lane_efuse *efuse = &pcie_phy->efuse[lane]; 137 struct device *dev = pcie_phy->dev; 138 char efuse_id[16]; 139 int ret; 140 141 snprintf(efuse_id, sizeof(efuse_id), "tx_ln%d_pmos", lane); 142 ret = nvmem_cell_read_variable_le_u32(dev, efuse_id, &efuse->tx_pmos); 143 if (ret) 144 return dev_err_probe(dev, ret, "Failed to read %s\n", efuse_id); 145 146 snprintf(efuse_id, sizeof(efuse_id), "tx_ln%d_nmos", lane); 147 ret = nvmem_cell_read_variable_le_u32(dev, efuse_id, &efuse->tx_nmos); 148 if (ret) 149 return dev_err_probe(dev, ret, "Failed to read %s\n", efuse_id); 150 151 snprintf(efuse_id, sizeof(efuse_id), "rx_ln%d", lane); 152 ret = nvmem_cell_read_variable_le_u32(dev, efuse_id, &efuse->rx_data); 153 if (ret) 154 return dev_err_probe(dev, ret, "Failed to read %s\n", efuse_id); 155 156 if (!(efuse->tx_pmos || efuse->tx_nmos || efuse->rx_data)) 157 return dev_err_probe(dev, -EINVAL, 158 "No eFuse data found for lane%d, but dts enable it\n", 159 lane); 160 161 efuse->lane_efuse_supported = true; 162 163 return 0; 164} 165 166static int mtk_pcie_read_efuse(struct mtk_pcie_phy *pcie_phy) 167{ 168 struct device *dev = pcie_phy->dev; 169 bool nvmem_enabled; 170 int ret, i; 171 172 /* nvmem data is optional */ 173 nvmem_enabled = device_property_present(dev, "nvmem-cells"); 174 if (!nvmem_enabled) 175 return 0; 176 177 ret = nvmem_cell_read_variable_le_u32(dev, "glb_intr", 178 &pcie_phy->efuse_glb_intr); 179 if (ret) 180 return dev_err_probe(dev, ret, "Failed to read glb_intr\n"); 181 182 pcie_phy->sw_efuse_en = true; 183 184 pcie_phy->efuse = devm_kzalloc(dev, pcie_phy->data->num_lanes * 185 sizeof(*pcie_phy->efuse), GFP_KERNEL); 186 if (!pcie_phy->efuse) 187 return -ENOMEM; 188 189 for (i = 0; i < pcie_phy->data->num_lanes; i++) { 190 ret = mtk_pcie_efuse_read_for_lane(pcie_phy, i); 191 if (ret) 192 return ret; 193 } 194 195 return 0; 196} 197 198static int mtk_pcie_phy_probe(struct platform_device *pdev) 199{ 200 struct device *dev = &pdev->dev; 201 struct phy_provider *provider; 202 struct mtk_pcie_phy *pcie_phy; 203 int ret; 204 205 pcie_phy = devm_kzalloc(dev, sizeof(*pcie_phy), GFP_KERNEL); 206 if (!pcie_phy) 207 return -ENOMEM; 208 209 pcie_phy->sif_base = devm_platform_ioremap_resource_byname(pdev, "sif"); 210 if (IS_ERR(pcie_phy->sif_base)) 211 return dev_err_probe(dev, PTR_ERR(pcie_phy->sif_base), 212 "Failed to map phy-sif base\n"); 213 214 pcie_phy->phy = devm_phy_create(dev, dev->of_node, &mtk_pcie_phy_ops); 215 if (IS_ERR(pcie_phy->phy)) 216 return dev_err_probe(dev, PTR_ERR(pcie_phy->phy), 217 "Failed to create PCIe phy\n"); 218 219 pcie_phy->dev = dev; 220 pcie_phy->data = of_device_get_match_data(dev); 221 if (!pcie_phy->data) 222 return dev_err_probe(dev, -EINVAL, "Failed to get phy data\n"); 223 224 if (pcie_phy->data->sw_efuse_supported) { 225 /* 226 * Failed to read the efuse data is not a fatal problem, 227 * ignore the failure and keep going. 228 */ 229 ret = mtk_pcie_read_efuse(pcie_phy); 230 if (ret == -EPROBE_DEFER || ret == -ENOMEM) 231 return ret; 232 } 233 234 phy_set_drvdata(pcie_phy->phy, pcie_phy); 235 236 provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); 237 if (IS_ERR(provider)) 238 return dev_err_probe(dev, PTR_ERR(provider), 239 "PCIe phy probe failed\n"); 240 241 return 0; 242} 243 244static const struct mtk_pcie_phy_data mt8195_data = { 245 .num_lanes = 2, 246 .sw_efuse_supported = true, 247}; 248 249static const struct of_device_id mtk_pcie_phy_of_match[] = { 250 { .compatible = "mediatek,mt8195-pcie-phy", .data = &mt8195_data }, 251 { }, 252}; 253MODULE_DEVICE_TABLE(of, mtk_pcie_phy_of_match); 254 255static struct platform_driver mtk_pcie_phy_driver = { 256 .probe = mtk_pcie_phy_probe, 257 .driver = { 258 .name = "mtk-pcie-phy", 259 .of_match_table = mtk_pcie_phy_of_match, 260 }, 261}; 262module_platform_driver(mtk_pcie_phy_driver); 263 264MODULE_DESCRIPTION("MediaTek PCIe PHY driver"); 265MODULE_AUTHOR("Jianjun Wang <jianjun.wang@mediatek.com>"); 266MODULE_LICENSE("GPL"); 267