Exynos4412 移植针对Samsung的Linux-6.1(六)【已解决】SROMC寄存器的数值不正确、无法赋值的问题

这篇具有很好参考价值的文章主要介绍了Exynos4412 移植针对Samsung的Linux-6.1(六)【已解决】SROMC寄存器的数值不正确、无法赋值的问题。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

系列文章目录

  • Exynos4412 移植针对Samsung的Linux-6.1(一)下载、配置、编译Linux-6.1
  • Exynos4412 移植针对Samsung的Linux-6.1(二)SD卡驱动——解决无法挂载SD卡的根文件系统
  • Exynos4412 移植针对Samsung的Linux-6.1(三)SD卡驱动——解决mmc0: Timeout waiting for hardware interrupt.
  • Exynos4412 移植针对Samsung的Linux-6.1(四)NandFlash卡驱动
  • Exynos4412 移植针对Samsung的Linux-6.1(五)DM9000网卡驱动
  • Exynos4412 移植针对Samsung的Linux-6.1(六)SROMC寄存器的数值不正确的问题
  • Exynos4412 移植Linux-6.1(七)挂载Ramdisk文件系统,【已解决】Couldn’t find valid RAM disk image starting at 0

问题描述

之前的博文中,Linux已经移植了SD卡、NandFlash、DM9000A网卡的驱动。挂载SD卡上的根文件系统之后,也能够成功启动。
问题是:启动Linux内核之后,ifconfig始终无法正确配置eth0。我在驱动中增加代码查看DM9000寄存器、SROMC寄存器数据的代码,结果如下,可以看出:

  • 引脚复用功能正常;
  • SROMC寄存器数据不正确,并且修改无效;
  • DM9000A寄存器数据不正确。
/ # ifconfig eth0 up
[ 2388.423303][   T89] dm9000aep_pre_init---before config DM9000---
[ 2388.423303][   T89] GPY0CON IS:220020 	GPY1CON IS:2222 //可以看出引脚复用功能正常
[ 2388.423303][   T89] GPY3CON IS:22222222	GPY3PUD IS:FFFF
[ 2388.423303][   T89] GPY5CON IS:22222222 	GPY5PUD IS:FFFF
[ 2388.423303][   T89] GPY6CON IS:22222222, GPY6PUD IS:FFFF
[ 2388.504815][   T89] exynos_config_sromc:before sromc bw value is:0
[ 2388.504815][   T89] bc value is:0		//可以看出SROMC寄存器数据不正确,并且修改无效
[ 2388.514251][   T89] exynos_config_sromc:after  sromc bw value is:f0
[ 2388.514251][   T89] bc value is:11051c91		
[ 2388.525407][   T89] ---funciton: dm9000_reset before reset---
[ 2388.530048][   T89] NCR (0X00):19 		//可以看出,DM9000A寄存器数据不正确
[ 2388.533403][   T89] GPR (0X1F):19 
[ 2388.536787][   T89] GPCR (0X1E):19 
[ 2388.578564][   T89] BMCR (0X00.):1919 
[ 2388.618559][   T89] DSCR (0X16.):1919 
[ 2388.618611][   T89] NSR (0X01):19 
[ 2388.618657][   T89] ISR (0XFE):19 
[ 2388.618807][   T89] dm9000 5000000.ethernet: dm9000 did not respond to first reset
[ 2388.618992][   T89] dm9000 5000000.ethernet: dm9000 did not respond to second reset
[ 2388.748792][   T89] dm9000 5000000.ethernet eth0: link down
/ #

分析经过

1、在really_probe()函数中打印寄存器数值

刚开始怀疑,是不是在加载某个硬件驱动时修改了SROMC寄存器,导致错误。所以,在drivers/base/dd.c的really_probe()函数中,增加printk,打印SROMC寄存器数值。
通过打印内核启动信息,发现加载驱动没有SROMC寄存器,但是在mmcblk驱动之前SROMC寄存器不正确。
内核启动信息部分如下:

