目录

1 简介

2 UPD720201寄存器上的信息

2.1 相关寄存器

2.2 读ROM的步骤(How to read ROM Data from External ROM)

2.3 写的步骤(How to write FW to External ROM)

3 修改驱动代码

3.1 添加ROM擦除函数

3.2 添加向ROM里写固件的函数

3.3 添加从ROM里读数据的函数

3.4 调用新添加的函数

4 将固件编译到内核镜像里


1 简介

在系统上电的时候,UPD720201芯片会从外部ROM里读取固件信息来对自己进行配置。

本文档是介绍在linux内核代码里来更新ROM里的固件的方法。

使用的硬件平台是瑞萨的RZG2H,软件平台是瑞萨官方提供的linux4.19内核。

注意:更新完ROM里的固件,需要重启板卡才有效。

2 UPD720201寄存器上的信息

2.1 相关寄存器

Accessing the External ROM related registers uses a total of five registers in the PCI Configuration registers of μPD720201 and μPD720202.

《r19uh0078ej0600_usb[uPD720201uPD720202+User's+Manual+Hardware].pdf》P120

<1> External ROM Information Register(Refer to Table 3-57)

<2> External ROM Configuration Register(Refer to Table 3-58)

<3> External ROM Access Control and Status Register(ERACSR)(Refer to Table 3-60)

Table 3-60. FW Control and Status Register (Offset Address: F6h)

Bits

Field

Read/Write

Value (Default)

Comment

0

External ROM Access Enable

RW

0b

When set to’1b’, External ROM Write Request is initiated. Before

setting to ‘1b’, FW data shall be written in the DATA0 register. When

the data0 download is completed, this bit is automatically cleared to

‘0b’. Setting Get Data0 or Get DATA1 while Set DATA0 is ‘1b’

results in undefined behavior.

1

External ROM Erase

RW

0b

When this bit is set to ‘1b’, External ROM Data is erased. When this

operation is complete, this bit is cleared to ‘0b’ automatically. Before

writing ‘1b’ to this bit, the DATA0 register must be set to 5A65726Fh.

2

Reload

RW

0b

When this bit is set to ‘1b’, External ROM Data is reloaded. This function is used when immediate reload is required after External ROM is updated. At the completion of reload process, this bit is cleared to ‘0b’ automatically.

3

Reserved

RO

0b

Reserved

6:4

Result Code

RO

000b

This field shows the result of External ROM update process.

000b : Invalid (no result yet)

001b : Success

010b : Error

111b~011b : Reserved.

7

Reserved

RO

0b

Reserved

8

Set DATA0

RW1S

0b

When set to’1b’, External ROM Write Request is initiated. Before

setting to ‘1b’, FW data shall be written in the DATA0 register. When

the data0 download is completed, this bit is automatically cleared to

‘0b’. Setting Get Data0 or Get DATA1 while Set DATA0 is ‘1b’

results in undefined behavior.

9

Set DATA1

RW1S

0b

When set to’1b’, External ROM Write Request is initiated. Before

setting to ‘1b’, FW data shall be written in the DATA1 register. When

the data1 download is completed, this bit is automatically cleared to

‘0b’. Setting Get Data0 or Get DATA1 while Set DATA1 is ‘1b’

results in undefined behavior.

10

Get DATA0

RW1S

0b

When set to’1b’, External ROM Read Request is initiated. This bit is

automatically cleared to ‘0b’ when valid data is available in the Data0

register. Setting Set Data0 or Set DATA1 while Get DATA0 is ‘1b’

results in undefined behavior.

11

Get DATA1

RW1S

0b

When set to’1b’, External ROM Read Request is initiated. This bit is

automatically cleared to ‘0b’ when valid data is available in the Data1

register. Setting Set Data0 or Set DATA1 while Get DATA1 is ‘1b’

results in undefined behavior.

14:12

Reserved

RO

000b

Reserved

15

External ROM Exists

RO

HwInit

Indicates that the External ROM is connected. Even if the external

ROM exists, FW can be downloaded from External ROM . In this case, FW in the xHC is overwritten by FW download data.

1 : External ROM Exists

0 : No External ROM Exists

<4> Data0 Register(Refer to Table 3-61)

<5> Data1 Register(Refer to Table 3-62)

2.2 读ROM的步骤(How to read ROM Data from External ROM)

1. Read “External ROM Exists” and confirm it is ‘1b’.
2. Write ‘53524F4Dh’ to “DATA0”.
3. Set “1b” to “External ROM Access Enable”
4. Read “Result Code” and confirm it is ‘000b’.
5. Set “Get DATA0” and “Get DATA1” to ‘1b’.
6. Read “Get DATA0” and confirm it is ‘0b’.
7. Get External ROM data from “DATA0”.
8. Set “Get DATA0” to ‘1b’.
9. Read “Get DATA1” and confirm it is ‘0b’.
10. Get External ROM data from “DATA1”.
11. Set “Get DATA1” to ‘1b’.
12. Return to sequence 6 and repeat sequence 6 to sequence 11.
13. After reading the last data of External ROM data, the System Software must set “External ROM Access Enable” to ‘0b’.

《r19uh0078ej0600_usb[uPD720201uPD720202+User's+Manual+Hardware].pdf》P123

2.3 写的步骤(How to write FW to External ROM)

1. Read “External ROM Exists” and confirm it is ‘1b’.
2. Write ‘53524F4Dh’ to “DATA0”.
3. Set “External ROM Access Enable” to ‘1b’
4. Read “Result Code” and confirm it is ‘000b’.
5. Read “Set DATA0” and confirm it is ‘0b’.
6. Write FW data to”DATA0”.
7. Read “Set DATA1” and confirm it is ‘0b’.
8. Write FW data to”DATA1”.
9. Set “Set DATA0” and “Set DATA1” to ‘1b’.
10. Read “Set DATA0” and confirm it is ‘0b’.
11. Write FW data to”DATA0”.
12. Set “Set DATA0” to ’1b’.
13. Read “Set DATA1” and confirm it is ‘0b’.
14. Write FW data to”DATA1”.
15. Set “Set DATA1” to ‘1b’.
16. Return to step 10 and repeat steps 10 to 15.
17. After writing the last data of FW, the System Software must set “External ROM Access Enable” to ‘0b’.
18. Read “Result Code” and confirm it is ‘001b’.

3 修改驱动代码

文件:drivers/usb/host/xhci-pci.c

3.1 添加ROM擦除函数

#define EXTERNAL_ROM_INFO   0xEC
#define EXTERNAL_ROM_CONF   0xF0
#define EXTERNAL_ROM_SATUS   0xF6
#define DATA0 0xF8
#define DATA1 0xFC
void erase_chip(struct pci_dev *dev)
{u16 data = 0;u32 loop = 0;/* 1. Read "External ROM Exists" and confirm it is '1b' */if(pci_read_config_word(dev, EXTERNAL_ROM_SATUS, &data)){printk(KERN_INFO"----- read status failed\n");return;}while(data & 4){pci_read_config_word(dev, EXTERNAL_ROM_SATUS, &data);udelay(1000);}printk(KERN_INFO"----- start erase, status = %x\n", data);if(!(data & (1 << 15))){printk(KERN_INFO"----- rom not exist \n");return;}/* 2. Write '5A65726Fh' to "DATA0" */pci_write_config_dword(dev, DATA0, 0x5A65726F);/* 3. Set '1b' to "External ROM Erase"*/pci_write_config_word(dev, EXTERNAL_ROM_SATUS, data | 0x2);/* 4. Read "External ROM Erase" and confirm it is '000b'*/do{pci_read_config_word(dev, EXTERNAL_ROM_SATUS, &data);}while((data & 2));
}

3.2 添加向ROM里写固件的函数

void write_FW(struct pci_dev *dev)
{unsigned long count = 0;int retval, index, j;u32 data;u32 loop = 0;u16 reg_val;const struct firmware *fw;//retval = request_firmware(&fw, "K2026090.mem", &(dev->dev));//retval = request_firmware(&fw, "K20280B0.mem", &(dev->dev));retval = request_firmware(&fw, "ROMimage2028.bin", &(dev->dev));if (retval){printk(KERN_INFO"----- request_firmware failed\n");return;}/* 1. Read "External ROM Exists" and confirm it is '1b' */if(pci_read_config_word(dev, EXTERNAL_ROM_SATUS, &reg_val)){printk(KERN_INFO"----- read status failed\n");return;}printk(KERN_INFO"----- start write,status = %x\n", reg_val);if(!(reg_val & (1 << 15))){printk(KERN_INFO"----- rom not exist \n");return;}/* 2. Write '53524F4Dh' to "DATA0" */pci_write_config_dword(dev, DATA0, 0x53524F4D);/* 3. Set "External ROM Access Enable" to '1b' */pci_write_config_word(dev, EXTERNAL_ROM_SATUS, reg_val | 0x1);/* 4. Read "Result Code" and confirm it is '000b' */do{pci_read_config_word(dev, EXTERNAL_ROM_SATUS, &reg_val);udelay(500);if(loop++ == 20){printk(KERN_INFO"-----  Result Code not 000b\n");return ;}}while(reg_val & (7 <<4));/* 5. Read "Set DATA0" and confirm it is '0b' */do{pci_read_config_word(dev, EXTERNAL_ROM_SATUS, &reg_val);udelay(500);}while(reg_val & (1 << 8));index = 0;/* 6. Write FW data to "DATA0" *//* to avoid reading beyond the end of the buffer */for (data = 0, j = 3; j >= 0; j--) {if ((j + index) < fw->size)data |= fw->data[index + j] << (8 * j);}pci_write_config_dword(dev, DATA0, data);/* 7. Read "Set DATA1" and confirm it is '0b' */do{pci_read_config_word(dev, EXTERNAL_ROM_SATUS, &reg_val);udelay(500);}while(reg_val& (1 << 9));/* 8. Write FW data to "DATA1" */index += 4;/* to avoid reading beyond the end of the buffer */for (data = 0, j = 3; j >= 0; j--) {if ((j + index) < fw->size)data |= fw->data[index + j] << (8 * j);}pci_write_config_dword(dev, DATA1, data);/* 9. Set "Set DATA0" and "Set DATA1" to '1b' */pci_write_config_word(dev, EXTERNAL_ROM_SATUS, reg_val | (3 << 8));while(index < fw->size){/* 10. Read "Set DATA0" and confirm it is '0b' */do{udelay(500);pci_read_config_word(dev, EXTERNAL_ROM_SATUS, &reg_val);}while(reg_val & (1 << 8));/* 11. Write FW data to "DATA0" */index += 4;/* to avoid reading beyond the end of the buffer */for (data = 0, j = 3; j >= 0; j--) {if ((j + index) < fw->size)data |= fw->data[index + j] << (8 * j);}pci_write_config_dword(dev, DATA0, data);//printk(KERN_DEBUG"----- %d, %08x\n",index / 4, data);/* 12. Set "Set DATA0" to '1b' */pci_write_config_word(dev, EXTERNAL_ROM_SATUS, reg_val | (1 << 8));
#if 1/* 13. Read "Set DATA1" and confirm it is '0b' */do{udelay(500);pci_read_config_word(dev, EXTERNAL_ROM_SATUS, &reg_val);}while(reg_val& (1 << 9));/* 14. Write FW data to "DATA1"  */index += 4;/* to avoid reading beyond the end of the buffer */for (data = 0, j = 3; j >= 0; j--) {if ((j + index) < fw->size)data |= fw->data[index + j] << (8 * j);}pci_write_config_dword(dev, DATA1, data);//printk(KERN_DEBUG"----- %d, %08x\n",index / 4, data);/* 15. Set "Set DATA1" to '1b'  */pci_write_config_word(dev, EXTERNAL_ROM_SATUS, reg_val | (1 << 9));
#endif/* 16. Return to step 10 and repeat steps 10 to 15  */
#if 0if(index > 200)break;
#endif}
#if 0do{pci_read_config_word(dev, EXTERNAL_ROM_SATUS, &reg_val);udelay(500);}while(reg_val & (3 << 8));
#endif/* 17. After writing the last data of FW, the System Software * must set "External ROM Access Enable" to '0b' */pci_write_config_word(dev, EXTERNAL_ROM_SATUS, reg_val & ~(1));/* 18. Read "Result Code" and confirm it is '001b'  */loop = 0;do{pci_read_config_word(dev, EXTERNAL_ROM_SATUS, &reg_val);udelay(5000);if(loop++ == 1000){printk(KERN_INFO"-----  Result Code not 001b,is %x, index = %d\n",reg_val, index);return ;}}while((reg_val & (7 <<4)) != (1 << 4));printk(KERN_INFO"-----  index = %d\n", index);
}

3.3 添加从ROM里读数据的函数

void read_FW(struct pci_dev *dev)
{u16 data = 0;u32 fw_data = 0;u32 loop = 0;unsigned long count = 0;/* 1. Read "External ROM Exists" and confirm it is '1b' */if(pci_read_config_word(dev, EXTERNAL_ROM_SATUS, &data)){printk(KERN_INFO"----- read status failed\n");return;}while(data & 4){pci_read_config_word(dev, EXTERNAL_ROM_SATUS, &data);udelay(1000);}printk(KERN_INFO"----- start read, status = %x\n", data);if(!(data & (1 << 15))){printk(KERN_INFO"----- rom not exist \n");return;}/* 2. Write '53524F4Dh' to "DATA0" */if(pci_write_config_dword(dev, DATA0, 0x53524F4D)){printk(KERN_INFO"-----  write DATA0 failed\n");return;}/* 3. Set '1b' to "External ROM Access Enable" */pci_write_config_word(dev, EXTERNAL_ROM_SATUS, data | 0x1);/* 4. Read "Result Code" and confirm it is '000b' */do{pci_read_config_word(dev, EXTERNAL_ROM_SATUS, &data);udelay(500);if(loop++ == 20){printk(KERN_INFO"-----  Result Code not 0\n");return ;}}while(data & (7 <<4));/* 5. Set "Get DATA0" and "Get DATA1" to '1b' */pci_write_config_word(dev, EXTERNAL_ROM_SATUS, data | (0x3 << 10));while(1){/* 6. Read "Get DATA0" and confirm it is '0b' */do{pci_read_config_word(dev, EXTERNAL_ROM_SATUS, &data);udelay(500);}while(data & (1 <<10));/* 7. Get External ROM data from "DATA0" */pci_read_config_dword(dev, DATA0, &fw_data);printk(KERN_DEBUG"-----  %lu, %08x\n",count * 2, fw_data);
#if 1if(fw_data == 0xffffffff)break;
#endif/* 8. Set "Get DATA0" to '1b' */pci_write_config_word(dev, EXTERNAL_ROM_SATUS, data | (0x1 << 10));/* 9. Read "Get DATA1" and confirm it is '0b' */do{pci_read_config_word(dev, EXTERNAL_ROM_SATUS, &data);udelay(500);}while(data & (1 <<11));/* 10. Get External ROM data from "DATA1" */pci_read_config_dword(dev, DATA1, &fw_data);//printk(KERN_INFO"-----  fw_data from DATA1 is %x\n",fw_data);printk(KERN_DEBUG"-----  %lu, %08x\n",count * 2 + 1, fw_data);
#if 1if(fw_data == 0xffffffff)break;
#endif/* 11. Set "Get DATA1" to '1b' */pci_write_config_word(dev, EXTERNAL_ROM_SATUS, data | (0x1 << 11));/* 12. Return to sequence 6 and repeat sequence 6 to sequence 11 */count ++;
#if 1if(count > 50)break;
#endif}printk(KERN_INFO"-----  count %lu\n",count);/* 13. After reading the last data of External ROM data, the System * Software must set "External ROM Access Enable" to '0b' */pci_write_config_word(dev, EXTERNAL_ROM_SATUS, data & ~(1));
}

3.4 调用新添加的函数

文件:drivers/usb/host/xhci-pci.c

函数:xhci_pci_probe();

pm_runtime_get_noresume(&dev->dev);

后面添加:

/************** load FW ***************/
erase_chip(dev);
write_FW(dev);
read_FW(dev);

4 将固件编译到内核镜像里

将固件文件(如:ROMimage2028.bin)拷贝到内核源码根目录下的firmware目录

配置内核

make menuconfig

在CONFIG_EXTRA_FIRMWARE配置里加上ROMimage2028.bin

配置完的.config相关内容如下:

CONFIG_EXTRA_FIRMWARE="... ROMimage2028.bin"
CONFIG_EXTRA_FIRMWARE_DIR="firmware"

在linux4.19内核下的UPD720201驱动里添加固件下载的代码相关推荐

  1. SoCFPGA-A10 内核ADRV9025设备与驱动的添加

    文章目录 前言 环境或说明 过程 总结 前言 收录疑难杂症 之 "内核ADRV9025设备与驱动的添加" ps 到目前为止(2021-2-7)ADI官方只有9009和9371的Li ...

  2. 给linux4.19内核打上补丁(支持RNDIS)

    来自 https://whycan.cn/t_1672.html git clone https://github.com/torvalds/linux.git cd linux git reset ...

  3. php 上一条下一条,thinkPhp里添加显示上一条和下一条

    newsinfo.php里的代码 if($front['id']!=null){ $id  = $front['id']; echo "上一条:$front[title]"; }e ...

  4. linux系统能装什么显卡,Linux系统下安装显卡驱动

    第一次使用Linux遇到的不是硬盘分区而是显卡驱动问题,因为Linux在图形界面方面作的不是很好,以后你安其它软件时就能感受到.好多时候看到图形界面出错不一定是软件出问题. Linux下安装显卡驱动 ...

  5. sonix uvc驱动的添加 RT5350支持H264

    请尊重别人的劳动成果 转载请务必注明出处 根据sonix提供的驱动,需要在内核下进行配置,以添加到内核或与模块的方式进行编译: 1.makefile中添加驱动的目录,尽量保持和原有的一致, obj-$ ...

  6. 【鸿蒙OS开发入门】06 - 启动流程代码分析之KernelOS:之启动Linux-4.19 Kernel内核 启动init进程

    [鸿蒙OS开发入门]06 - 启动流程代码分析之KernelOS:之启动Linux-4.19 Kernel内核 一.head.S 启动start_kernel() 1.1 start_kernel() ...

  7. S3C2440移植Linux4.19.275内核以及过程中遇到的问题

    目录 1 问题一:内核移植时MTD分区问题 2 问题二:uboot的MTDPARTS_DEFAULT定义的MTD分区,bootargs中的文件系统分区,内核的mtd_partition smdk_de ...

  8. 瑞萨linux编译环境,瑞萨RZ/A2M Linux4.19系统构建与驱动移植纪实之一:BSP环境搭建...

    瑞萨RZ/A2M Linux4.19系统构建与驱动移植纪实之一:BSP环境搭建 我的系统信息 下载RZ/A Linux-4.19 BSP 编译安装带有SSL模块的Python 2.7 我的系统信息 下 ...

  9. [linux kernel] 内核下ksz8081驱动调试

    系统版本:Ubuntu18.04-64 编译器版本:gcc version 7.4.0 (Ubuntu/Linaro 7.4.0-1ubuntu1~18.04.1) uboot版本:2018.07 - ...

  10. linux内核下网络驱动流程,基于Linux内核驱动的网络带宽测速方法与流程

    本发明涉及一种测速方法,尤其是一种网络带宽测速方法. 背景技术: :电信运营商为客户提供一定带宽的Internet接入:为了检验带宽是否达标,一般均由客户使用个人电脑在网页上直接测速.但是随着智能网关 ...

最新文章

  1. 如何构建日均千万PV Web站点(二) 之~缓存为王~
  2. Java新手问题集锦
  3. python登录验证码(基于django框架)
  4. 抛弃鼠标的神器——Vimium
  5. Oracle 从入门到精通视频教程(11G版本)
  6. 开源cms 和 开源博客_BackBee CMS如何以及为何开源
  7. mysql将查到的数据删除_MySQL基本SQL语句之数据插入、删除数据和更新数据 | 旺旺知识库...
  8. jquery跨域调用webService
  9. java获取数据库列的别名_java – JDBC ResultSet获取具有表别名的列
  10. cocos2d 浅析
  11. 图象关于y轴对称是什么意思_高中数学常考问题1:函数、基本初等函数的图象与性质,真题分析...
  12. 织梦内核PHP在线教育知识付费课程分销网站源码 带手机端+集成支付功能
  13. 2022跨年烟花代码(五)HTML5全屏烟花特效
  14. 快速了解FTTx/FTTC/FTTB/FTTH
  15. 北京春运更智能:自助验票、微信查询
  16. 小米5S刷机认真看一眼就能会的简单详细教图文
  17. Java程序员找工作很难吗?可能没有get这些内容
  18. 使用touch命令改变文件修改时间--用Enki学Linux系列(11)
  19. 2017 android平板,苹果2017款iPad评测:史上性价比最高的体面iPad平板
  20. 想通过参加会议年入30万,没这些能力可不行——百格活动

热门文章

  1. 银行IT系统 -整体架构
  2. php 0xc0000135,php 错误代码 0xc0000135是什么情况
  3. 苹果id怎么注册?老果粉教你创建新的Apple ID
  4. 智力题------赛马问题
  5. 测绘——利用ExifTool提取照片exif信息【windows环境下】(信息非常全)
  6. 英特尔神经计算棒_如何设置英特尔Movidius神经计算棒
  7. kuka机器人码垛编程网盘_kuka机器人循环指令码垛编程探索
  8. web前端期末大作业 基于HTML+CSS家乡主题毕业设计源码 (1)
  9. stm32f103r6最小系统原理图_stm32f103c8t6封装及最小系统原理图
  10. 安装Vista与XP双系统后如何做好备份