KERNEL Q&A

Q1:910 PAD_FUART_RTS引脚如何复用成GPIO

kernel\arch\arm\boot\dts\mercury6-ssc017-s01a-padmux.dtsi,看下PAD_FUART_RTS是否有复用其它功能,如果有则需要拿掉;

另外增加一行:

<PAD_FUART_RTS           PINMUX_FOR_GPIO_MODE          MDRV_PUSE_NA>,

复用PAD_FUART_RTS为GPIO模式;然后就可以参考《GPIO使用参考》进行操作了。

另外附上PAD_FUART_RTS为GPIO模式下的寄存器对照表,可以确认是否有设置正确,便于排查。

GPIO index Ball Name Configuration
(default value)
Base Addr Offset Configuration
(register settings)
OEN
0: output
1: input
IN OUT
36 PAD_FUART_RTS GPIO 103E a reg_gpio_en;
reg[103E14]#3= 1b
reg[103E14]#2 reg[103E14]#0 reg[103E14]#1

注意这里寄存器的偏移地址是8bit的,而riu_r是按16bit偏移地址读出来的。如果要对比,需要将8bit偏移地址除2,能整除代表低8位,余1则为高8位。比如寄存器地址0x103E14,偏移地址为0x14(8bit),转换为16bit偏移地址即为0x14/2=0xA(低8位)。

Q2:设置GPIO复用方法(以PAD_PM_I2CM_SCL/PAD_PM_I2CM_SDA复用I2C功能为例)

  1. 找到需要复用的GPIO管脚以及功能,比如

    PAD_PM_I2CM_SCL/PAD_PM_I2CM_SDA做I2C用。

  2. 参考文档《SSR910 HW Checklist.xlsx》(如果是920平台则看920的HW文档)GPIO tmux栏位,看到PAD_PM_I2CM_SCL/PAD_PM_I2CM_SDA可以作为多组IIC来用,这里根据硬件规划选择使用,比如做为IIC2使用,则对应是mode1。

  3. 找到padmux dtsi,比如使用的是kernel\arch\arm\boot\dts\mercury6-ssc017a-s01a-padmux.dtsi,添加PAD_PM_I2CM_SCL/PAD_PM_I2CM_SDA复用关系,并注释掉有冲突或没在使用的管脚,类似下图修改。

  4. 修改完启动后读取寄存器确认设置mode是否生效,根据表格mode值由reg[103CDF]#2 ~ #0决定(注意是8bit寄存器)。

Q3:设置gpio管脚复用不生效

  1. 排查所用padmux.dtsi(比如mercury6-ssc016a-s01a-demo-padmux.dtsi)是否有其它地方同样设置了管脚复用;注意如果复用功能有多个引脚,每个引脚都要排查,只要有一个脚被占用都不行。

  2. 排查所用dts文件(比如mercury6-ssc016a-s01a-demo.dts)看相关引脚是否有做其它控制用。

  3. 确定设的mode是否有生效。比如设置PAD_PM_GPIO0~3为spi2 mode1

    对应寄存器103CD1 bit2:0应该为1,注意这里寄存器是8bit,通过riu_r命令读到的是16bit,需要转换,即0xD½ = 0x68 bit15:8。

  4. 确定代码有没有哪个地方写死占用(这个概率很低,可以全局搜索确认)。

  5. 设置相关引脚为gpio mode看是否能正常使用。

  6. 如果上面都没问题,需要确认硬件接法。

Q4:设置reserved-memory开机启动挂掉

环境:920G外挂1GB内存,mma(sdk预留内存用量)分配大小为0x22a00000。

在dts增加reserved-memory如下:

/*!!IMPORTANT!! The reserved memory must be 1MB aligned*/
reserved-memory {
#address-cells = <1>;
#size-cells = <1>;
ranges;

dgsmem {
reg= <0x3D500000 0x2000>;
no-map;
};
};

从log报错看起来是mma reserve失败导致bugon挂掉,原本以为mma会从ddr的末尾往前分配,1GB=0x40000000再减去mma大小0x22A00000应该等于0x1D600000,

所以从0x3D500000(需要加上0x20000000的偏移)开始预留应该没有问题才对。

实际情况我们还会从DDR末尾预留16M给kernel启动用,而reserved-memory比mma reserve优先,如果在0x3D500000处预留会导致1GB内存被截断,导致mma预留失败。

预留16M可以从log看出

Uncompressing Kernel Image ...
[XZ] !!!reserved 0x21000000 length=0x 1000000 for xz!!
XZ: uncompressed size=0x400000, ret=7

mma预留起始地址可以从正常启动环境proc信息看出;如果要reserved-memory,可以在heap_base_cpu_bus_addr前的地址开始预留。