[    4.934884][   T36] bus: 'platform': really_probe: probing driver s3c-sdhci with device 12530000.mmc
[    4.941972][    T9] bus: 'platform': really_probe: probing driver dwmmc_exynos with device 12550000.mmc
[    4.942183][    T1] bus: 'platform': really_probe: probing driver exynos-rng with device 10830400.rng
[    4.942861][    T1] bus: 'platform': really_probe: probing driver s5p-secss with device 10830000.sss
[    4.943851][    T1] s5p-secss 10830000.sss: s5p-sss driver registered
[...]
[    5.782241][   T36] mmc0: SDHCI controller on samsung-hsmmc [12530000.mmc] using ADMA
[    5.783122][    T1] Waiting for root device /dev/mmcblk0p3...
[    6.023886][   T12] mmc0: new high speed SD card at address 0002
[    6.024794][   T12] bus: 'mmc': really_probe: probing driver mmcblk with device mmc0:0002
[...]
[    6.024982][   T12] really_probe:before sromc bw value is:0
[    6.024982][   T12] bc value is:0
[...]

Please press Enter to activate this console. 
/ # 

2、在 exynos_pd_power()函数中打印寄存器数值

在启动信息中,会显示Power domain ISP disable failed,所以怀疑是不是电源管理更改了SROMC寄存器。于是,在drivers/soc/samsung/pm_domains.c的exynos_pd_power()函数中增加printk,打印SROMC寄存器数值。

[...]
[   20.651465][    T1] pd off:device name is:ISP :before sromc bw value is:f9
[   20.651465][    T1] bc value is:11051c91
[...]
[   21.372000][    T1] pd off:device name is:ISP :before sromc bw value is:0
[   21.372000][    T1] bc value is:0

3、在exynos_pd_power()函数中打印堆栈

到底是哪个函数调用exynos_pd_power(),导致SROMC寄存器数值错误呢?于是在exynos_pd_power()函数中增加dump_stack(),打印查看堆栈中的函数。
结果发现是在系统初始化的时候,调用了clk_disable_unused()函数,关闭了时钟源,导致SROMC寄存器数值错误。

[...]
[   20.831820][    T1] CPU: 3 PID: 1 Comm: swapper/0 Not tainted 6.1.0-g4467c3e35969-dirty #8
[   20.838583][    T1] Hardware name: Samsung Exynos (Flattened Device Tree)
[   20.845354][    T1]  unwind_backtrace from show_stack+0x10/0x14
[   20.851256][    T1]  show_stack from dump_stack_lvl+0x58/0x70
[   20.856985][    T1]  dump_stack_lvl from exynos_pd_power.constprop.0+0xc/0xe4
[   20.864102][    T1]  exynos_pd_power.constprop.0 from _genpd_power_on+0x88/0x164
[   20.871480][    T1]  _genpd_power_on from genpd_power_on.part.0+0xac/0x180
[   20.878337][    T1]  genpd_power_on.part.0 from genpd_runtime_resume+0x114/0x2e0
[   20.885715][    T1]  genpd_runtime_resume from __rpm_callback+0x3c/0x108
[   20.892399][    T1]  __rpm_callback from rpm_callback+0x50/0x54
[   20.898301][    T1]  rpm_callback from rpm_resume+0x54c/0x780
[   20.904030][    T1]  rpm_resume from __pm_runtime_resume+0x48/0xa0
[   20.910193][    T1]  __pm_runtime_resume from clk_pm_runtime_get.part.0+0x14/0x64
[   20.917657][    T1]  clk_pm_runtime_get.part.0 from clk_unprepare_unused_subtree+0xbc/0x19c
[   20.925990][    T1]  clk_unprepare_unused_subtree from clk_unprepare_unused_subtree+0x6c/0x19c
[   20.934583][    T1]  clk_unprepare_unused_subtree from clk_unprepare_unused_subtree+0x6c/0x19c
[   20.943176][    T1]  clk_unprepare_unused_subtree from clk_unprepare_unused_subtree+0x6c/0x19c
[   20.951770][    T1]  clk_unprepare_unused_subtree from clk_disable_unused+0xb4/0xf8
[   20.959408][    T1]  clk_disable_unused from do_one_initcall+0x64/0x380
[   20.966005][    T1]  do_one_initcall from kernel_init_freeable+0x1c4/0x22c
[   20.972862][    T1]  kernel_init_freeable from kernel_init+0x18/0x12c
[   20.979286][    T1]  kernel_init from ret_from_fork+0x14/0x2c
[   20.985014][    T1] Exception stack(0xf0845fb0 to 0xf0845ff8)
[   20.990744][    T1] 5fa0:                                     00000000 00000000 00000000 00000000
[   20.999599][    T1] 5fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[   21.008452][    T1] 5fe0: 00000000 00000000 00000000 00000000 00000013 00000000
[   21.015945][    T1] pd off:device name is:ISP :before sromc bw value is:0
[   21.015945][    T1] bc value is:0

