RTL9000BRG调试总结

RTL9000是百兆PHY芯片,调试的板子是使用的RGMII。

调试一款phy芯片最简单直接的方式是查看内核中是否支持这类型号。路径如下:

kernel/drivers/net/phy/realtek.c

查看代码中只是支持了8211系列。


static struct phy_driver realtek_drvs[] = {
	{
		.phy_id         = 0x00008201,
		.name           = "RTL8201CP Ethernet",
		.phy_id_mask    = 0x0000ffff,
		.features       = PHY_BASIC_FEATURES,
		.flags          = PHY_HAS_INTERRUPT,
		.config_aneg    = &genphy_config_aneg,
		.read_status    = &genphy_read_status,
	}, {
		.phy_id		= 0x001cc912,
		.name		= "RTL8211B Gigabit Ethernet",
		.phy_id_mask	= 0x001fffff,
		.features	= PHY_GBIT_FEATURES,
		.flags		= PHY_HAS_INTERRUPT,
		.config_aneg	= &genphy_config_aneg,
		.read_status	= &genphy_read_status,
		.ack_interrupt	= &rtl821x_ack_interrupt,
		.config_intr	= &rtl8211b_config_intr,
		.read_mmd	= &genphy_read_mmd_unsupported,
		.write_mmd	= &genphy_write_mmd_unsupported,
	}, {
		.phy_id		= 0x001cc914,
		.name		= "RTL8211DN Gigabit Ethernet",
		.phy_id_mask	= 0x001fffff,
		.features	= PHY_GBIT_FEATURES,
		.flags		= PHY_HAS_INTERRUPT,
		.config_aneg	= genphy_config_aneg,
		.read_status	= genphy_read_status,
		.ack_interrupt	= rtl821x_ack_interrupt,
		.config_intr	= rtl8211e_config_intr,
		.suspend	= genphy_suspend,
		.resume		= genphy_resume,
	}, {
		.phy_id		= 0x001cc915,
		.name		= "RTL8211E Gigabit Ethernet",
		.phy_id_mask	= 0x001fffff,
		.features	= PHY_GBIT_FEATURES,
		.flags		= PHY_HAS_INTERRUPT,
		.config_aneg	= &genphy_config_aneg,
		.read_status	= &genphy_read_status,
		.ack_interrupt	= &rtl821x_ack_interrupt,
		.config_intr	= &rtl8211e_config_intr,
		.suspend	= genphy_suspend,
		.resume		= genphy_resume,
	}, {
		.phy_id		= 0x001cc916,
		.name		= "RTL8211F Gigabit Ethernet",
		.phy_id_mask	= 0x001fffff,
		.features	= PHY_GBIT_FEATURES,
		.flags		= PHY_HAS_INTERRUPT,
		.config_aneg	= &genphy_config_aneg,
		.config_init	= &rtl8211f_config_init,
		.read_status	= &genphy_read_status,
		.ack_interrupt	= &rtl8211f_ack_interrupt,
		.config_intr	= &rtl8211f_config_intr,
		.suspend	= genphy_suspend,
		.resume		= genphy_resume,
	},
};

所以需要自己适配RTL9000。

1.配置设备树

&ethernet {
	status = "okay";
	phy-handle = <&phy1>;
	phy-mode = "rgmii-id";
	phy-reset-gpios = <112>;
	phy-reset-duration = <12>;
	phy-reset-post-delay = <10>;
	mdio {
		#address-cells = <0x1>;
		#size-cells = <0x0>;
		phy1: phy@1 {
			compatible = "RTL8211F Gigabit Ethernet","ethernet-phy-ieee802.3-c45";
			reg = <0x1>;
		};
	};
};

2.明确phy id

 根据寄存器值可以确定phy id是0x001ccb00

3.填充驱动

/*
 * drivers/net/phy/realtek.c
 *
 * Driver for Realtek PHYs
 *
 * Author: Johnson Leung <r58129@freescale.com>
 *
 * Copyright (c) 2004 Freescale Semiconductor, Inc.
 *
 * This program is free software; you can redistribute  it and/or modify it
 * under  the terms of  the GNU General  Public License as published by the
 * Free Software Foundation;  either version 2 of the  License, or (at your
 * option) any later version.
 *
 */
