rk3568 | rk平台GPIO冲突检测小技巧
sinye56 2024-12-14 15:04 6 浏览 0 评论
上一篇我们讲解了如何编写gpio驱动,但是实际操作中,经常发现gpio引脚被占用的情况发生,那么本篇文章就详细讲解rxw平台下如何快速定位gpio复用问题以及如何解决。
一、GPIO寄存器查找
要想查看某个GPIO引脚可以配置的功能以及地址信息,需要查看TRM手册:
《Rockchip RK3568 TRM Part1》
- 第一步: 对于GPIO2 A2,我们转换成下面字符串然后搜索
gpio2a2_sel
这样我们就可以直接找到该引脚iomux配置寄存器,bit[10:8]。 该寄存器地址:
基地址+0x0020
那么如何找到基地址呢?
- 第二步:
搜索该引脚寄存器的名字:
GRF_GPIO2A_IOMUX_L
注意向上搜索
可以得到该寄存器基地址名称:
SYS_GRF
- 第三步 直接进入chapter 3
可得SYS_GRF 基地址
0xFDC60000
那么我们就得到了GPIO2 A2的IOMUX配置寄存器地址为
0xFDC60000 + 0x0020
该寄存器的bit[10:8]用于设置该寄存器功能。
当然也可以用下图来查找,更加方便:
那么找到了这个寄存器地址,我要如何来直接读取这个寄存器的值呢?
这个可以借助于一个命令io。
二、io命令
io命令可以直接操作某个寄存器,用于查看设置某个PIO 引脚配置了什么iomux,非常方便。
1. 移植io命令需要的驱动
RK 的 Android 平台,默认有包含 io 工具(源码位置: external\io), linux 系统平台如果没有此源码, 可以将 Android 平台此源码打包过去编译即可( linux 平台代码同步最新都已带有 IO 工具,可直接使用命令)。
- 第一步:修改Makefile、Kconfig
vim drivers/char/Makefile
增加
+obj-$(CONFIG_DEVMEM) += mem.o
vim drivers/char/Kconfig
改文件已经包含下面信息
10 config DEVMEM
11 bool "/dev/mem virtual device support"
12 default y
13 help
14 Say Y here if you want to support the /dev/mem device.
15 The /dev/mem device is used to access areas of physical
16 memory.
17 When in doubt, say "Y".
- 第二步:修改驱动文件
io命令需要内核驱动支持,驱动文件如下:
drivers/char/mem.c
找到下面代码:
#ifdef CONFIG_DEVMEM
[1] = { "mem", 0, &mem_fops, FMODE_UNSIGNED_OFFSET },
#endif
修改为
+//#ifdef CONFIG_DEVMEM
[1] = { "mem", 0, &mem_fops, FMODE_UNSIGNED_OFFSET },
+//#endif
- 第三步:修改配置文件rockchip_defconfig
vim arch/arm64/configs/rockchip_defconfig
增加
+CONFIG_DEVMEM=y
重新编译内核,烧录重启。
rockchip_defconfig需要根据平台选择
- 第四步:查看mem字符设备:
rk3568_r:/ # ls /dev/mem -l
ls /dev/mem -l
crw------- 1 media media 1, 1 2017-08-04 09:00 /dev/mem
io命令正是通过这个字符设备来实现寄存器的读写的。
2. 命令说明
rk3568_r:/dev # io
io
Raw memory i/o utility - $Revision: 1.5 $
io -v -1|2|4 -r|w [-l <len>] [-f <file>] <addr> [<value>]
-v Verbose, asks for confirmation
-1|2|4 Sets memory access size in bytes (default byte)
-l <len> Length in bytes of area to access (defaults to
one access, or whole file length)
-r|w Read from or Write to memory (default read)
-f <file> File to write on memory read, or
to read on memory write
<addr> The memory address to access
<val> The value to write (implies -w)
Examples:
io 0x1000 Reads one byte from 0x1000
io 0x1000 0x12 Writes 0x12 to location 0x1000
io -2 -l 8 0x1000 Reads 8 words from 0x1000
io -r -f dmp -l 100 200 Reads 100 bytes from addr 200 to file
io -w -f img 0x10000 Writes the whole of file to memory
Note access size (-1|2|4) does not apply to file based accesses.
3. 举例1,通过IO读寄存器:
读取gpio2 A2引脚配置寄存器
io -4 -l 0x30 0xFDC60000
-4 : 按字(4个字节) 访问内存
0x30 : 读取0x30(48)个字节
0xFDC60000 : 基地址
由上图可得0xFDC60020的bit[10:8]值为1
所以该io引脚被设置的iomux为
3'h1: SDMMC0_CLK
如果我们是希望通过设备树设置该引脚为普通gpio,那么该值应该为0,
那么这就说明了,我们设置失败了,
那就可以到设备树中查找设置SDMMC0的地方,将其注释掉。
要读取单个寄存器,可以用下面命令:
io -4 -r 0xFDC60024
4. 举例2,通过IO写寄存器
比如已经通过命令: io -4 -r 0xFDC60024读出了寄存器的值,那么此时想把gpio2 A2修改为普通GPIO, 那么只需要对0xFDC60024这个寄存器的第 3 个 1 写 0,那么可以如下操作:
io -4 –w 0xFDC60024 0x01002011
注意:
- 第三个1对应是bit[10:8]
- 通过 io 写的寄存器值 reboot 后不会保留
- 为什么寄存器地址后面的十六进制值的 bit [24]写 1? 因为该寄存器的 16bit 至31 bit 是写有效位,默认为 0,即不可写。因为要往[8] bit 写 1,所以[8] bit 对应的 写有效位 16 bit 也要对应置 1 才可写入,这个是根据寄存器描述而定的。
修改过后,再查看,可以发现对应的位的值变为了1:
三、 通过函数gpiod_direction_output()
思 路 : 驱 动 里 如 果 想 要 去 操 作 GPIO , 肯 定 会 调 用 到 gpio_direction_output 、gpio_direction_input、 gpiod_direction_output、 gpiod_direction_input 这几个接口, 他们的定义位置是:
vim kernel/drivers/gpio/gpiolib.c
在这些接口里添加判断对应查询的 IO 口条件,通过以下函数就可以打印出哪些模块复用了该引脚:
dump_stack();
注意: 在 linux3.10 内核的 sdk 中用的是 gpio_direction_output 和gpio_direction_input 接 口 , 在 linux4.4 内 核 中 则 是 gpiod_direction_output 和gpiod_direction_input。
下面以 linux4.4 版本为例来讲解如何查看引脚:gpio4 b3。
首先,需要计算出代表 gpio4b3 的值,算法如下:
gpio4_B3 = 4 *32 + (B-A) * 8 + 3 = 3 *32 + 1 * 8 + 3 = 139
计算方法参考: 《rk3568 | 瑞芯微平台GPIO引脚驱动编写》
- 最前面和 32 相乘的数字因为是 gpio4,所以是 432。如果是 gpio3,那就是 332;
- 括号里面的 A、 B、 C、 D 分别代表数值 0、 1、 2、 3,在计算时候分别对应去减即可,这里因为是 B3,所以用 B-A,如果是 C3,就是 C-A;
- 最后的+3 是因为是 B3,如果是 GPIO4B2,那么最后就+2。
注:在 linux4.4 内核, io 引脚的值有些变化,也就是按照上文算法计算的结 果要+1000,所以 GPIO4B3 如果是 linux4.4 内核里要填 1139。
int gpiod_direction_output(struct gpio_desc *desc, int value)
{
if (!desc || !desc->chip) {
pr_warn("%s: invalid GPIO\n", __func__);
return -EINVAL;
}
+ if ( desc_to_gpio(desc) == 1139)
+ {
+ printk("dump_stack_start\n");
+ dump_stack();
+ printk("dump_stack_end\n");
+ }
if (test_bit(FLAG_ACTIVE_LOW, &desc->flags))
value = !value;
return _gpiod_direction_output_raw(desc, value);
}
添加后编译烧录,只要对应判断的引脚有被调用,启动 log 中就会打印出堆栈,可以根据找出结果查看,找到驱动调用函数。
四、通过函数rockchip_set_mux()
配置IOMUX会调用该接口,
仍然以引脚gpio4 b3为例。
[drivers/pinctrl/pinctrl-rockchip.c]
@@ -1224,6 +1224,17 @@ static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
dev_dbg(info->dev, "setting mux of GPIO%d-%d to %d\n",
bank->bank_num, pin, mux);
+ if((bank->bank_num == 4)&&(pin == 11)){
+ printk("6902 setting mux of GPIO%d-%d to %d\n",
+ bank->bank_num, pin, mux);
+ dump_stack();
+ }
if (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU)
regmap = info->regmap_pmu;
- bank_num 表示gpio4
- 这里“ pin ==”后面跟的值计算方式为: 将 A0 至 D7 32 个引脚顺序对应数值 0 至 31,b3为11。
五、如何去掉设备树中的复用引脚信息?
刚才分析,发现GPIO2 A2被SDMMC0占用,那么如何来解决这个冲突呢?
只要从设备树下手即可。
瑞芯微平台的设备树,根据平台区分,往往前缀是:
rk + 平台 + 板子型号 + ddr型号 + 版本
比如rk3568系列设计的设备树文件如下:
arch/arm64/boot/dts/rockchip/rk3568-amp.dtsi
arch/arm64/boot/dts/rockchip/rk3568-android9.dtsi
arch/arm64/boot/dts/rockchip/rk3568-android.dtsi
arch/arm64/boot/dts/rockchip/rk3568-dram-default-timing.dtsi
arch/arm64/boot/dts/rockchip/rk3568.dtsi
arch/arm64/boot/dts/rockchip/rk3568-evb1-ddr4-v10-android9.dts
arch/arm64/boot/dts/rockchip/rk3568-evb1-ddr4-v10.dtb
arch/arm64/boot/dts/rockchip/rk3568-evb1-ddr4-v10.dts
arch/arm64/boot/dts/rockchip/rk3568-evb1-ddr4-v10.dtsi
arch/arm64/boot/dts/rockchip/rk3568-evb1-ddr4-v10-linux.dts
arch/arm64/boot/dts/rockchip/rk3568-evb1-ddr4-v10-linux-spi-nor.dts
arch/arm64/boot/dts/rockchip/rk3568-evb2-lp4x-v10-bt1120-to-hdmi.dts
arch/arm64/boot/dts/rockchip/rk3568-evb2-lp4x-v10.dts
arch/arm64/boot/dts/rockchip/rk3568-evb2-lp4x-v10.dtsi
arch/arm64/boot/dts/rockchip/rk3568-evb4-lp3-v10.dts
arch/arm64/boot/dts/rockchip/rk3568-evb5-ddr4-v10.dts
arch/arm64/boot/dts/rockchip/rk3568-evb5-ddr4-v10.dtsi
arch/arm64/boot/dts/rockchip/rk3568-evb6-ddr3-v10.dts
arch/arm64/boot/dts/rockchip/rk3568-evb6-ddr3-v10.dtsi
arch/arm64/boot/dts/rockchip/rk3568-evb6-ddr3-v10-linux.dts
arch/arm64/boot/dts/rockchip/rk3568-evb6-ddr3-v10-rk628-bt1120-to-hdmi.dts
arch/arm64/boot/dts/rockchip/rk3568-evb6-ddr3-v10-rk628-rgb2hdmi.dts
arch/arm64/boot/dts/rockchip/rk3568-evb6-ddr3-v10-rk630-bt656-to-cvbs.dts
arch/arm64/boot/dts/rockchip/rk3568-evb7-ddr4-v10.dts
arch/arm64/boot/dts/rockchip/rk3568-evb.dtsi
arch/arm64/boot/dts/rockchip/rk3568-iotest-ddr3-v10.dts
arch/arm64/boot/dts/rockchip/rk3568-iotest-ddr3-v10-linux.dts
arch/arm64/boot/dts/rockchip/rk3568-linux.dtsi
arch/arm64/boot/dts/rockchip/rk3568-nvr-demo-v10.dts
arch/arm64/boot/dts/rockchip/rk3568-nvr-demo-v10.dtsi
arch/arm64/boot/dts/rockchip/rk3568-nvr-demo-v10-linux.dts
arch/arm64/boot/dts/rockchip/rk3568-nvr-demo-v10-linux-spi-nand.dts
arch/arm64/boot/dts/rockchip/rk3568-nvr-demo-v12.dtsi
arch/arm64/boot/dts/rockchip/rk3568-nvr-demo-v12-linux.dts
arch/arm64/boot/dts/rockchip/rk3568-nvr-demo-v12-linux-spi-nand.dts
arch/arm64/boot/dts/rockchip/rk3568-nvr.dtsi
arch/arm64/boot/dts/rockchip/rk3568-nvr-linux.dtsi
arch/arm64/boot/dts/rockchip/rk3568-pinctrl.dtsi
一口君的板子是evb1,ddr4,v10版本,所以去掉其他的文件,
我们只需要关注以下文件即可。
arch/arm64/boot/dts/rockchip/rk3568-android.dtsi
与安卓相关的信息
arch/arm64/boot/dts/rockchip/rk3568.dtsi
描述cpu、memory、timer、clk、sata、usb host、gic、视频控制器、sram、cru、i2c控制器、uart、pwm、pmu等各种Soc内部硬件信息
arch/arm64/boot/dts/rockchip/rk3568-evb1-ddr4-v10.dts
arch/arm64/boot/dts/rockchip/rk3568-evb1-ddr4-v10.dtsi
arch/arm64/boot/dts/rockchip/rk3568-evb.dtsi
与evb1底板相关的外设硬件信息
arch/arm64/boot/dts/rockchip/rk3568-pinctrl.dtsi
pinctl相关硬件信息
还有1个描述pinctl引脚驱动能力的文件:
rockchip-pinconf.dtsi
使用grep命令来查询:
grep sdmmc0 arch/arm64/boot/dts/rockchip/rk3568* -nr
好在信息不多,逐个查看,下面这个文件,我们找到了复用的地方。
rk3568-pinctrl.dtsi
该引脚被定义为sdmmc0_clk,作为时钟被使用了。
sdmmc0 {
………………
/omit-if-no-ref/
sdmmc0_clk: sdmmc0-clk {
rockchip,pins =
/* sdmmc0_clk */
<2 RK_PA2 1 &pcfg_pull_up_drv_level_2>;
};
修改的方法有很多种:
- 投机取巧法 将sdmmc0_clk改成其他没有用的gpio
- 简单粗暴法 如果确定没有使用sdmmc0,可以将所有sdmmc0地方全部注释掉
设备树支持下面这种方法:
#if 0
#endif
- 硬件飞线法
找硬件工程师飞线,改用其他的GPIO
- 最优法 如果sdmmc0也用到了,
那就只能修改冲突的GPIO,
但是这种情况,往往会牵一发而动全身,
要改好几处,那就需要各位老铁细心慢慢修改了。
好了,本文到底结束。
一口君目标是写100篇瑞芯微平台的文章,
有喜欢瑞芯微的老铁,
欢迎大家关注学习。
相关推荐
- 一个不错的软件版本命名规范!
-
之前写了一篇如何自动生成版本号的文章,《让你的C程序,自动打印版本信息》初衷是让自己的程序在运行时自动打印与版本相关的信息,避免测试时因为版本信息不确定导致的一些功能对应不上去的问题,当时留了一个坑,...
- 国产操作系统迎来发展风口 公务领域更能培育起Linux生态
-
谷歌和微软在俄罗斯市场的一番套路猛如虎,就让我们深刻地意识到了,只有自己的东西才能靠得住。也由此,国内操作系统发展迎来了发展风口。我就看到有朋友就秀出了他们单位采购的纯国产的主机,一款华为的主机,纯国...
- 5个大有“前途”的Linux桌面发行版本
-
ZD至顶网CIO与应用频道08月27日专栏:Linux无处不在。你的服务器里,你的电话、汽车、手表、烤面包机、冰箱……和台式机里都有Linux的身影。虽然在桌面上见到Linux的用户比在自动调温...
- Linux 常用应用软件大全
-
编译自:https://www.fossmint.com/most-used-linux-applications/作者:MartinsD.Okoi译者:HankChow对于许多应用程序...
- Linux 4.1 系列的最大版本 4.1.18 LTS发布,带来大量修改
-
(LCTT译注:这是一则过期的消息,但是为了披露更新内容,还是发布出来给大家参考)著名的内核维护者GregKroah-Hartman貌似正在度假中,因为SashaLevin2016年2月16日的...
- Linux发行版需要杀软吗?卡巴斯基推出免费KVRT病毒扫描清理工具
-
IT之家6月4日消息,你认为使用Linux发行版,需要杀毒软件吗?或许很多用户认为Linux发行版偏小众,因此受到黑客攻击的风险也相对较小,不过卡巴斯基并不这么认为,近期推出了适用于...
- 适合开发人员的 5款 Linux 发行版
-
什么是Linux?Linux是基于Unix的操作系统。由LinusTorvalds开发于1991年首次发布其内核。因为Linux是开源软件,其发行版由不同组织发布,因此不同的发行版具有不同的风格...
- VMware Workstation 17.0 Pro 发布:新增 TPM 2.0 完美兼容Win11
-
IT之家11月18日消息,VMwareWorkstation17.0Pro现已发布,它带来了许多新特性,例如微软Windows11硬性要求:虚拟可信平台模块(TPM)2.0。...
- 你是否需要一个容器专用的Linux发行版本?
-
单单使用容器是不够的,提供商们认为你需要一个容器专用的Linux发行版本。我们可以让容器在不同的操作系统上运行,不同的操作系统都有自己的虚拟化服务,如:SolarisZones、BSDJails、...
- Tizen 3.0版本发布 采用Linux 4.1内核
-
2015-09-2111:31:39作者:马荣【中关村在线软件资讯】9月21日消息:尽管三星靠着Android系统设备在移动市场赚钱,但是仍然没有忘记自家的Tizen开发。现在Tizen3.0版...
- 欧拉操作系统演进:应用累计超130万套 支持鲲鹏、英特尔、飞腾等芯片
-
21世纪经济报道记者倪雨晴深圳报道4月15日,在欧拉开发者大会(openEulerDeveloperDay2022)的主论坛上,欧拉首个数字基础设施全场景长周期版openEuler22.03...
- Papyros:以Material Design为灵感的Linux发行版本
-
项目团队并不希望只是采用传统的桌面主题,而是致敬谷歌Android系统的MaterialDesign设计语言想要打造出某些不同以往足够吸引用户的Linux发行版本,自然该版本还在不断的更新和改进中,...
- 比特网早报:全国空间计量技术委员会成立,银河麒麟操作系统上架微信Linux4.0.0版本
-
2024年11月6日消息,昨夜今晨,科技圈都发生了哪些大事?行业大咖抛出了哪些新的观点?比特网为您带来值得关注的科技资讯:全国空间计量技术委员会在北京成立近日,经市场监管总局批准,全国空间计量技术委员...
- 2024年最稳定的5个Linux发行版,赶紧收藏!
-
Linux是最流行的免费开源平台之一。Linux已被广泛使用,因为它安全、可扩展和灵活。Linux发行版收集开源代码,对其进行编译,并将其组合成一个可以轻松启动和安装的操作系统。它们还提供不同的...
- 彰显Linux生态繁华,Ubuntu、Fedora等四发行版同时发布新版本
-
上周对于开源社区来说是忙碌的一周。EndeavourOS和TrueNASScale于周二(4月16日)发布,Fedora于周三(4月17日)发布,Ubuntu于周四(4月18日)发布。四个新版本中都...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- oracle忘记用户名密码 (59)
- oracle11gr2安装教程 (55)
- mybatis调用oracle存储过程 (67)
- oracle spool的用法 (57)
- oracle asm 磁盘管理 (67)
- 前端 设计模式 (64)
- 前端面试vue (56)
- linux格式化 (55)
- linux图形界面 (62)
- linux文件压缩 (75)
- Linux设置权限 (53)
- linux服务器配置 (62)
- mysql安装linux (71)
- linux启动命令 (59)
- 查看linux磁盘 (72)
- linux用户组 (74)
- linux多线程 (70)
- linux设备驱动 (53)
- linux自启动 (59)
- linux网络命令 (55)
- linux传文件 (60)
- linux打包文件 (58)
- linux查看数据库 (61)
- linux获取ip (64)
- linux进程通信 (63)