4、查看clk_disable_unused()函数

在drivers/clk/clk.c的1379行,有clk_disable_unused()函数。可以看出,如果布尔变量clk_ignore_unused=true,那么,就不会关闭未使用的时钟("clk: Not disabling unused clocks\n")。
那么问题来了,怎样给clk_ignore_unused赋值呢?

5、给clk_ignore_unused赋值

通过在互联网上搜索关键字clk_ignore_unused,发现通过u-boot的bootargs可以给clk_ignore_unused赋值。u-boot启动之后、加载Linux之前,修改bootargs,启动Linux之后,成功ifconfig eth0 参数。完整bootargs如下:

setenv bootargs root=/dev/ram rw initrd=0x43000040,8M console=ttySAC0,115200n8 init=/linuxrc clk_ignore_unused=true earlyprintk loglevel=15 rootfstype=ext2;
tftp 50000000 uImage;tftp 43000000 ramdisk.img;tftp 51000000 exynos4412-cbt4412.dtb;bootm 50000000 43000000 51000000

执行ifconfig结果如下:

[root@fcbt4412 ]# ifconfig eth0 192.168.1.230 netmask 255.255.255.0 up
[...]
[   96.438961][   T84] exynos_config_sromc:after  sromc bw value is:f9
[   96.438961][   T84] bc value is:11051c91
[...]
[   96.526904][   T84] ---funciton: dm9000_reset 	  after reset---
[   96.527051][   T84] NCR (0X00):0 
[   96.527167][   T84] GPR (0X1F):58 
[   96.527283][   T84] GPCR (0X1E):71 
[   96.556720][   T84] BMCR (0X00.):3100 
[   96.586643][   T84] DSCR (0X16.):414 
[   96.586778][   T84] NSR (0X01):0 
[   96.586897][   T84] ISR (0XFE):0 
[   96.647299][   T84] dm9000 5000000.ethernet eth0: link down
[root@cbt4412 ]# [   96.917789][    T7] IPv6: ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready
[   96.975095][   T85] dm9000 5000000.ethernet eth0: link up, 100Mbps, full-duplex, lpa 0xCDE1

[root@cbt4412 ]# ping 192.168.1.7
PING 192.168.1.7 (192.168.1.7): 56 data bytes
64 bytes from 192.168.1.7: seq=0 ttl=64 time=2.101 ms
64 bytes from 192.168.1.7: seq=1 ttl=64 time=3.425 ms

小 结(读取寄存器数值的方法)

exynos4412本质上还是嵌入式系统,根本是操作内部寄存器。在调试代码的时候,还是要想办法查看、分析各种寄存器的数据。

1、SROMC寄存器数值代码示例如下:

#define EXYNOS4412_SROMC_BASE 0x12570000
struct exynos_sromc {
    unsigned int bw;
    unsigned int bc[6];
};

struct exynos_sromc *srom = (struct exynos_sromc *)(ioremap(EXYNOS4412_SROMC_BASE,0x10000));

printk(KERN_DEBUG "%s:before sromc bw value is:%x\n" \
            "bc value is:%x\n",__func__,srom->bw,srom->bc[1]);

2、GPIO寄存器的读取方法

    /* gpio configuration */
    gpy0con = ioremap(0x11000000 + 0x120,4);
    gpy1con = ioremap(0x11000000 + 0x140,4);
    /* 16 Bit bus width */
    gpy3con = ioremap(0x11000000 + 0x180,4);
    gpy3pud = ioremap(0x11000000 + 0x188,4);
    gpy5con = ioremap(0x11000000 + 0x1C0,4);
    gpy5pud = ioremap(0x11000000 + 0x1C8,4);
    gpy6con = ioremap(0x11000000 + 0x1E0,4);
    gpy6pud = ioremap(0x11000000 + 0x1E8,4);

    printk(KERN_DEBUG "%s---before config DM9000---\n" \
            "GPY0CON IS:%X GPY1CON IS:%X\n" \
            "GPY3CON IS:%X  GPY3PUD IS:%X\n" \
            "GPY5CON IS:%X GPY5PUD IS:%X\n " \
            "GPY6CON IS:%X, GPY6PUD IS:%X\n" \
            __func__,\
            readl(gpy0con),readl(gpy1con),\
            readl(gpy3con),readl(gpy3pud),\
            readl(gpy5con),readl(gpy5pud),\
            readl(gpy5con),readl(gpy5pud));