#include <linux/phy.h>
#include <linux/module.h>
#include <linux/delay.h>

#define RTL821x_PHYSR		0x11
#define RTL821x_PHYSR_DUPLEX	0x2000
#define RTL821x_PHYSR_SPEED	0xc000
#define RTL821x_INER		0x12
#define RTL821x_INER_INIT	0x6400
#define RTL821x_INSR		0x13
#define RTL8211E_INER_LINK_STATUS 0x400

#define RTL8211F_INER_LINK_STATUS 0x0010
#define RTL8211F_INSR		0x1d
#define RTL8211F_PAGE_SELECT	0x1f
#define RTL8211F_TX_DELAY	0x100


#define MIIM_RTL9000_SRAM_ADDR        0x1b
#define MIIM_RTL9000_SRAM_DATA        0x1c
#define MIIM_RTL9000_PAGE_SELECT      0x1f

/*
* For RTL9000 RGMII Control Registers
* special register
*/
#define MIIM_RTL9000_RGRXCR           0xd082
#define MIIM_RTL9000_TX_DELAY         0x10<<8
#define MIIM_RTL9000_PHY_STATUS       0x1a
#define MIIM_RTL9000_PHYSTAT_LINK     0x0004
#define MIIM_RTL9000_PHYSTAT_DUPLEX   0x0100
#define MIIM_RTL9000_PHYSTAT_SPEED    0x2040

unsigned int param_check[6*3]={0, 0x8017, 0xFB03, 0, 0x8092, 0x6000,
	0, 0x80AF, 0x6000, 0, 0x807D, 0x4443, 0, 0x809A, 0x4443, 0, 0x81A3, 0x0F00};

MODULE_DESCRIPTION("Realtek PHY driver");
MODULE_AUTHOR("Johnson Leung");
MODULE_LICENSE("GPL");

static int rtl821x_ack_interrupt(struct phy_device *phydev)
{
	int err;

	err = phy_read(phydev, RTL821x_INSR);

	return (err < 0) ? err : 0;
}

static int rtl8211f_ack_interrupt(struct phy_device *phydev)
{
	int err;

	phy_write(phydev, RTL8211F_PAGE_SELECT, 0xa43);
	err = phy_read(phydev, RTL8211F_INSR);
	/* restore to default page 0 */
	phy_write(phydev, RTL8211F_PAGE_SELECT, 0x0);

	return (err < 0) ? err : 0;
}

static int rtl8211b_config_intr(struct phy_device *phydev)
{
	int err;

	if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
		err = phy_write(phydev, RTL821x_INER,
				RTL821x_INER_INIT);
	else
		err = phy_write(phydev, RTL821x_INER, 0);

	return err;
}

static int rtl8211e_config_intr(struct phy_device *phydev)
{
	int err;

	if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
		err = phy_write(phydev, RTL821x_INER,
				RTL8211E_INER_LINK_STATUS);
	else
		err = phy_write(phydev, RTL821x_INER, 0);

	return err;
}

static int rtl8211f_config_intr(struct phy_device *phydev)
{
	int err;

	if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
		err = phy_write(phydev, RTL821x_INER,
				RTL8211F_INER_LINK_STATUS);
	else
		err = phy_write(phydev, RTL821x_INER, 0);

	return err;
}

static int rtl8211f_config_init(struct phy_device *phydev)
{
	int ret;
	u16 reg;

	ret = genphy_config_init(phydev);
	if (ret < 0)
		return ret;

	phy_write(phydev, RTL8211F_PAGE_SELECT, 0xd08);
	reg = phy_read(phydev, 0x11);

	/* enable TX-delay for rgmii-id and rgmii-txid, otherwise disable it */
	if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
	    phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID)
		reg |= RTL8211F_TX_DELAY;
	else
		reg &= ~RTL8211F_TX_DELAY;

	phy_write(phydev, 0x11, reg);
	/* restore to default page 0 */
	phy_write(phydev, RTL8211F_PAGE_SELECT, 0x0);

	return 0;
}


