rtl8367b: initial support for rtl8367s
authorSerge Vasilugin <vasilugin@yandex.ru>
Thu, 15 Aug 2019 08:28:28 +0000 (15:28 +0700)
committerChuanhong Guo <gch981213@gmail.com>
Tue, 29 Sep 2020 06:32:01 +0000 (14:32 +0800)
From driver point of view no differance between rtl8367b and rtl8367s
if it connected through EXT2 (rgmii only).
So this trivial patch add some identification and initialization only.
SGMII/HSGMII mode for EXT1 is not implemented for the sake of patch
clairity.

Signed-off-by: Serge Vasilugin <vasilugin@yandex.ru>
[Fix code format]
Signed-off-by: DENG Qingfang <dengqf6@mail2.sysu.edu.cn>
[add flags to separate chip_num/chip_id detection; drop error print in
rtl8367b_init_regs, drop unnecessary info prints, code style fixes]
Signed-off-by: Chuanhong Guo <gch981213@gmail.com>
target/linux/generic/files/drivers/net/phy/rtl8366_smi.h
target/linux/generic/files/drivers/net/phy/rtl8367b.c

index 0b0f7e9948276f9df3e84ebea4bcd12ebb8d89b0..e96d50ce342318060b50061b7805517090ee989c 100644 (file)
@@ -65,6 +65,7 @@ struct rtl8366_smi {
 #endif
        struct mii_bus          *ext_mbus;
        int                     phy_id;
+       u32                     flags;
 };
 
 struct rtl8366_vlan_mc {
index 3599791a517bbf5389daf42a2c2d8c67535e32de..d88a7b0dac240f5d25099a0f4768fc57f794b524 100644 (file)
 
 #define RTL8367B_CPU_PORT_NUM          5
 #define RTL8367B_NUM_PORTS             8
+#define RTL8367B_NUM_PHYS              5
 #define RTL8367B_NUM_VLANS             32
 #define RTL8367B_NUM_VIDS              4096
 #define RTL8367B_PRIORITYMAX           7
         RTL8367B_PORT_3 | RTL8367B_PORT_4 | RTL8367B_PORT_E1 | \
         RTL8367B_PORT_E2)
 