3、dm9000寄存器的读取方法

控制和状态寄存器的数据,可以调用ior()函数来读取。PHY 寄存器的数据,可以稍微修改驱动中的dm9000_phy_read()的形参,把struct net_device *dev更改为struct board_info *db。文章来源地址https://www.toymoban.com/news/detail-461067.html

static void dm9000_msleep(struct board_info *db, unsigned int ms);
/* Read a word from phyxcer */
static int
dm9000_phy_read_db(struct board_info *db, int reg)
{
    unsigned long flags;
    unsigned int reg_save;
    int ret;

    mutex_lock(&db->addr_lock);

    spin_lock_irqsave(&db->lock, flags);

    /* Save previous register address */
    reg_save = readb(db->io_addr);
    /* Fill the phyxcer register into REG_0C */
    iow(db, DM9000_EPAR, DM9000_PHY | reg);

    /* Issue phyxcer read command */
    iow(db, DM9000_EPCR, EPCR_ERPRR | EPCR_EPOS);

    writeb(reg_save, db->io_addr);
    spin_unlock_irqrestore(&db->lock, flags);

    dm9000_msleep(db, 1);       /* Wait read complete */

    spin_lock_irqsave(&db->lock, flags);
    reg_save = readb(db->io_addr);

    iow(db, DM9000_EPCR, 0x0);  /* Clear phyxcer read command */

    /* The read data keeps on REG_0D & REG_0E */
    ret = (ior(db, DM9000_EPDRH) << 8) | ior(db, DM9000_EPDRL);

    /* restore the previous address */
    writeb(reg_save, db->io_addr);
    spin_unlock_irqrestore(&db->lock, flags);

    mutex_unlock(&db->addr_lock);

    dm9000_dbg(db, 5, "phy_read[%02x] -> %04x\n", reg, ret);
    return ret;
}

#define GPCR_GPIO0_OUT      (7<<1) //GPCR bit[3~1]=111,meaning output
#define MII_DSCR 16 //MII_DSCR address

static void 
dm9000_reset(struct board_info *db) 
{
    dev_dbg(db->dev, "resetting device\n");
    printk(KERN_DEBUG "---funciton: %s befor reset---\n", __func__);// my_printk_debug
    printk(KERN_DEBUG "NCR (0X00):%x \n", ior(db, 0x00));// my_printk_debug
    printk(KERN_DEBUG "GPR (0X1F):%x \n", ior(db, 0x1f));// my_printk_debug
    printk(KERN_DEBUG "GPCR (0X1E):%x \n", ior(db, 0x1e));// my_printk_debug
    printk(KERN_DEBUG "BMCR (0X00.):%x \n", dm9000_phy_read_db(db, 0x00));// my_printk_debug
    printk(KERN_DEBUG "DSCR (0X16.):%x \n", dm9000_phy_read_db(db, MII_DSCR));// my_printk_debug
    printk(KERN_DEBUG "NSR (0X01):%x \n", ior(db, 0x01));// my_printk_debug
    printk(KERN_DEBUG "ISR (0XFE):%x \n", ior(db, 0xfe));// my_printk_debug
[...]
}

遗留问题

  1. 大家用什么集成开发环境可以实现调试查看寄存器,请在留言区讨论留言。