static void RTL9000Bxx_Initial_Config_Erratum1(struct phy_device *phydev)
{
	int io_data = 0;
	int timer = 2000;
	//sample_code 04
	//phy_write(phydev, 0x1F, 0x0A43);
	phy_write(phydev, 0x1B, 0x8017);
	phy_write(phydev, 0x1C, 0xFB03);	// PHY patch request
	phy_write(phydev, 0x1B, 0x8092);
	phy_write(phydev, 0x1C, 0x6000);
	phy_write(phydev, 0x1B, 0x80AF);
	phy_write(phydev, 0x1C, 0x6000);
	phy_write(phydev, 0x1B, 0x807D);
	phy_write(phydev, 0x1C, 0x4443);
	phy_write(phydev, 0x1B, 0x809A);
	phy_write(phydev, 0x1C, 0x4443);
	phy_write(phydev, 0x1B, 0x81A3);
	phy_write(phydev, 0x1C, 0x0F00);
	phy_write(phydev, 0x1F, 0x0A81);
	phy_write(phydev, 0x12, 0x0004);
	phy_write(phydev, 0x1B, 0x83C8);
	phy_write(phydev, 0x1C, 0x0005);
	phy_write(phydev, 0x1F, 0x0A5C);
	phy_write(phydev, 0x12, 0x0003);
	phy_write(phydev, 0x1B, 0xB820);
	phy_write(phydev, 0x1C, 0x0010);
	phy_write(phydev, 0x1B, 0xB830);
	phy_write(phydev, 0x1C, 0x8000);
	//phy_write(phydev, 0x1B, 0xB800);
	do {
		phy_write(phydev, 0x1B, 0xB800);
		io_data = (phy_read(phydev, 0x1C)) & 0x40;
		timer--;
		if (timer == 0) {
			timer = 2000;
			break;
		}
	} while (io_data == 0);

	phy_write(phydev, 0x1B, 0x8020);
	phy_write(phydev, 0x1C, 0x3300);
	phy_write(phydev, 0x1B, 0xB82E);
	phy_write(phydev, 0x1C, 0x0001);
	phy_write(phydev, 0x1B, 0xB820);
	phy_write(phydev, 0x1C, 0x0290);
	phy_write(phydev, 0x1B, 0xA012);
	phy_write(phydev, 0x1C, 0x0000);
	phy_write(phydev, 0x1B, 0xA014);
	phy_write(phydev, 0x1C, 0x401C);
	phy_write(phydev, 0x1C, 0xA610);
	phy_write(phydev, 0x1C, 0x8520);
	phy_write(phydev, 0x1C, 0xA510);
	phy_write(phydev, 0x1C, 0x21F4);
	phy_write(phydev, 0x1B, 0xA01A);
	phy_write(phydev, 0x1C, 0x0000);
	phy_write(phydev, 0x1B, 0xA000);
	phy_write(phydev, 0x1C, 0x11EF);
	phy_write(phydev, 0x1B, 0xB820);
	phy_write(phydev, 0x1C, 0x0210);
	phy_write(phydev, 0x1B, 0xB82E);
	phy_write(phydev, 0x1C, 0x0000);
	phy_write(phydev, 0x1B, 0x8020);
	phy_write(phydev, 0x1C, 0x0000);
	phy_write(phydev, 0x1B, 0xB820);
	phy_write(phydev, 0x1C, 0x0000);
	//phy_write(phydev, 0x1B, 0xB800);
	do {
		phy_write(phydev, 0x1B, 0xB800);
		io_data = (phy_read(phydev, 0x1C)) & 0x40;
		timer--;
		if (timer == 0) {
			break;
		}
	} while (io_data != 0);
}


