0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/interrupt.h>
0009 #include <linux/iopoll.h>
0010 #include <linux/acpi.h>
0011 #include <linux/of_device.h>
0012 #include "emac.h"
0013 #include "emac-mac.h"
0014 #include "emac-sgmii.h"
0015
0016
0017 #define EMAC_SGMII_PHY_AUTONEG_CFG2 0x0048
0018 #define EMAC_SGMII_PHY_SPEED_CFG1 0x0074
0019 #define EMAC_SGMII_PHY_IRQ_CMD 0x00ac
0020 #define EMAC_SGMII_PHY_INTERRUPT_CLEAR 0x00b0
0021 #define EMAC_SGMII_PHY_INTERRUPT_MASK 0x00b4
0022 #define EMAC_SGMII_PHY_INTERRUPT_STATUS 0x00b8
0023 #define EMAC_SGMII_PHY_RX_CHK_STATUS 0x00d4
0024
0025 #define FORCE_AN_TX_CFG BIT(5)
0026 #define FORCE_AN_RX_CFG BIT(4)
0027 #define AN_ENABLE BIT(0)
0028
0029 #define DUPLEX_MODE BIT(4)
0030 #define SPDMODE_1000 BIT(1)
0031 #define SPDMODE_100 BIT(0)
0032 #define SPDMODE_10 0
0033
0034 #define CDR_ALIGN_DET BIT(6)
0035
0036 #define IRQ_GLOBAL_CLEAR BIT(0)
0037
0038 #define DECODE_CODE_ERR BIT(7)
0039 #define DECODE_DISP_ERR BIT(6)
0040
0041 #define SGMII_PHY_IRQ_CLR_WAIT_TIME 10
0042
0043 #define SGMII_PHY_INTERRUPT_ERR (DECODE_CODE_ERR | DECODE_DISP_ERR)
0044 #define SGMII_ISR_MASK (SGMII_PHY_INTERRUPT_ERR)
0045
0046 #define SERDES_START_WAIT_TIMES 100
0047
0048 int emac_sgmii_init(struct emac_adapter *adpt)
0049 {
0050 if (!(adpt->phy.sgmii_ops && adpt->phy.sgmii_ops->init))
0051 return 0;
0052
0053 return adpt->phy.sgmii_ops->init(adpt);
0054 }
0055
0056 int emac_sgmii_open(struct emac_adapter *adpt)
0057 {
0058 if (!(adpt->phy.sgmii_ops && adpt->phy.sgmii_ops->open))
0059 return 0;
0060
0061 return adpt->phy.sgmii_ops->open(adpt);
0062 }
0063
0064 void emac_sgmii_close(struct emac_adapter *adpt)
0065 {
0066 if (!(adpt->phy.sgmii_ops && adpt->phy.sgmii_ops->close))
0067 return;
0068
0069 adpt->phy.sgmii_ops->close(adpt);
0070 }
0071
0072 int emac_sgmii_link_change(struct emac_adapter *adpt, bool link_state)
0073 {
0074 if (!(adpt->phy.sgmii_ops && adpt->phy.sgmii_ops->link_change))
0075 return 0;
0076
0077 return adpt->phy.sgmii_ops->link_change(adpt, link_state);
0078 }
0079
0080 void emac_sgmii_reset(struct emac_adapter *adpt)
0081 {
0082 if (!(adpt->phy.sgmii_ops && adpt->phy.sgmii_ops->reset))
0083 return;
0084
0085 adpt->phy.sgmii_ops->reset(adpt);
0086 }
0087
0088
0089 static void emac_sgmii_link_init(struct emac_adapter *adpt)
0090 {
0091 struct emac_sgmii *phy = &adpt->phy;
0092 u32 val;
0093
0094
0095
0096
0097 val = readl(phy->base + EMAC_SGMII_PHY_AUTONEG_CFG2);
0098 val &= ~(FORCE_AN_RX_CFG | FORCE_AN_TX_CFG);
0099 val |= AN_ENABLE;
0100 writel(val, phy->base + EMAC_SGMII_PHY_AUTONEG_CFG2);
0101 }
0102
0103 static int emac_sgmii_irq_clear(struct emac_adapter *adpt, u8 irq_bits)
0104 {
0105 struct emac_sgmii *phy = &adpt->phy;
0106 u8 status;
0107
0108 writel_relaxed(irq_bits, phy->base + EMAC_SGMII_PHY_INTERRUPT_CLEAR);
0109 writel_relaxed(IRQ_GLOBAL_CLEAR, phy->base + EMAC_SGMII_PHY_IRQ_CMD);
0110
0111 wmb();
0112
0113
0114
0115
0116
0117 if (readl_poll_timeout_atomic(phy->base +
0118 EMAC_SGMII_PHY_INTERRUPT_STATUS,
0119 status, !(status & irq_bits), 1,
0120 SGMII_PHY_IRQ_CLR_WAIT_TIME)) {
0121 net_err_ratelimited("%s: failed to clear SGMII irq: status:0x%x bits:0x%x\n",
0122 adpt->netdev->name, status, irq_bits);
0123 return -EIO;
0124 }
0125
0126
0127 writel_relaxed(0, phy->base + EMAC_SGMII_PHY_IRQ_CMD);
0128 writel_relaxed(0, phy->base + EMAC_SGMII_PHY_INTERRUPT_CLEAR);
0129
0130
0131 wmb();
0132
0133 return 0;
0134 }
0135
0136
0137 #define DECODE_ERROR_LIMIT 2
0138
0139 static irqreturn_t emac_sgmii_interrupt(int irq, void *data)
0140 {
0141 struct emac_adapter *adpt = data;
0142 struct emac_sgmii *phy = &adpt->phy;
0143 u8 status;
0144
0145 status = readl(phy->base + EMAC_SGMII_PHY_INTERRUPT_STATUS);
0146 status &= SGMII_ISR_MASK;
0147 if (!status)
0148 return IRQ_HANDLED;
0149
0150
0151
0152
0153
0154
0155 if (status & SGMII_PHY_INTERRUPT_ERR) {
0156 int count;
0157
0158
0159
0160
0161
0162
0163 count = atomic_inc_return(&phy->decode_error_count);
0164 if (count == DECODE_ERROR_LIMIT) {
0165 schedule_work(&adpt->work_thread);
0166 atomic_set(&phy->decode_error_count, 0);
0167 }
0168 } else {
0169
0170 atomic_set(&phy->decode_error_count, 0);
0171 }
0172
0173 if (emac_sgmii_irq_clear(adpt, status))
0174 schedule_work(&adpt->work_thread);
0175
0176 return IRQ_HANDLED;
0177 }
0178
0179 static void emac_sgmii_reset_prepare(struct emac_adapter *adpt)
0180 {
0181 struct emac_sgmii *phy = &adpt->phy;
0182 u32 val;
0183
0184
0185 val = readl(phy->base + EMAC_EMAC_WRAPPER_CSR2);
0186 writel(((val & ~PHY_RESET) | PHY_RESET), phy->base +
0187 EMAC_EMAC_WRAPPER_CSR2);
0188
0189 msleep(50);
0190 val = readl(phy->base + EMAC_EMAC_WRAPPER_CSR2);
0191 writel((val & ~PHY_RESET), phy->base + EMAC_EMAC_WRAPPER_CSR2);
0192
0193
0194
0195 msleep(50);
0196 }
0197
0198 static void emac_sgmii_common_reset(struct emac_adapter *adpt)
0199 {
0200 int ret;
0201
0202 emac_sgmii_reset_prepare(adpt);
0203 emac_sgmii_link_init(adpt);
0204
0205 ret = emac_sgmii_init(adpt);
0206 if (ret)
0207 netdev_err(adpt->netdev,
0208 "could not reinitialize internal PHY (error=%i)\n",
0209 ret);
0210 }
0211
0212 static int emac_sgmii_common_open(struct emac_adapter *adpt)
0213 {
0214 struct emac_sgmii *sgmii = &adpt->phy;
0215 int ret;
0216
0217 if (sgmii->irq) {
0218
0219 ret = emac_sgmii_irq_clear(adpt, 0xff);
0220 if (ret)
0221 return ret;
0222 writel(0, sgmii->base + EMAC_SGMII_PHY_INTERRUPT_MASK);
0223
0224 ret = request_irq(sgmii->irq, emac_sgmii_interrupt, 0,
0225 "emac-sgmii", adpt);
0226 if (ret) {
0227 netdev_err(adpt->netdev,
0228 "could not register handler for internal PHY\n");
0229 return ret;
0230 }
0231 }
0232
0233 return 0;
0234 }
0235
0236 static void emac_sgmii_common_close(struct emac_adapter *adpt)
0237 {
0238 struct emac_sgmii *sgmii = &adpt->phy;
0239
0240
0241 writel(0, sgmii->base + EMAC_SGMII_PHY_INTERRUPT_MASK);
0242 free_irq(sgmii->irq, adpt);
0243 }
0244
0245
0246 static int emac_sgmii_common_link_change(struct emac_adapter *adpt, bool linkup)
0247 {
0248 struct emac_sgmii *sgmii = &adpt->phy;
0249 int ret;
0250
0251 if (linkup) {
0252
0253 ret = emac_sgmii_irq_clear(adpt, 0xff);
0254 if (ret)
0255 return ret;
0256
0257 writel(SGMII_ISR_MASK,
0258 sgmii->base + EMAC_SGMII_PHY_INTERRUPT_MASK);
0259 } else {
0260
0261 writel(0, sgmii->base + EMAC_SGMII_PHY_INTERRUPT_MASK);
0262 synchronize_irq(sgmii->irq);
0263 }
0264
0265 return 0;
0266 }
0267
0268 static struct sgmii_ops fsm9900_ops = {
0269 .init = emac_sgmii_init_fsm9900,
0270 .open = emac_sgmii_common_open,
0271 .close = emac_sgmii_common_close,
0272 .link_change = emac_sgmii_common_link_change,
0273 .reset = emac_sgmii_common_reset,
0274 };
0275
0276 static struct sgmii_ops qdf2432_ops = {
0277 .init = emac_sgmii_init_qdf2432,
0278 .open = emac_sgmii_common_open,
0279 .close = emac_sgmii_common_close,
0280 .link_change = emac_sgmii_common_link_change,
0281 .reset = emac_sgmii_common_reset,
0282 };
0283
0284 #ifdef CONFIG_ACPI
0285 static struct sgmii_ops qdf2400_ops = {
0286 .init = emac_sgmii_init_qdf2400,
0287 .open = emac_sgmii_common_open,
0288 .close = emac_sgmii_common_close,
0289 .link_change = emac_sgmii_common_link_change,
0290 .reset = emac_sgmii_common_reset,
0291 };
0292 #endif
0293
0294 static int emac_sgmii_acpi_match(struct device *dev, void *data)
0295 {
0296 #ifdef CONFIG_ACPI
0297 static const struct acpi_device_id match_table[] = {
0298 {
0299 .id = "QCOM8071",
0300 },
0301 {}
0302 };
0303 const struct acpi_device_id *id = acpi_match_device(match_table, dev);
0304 struct sgmii_ops **ops = data;
0305
0306 if (id) {
0307 acpi_handle handle = ACPI_HANDLE(dev);
0308 unsigned long long hrv;
0309 acpi_status status;
0310
0311 status = acpi_evaluate_integer(handle, "_HRV", NULL, &hrv);
0312 if (status) {
0313 if (status == AE_NOT_FOUND)
0314
0315
0316
0317 hrv = 1;
0318 else
0319
0320 return 0;
0321 }
0322
0323 switch (hrv) {
0324 case 1:
0325 *ops = &qdf2432_ops;
0326 return 1;
0327 case 2:
0328 *ops = &qdf2400_ops;
0329 return 1;
0330 }
0331 }
0332 #endif
0333
0334 return 0;
0335 }
0336
0337 static const struct of_device_id emac_sgmii_dt_match[] = {
0338 {
0339 .compatible = "qcom,fsm9900-emac-sgmii",
0340 .data = &fsm9900_ops,
0341 },
0342 {
0343 .compatible = "qcom,qdf2432-emac-sgmii",
0344 .data = &qdf2432_ops,
0345 },
0346 {}
0347 };
0348
0349 int emac_sgmii_config(struct platform_device *pdev, struct emac_adapter *adpt)
0350 {
0351 struct platform_device *sgmii_pdev = NULL;
0352 struct emac_sgmii *phy = &adpt->phy;
0353 struct resource *res;
0354 int ret;
0355
0356 if (has_acpi_companion(&pdev->dev)) {
0357 struct device *dev;
0358
0359 dev = device_find_child(&pdev->dev, &phy->sgmii_ops,
0360 emac_sgmii_acpi_match);
0361
0362 if (!dev) {
0363 dev_warn(&pdev->dev, "cannot find internal phy node\n");
0364 return 0;
0365 }
0366
0367 sgmii_pdev = to_platform_device(dev);
0368 } else {
0369 const struct of_device_id *match;
0370 struct device_node *np;
0371
0372 np = of_parse_phandle(pdev->dev.of_node, "internal-phy", 0);
0373 if (!np) {
0374 dev_err(&pdev->dev, "missing internal-phy property\n");
0375 return -ENODEV;
0376 }
0377
0378 sgmii_pdev = of_find_device_by_node(np);
0379 of_node_put(np);
0380 if (!sgmii_pdev) {
0381 dev_err(&pdev->dev, "invalid internal-phy property\n");
0382 return -ENODEV;
0383 }
0384
0385 match = of_match_device(emac_sgmii_dt_match, &sgmii_pdev->dev);
0386 if (!match) {
0387 dev_err(&pdev->dev, "unrecognized internal phy node\n");
0388 ret = -ENODEV;
0389 goto error_put_device;
0390 }
0391
0392 phy->sgmii_ops = (struct sgmii_ops *)match->data;
0393 }
0394
0395
0396 res = platform_get_resource(sgmii_pdev, IORESOURCE_MEM, 0);
0397 if (!res) {
0398 ret = -EINVAL;
0399 goto error_put_device;
0400 }
0401
0402 phy->base = ioremap(res->start, resource_size(res));
0403 if (!phy->base) {
0404 ret = -ENOMEM;
0405 goto error_put_device;
0406 }
0407
0408
0409 res = platform_get_resource(sgmii_pdev, IORESOURCE_MEM, 1);
0410 if (res) {
0411 phy->digital = ioremap(res->start, resource_size(res));
0412 if (!phy->digital) {
0413 ret = -ENOMEM;
0414 goto error_unmap_base;
0415 }
0416 }
0417
0418 ret = emac_sgmii_init(adpt);
0419 if (ret)
0420 goto error;
0421
0422 emac_sgmii_link_init(adpt);
0423
0424 ret = platform_get_irq(sgmii_pdev, 0);
0425 if (ret > 0)
0426 phy->irq = ret;
0427
0428
0429
0430
0431 put_device(&sgmii_pdev->dev);
0432
0433 return 0;
0434
0435 error:
0436 if (phy->digital)
0437 iounmap(phy->digital);
0438 error_unmap_base:
0439 iounmap(phy->base);
0440 error_put_device:
0441 put_device(&sgmii_pdev->dev);
0442
0443 return ret;
0444 }