1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Copyright (c) 2019, Linaro Limited 4 */ 5 6#include <cpu_func.h> 7#include <log.h> 8#include <malloc.h> 9#include <asm/cache.h> 10#include <asm/io.h> 11#include <console.h> 12#include <linux/bitops.h> 13#include <linux/bug.h> 14#include <linux/delay.h> 15#include <linux/mii.h> 16#include <miiphy.h> 17#include <net.h> 18#include <reset.h> 19#include <wait_bit.h> 20 21#define STATION_ADDR_LOW 0x0000 22#define STATION_ADDR_HIGH 0x0004 23#define MAC_DUPLEX_HALF_CTRL 0x0008 24#define PORT_MODE 0x0040 25#define PORT_EN 0x0044 26#define BIT_TX_EN BIT(2) 27#define BIT_RX_EN BIT(1) 28#define MODE_CHANGE_EN 0x01b4 29#define BIT_MODE_CHANGE_EN BIT(0) 30#define MDIO_SINGLE_CMD 0x03c0 31#define BIT_MDIO_BUSY BIT(20) 32#define MDIO_READ (BIT(17) | BIT_MDIO_BUSY) 33#define MDIO_WRITE (BIT(16) | BIT_MDIO_BUSY) 34#define MDIO_SINGLE_DATA 0x03c4 35#define MDIO_RDATA_STATUS 0x03d0 36#define BIT_MDIO_RDATA_INVALID BIT(0) 37#define RX_FQ_START_ADDR 0x0500 38#define RX_FQ_DEPTH 0x0504 39#define RX_FQ_WR_ADDR 0x0508 40#define RX_FQ_RD_ADDR 0x050c 41#define RX_FQ_REG_EN 0x0518 42#define RX_BQ_START_ADDR 0x0520 43#define RX_BQ_DEPTH 0x0524 44#define RX_BQ_WR_ADDR 0x0528 45#define RX_BQ_RD_ADDR 0x052c 46#define RX_BQ_REG_EN 0x0538 47#define TX_BQ_START_ADDR 0x0580 48#define TX_BQ_DEPTH 0x0584 49#define TX_BQ_WR_ADDR 0x0588 50#define TX_BQ_RD_ADDR 0x058c 51#define TX_BQ_REG_EN 0x0598 52#define TX_RQ_START_ADDR 0x05a0 53#define TX_RQ_DEPTH 0x05a4 54#define TX_RQ_WR_ADDR 0x05a8 55#define TX_RQ_RD_ADDR 0x05ac 56#define TX_RQ_REG_EN 0x05b8 57#define BIT_START_ADDR_EN BIT(2) 58#define BIT_DEPTH_EN BIT(1) 59#define DESC_WR_RD_ENA 0x05cc 60#define BIT_RX_OUTCFF_WR BIT(3) 61#define BIT_RX_CFF_RD BIT(2) 62#define BIT_TX_OUTCFF_WR BIT(1) 63#define BIT_TX_CFF_RD BIT(0) 64#define BITS_DESC_ENA (BIT_RX_OUTCFF_WR | BIT_RX_CFF_RD | \ 65 BIT_TX_OUTCFF_WR | BIT_TX_CFF_RD) 66 67/* MACIF_CTRL */ 68#define RGMII_SPEED_1000 0x2c 69#define RGMII_SPEED_100 0x2f 70#define RGMII_SPEED_10 0x2d 71#define MII_SPEED_100 0x0f 72#define MII_SPEED_10 0x0d 73#define GMAC_SPEED_1000 0x05 74#define GMAC_SPEED_100 0x01 75#define GMAC_SPEED_10 0x00 76#define GMAC_FULL_DUPLEX BIT(4) 77 78#define RX_DESC_NUM 64 79#define TX_DESC_NUM 2 80#define DESC_SIZE 32 81#define DESC_WORD_SHIFT 3 82#define DESC_BYTE_SHIFT 5 83#define DESC_CNT(n) ((n) >> DESC_BYTE_SHIFT) 84#define DESC_BYTE(n) ((n) << DESC_BYTE_SHIFT) 85#define DESC_VLD_FREE 0 86#define DESC_VLD_BUSY 1 87 88#define MAC_MAX_FRAME_SIZE 1600 89 90enum higmac_queue { 91 RX_FQ, 92 RX_BQ, 93 TX_BQ, 94 TX_RQ, 95}; 96 97struct higmac_desc { 98 unsigned int buf_addr; 99 unsigned int buf_len:11; 100 unsigned int reserve0:5; 101 unsigned int data_len:11; 102 unsigned int reserve1:2; 103 unsigned int fl:2; 104 unsigned int descvid:1; 105 unsigned int reserve2[6]; 106}; 107 108struct higmac_priv { 109 void __iomem *base; 110 void __iomem *macif_ctrl; 111 struct reset_ctl rst_phy; 112 struct higmac_desc *rxfq; 113 struct higmac_desc *rxbq; 114 struct higmac_desc *txbq; 115 struct higmac_desc *txrq; 116 int rxdesc_in_use; 117 struct mii_dev *bus; 118 struct phy_device *phydev; 119 int phyintf; 120 int phyaddr; 121}; 122 123#define flush_desc(d) flush_cache((unsigned long)(d), sizeof(*(d))) 124#define invalidate_desc(d) \ 125 invalidate_dcache_range((unsigned long)(d), \ 126 (unsigned long)(d) + sizeof(*(d))) 127 128static int higmac_write_hwaddr(struct udevice *dev) 129{ 130 struct eth_pdata *pdata = dev_get_plat(dev); 131 struct higmac_priv *priv = dev_get_priv(dev); 132 unsigned char *mac = pdata->enetaddr; 133 u32 val; 134 135 val = mac[1] | (mac[0] << 8); 136 writel(val, priv->base + STATION_ADDR_HIGH); 137 138 val = mac[5] | (mac[4] << 8) | (mac[3] << 16) | (mac[2] << 24); 139 writel(val, priv->base + STATION_ADDR_LOW); 140 141 return 0; 142} 143 144static int higmac_free_pkt(struct udevice *dev, uchar *packet, int length) 145{ 146 struct higmac_priv *priv = dev_get_priv(dev); 147 148 /* Inform GMAC that the RX descriptor is no longer in use */ 149 writel(DESC_BYTE(priv->rxdesc_in_use), priv->base + RX_BQ_RD_ADDR); 150 151 return 0; 152} 153 154static int higmac_recv(struct udevice *dev, int flags, uchar **packetp) 155{ 156 struct higmac_priv *priv = dev_get_priv(dev); 157 struct higmac_desc *fqd = priv->rxfq; 158 struct higmac_desc *bqd = priv->rxbq; 159 int fqw_pos, fqr_pos, bqw_pos, bqr_pos; 160 int timeout = 100000; 161 int len = 0; 162 int space; 163 int i; 164 165 fqw_pos = DESC_CNT(readl(priv->base + RX_FQ_WR_ADDR)); 166 fqr_pos = DESC_CNT(readl(priv->base + RX_FQ_RD_ADDR)); 167 168 if (fqw_pos >= fqr_pos) 169 space = RX_DESC_NUM - (fqw_pos - fqr_pos); 170 else 171 space = fqr_pos - fqw_pos; 172 173 /* Leave one free to distinguish full filled from empty buffer */ 174 for (i = 0; i < space - 1; i++) { 175 fqd = priv->rxfq + fqw_pos; 176 invalidate_dcache_range(fqd->buf_addr, 177 fqd->buf_addr + MAC_MAX_FRAME_SIZE); 178 179 if (++fqw_pos >= RX_DESC_NUM) 180 fqw_pos = 0; 181 182 writel(DESC_BYTE(fqw_pos), priv->base + RX_FQ_WR_ADDR); 183 } 184 185 bqr_pos = DESC_CNT(readl(priv->base + RX_BQ_RD_ADDR)); 186 bqd += bqr_pos; 187 /* BQ is only ever written by GMAC */ 188 invalidate_desc(bqd); 189 190 do { 191 bqw_pos = DESC_CNT(readl(priv->base + RX_BQ_WR_ADDR)); 192 udelay(1); 193 } while (--timeout && bqw_pos == bqr_pos); 194 195 if (!timeout) 196 return -ETIMEDOUT; 197 198 if (++bqr_pos >= RX_DESC_NUM) 199 bqr_pos = 0; 200 201 len = bqd->data_len; 202 203 /* CPU should not have touched this buffer since we added it to FQ */ 204 invalidate_dcache_range(bqd->buf_addr, bqd->buf_addr + len); 205 *packetp = (void *)(unsigned long)bqd->buf_addr; 206 207 /* Record the RX_BQ descriptor that is holding RX data */ 208 priv->rxdesc_in_use = bqr_pos; 209 210 return len; 211} 212 213static int higmac_send(struct udevice *dev, void *packet, int length) 214{ 215 struct higmac_priv *priv = dev_get_priv(dev); 216 struct higmac_desc *bqd = priv->txbq; 217 int bqw_pos, rqw_pos, rqr_pos; 218 int timeout = 1000; 219 220 flush_cache((unsigned long)packet, length); 221 222 bqw_pos = DESC_CNT(readl(priv->base + TX_BQ_WR_ADDR)); 223 bqd += bqw_pos; 224 bqd->buf_addr = (unsigned long)packet; 225 bqd->descvid = DESC_VLD_BUSY; 226 bqd->data_len = length; 227 flush_desc(bqd); 228 229 if (++bqw_pos >= TX_DESC_NUM) 230 bqw_pos = 0; 231 232 writel(DESC_BYTE(bqw_pos), priv->base + TX_BQ_WR_ADDR); 233 234 rqr_pos = DESC_CNT(readl(priv->base + TX_RQ_RD_ADDR)); 235 if (++rqr_pos >= TX_DESC_NUM) 236 rqr_pos = 0; 237 238 do { 239 rqw_pos = DESC_CNT(readl(priv->base + TX_RQ_WR_ADDR)); 240 udelay(1); 241 } while (--timeout && rqr_pos != rqw_pos); 242 243 if (!timeout) 244 return -ETIMEDOUT; 245 246 writel(DESC_BYTE(rqr_pos), priv->base + TX_RQ_RD_ADDR); 247 248 return 0; 249} 250 251static int higmac_adjust_link(struct higmac_priv *priv) 252{ 253 struct phy_device *phydev = priv->phydev; 254 int interface = priv->phyintf; 255 u32 val; 256 257 switch (interface) { 258 case PHY_INTERFACE_MODE_RGMII: 259 if (phydev->speed == SPEED_1000) 260 val = RGMII_SPEED_1000; 261 else if (phydev->speed == SPEED_100) 262 val = RGMII_SPEED_100; 263 else 264 val = RGMII_SPEED_10; 265 break; 266 case PHY_INTERFACE_MODE_MII: 267 if (phydev->speed == SPEED_100) 268 val = MII_SPEED_100; 269 else 270 val = MII_SPEED_10; 271 break; 272 default: 273 debug("unsupported mode: %d\n", interface); 274 return -EINVAL; 275 } 276 277 if (phydev->duplex) 278 val |= GMAC_FULL_DUPLEX; 279 280 writel(val, priv->macif_ctrl); 281 282 if (phydev->speed == SPEED_1000) 283 val = GMAC_SPEED_1000; 284 else if (phydev->speed == SPEED_100) 285 val = GMAC_SPEED_100; 286 else 287 val = GMAC_SPEED_10; 288 289 writel(BIT_MODE_CHANGE_EN, priv->base + MODE_CHANGE_EN); 290 writel(val, priv->base + PORT_MODE); 291 writel(0, priv->base + MODE_CHANGE_EN); 292 writel(phydev->duplex, priv->base + MAC_DUPLEX_HALF_CTRL); 293 294 return 0; 295} 296 297static int higmac_start(struct udevice *dev) 298{ 299 struct higmac_priv *priv = dev_get_priv(dev); 300 struct phy_device *phydev = priv->phydev; 301 int ret; 302 303 ret = phy_startup(phydev); 304 if (ret) 305 return ret; 306 307 if (!phydev->link) { 308 debug("%s: link down\n", phydev->dev->name); 309 return -ENODEV; 310 } 311 312 ret = higmac_adjust_link(priv); 313 if (ret) 314 return ret; 315 316 /* Enable port */ 317 writel(BITS_DESC_ENA, priv->base + DESC_WR_RD_ENA); 318 writel(BIT_TX_EN | BIT_RX_EN, priv->base + PORT_EN); 319 320 return 0; 321} 322 323static void higmac_stop(struct udevice *dev) 324{ 325 struct higmac_priv *priv = dev_get_priv(dev); 326 327 /* Disable port */ 328 writel(0, priv->base + PORT_EN); 329 writel(0, priv->base + DESC_WR_RD_ENA); 330} 331 332static const struct eth_ops higmac_ops = { 333 .start = higmac_start, 334 .send = higmac_send, 335 .recv = higmac_recv, 336 .free_pkt = higmac_free_pkt, 337 .stop = higmac_stop, 338 .write_hwaddr = higmac_write_hwaddr, 339}; 340 341static int higmac_mdio_read(struct mii_dev *bus, int addr, int devad, int reg) 342{ 343 struct higmac_priv *priv = bus->priv; 344 int ret; 345 346 ret = wait_for_bit_le32(priv->base + MDIO_SINGLE_CMD, BIT_MDIO_BUSY, 347 false, 1000, false); 348 if (ret) 349 return ret; 350 351 writel(MDIO_READ | addr << 8 | reg, priv->base + MDIO_SINGLE_CMD); 352 353 ret = wait_for_bit_le32(priv->base + MDIO_SINGLE_CMD, BIT_MDIO_BUSY, 354 false, 1000, false); 355 if (ret) 356 return ret; 357 358 if (readl(priv->base + MDIO_RDATA_STATUS) & BIT_MDIO_RDATA_INVALID) 359 return -EINVAL; 360 361 return readl(priv->base + MDIO_SINGLE_DATA) >> 16; 362} 363 364static int higmac_mdio_write(struct mii_dev *bus, int addr, int devad, 365 int reg, u16 value) 366{ 367 struct higmac_priv *priv = bus->priv; 368 int ret; 369 370 ret = wait_for_bit_le32(priv->base + MDIO_SINGLE_CMD, BIT_MDIO_BUSY, 371 false, 1000, false); 372 if (ret) 373 return ret; 374 375 writel(value, priv->base + MDIO_SINGLE_DATA); 376 writel(MDIO_WRITE | addr << 8 | reg, priv->base + MDIO_SINGLE_CMD); 377 378 return 0; 379} 380 381static int higmac_init_rx_descs(struct higmac_desc *descs, int num) 382{ 383 int i; 384 385 for (i = 0; i < num; i++) { 386 struct higmac_desc *desc = &descs[i]; 387 388 desc->buf_addr = (unsigned long)memalign(ARCH_DMA_MINALIGN, 389 MAC_MAX_FRAME_SIZE); 390 if (!desc->buf_addr) 391 goto free_bufs; 392 393 desc->descvid = DESC_VLD_FREE; 394 desc->buf_len = MAC_MAX_FRAME_SIZE - 1; 395 flush_desc(desc); 396 } 397 398 return 0; 399 400free_bufs: 401 while (--i > 0) 402 free((void *)(unsigned long)descs[i].buf_addr); 403 return -ENOMEM; 404} 405 406static int higmac_init_hw_queue(struct higmac_priv *priv, 407 enum higmac_queue queue) 408{ 409 struct higmac_desc *desc, **pdesc; 410 u32 regaddr, regen, regdep; 411 int depth; 412 int len; 413 414 switch (queue) { 415 case RX_FQ: 416 regaddr = RX_FQ_START_ADDR; 417 regen = RX_FQ_REG_EN; 418 regdep = RX_FQ_DEPTH; 419 depth = RX_DESC_NUM; 420 pdesc = &priv->rxfq; 421 break; 422 case RX_BQ: 423 regaddr = RX_BQ_START_ADDR; 424 regen = RX_BQ_REG_EN; 425 regdep = RX_BQ_DEPTH; 426 depth = RX_DESC_NUM; 427 pdesc = &priv->rxbq; 428 break; 429 case TX_BQ: 430 regaddr = TX_BQ_START_ADDR; 431 regen = TX_BQ_REG_EN; 432 regdep = TX_BQ_DEPTH; 433 depth = TX_DESC_NUM; 434 pdesc = &priv->txbq; 435 break; 436 case TX_RQ: 437 regaddr = TX_RQ_START_ADDR; 438 regen = TX_RQ_REG_EN; 439 regdep = TX_RQ_DEPTH; 440 depth = TX_DESC_NUM; 441 pdesc = &priv->txrq; 442 break; 443 } 444 445 /* Enable depth */ 446 writel(BIT_DEPTH_EN, priv->base + regen); 447 writel(depth << DESC_WORD_SHIFT, priv->base + regdep); 448 writel(0, priv->base + regen); 449 450 len = depth * sizeof(*desc); 451 desc = memalign(ARCH_DMA_MINALIGN, len); 452 if (!desc) 453 return -ENOMEM; 454 memset(desc, 0, len); 455 flush_cache((unsigned long)desc, len); 456 *pdesc = desc; 457 458 /* Set up RX_FQ descriptors */ 459 if (queue == RX_FQ) 460 higmac_init_rx_descs(desc, depth); 461 462 /* Enable start address */ 463 writel(BIT_START_ADDR_EN, priv->base + regen); 464 writel((unsigned long)desc, priv->base + regaddr); 465 writel(0, priv->base + regen); 466 467 return 0; 468} 469 470static int higmac_hw_init(struct higmac_priv *priv) 471{ 472 int ret; 473 474 /* Initialize hardware queues */ 475 ret = higmac_init_hw_queue(priv, RX_FQ); 476 if (ret) 477 return ret; 478 479 ret = higmac_init_hw_queue(priv, RX_BQ); 480 if (ret) 481 goto free_rx_fq; 482 483 ret = higmac_init_hw_queue(priv, TX_BQ); 484 if (ret) 485 goto free_rx_bq; 486 487 ret = higmac_init_hw_queue(priv, TX_RQ); 488 if (ret) 489 goto free_tx_bq; 490 491 /* Reset phy */ 492 reset_deassert(&priv->rst_phy); 493 mdelay(10); 494 reset_assert(&priv->rst_phy); 495 mdelay(30); 496 reset_deassert(&priv->rst_phy); 497 mdelay(30); 498 499 return 0; 500 501free_tx_bq: 502 free(priv->txbq); 503free_rx_bq: 504 free(priv->rxbq); 505free_rx_fq: 506 free(priv->rxfq); 507 return ret; 508} 509 510static int higmac_probe(struct udevice *dev) 511{ 512 struct higmac_priv *priv = dev_get_priv(dev); 513 struct phy_device *phydev; 514 struct mii_dev *bus; 515 int ret; 516 517 ret = higmac_hw_init(priv); 518 if (ret) 519 return ret; 520 521 bus = mdio_alloc(); 522 if (!bus) 523 return -ENOMEM; 524 525 bus->read = higmac_mdio_read; 526 bus->write = higmac_mdio_write; 527 bus->priv = priv; 528 priv->bus = bus; 529 530 ret = mdio_register_seq(bus, dev_seq(dev)); 531 if (ret) 532 return ret; 533 534 phydev = phy_connect(bus, priv->phyaddr, dev, priv->phyintf); 535 if (!phydev) 536 return -ENODEV; 537 538 phydev->supported &= PHY_GBIT_FEATURES; 539 phydev->advertising = phydev->supported; 540 priv->phydev = phydev; 541 542 return phy_config(phydev); 543} 544 545static int higmac_remove(struct udevice *dev) 546{ 547 struct higmac_priv *priv = dev_get_priv(dev); 548 int i; 549 550 mdio_unregister(priv->bus); 551 mdio_free(priv->bus); 552 553 /* Free RX packet buffers */ 554 for (i = 0; i < RX_DESC_NUM; i++) 555 free((void *)(unsigned long)priv->rxfq[i].buf_addr); 556 557 return 0; 558} 559 560static int higmac_of_to_plat(struct udevice *dev) 561{ 562 struct higmac_priv *priv = dev_get_priv(dev); 563 ofnode phy_node; 564 565 priv->base = dev_remap_addr_index(dev, 0); 566 priv->macif_ctrl = dev_remap_addr_index(dev, 1); 567 568 priv->phyintf = dev_read_phy_mode(dev); 569 if (priv->phyintf == PHY_INTERFACE_MODE_NA) 570 return -ENODEV; 571 572 phy_node = dev_read_subnode(dev, "phy"); 573 if (!ofnode_valid(phy_node)) { 574 debug("failed to find phy node\n"); 575 return -ENODEV; 576 } 577 priv->phyaddr = ofnode_read_u32_default(phy_node, "reg", 0); 578 579 return reset_get_by_name(dev, "phy", &priv->rst_phy); 580} 581 582static const struct udevice_id higmac_ids[] = { 583 { .compatible = "hisilicon,hi3798cv200-gmac" }, 584 { } 585}; 586 587U_BOOT_DRIVER(eth_higmac) = { 588 .name = "eth_higmac", 589 .id = UCLASS_ETH, 590 .of_match = higmac_ids, 591 .of_to_plat = higmac_of_to_plat, 592 .probe = higmac_probe, 593 .remove = higmac_remove, 594 .ops = &higmac_ops, 595 .priv_auto = sizeof(struct higmac_priv), 596 .plat_auto = sizeof(struct eth_pdata), 597}; 598