static int RTL9000Bxx_init(struct phy_device *phydev)
{
	int mdio_data = 0;
	int ret;
	int set_master = 0;
	int power_section = 5;

	unsigned int mdio_data_chk = 0;
	unsigned int page;
	unsigned int reg, i;

	/*  check PHY accessible  */
	while (mdio_data != 0x0003) {
		phy_write(phydev, 0x1F, 0x0A42);
		mdio_data = phy_read(phydev, 0x10);
		mdio_data = mdio_data & 0x0007;
	}

	/*  hardware reset  */
	// phy_write(phydev, 0x1B, 0xDD00);
	// mdio_data = phy_read(phydev, 0x1C);
	// phy_write(phydev, 0x1C, (mdio_data | 0x0020));

	phy_write(phydev, 0x1F, 0x0A42);//change page to default value
	//check PHY accessible

	mdio_data = 0;
	while (mdio_data != 0x0003) {
		mdio_data = phy_read(phydev, 0x10);
		mdio_data = mdio_data & 0x0007;
	}

	/*  init parameter  */
	RTL9000Bxx_Initial_Config_Erratum1(phydev);

	/*  check init success  */
	for(i = 0; i < 6*3; i = i+3) {
		page = param_check[i];
		mdio_data_chk = param_check[i+2];
		reg = param_check[i+1];
		if(page == 0) {
			phy_write(phydev, 0x1B, reg);
			mdio_data = phy_read(phydev, 0x1C);
		} else {
			phy_write(phydev, 0x1F, reg);
			mdio_data = phy_read(phydev, reg);
		}
		if(mdio_data_chk!= mdio_data) {
			printk(("%dth param error page=0x%04X reg=0x%04X data=0x%04X\n",
				i/3, page, reg, mdio_data));
			printk("phyInit error\n");
		}
	}
	printk("phy Init success\n");

	/*  I/O Power Sllection  */
	phy_write(phydev, 0x1F, 0x0A4C);//change page to default value
	mdio_data = phy_read(phydev, 0x12);
	mdio_data &= 0xC7FF;
	mdio_data |= 4 << 11;
	phy_write(phydev, 0x12, mdio_data);



	/***************************here is optional **********************/
	/*  role setting  */
	if (set_master == 1) {
		// Master or Slave mode depends on customer's application.
		mdio_data = phy_read(phydev, 9);
		phy_write(phydev, 9, (mdio_data | 0x0800));	// Set as Master
	} else {
		mdio_data = phy_read(phydev, 9);
		phy_write(phydev, 9, (mdio_data & 0xF7FF));	// Set as Slave
	}
	//.....other applications
	/*****************************************************************/


	/*  power supply selection */
	switch (power_section) {
	case 0://external 3.3V
		phy_write(phydev, 0x1F, 0x0A43); //change page to 0xa43
		phy_write(phydev, 0x1B, 0xDC06);
		phy_write(phydev, 0x1C, 0x0DF8);
		break;
	case 1://internal LDO 2.5V
		phy_write(phydev, 0x1F, 0x0A43);
		phy_write(phydev, 0x1B, 0xDC06);
		phy_write(phydev, 0x1C, 0x5DF9);
		break;
	case 2://external 2.5V
		phy_write(phydev, 0x1F, 0x0A43);
		phy_write(phydev, 0x1B, 0xDC06);
		phy_write(phydev, 0x1C, 0xDDF9);
		break;
	case 3://internal LDO 1.8v
		phy_write(phydev, 0x1F, 0x0A43);
		phy_write(phydev, 0x1B, 0xDC06);
		phy_write(phydev, 0x1C, 0xADFA);
		break;
	case 4://external 1.8v
		phy_write(phydev, 0x1F, 0x0A43);
		phy_write(phydev, 0x1B, 0xDC06);
		phy_write(phydev, 0x1C, 0xEDFA);
		break;
	case 5://RTL9000BRG
		//phy_write(phydev, 0x1F, 0x0A43);
		phy_write(phydev, 0x1B, 0xD414);
		ret = (phy_read(phydev, 0x1C)) | 0x1010;
		phy_write(phydev, 0x1C, ret);

		phy_write(phydev, 0x1B, 0xD416);
		ret = (phy_read(phydev, 0x1C)) | 0x1010;
		phy_write(phydev, 0x1C, ret);

		phy_write(phydev, 0x1B, 0xD418);
		ret = (phy_read(phydev, 0x1C)) | 0x1000;
		phy_write(phydev, 0x1C, ret);

		phy_write(phydev, 0x1B, 0xD41A);
		ret = (phy_read(phydev, 0x1C)) | 0x1000;
		phy_write(phydev, 0x1C, ret);
		phy_write(phydev, 0x1B, 0xD42E);
		phy_write(phydev, 0x1C, 0x7E7E);
	}

	/* Settting delay */
	phy_write(phydev, 0x1F, 0x0a43);
	phy_write(phydev, 0x1B, 0xD082);
	reg = phy_read(phydev, 0x1C);

	/* enable TX-delay for rgmii-id and rgmii-txid, otherwise disable it */
	if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
	    phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) {
		reg &= 0xFCF8;
		reg |= 7;      //RX delay
		//reg |= 1 << 8;   //TX delay
	} else {
		reg &= ~(0x10 << 8);
	}
	phy_write(phydev, 0x1B, 0xD082);
	phy_write(phydev, 0x1C, reg);
	phy_write(phydev, 0x1F, 0xa42);



	//software reset
	phy_write(phydev, 0, 0x8000);	// PHY soft-reset
	mdelay(30);

	/*  Check soft-reset complete  */
	mdio_data = 0;
	mdio_data = phy_read(phydev, 0);
	int num = 0;
	while (mdio_data != 0x2100) {
		mdio_data = phy_read(phydev, 0);
		if(num == 9)
			break;
		++num;
	}

	return 0;
}