到了这里,关于Exynos4412 移植针对Samsung的Linux-6.1(六)【已解决】SROMC寄存器的数值不正确、无法赋值的问题的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • ARM接口编程—GPIO(exynox 4412平台)

    GPIO(General-purpose input/output)即通用型输入输出,GPIO可以控制连接在其之上的引脚实现信号的输入和输出 芯片的引脚与外部设备相连,从而实现与外部硬件设备的通讯、控制及信号采集等功能 我们用开发板的LED为例,查看LED电路原理图,可以看到LED2是连接在GPX2_7这个引脚上

    2024年02月09日
    浏览(29)
  • 针对3389端口严重安全漏洞及解决方法

    微软公司于2019年5月14日发布重要更新安全公告,其操作系统远程桌面(Remote Desktop Services),俗称的3389服务存在严重安全漏洞(编号CVE-2019-0708):该漏洞影响了某些旧版本的Windows系统。此漏洞是预身份验证,无需用户交互。当未经身份验证的攻击者使用RDP(常见端口3389)连

    2024年02月11日
    浏览(51)
  • Linux 内核移植

    linux内核移植和uboot移植总体上差不多 解压内核文件,这里改名如图一 图一 安装 lzop 库,否则内核编译会失败,提示“ recipe for target ‘arch/arm/boot/compressed/piggy.lzo sudo apt-get install lzop 创建打开工程目录 直接在顶层 Makefile 文件里面定义 ARCH 和 CROSS_COMPILE 这两个的变量值为 “

    2024年02月10日
    浏览(53)
  • ARM-liunx-Eclipse-FS4412交叉环境搭建

              1.windows准备工作            2.liunx系统搭建            3.Ecilpase的基本使用 所需要的文件 百度网盘 链接:https://pan.baidu.com/s/1Mc0WgfC7EZXL3XXiuY9gEQ?pwd=1234  提取码:1234         第一步 串口驱动配置                   1.下载安装CH340驱动(注意版本不要太新)  

    2024年04月22日
    浏览(32)
  • keil移植linux(makefile)

    ubuntu18.04.melodic 宏基暗影骑士笔记本 stm32f427IIH6 stlink 9-24v可调电源 robomaster A 板 1)修改cubeMX配置 选择makefile 2)setting设置 3)launch设置 修改成以下内容:可执行文件名是freeRTOS_LED.elf 4)修改makefile makefile中只包含工程生成的src文件,没有包含applications中的编写的 .c 文件 make,报错内

    2024年02月01日
    浏览(28)
  • 智慧灌区解决方案:针对典型灌区水利管理需求

    ​随着国家对农业水利的重视,各地积极推进智慧灌区建设,以实现对水资源的精准调度和科学化管理。下面我们针对典型灌区水利管理需求,推荐智慧灌区解决方案。 一、方案构成智慧水利解决方案- 智慧水利信息化系统-智慧水利平台-智慧水利公司 - 星创智慧水利 一、方案构

    2024年01月20日
    浏览(36)
  • 针对电子企业的数字工厂管理系统解决方案

    随着科技的飞速发展和市场竞争的日益激烈,电子企业需要一种高效、智能的数字工厂管理系统解决方案,以提升生产效率、优化资源利用、降低运营成本,并确保高品质产品的输出。本文将详细探讨针对电子企业的数字工厂管理系统解决方案。 一、数字工厂管理系统的优势

    2024年02月09日
    浏览(37)
  • linux重装系统步骤 包含raid【主要针对服务器重装】,腾讯Linux运维开发面试记录

    8 、查看网关主机名: cat /etc/sysconfig/network 9 、查看单条网卡信息: ethtool 物理网卡名 比如有很多网卡 ,不知道 使用哪个网卡的时候,就用这个方法。 (万兆网Link为yes就是使用的网卡) ​​ 10、查看cpu内存 查看cpu 最简单方法:输入 top 后按 1 即可查看。 查看CPU信息(型号

    2024年04月12日
    浏览(41)
  • rk3399移植linux kernel

    参考文章: 1.RK3399移植u-boot 2.I.MX6Q-SDB开发板移植ubuntu 3.Rockchip RK3399 - 移植ubuntu 20.04.4根文件系统 4.Rockchip RK3399 - 移植uboot 2023.04 linux 6.3   在前一节中移植了rk3399的u-boot,这一节就继续移植linux kernel。不过rk3399在移植kenel前,需要先制作根文件系统,这样才能在生成内核镜像

    2024年02月14日
    浏览(44)
  • OpenSSH移植到Linux开发板

    在Linux开发中,有时候需要远程登录到开发板上对系统进行一些操作,这个时候就需要用到SSH服务。SSH(Secure Shell 安全外壳协议)是较可靠,专为远程登录会话和其他网络服务提供安全性的协议,OpenSSH是SSH协议的一个免费开源版本。 这里一共需要移植三个软件包: zlib,openss

    2023年04月26日
    浏览(36)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包