+#define RTL8367B_FLAG_MATCH_CHIP_NUM   BIT(0)
+
 struct rtl8367b_initval {
        u16 reg;
        u16 val;
@@ -605,6 +608,20 @@ static const struct rtl8367b_initval rtl8367r_vb_initvals_1[] = {
        {0x133E, 0x000E}, {0x133F, 0x0010},
 };
 
+static const struct rtl8367b_initval rtl8367c_initvals[] = {
+       {0x13c2, 0x0000}, {0x0018, 0x0f00}, {0x0038, 0x0f00}, {0x0058, 0x0f00},
+       {0x0078, 0x0f00}, {0x0098, 0x0f00}, {0x1d15, 0x0a69}, {0x2000, 0x1340},
+       {0x2020, 0x1340}, {0x2040, 0x1340}, {0x2060, 0x1340}, {0x2080, 0x1340},
+       {0x13eb, 0x15bb}, {0x1303, 0x06d6}, {0x1304, 0x0700}, {0x13E2, 0x003F},
+       {0x13F9, 0x0090}, {0x121e, 0x03CA}, {0x1233, 0x0352}, {0x1237, 0x00a0},
+       {0x123a, 0x0030}, {0x1239, 0x0084}, {0x0301, 0x1000}, {0x1349, 0x001F},
+       {0x18e0, 0x4004}, {0x122b, 0x641c}, {0x1305, 0xc000}, {0x1200, 0x7fcb},
+       {0x0884, 0x0003}, {0x06eb, 0x0001}, {0x00cf, 0xffff}, {0x00d0, 0x0007},
+       {0x00ce, 0x48b0}, {0x00ce, 0x48b0}, {0x0398, 0xffff}, {0x0399, 0x0007},
+       {0x0300, 0x0001}, {0x03fa, 0x0007}, {0x08c8, 0x00c0}, {0x0a30, 0x020e},
+       {0x0800, 0x0000}, {0x0802, 0x0000}, {0x09da, 0x0017}, {0x1d32, 0x0002},
+};
+
 static int rtl8367b_write_initvals(struct rtl8366_smi *smi,
                                  const struct rtl8367b_initval *initvals,
                                  int count)
@@ -716,33 +733,46 @@ static int rtl8367b_write_phy_reg(struct rtl8366_smi *smi,
 static int rtl8367b_init_regs(struct rtl8366_smi *smi)
 {
        const struct rtl8367b_initval *initvals;
+       u32 chip_num;
        u32 chip_ver;
        u32 rlvid;
        int count;
        int err;
 
        REG_WR(smi, RTL8367B_RTL_MAGIC_ID_REG, RTL8367B_RTL_MAGIC_ID_VAL);
+       REG_RD(smi, RTL8367B_CHIP_NUMBER_REG, &chip_num);
        REG_RD(smi, RTL8367B_CHIP_VER_REG, &chip_ver);
 
        rlvid = (chip_ver >> RTL8367B_CHIP_VER_RLVID_SHIFT) &
                RTL8367B_CHIP_VER_RLVID_MASK;
 
-       switch (rlvid) {
-       case 0:
-               initvals = rtl8367r_vb_initvals_0;
-               count = ARRAY_SIZE(rtl8367r_vb_initvals_0);
-               break;
+       if (smi->flags & RTL8367B_FLAG_MATCH_CHIP_NUM) {
+               switch (chip_num) {
+               case 0x0276:
+               case 0x0597:
+               case 0x6367:
+                       initvals = rtl8367c_initvals;
+                       count = ARRAY_SIZE(rtl8367c_initvals);
+                       break;
+               default:
+                       return -ENODEV;
+               }
+       } else {
+               switch (rlvid) {
+               case 0:
+                       initvals = rtl8367r_vb_initvals_0;
+                       count = ARRAY_SIZE(rtl8367r_vb_initvals_0);
+                       break;
 
-       case 1:
-               initvals = rtl8367r_vb_initvals_1;
-               count = ARRAY_SIZE(rtl8367r_vb_initvals_1);
-               break;
+               case 1:
+                       initvals = rtl8367r_vb_initvals_1;
+                       count = ARRAY_SIZE(rtl8367r_vb_initvals_1);
+                       break;
 
-       default:
-               dev_err(smi->parent, "unknow rlvid %u\n", rlvid);
-               return -ENODEV;
+               default:
+                       return -ENODEV;
+               }
        }
-
        /* TODO: disable RLTP */
 
        return rtl8367b_write_initvals(smi, initvals, count);
@@ -1021,6 +1051,16 @@ static int rtl8367b_setup(struct rtl8366_smi *smi)
                        RTL8367B_PORT_MISC_CFG_EGRESS_MODE_ORIGINAL <<
                                RTL8367B_PORT_MISC_CFG_EGRESS_MODE_SHIFT);
 
+       for (i = 0; i < RTL8367B_NUM_PHYS; i++) {
+               int data;
+               rtl8367b_read_phy_reg(smi, i, 0, &data);
+               /* release phy power down */
+               data &= ~BIT(11);
+               /* restart auto negotiation */
+               data |= BIT(9);
+               rtl8367b_write_phy_reg(smi, i, 0, data);
+       }
+
        return 0;
 }
 
@@ -1509,7 +1549,7 @@ static int rtl8367b_mii_write(struct mii_bus *bus, int addr, int reg, u16 val)
 
 static int rtl8367b_detect(struct rtl8366_smi *smi)
 {
-       const char *chip_name;
+       const char *chip_name = NULL;
        u32 chip_num;
        u32 chip_ver;
        u32 chip_mode;
@@ -1540,14 +1580,26 @@ static int rtl8367b_detect(struct rtl8366_smi *smi)
                return ret;
        }
 
-       switch (chip_ver) {
-       case 0x1000:
-               chip_name = "8367RB";
-               break;
-       case 0x1010:
-               chip_name = "8367R-VB";
-               break;
-       default:
+       if (smi->flags & RTL8367B_FLAG_MATCH_CHIP_NUM) {
+               switch (chip_num) {
+               case 0x0276:
+               case 0x0597:
+               case 0x6367:
+                       chip_name = "8367C";
+                       break;
+               }
+       } else {
+               switch (chip_ver) {
+               case 0x1000:
+                       chip_name = "8367RB";
+                       break;
+               case 0x1010:
+                       chip_name = "8367R-VB";
+                       break;
+               }
+       }
+
+       if (!chip_name) {
                dev_err(smi->parent,
                        "unknown chip num:%04x ver:%04x, mode:%04x\n",
                        chip_num, chip_ver, chip_mode);
@@ -1580,8 +1632,23 @@ static struct rtl8366_smi_ops rtl8367b_smi_ops = {
        .enable_port    = rtl8367b_enable_port,
 };
 
+#ifdef CONFIG_OF
+static const struct of_device_id rtl8367b_match[] = {
+       { .compatible = "realtek,rtl8367b" },
+       {
+               .compatible = "realtek,rtl8367c",
+               .data = (void *)RTL8367B_FLAG_MATCH_CHIP_NUM,
+       },
+       {},
+};
+MODULE_DEVICE_TABLE(of, rtl8367b_match);
+#endif
+
 static int  rtl8367b_probe(struct platform_device *pdev)
 {
+#ifdef CONFIG_OF
+       const struct of_device_id *match;
+#endif
        struct rtl8366_smi *smi;
        int err;
 
@@ -1589,6 +1656,12 @@ static int  rtl8367b_probe(struct platform_device *pdev)
        if (IS_ERR(smi))
                return PTR_ERR(smi);
 
+#ifdef CONFIG_OF
+       match = of_match_device(rtl8367b_match, &pdev->dev);
+       if (match)
+               smi->flags = (u32)match->data;
+#endif
+
        smi->clk_delay = 1500;
        smi->cmd_read = 0xb9;
        smi->cmd_write = 0xb8;
@@ -1643,14 +1716,6 @@ static void rtl8367b_shutdown(struct platform_device *pdev)
                rtl8367b_reset_chip(smi);
 }
 
-#ifdef CONFIG_OF
-static const struct of_device_id rtl8367b_match[] = {
-       { .compatible = "realtek,rtl8367b" },
-       {},
-};
-MODULE_DEVICE_TABLE(of, rtl8367b_match);
-#endif
-
 static struct platform_driver rtl8367b_driver = {
        .driver = {
                .name           = RTL8367B_DRIVER_NAME,