static int rtl9000_config_init(struct phy_device *phydev)
{
	unsigned int reg;
	phy_write(phydev, 0, 0x8000);	// PHY soft-reset
	mdelay(30);

	RTL9000Bxx_init(phydev);

	/* Set green LED for Link, yellow LED for Active */
	// phy_write(phydev, MDIO_DEVAD_NONE,
	// 	  MIIM_RTL9000_PAGE_SELECT, 0xd04);
	// phy_write(phydev, MDIO_DEVAD_NONE, 0x10, 0x617f);
	// phy_write(phydev, MDIO_DEVAD_NONE,
	// 	  MIIM_RTL9000_PAGE_SELECT, 0x0);


	phydev->autoneg = AUTONEG_DISABLE;
	phydev->duplex = DUPLEX_FULL;
	//genphy_config_aneg(phydev);
	phy_write(phydev, MIIM_RTL9000_PAGE_SELECT, 0x0);
	reg = phy_read(phydev, MII_BMCR);
	if((reg & MIIM_RTL9000_PHYSTAT_SPEED) == 0x2000) {
		printk("phy speed: %d\n", SPEED_100);
		phydev->speed = SPEED_100;
	} else {
		printk("error speed : 0x%x\n", reg);
		return -EINVAL;
	}
	return 0;
}

static int rtl9000_config_aneg(struct phy_device *phydev)
{
       phydev->autoneg = AUTONEG_DISABLE;
	   phydev->duplex = DUPLEX_FULL;
       return 0;
}

static int rtl9000_ack_interrupt(struct phy_device *phydev)
{
    return 0;
}

static int rtl9000_config_intr(struct phy_device *phydev)
{
       return 0;
}

static int rtl9000_suspend(struct phy_device *phydev)
{
       return 0;
}

static int rtl9000_resume(struct phy_device *phydev)
{
       return 0;
}

static int rtl9000_read_status(struct phy_device *phydev)
{
	if(phydev){
		phydev->duplex = DUPLEX_FULL;
		phydev->speed = SPEED_100;
		phydev->pause = 0;
		phydev->asym_pause = 0;
		phydev->link = 1;
	} else {
		printk(KERN_ERR "%s phydev NULL\n", __func__);
	}
	return 0;
}

static int rtl9000_aneg_done(struct phy_device *phydev)
{
	return 0;
}

static int rtl9000_soft_reset(struct phy_device *phydev)
{
	int mdio_data = 0;
	phy_write(phydev, 0, 0x8000);	// PHY soft-reset
	mdelay(30);
	mdio_data = phy_read(phydev, 0);
	int num = 0;
	while (mdio_data != 0x2100) {
		mdio_data = phy_read(phydev, 0);
		if(num == 9)
			break;
		++num;
	}

	return 0;
}


