mirror of
https://github.com/logicog/RTLPlayground.git
synced 2026-08-30 14:52:51 +08:00
Handle RTL8261BE SerDes configuration
The RTL8261BE uses a 10GBit QSGMII connection. Add handler for initial configuration of the SerDes speed and upon link changes.
This commit is contained in:
+31
-26
@@ -19,14 +19,6 @@ extern __xdata struct machine_runtime machine_detected;
|
||||
*/
|
||||
void static sds_init(void)
|
||||
{
|
||||
/*
|
||||
p001e.000d:9535 R02f8-00009535 R02f4-0000953a P000001.1e00000d:953a
|
||||
p001e.000d:953a p001e.000d:953a R02f8-0000953a R02f4-00009530 P000001.1e00000d:9530
|
||||
|
||||
RTL8373:
|
||||
p001e.000d:0010 R02f8-00000010 R02f4-0000001a P000001.1e00000d:b7fe
|
||||
p001e.000d:0010 p001e.000d:0010 R02f8-00000010 R02f4-00000010 P000001.1e00000d:b7fe
|
||||
*/
|
||||
phy_read(0, PHY_MMD30, 0xd);
|
||||
uint16_t pval = SFR_DATA_U16;
|
||||
|
||||
@@ -55,6 +47,8 @@ void static sds_init(void)
|
||||
uint16_t pval;
|
||||
|
||||
print_string(" N-settings");
|
||||
if (machine.n_10g)
|
||||
print_string(" - 10g");
|
||||
// Serdes 0 RX PN swap for 64B/66B
|
||||
sds_read(1, 6, 2);
|
||||
pval = SFR_DATA_U16;
|
||||
@@ -70,23 +64,31 @@ void static sds_init(void)
|
||||
pval = SFR_DATA_U16;
|
||||
sds_write_v(0, 6, 2, pval | 0x2000);
|
||||
|
||||
if (machine_detected.isRTL8373) {
|
||||
// RTL8224: Serdes 0 RX PN swap for 64B/66B
|
||||
// We assume that RTL8373N always paired with RTL8224N.
|
||||
// This sds register value is 0x0000 at reset.
|
||||
// So only write to it.
|
||||
RTL8224_SDS_WRITE(0, 6, 2, 0x2000);
|
||||
} else {
|
||||
// Serdes 0 RX PN swap for 8B/10B
|
||||
sds_read(0, 0, 0);
|
||||
pval = SFR_DATA_U16;
|
||||
sds_write_v(0, 0, 0, pval | 0x200);
|
||||
if (!machine.n_10g) {
|
||||
if (machine_detected.isRTL8373) {
|
||||
// RTL8224: Serdes 0 RX PN swap for 64B/66B
|
||||
// We assume that RTL8373N always paired with RTL8224N.
|
||||
// This sds register value is 0x0000 at reset.
|
||||
// So only write to it.
|
||||
RTL8224_SDS_WRITE(0, 6, 2, 0x2000);
|
||||
} else {
|
||||
// Serdes 0 RX PN swap for 8B/10B
|
||||
sds_read(0, 0, 0);
|
||||
pval = SFR_DATA_U16;
|
||||
sds_write_v(0, 0, 0, pval | 0x200);
|
||||
}
|
||||
}
|
||||
if (machine.n_10g) {
|
||||
reg_read_m(RTL837X_CFG_PHY_MDI_REVERSE);
|
||||
sfr_mask_data(0, 0x0f,0x0c);
|
||||
reg_write_m(RTL837X_CFG_PHY_MDI_REVERSE);
|
||||
REG_SET(RTL837X_CFG_PHY_TX_POLARITY_SWAP, 0x0000596a);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void rtl8373_init(void) __banked
|
||||
void rtl8373_init(void)
|
||||
{
|
||||
print_string("\nrtl8373_init called\n");
|
||||
|
||||
@@ -183,7 +185,7 @@ void rtl8373_init(void) __banked
|
||||
}
|
||||
|
||||
|
||||
void rtl8372_init(void) __banked
|
||||
void rtl8372_init(void)
|
||||
{
|
||||
print_string("\nrtl8372_init called\n");
|
||||
|
||||
@@ -192,11 +194,14 @@ void rtl8372_init(void) __banked
|
||||
phy_config(3); // PHY configuration: all internal PHYs?
|
||||
// Set the MAC SerDes Modes Bits 0-4: SDS 0 = 0x2 (0x2), Bits 5-9: SDS 1: 1f (off)
|
||||
// r7b20:00000bff R7b20-00000bff r7b20:00000bff R7b20-00000bff r7b20:00000bff R7b20-000003ff r7b20:000003ff R7b20-000003e2 r7b20:000003e2 R7b20-000003e2
|
||||
reg_read_m(RTL837X_REG_SDS_MODES);
|
||||
sfr_mask_data(1, 0, 0x03);
|
||||
sfr_mask_data(0, 0, 0xe2);
|
||||
reg_write_m(RTL837X_REG_SDS_MODES);
|
||||
|
||||
if (machine.n_10g) {
|
||||
REG_SET(RTL837X_REG_SDS_MODES, 0x3ed); // Disable SFP for now, set RTL8261BE SDS 0 to 0xd
|
||||
} else {
|
||||
reg_read_m(RTL837X_REG_SDS_MODES);
|
||||
sfr_mask_data(1, 0, 0x03);
|
||||
sfr_mask_data(0, 0, 0xe2);
|
||||
reg_write_m(RTL837X_REG_SDS_MODES);
|
||||
}
|
||||
// r0a90:000000f3 R0a90-000000fc
|
||||
reg_read_m(RTL837X_CFG_PHY_MDI_REVERSE);
|
||||
sfr_mask_data(0, 0x0f, 0x0c);
|
||||
|
||||
+33
-5
@@ -867,13 +867,14 @@ void early_boot_handle_button(void)
|
||||
* to connect to an SFP module or a PHY
|
||||
* Valid modes are SDS_10GR, SDS_QXGMII, SDS_HISGMII, SDS_HSG, SDS_SGMII and SDS_1000BX_FIBER
|
||||
* The SerDes ID may be 0 or 1 for RTL8272 and 0-2 for RTL8373
|
||||
* SDS_QXGMII is used for 10G Fiber, RTL8224 and RTL8261BE
|
||||
*/
|
||||
void sds_config(uint8_t sds, uint8_t mode)
|
||||
{
|
||||
print_string("sds_config sds: "); print_byte(sds); print_string(", mode: "); print_byte(mode); write_char('\n');
|
||||
sds_config_mac(sds, mode);
|
||||
|
||||
if (mode == SDS_10GR || mode == SDS_QXGMII) // 10G Fiber, 10G connection to RTL8224
|
||||
if (mode == SDS_10GR || mode == SDS_QXGMII)
|
||||
sds_write_v(sds, 0x21, 0x10, 0x4480); // Q002110:6480
|
||||
else
|
||||
sds_write_v(sds, 0x21, 0x10, 0x6480); // Q002110:6480
|
||||
@@ -909,7 +910,7 @@ void sds_config(uint8_t sds, uint8_t mode)
|
||||
}
|
||||
sds_write_v(sds, 0x36, 0x10, v); // Q003610:0200
|
||||
|
||||
if (page == 0x2e) { // 10G Fiber
|
||||
if (page == 0x2e) { // 10G Fiber / SDS_QXGMII
|
||||
sds_write_v(sds, page, 0x04, 0x0080); // Q012e04:0080
|
||||
sds_write_v(sds, page, 0x06, 0x0408); // Q012e06:0408
|
||||
sds_write_v(sds, page, 0x07, 0x020d); // Q012e07:020d
|
||||
@@ -938,6 +939,30 @@ void sds_config(uint8_t sds, uint8_t mode)
|
||||
sds_write_v(sds, 0x07, 0x0c, 0x9401); // Q00070c:9401
|
||||
sds_write_v(sds, 0x1f, 0x0b, 0x0003); // Q001f0b:0003
|
||||
sds_write_v(sds, 0x06, 0x03, 0xc45c); // Q000603:c45c
|
||||
|
||||
// RTL8261BE
|
||||
if (machine.n_10g && mode == SDS_QXGMII) {
|
||||
sds_write_v(sds, 0x06, 0x1f, 0x2100); // Q00061f:2100
|
||||
sds_write_v(sds, 0x07, 0x11, 0x054f); // Q000711:054f
|
||||
sds_write_v(sds, 0x20, 0x00, 0x0030); // Q002000:0030
|
||||
sds_write_v(sds, 0x20, 0x00, 0x0010); // Q002000:0010
|
||||
sds_write_v(sds, 0x20, 0x00, 0x0050); // Q002000:0050
|
||||
sds_write_v(sds, 0x20, 0x00, 0x00d0); // Q002000:00d0
|
||||
sds_write_v(sds, 0x20, 0x00, 0x0cd0); // Q002000:0cd0
|
||||
sds_write_v(sds, 0x20, 0x00, 0x04d0); // Q002000:04d0
|
||||
sds_write_v(sds, 0x20, 0x00, 0x04d0); // Q002000:04d0
|
||||
sds_write_v(sds, 0x20, 0x00, 0x0cd0); // Q002000:0cd0
|
||||
sds_write_v(sds, 0x20, 0x00, 0x00d0); // Q002000:00d0
|
||||
sds_write_v(sds, 0x20, 0x00, 0x00d0); // Q002000:00d0
|
||||
sds_write_v(sds, 0x20, 0x00, 0x0050); // Q002000:0050
|
||||
sds_write_v(sds, 0x20, 0x00, 0x0010); // Q002000:0010
|
||||
sds_write_v(sds, 0x20, 0x00, 0x0010); // Q002000:0010
|
||||
sds_write_v(sds, 0x20, 0x00, 0x0030); // Q002000:0030
|
||||
sds_write_v(sds, 0x20, 0x00, 0x0000); // Q002000:0000
|
||||
sds_write_v(sds, 0x1f, 0x00, 0x000b); // Q001f00:000b
|
||||
sds_write_v(sds, 0x1f, 0x00, 0x0000); // Q001f00:0000
|
||||
return;
|
||||
}
|
||||
if (mode != SDS_QXGMII)
|
||||
sds_write_v(sds, 0x06, 0x1f, 0x2100); // Q00061f:2100
|
||||
|
||||
@@ -1342,13 +1367,17 @@ void idle(void)
|
||||
uint8_t p5 = sfr_data[2] >> 4;
|
||||
uint8_t p5_last = linkbits_last[2] >> 4;
|
||||
cpy_4(linkbits_last, sfr_data);
|
||||
// Handle link change of the RTL8221 PHY, adjust SDS mode
|
||||
if (p5_last != p5) {
|
||||
// Handle link change of the RTL8221 PHY, adjust SDS mode, RTL8261BE always uses SDS_QXGMII
|
||||
if (!machine.n_10g && p5_last != p5) {
|
||||
if (p5 == 0x5) // 2.5GBit Mode
|
||||
sds_config(0, SDS_HISGMII);
|
||||
else if (p5 == 0x2) // 1GBit
|
||||
sds_config(0, SDS_SGMII);
|
||||
}
|
||||
if (machine.n_10g)
|
||||
sds_config(0, SDS_QXGMII);
|
||||
if (machine.n_10g == 2)
|
||||
sds_config(1, SDS_QXGMII);
|
||||
} else {
|
||||
cpy_4(linkbits_last, sfr_data);
|
||||
}
|
||||
@@ -2016,7 +2045,6 @@ void main(void)
|
||||
|
||||
setup_i2c();
|
||||
setup_sfp_gpio();
|
||||
|
||||
print_string(greeting);
|
||||
|
||||
print_string("\nClock register: ");
|
||||
|
||||
Reference in New Issue
Block a user