267 lines · c
1// SPDX-License-Identifier: GPL-2.02/*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 0x900018/* Internal Resistor Selection of TX Bias Current */19#define EFUSE_GLB_INTR_SEL GENMASK(28, 24)20 21#define PEXTP_ANA_LN0_TRX_REG 0xa00022 23#define PEXTP_ANA_TX_REG 0x0424/* 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 0x3c30/* RX impedance selection */31#define EFUSE_LN_RX_SEL GENMASK(3, 0)32 33#define PEXTP_ANA_LANE_OFFSET 0x10034 35/**36 * struct mtk_pcie_lane_efuse - eFuse data for each lane37 * @tx_pmos: TX PMOS impedance selection data38 * @tx_nmos: TX NMOS impedance selection data39 * @rx_data: RX impedance selection data40 * @lane_efuse_supported: software eFuse data is supported for this lane41 */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 SoC51 * @num_lanes: supported lane numbers52 * @sw_efuse_supported: support software to load eFuse data53 */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 structure61 * @dev: pointer to device62 * @phy: pointer to generic phy63 * @sif_base: IO mapped register base address of system interface64 * @data: pointer to SoC dependent data65 * @sw_efuse_en: software eFuse enable status66 * @efuse_glb_intr: internal resistor selection of TX bias current data67 * @efuse: pointer to eFuse data for each lane68 */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 phy104 * @phy: the phy to be initialized105 *106 * Initialize the phy by setting the efuse data.107 * The hardware settings will be reset during suspend, it should be108 * 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