static struct phy_driver realtek_drvs[] = {
	{
		.phy_id         = 0x00008201,
		.name           = "RTL8201CP Ethernet",
		.phy_id_mask    = 0x0000ffff,
		.features       = PHY_BASIC_FEATURES,
		.flags          = PHY_HAS_INTERRUPT,
		.config_aneg    = &genphy_config_aneg,
		.read_status    = &genphy_read_status,
	}, {
		.phy_id		= 0x001cc912,
		.name		= "RTL8211B Gigabit Ethernet",
		.phy_id_mask	= 0x001fffff,
		.features	= PHY_GBIT_FEATURES,
		.flags		= PHY_HAS_INTERRUPT,
		.config_aneg	= &genphy_config_aneg,
		.read_status	= &genphy_read_status,
		.ack_interrupt	= &rtl821x_ack_interrupt,
		.config_intr	= &rtl8211b_config_intr,
		.read_mmd	= &genphy_read_mmd_unsupported,
		.write_mmd	= &genphy_write_mmd_unsupported,
	}, {
		.phy_id		= 0x001cc914,
		.name		= "RTL8211DN Gigabit Ethernet",
		.phy_id_mask	= 0x001fffff,
		.features	= PHY_GBIT_FEATURES,
		.flags		= PHY_HAS_INTERRUPT,
		.config_aneg	= genphy_config_aneg,
		.read_status	= genphy_read_status,
		.ack_interrupt	= rtl821x_ack_interrupt,
		.config_intr	= rtl8211e_config_intr,
		.suspend	= genphy_suspend,
		.resume		= genphy_resume,
	}, {
		.phy_id		= 0x001cc915,
		.name		= "RTL8211E Gigabit Ethernet",
		.phy_id_mask	= 0x001fffff,
		.features	= PHY_GBIT_FEATURES,
		.flags		= PHY_HAS_INTERRUPT,
		.config_aneg	= &genphy_config_aneg,
		.read_status	= &genphy_read_status,
		.ack_interrupt	= &rtl821x_ack_interrupt,
		.config_intr	= &rtl8211e_config_intr,
		.suspend	= genphy_suspend,
		.resume		= genphy_resume,
	}, {
		.phy_id		= 0x001cc916,
		.name		= "RTL8211F Gigabit Ethernet",
		.phy_id_mask	= 0x001fffff,
		.features	= PHY_GBIT_FEATURES,
		.flags		= PHY_HAS_INTERRUPT,
		.config_aneg	= &genphy_config_aneg,
		.config_init	= &rtl8211f_config_init,
		.read_status	= &genphy_read_status,
		.ack_interrupt	= &rtl8211f_ack_interrupt,
		.config_intr	= &rtl8211f_config_intr,
		.suspend	= genphy_suspend,
		.resume		= genphy_resume,
	}, {
		.phy_id		= 0x001ccb00,
		.name		= "RTL9000BRG Gigabit Ethernet",
		.phy_id_mask	= 0x001fffff,
		.features	= PHY_BASIC_FEATURES,
		.flags		= PHY_HAS_INTERRUPT,
		.soft_reset     = &rtl9000_soft_reset,
		.config_init    = &rtl9000_config_init,
		.config_aneg	= &rtl9000_config_aneg,
		.read_status	= &rtl9000_read_status,
		.ack_interrupt	= &rtl9000_ack_interrupt,
		.config_intr	= &rtl9000_config_intr,
		.aneg_done      = &rtl9000_aneg_done,
		.suspend	= genphy_suspend,
		.resume		= genphy_resume,
	},
};

module_phy_driver(realtek_drvs);

static struct mdio_device_id __maybe_unused realtek_tbl[] = {
	{ 0x001cc912, 0x001fffff },
	{ 0x001cc914, 0x001fffff },
	{ 0x001cc915, 0x001fffff },
	{ 0x001cc916, 0x001fffff },
	{ 0x001ccb00, 0x001fffff },
	{ }
};

MODULE_DEVICE_TABLE(mdio, realtek_tbl);

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值