Mastering Embedded Linux Programming 学习 (五)在百问网157开发板上,解决网络配置问题
思考、参考
搜索发现,需要配置设备树,参考这个链接
修改设备树
找到百问网的补丁文件里面的ethernet0节点,内容如下所示
ðernet0 {
status = "okay";
pinctrl-0 = <ðernet0_rgmii_pins_a>;
pinctrl-1 = <ðernet0_rgmii_pins_sleep_a>;
pinctrl-names = "default", "sleep";
phy-mode = "rgmii";
max-speed = <1000>;
phy-handle = <&phy0>;
mdio0 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "snps,dwmac-mdio";
phy0: ethernet-phy@6 {
reg = <6>;
};
};
};
首先把它添加到u-boot的设备树文件里头
修改arch/arm/dts/stm32mp15xx-myboard.dtsi
将文件里的ethernet0节点,修改成上面的ethernet0节点
ethernet0的引脚
注意ethernet0_rgmii_pins_sleep_a,百问网的补丁文件重新定义了,不是简单的修改成原来的ethernet0_rgmii_sleep_pins_a就完事
修改arch/arm/dts/stm32mp15-pinctrl.dtsi
在pinctrl节点下的ethernet0_rgmii_sleep_pins_a节点前面添加下面的两个节点
注意要把原来的ethernet0_rgmii_pins_a节点删掉
ethernet0_rgmii_pins_a: rgmii-0 {
pins1 {
pinmux = <STM32_PINMUX('G', 5, AF11)>, /* ETH_RGMII_CLK125 */
<STM32_PINMUX('G', 4, AF11)>, /* ETH_RGMII_GTX_CLK */
<STM32_PINMUX('G', 13, AF11)>, /* ETH_RGMII_TXD0 */
<STM32_PINMUX('G', 14, AF11)>, /* ETH_RGMII_TXD1 */
<STM32_PINMUX('C', 2, AF11)>, /* ETH_RGMII_TXD2 */
<STM32_PINMUX('E', 2, AF11)>, /* ETH_RGMII_TXD3 */
<STM32_PINMUX('B', 11, AF11)>, /* ETH_RGMII_TX_CTL */
<STM32_PINMUX('A', 2, AF11)>, /* ETH_MDIO */
<STM32_PINMUX('C', 1, AF11)>; /* ETH_MDC */
bias-disable;
drive-push-pull;
slew-rate = <2>;
};
pins2 {
pinmux = <STM32_PINMUX('C', 4, AF11)>, /* ETH_RGMII_RXD0 */
<STM32_PINMUX('C', 4, AF11)>, /* ETH_RGMII_RXD0 */
<STM32_PINMUX('C', 5, AF11)>, /* ETH_RGMII_RXD1 */
<STM32_PINMUX('B', 0, AF11)>, /* ETH_RGMII_RXD2 */
<STM32_PINMUX('B', 1, AF11)>, /* ETH_RGMII_RXD3 */
<STM32_PINMUX('A', 1, AF11)>, /* ETH_RGMII_RX_CLK */
<STM32_PINMUX('A', 7, AF11)>; /* ETH_RGMII_RX_CTL */
bias-disable;
};
};
ethernet0_rgmii_pins_sleep_a: rgmii-sleep-0 {
pins1 {
pinmux = <STM32_PINMUX('G', 5, ANALOG)>, /* ETH_RGMII_CLK125 */
<STM32_PINMUX('G', 4, ANALOG)>, /* ETH_RGMII_GTX_CLK */
<STM32_PINMUX('G', 13, ANALOG)>, /* ETH_RGMII_TXD0 */
<STM32_PINMUX('G', 14, ANALOG)>, /* ETH_RGMII_TXD1 */
<STM32_PINMUX('C', 2, ANALOG)>, /* ETH_RGMII_TXD2 */
<STM32_PINMUX('E', 2, ANALOG)>, /* ETH_RGMII_TXD3 */
<STM32_PINMUX('B', 11, ANALOG)>, /* ETH_RGMII_TX_CTL */
<STM32_PINMUX('A', 2, ANALOG)>, /* ETH_MDIO */
<STM32_PINMUX('C', 1, ANALOG)>, /* ETH_MDC */
<STM32_PINMUX('C', 4, ANALOG)>, /* ETH_RGMII_RXD0 */
<STM32_PINMUX('C', 5, ANALOG)>, /* ETH_RGMII_RXD1 */
<STM32_PINMUX('B', 0, ANALOG)>, /* ETH_RGMII_RXD2 */
<STM32_PINMUX('B', 1, ANALOG)>, /* ETH_RGMII_RXD3 */
<STM32_PINMUX('A', 1, ANALOG)>, /* ETH_RGMII_RX_CLK */
<STM32_PINMUX('A', 7, ANALOG)>; /* ETH_RGMII_RX_CTL */
};
};
修改arch/arm/dts/stm32mp15xx-myboard.dtsi
把adc节点的status属性修改为disable
然后重新烧录编译
启动u-boot
设置网络参数
setenv ipaddr 192.168.123.18
setenv gatewayip 192.168.123.1
setenv netmask 255.255.255.0
setenv serverip 192.168.123.220
saveenv
修改ethernet0节点
备份arch/arm/dts/stm32mp151.dtsi
修改arch/arm/dts/stm32mp151.dtsi下的ethernet0节点
修改成如下的格式
ethernet0: ethernet@5800a000 {
compatible = "st,stm32mp1-dwmac", "snps,dwmac-4.20a";
reg = <0x5800a000 0x2000>;
reg-names = "stmmaceth";
interrupts-extended = <&intc GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>,
<&exti 70 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "macirq",
"eth_wake_irq";
clock-names = "stmmaceth",
"mac-clk-tx",
"mac-clk-rx",
"ethstp",
"ethstp";
clocks = <&rcc ETHMAC>,
<&rcc ETHTX>,
<&rcc ETHRX>,
<&rcc ETHCK_K>,
<&rcc ETHSTP>;
st,syscon = <&syscfg 0x4>;
snps,mixed-burst;
snps,pbl = <2>;
snps,en-tx-lpi-clockgating;
snps,axi-config = <&stmmac_axi_config_0>;
snps,tso;
power-domains = <&pd_core>;
status = "disabled";
};
重新编译烧录
pd_core不存在
提示pd_core不存在
在100ask的arch/arm/dts/stm32mp151.dtsi文件找到如下节点
编译成功
修改**arch/arm/dts/stm32mp15xx-myboard.dtsi **下的adc节点的adc1节点的status为disable
重新编译烧录
不报adc错误了,但是提示找不到adc设备
使用dhcp命令报错
搜索源码发现是在这个文件里
然后发现是这个玩意的驱动
发现是出错在这里
找到157相关的寄存器,发现有提示,难道是时钟没有配置好?
参考补丁开始修改
修改board/st/common/stusb160x.c
把STUSB1600_CC_CONNECTION_STATUS修改为0x42
但是在board/st/stm32mp1/stm32mp1.c找不到这一个,不过发现下面这一行头文件
最后发现是在这个文件里面
board/st/common/stusb160x.c
而且变成了这个形式
修改这两个宏如下
修改board/st/stm32mp1/stm32mp1.c
继续修改stm32mp151.c,在最后一个endif下面添加下面的代码
static bool board_is_ya15xc_v2(void)
{
if (CONFIG_IS_ENABLED(TARGET_ST_STM32MP15x) && of_machine_is_compatible("st,stm32mp157"))
return true;
return false;
}
static int phy_power(void)
{
ofnode node1;
struct gpio_desc phy;
int ret = 0;
node1 = ofnode_path("/wifi_bt_power/phy");
if (!ofnode_valid(node1)) {
printf("%s: no phy-power?\n", __func__);
return -ENOENT;
}
if (gpio_request_by_name_nodev(node1, "gpios", 0,
&phy, GPIOD_IS_OUT)) {
printf("%s: could not find reset-gpios1\n",
__func__);
return -ENOENT;
}
ret = dm_gpio_set_value(&phy, 1);
if (ret) {
pr_err("%s: can't set_value for phy reset gpio", __func__);
goto error;
}
error:
return ret;
}
static bool board_is_ya15xc(void)
{
if (CONFIG_IS_ENABLED(TARGET_ST_STM32MP15x) &&
(of_machine_is_compatible("st,stm32mp157") ||
of_machine_is_compatible("st,stm32mp157c-ya157c-v2")))
return true;
return false;
}
//reset the wifi-bt
static int wifi_bt_power(void)
{
ofnode node1, node2;
struct gpio_desc wifi, bt;
int ret = 0;
node1 = ofnode_path("/wifi_bt_power/wifi");
if (!ofnode_valid(node1)) {
printf("%s: no wifi-power?\n", __func__);
return -ENOENT;
}
node2 = ofnode_path("/wifi_bt_power/bt");
if (!ofnode_valid(node2)) {
printf("%s: no bt-power?\n", __func__);
return -ENOENT;
}
if (gpio_request_by_name_nodev(node1, "gpios", 0,
&wifi, GPIOD_IS_OUT)) {
printf("%s: could not find reset-gpios1\n",
__func__);
return -ENOENT;
}
if (gpio_request_by_name_nodev(node2, "gpios", 0,
&bt, GPIOD_IS_OUT)) {
printf("%s: could not find reset-gpios2\n",
__func__);
return -ENOENT;
}
ret = dm_gpio_set_value(&wifi, 0);
if (ret) {
pr_err("%s: can't set_value for wifi reset gpio", __func__);
goto error;
}
ret = dm_gpio_set_value(&bt, 0);
if (ret) {
pr_err("%s: can't set_value for bt reset gpio", __func__);
goto error;
}
mdelay(100);//delay
ret = dm_gpio_set_value(&wifi, 1);
if (ret) {
pr_err("%s: can't set_value for wifi reset gpio", __func__);
goto error;
}
ret = dm_gpio_set_value(&bt, 1);
if (ret) {
pr_err("%s: can't set_value for bt reset gpio", __func__);
goto error;
}
error:
return ret;
}
搜索board_key_check,在board_init()函数调用board_key_check函数的后面添加如下代码
if (board_is_ya15xc())
{
wifi_bt_power();
dk2_i2c1_fix();
}
if (board_is_ya15xc_v2())
{
phy_power();
}
考虑到把函数定义放在了后面,需要在board_init函数前放我们上面的函数声明
static bool board_is_ya15xc_v2(void);
static int phy_power(void);
static bool board_is_ya15xc(void);
static int wifi_bt_power(void);
/* board dependent setup after realloc */
int board_init(void)
...
修改drivers/clk/clk_stm32mp1.c
修改drivers/dfu/dfu.c
做如下修改
修改drivers/net/dwc_eth_qos.c
修改drivers/net/phy/atheros.c
在int ret 下添加下面的内容
u16 val;
/*----------------------------------------------*/
/* Ar803x phy SmartEEE feature cause link status generates glitch,
* which cause ethernet link down/up issue, so disable SmartEEE
*/
phy_write(phydev,MDIO_DEVAD_NONE, 0xd, 0x3);
phy_write(phydev,MDIO_DEVAD_NONE, 0xe, 0x805d);
phy_write(phydev,MDIO_DEVAD_NONE, 0xd, 0x4003);
val = phy_read(phydev,MDIO_DEVAD_NONE, 0xe);
phy_write(phydev,MDIO_DEVAD_NONE, 0xe, val & ~(1 << 8));
/* To enable AR8031 output a 125MHz clk from CLK_25M */
phy_write(phydev,MDIO_DEVAD_NONE, 0xd, 0x7);
phy_write(phydev,MDIO_DEVAD_NONE, 0xe, 0x8016);
phy_write(phydev,MDIO_DEVAD_NONE, 0xd, 0x4007);
val = phy_read(phydev,MDIO_DEVAD_NONE, 0xe);
val &= 0xffe3;
val |= 0x18;
phy_write(phydev,MDIO_DEVAD_NONE, 0xe, val);
phy_write(phydev,MDIO_DEVAD_NONE, 0x1d, 0x5);
val = phy_read(phydev,MDIO_DEVAD_NONE, 0x1e);
val |= 0x0100;
phy_write(phydev,MDIO_DEVAD_NONE, 0x1e, val);
printf("test ar8035 !!!");
/*------------------------------------------*/
修改drivers/net/phy/phy.c
在phy_probe函数下添加如下内容
phydev->supported = phydev->drv->features;
phydev->mmds = phydev->drv->mmds;
u16 val;
/*----------------------------------------------*/
/* Ar803x phy SmartEEE feature cause link status generates glitch,
* which cause ethernet link down/up issue, so disable SmartEEE
*/
phy_write(phydev,MDIO_DEVAD_NONE, 0xd, 0x3);
phy_write(phydev,MDIO_DEVAD_NONE, 0xe, 0x805d);
phy_write(phydev,MDIO_DEVAD_NONE, 0xd, 0x4003);
val = phy_read(phydev,MDIO_DEVAD_NONE, 0xe);
phy_write(phydev,MDIO_DEVAD_NONE, 0xe, val & ~(1 << 8));
/* To enable AR8031 output a 125MHz clk from CLK_25M */
phy_write(phydev,MDIO_DEVAD_NONE, 0xd, 0x7);
phy_write(phydev,MDIO_DEVAD_NONE, 0xe, 0x8016);
phy_write(phydev,MDIO_DEVAD_NONE, 0xd, 0x4007);
val = phy_read(phydev,MDIO_DEVAD_NONE, 0xe);
val &= 0xffe3;
val |= 0x18;
phy_write(phydev,MDIO_DEVAD_NONE, 0xe, val);
phy_write(phydev,MDIO_DEVAD_NONE, 0x1d, 0x5);
val = phy_read(phydev,MDIO_DEVAD_NONE, 0x1e);
val |= 0x0100;
phy_write(phydev,MDIO_DEVAD_NONE, 0x1e, val);
//--------------------------------------
编译成功,重新烧录
提示这个,需要继续修改设备树文件
修改arch/arm/dts/stm32mp157c-myboard.dts
在根节点下添加
wifi_bt_power:wifi_bt_power {
compatible = "wifibt-rst";
wifi {
label = "wifi-rst";
gpios = <&gpioi 3 GPIO_ACTIVE_HIGH>;
};
bt {
label = "bt-rst";
gpios = <&gpioa 15 GPIO_ACTIVE_HIGH>;
};
phy {
label = "phy-rest";
gpios = <&gpiog 0 GPIO_ACTIVE_HIGH>;
};
};
编译成功,重新烧录
成功搞定!!!