[U-Boot] [PATCH v4 2/2] usb: eth: add Realtek RTL8152B/RTL8153 DRIVER
Marek Vasut
marex at denx.de
Thu Jan 14 06:37:06 CET 2016
On Thursday, January 14, 2016 at 06:22:07 AM, Ted Chen wrote:
> This patch adds driver support for the Realtek RTL8152B/RTL8153 USB
> network adapters.
[...]
> +static void rtl8152_wait_fifo_empty(struct r8152 *tp)
> +{
> + int i;
> + u32 ocp_data;
> +
> + for (i = 0; i < FIFO_EMPTY_TIMEOUT; i++) {
> + ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL);
> + if ((ocp_data & FIFO_EMPTY) == FIFO_EMPTY)
> + break;
> +
> + mdelay(1);
> + }
> +
> + if (i == FIFO_EMPTY_TIMEOUT)
> + debug("Timeout waiting for FIFO empty\n");
> +
> + for (i = 0; i < FIFO_EMPTY_TIMEOUT; i++) {
> + if (ocp_read_word(tp, MCU_TYPE_PLA, PLA_TCR0) & TCR0_TX_EMPTY)
> + break;
> + mdelay(1);
You can implement something like wait_for_bit() here to avoid having multiple
copies of the same code.
> + }
> +
> + if (i == FIFO_EMPTY_TIMEOUT)
> + debug("Timeout waiting for TX empty\n");
> +}
> +
> +static void rtl8152_nic_reset(struct r8152 *tp)
> +{
> + int i;
> +
> + ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CR, PLA_CR_RST);
> +
> + for (i = 0; i < NIC_RESET_TIMEOUT; i++) {
> + if (!(ocp_read_byte(tp, MCU_TYPE_PLA, PLA_CR) & PLA_CR_RST))
> + break;
> +
> + mdelay(1);
> + }
DTTO here.
> + if (i == NIC_RESET_TIMEOUT)
> + debug("Timeout waiting for NIC reset\n");
> +}
> +
> +static u8 rtl8152_get_speed(struct r8152 *tp)
> +{
> + return ocp_read_byte(tp, MCU_TYPE_PLA, PLA_PHYSTATUS);
> +}
[...]
> +static void r8152b_get_version(struct r8152 *tp)
> +{
> + u32 ocp_data;
> + u16 version;
> +
> + ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_TCR1);
> + version = (u16)(ocp_data & VERSION_MASK);
> +
> + switch (version) {
> + case 0x4c00:
> + tp->version = RTL_VER_01;
I'd implement this as a lookup table, it might be more readable.
What do you think ?
> + break;
> + case 0x4c10:
> + tp->version = RTL_VER_02;
> + break;
> + case 0x5c00:
> + tp->version = RTL_VER_03;
> + tp->supports_gmii = 1;
> + break;
> + case 0x5c10:
> + tp->version = RTL_VER_04;
> + tp->supports_gmii = 1;
> + break;
> + case 0x5c20:
> + tp->version = RTL_VER_05;
> + tp->supports_gmii = 1;
> + break;
> + case 0x5c30:
> + tp->version = RTL_VER_06;
> + tp->supports_gmii = 1;
> + break;
> + case 0x4800:
> + tp->version = RTL_VER_07;
> + break;
> + default:
> + printf("Unknown version 0x%04x\n", version);
> + break;
> + }
> +}
> +
[...]
> +static void r8153_init(struct r8152 *tp)
> +{
> + u32 ocp_data;
> + int i;
> +
> + r8153_disable_aldps(tp);
> + r8153_u1u2en(tp, false);
> +
> + for (i = 0; i < 500; i++) {
> + if (ocp_read_word(tp, MCU_TYPE_PLA, PLA_BOOT_CTRL) &
> + AUTOLOAD_DONE)
> + break;
> + mdelay(20);
Yet another ad-hoc wait_for_bit() implementation here.
> + }
> +
> + for (i = 0; i < 500; i++) {
> + ocp_data = ocp_reg_read(tp, OCP_PHY_STATUS) & PHY_STAT_MASK;
> + if (ocp_data == PHY_STAT_LAN_ON || ocp_data == PHY_STAT_PWRDN)
> + break;
> + mdelay(20);
And here ...
> + }
> +
> + r8153_u2p3en(tp, false);
> +
> + if (tp->version == RTL_VER_04) {
> + ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_SSPHYLINK2);
> + ocp_data &= ~pwd_dn_scale_mask;
> + ocp_data |= pwd_dn_scale(96);
> + ocp_write_word(tp, MCU_TYPE_USB, USB_SSPHYLINK2, ocp_data);
> +
> + ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, USB_USB2PHY);
> + ocp_data |= USB2PHY_L1 | USB2PHY_SUSPEND;
> + ocp_write_byte(tp, MCU_TYPE_USB, USB_USB2PHY, ocp_data);
> + } else if (tp->version == RTL_VER_05) {
> + ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_DMY_REG0);
> + ocp_data &= ~ECM_ALDPS;
> + ocp_write_byte(tp, MCU_TYPE_PLA, PLA_DMY_REG0, ocp_data);
> +
> + ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, USB_CSR_DUMMY1);
> + if (ocp_read_word(tp, MCU_TYPE_USB, USB_BURST_SIZE) == 0)
> + ocp_data &= ~DYNAMIC_BURST;
> + else
> + ocp_data |= DYNAMIC_BURST;
> + ocp_write_byte(tp, MCU_TYPE_USB, USB_CSR_DUMMY1, ocp_data);
> + } else if (tp->version == RTL_VER_06) {
> + ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, USB_CSR_DUMMY1);
> + if (ocp_read_word(tp, MCU_TYPE_USB, USB_BURST_SIZE) == 0)
> + ocp_data &= ~DYNAMIC_BURST;
> + else
> + ocp_data |= DYNAMIC_BURST;
> + ocp_write_byte(tp, MCU_TYPE_USB, USB_CSR_DUMMY1, ocp_data);
> + }
> +
> + ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, USB_CSR_DUMMY2);
> + ocp_data |= EP4_FULL_FC;
> + ocp_write_byte(tp, MCU_TYPE_USB, USB_CSR_DUMMY2, ocp_data);
> +
> + ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_WDT11_CTRL);
> + ocp_data &= ~TIMER11_EN;
> + ocp_write_word(tp, MCU_TYPE_USB, USB_WDT11_CTRL, ocp_data);
> +
> + ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_LED_FEATURE);
> + ocp_data &= ~LED_MODE_MASK;
> + ocp_write_word(tp, MCU_TYPE_PLA, PLA_LED_FEATURE, ocp_data);
> +
> + ocp_data = FIFO_EMPTY_1FB | ROK_EXIT_LPM;
> + if (tp->version == RTL_VER_04 && tp->udev->speed != USB_SPEED_SUPER)
> + ocp_data |= LPM_TIMER_500MS;
> + else
> + ocp_data |= LPM_TIMER_500US;
> + ocp_write_byte(tp, MCU_TYPE_USB, USB_LPM_CTRL, ocp_data);
> +
> + ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_AFE_CTRL2);
> + ocp_data &= ~SEN_VAL_MASK;
> + ocp_data |= SEN_VAL_NORMAL | SEL_RXIDLE;
> + ocp_write_word(tp, MCU_TYPE_USB, USB_AFE_CTRL2, ocp_data);
> +
> + ocp_write_word(tp, MCU_TYPE_USB, USB_CONNECT_TIMER, 0x0001);
> +
> + r8153_power_cut_en(tp, false);
> +
> + r8152b_enable_fc(tp);
> + rtl_tally_reset(tp);
> +}
> +
> +static void rtl8152_unload(struct r8152 *tp)
> +{
> + if (tp->version != RTL_VER_01)
> + r8152_power_cut_en(tp, true);
> +}
> +
> +static void rtl8153_unload(struct r8152 *tp)
> +{
> + r8153_power_cut_en(tp, false);
> +}
[...]
> diff --git a/drivers/usb/eth/r8152_fw.c b/drivers/usb/eth/r8152_fw.c
> new file mode 100644
> index 0000000..8dc8cad
> --- /dev/null
> +++ b/drivers/usb/eth/r8152_fw.c
[...]
> +static void patch4(struct r8152 *tp)
Please make this consistent and name it with r8153_ prefix. Some more
obvious name would help too, patch4 doesn't tell me anything about the
function or what it does.
> +{
> + u8 data;
> +
> + data = ocp_read_byte(tp, MCU_TYPE_USB, 0xd429);
> + data |= 0x80;
> + ocp_write_byte(tp, MCU_TYPE_USB, 0xd429, data);
> + ocp_write_word(tp, MCU_TYPE_USB, 0xc0ce, 0x0210);
> + data = ocp_read_byte(tp, MCU_TYPE_USB, 0xd429);
> + data &= ~0x80;
> + ocp_write_byte(tp, MCU_TYPE_USB, 0xd429, data);
> +}
[...]
> +static void r8153_wdt1_end(struct r8152 *tp)
> +{
This is, again, ad-hoc implementation of wait_for_bit() alike.
> + int i;
> +
> + for (i = 0; i < 104; i++) {
> + if (!(ocp_read_byte(tp, MCU_TYPE_USB, 0xe404) & 1))
> + break;
> + mdelay(2);
> + }
> +}
[...]
Thanks!
More information about the U-Boot
mailing list