单龙芯3A3000-7A1000PMON研究学习-(26)撸起袖子干-再来一杯代码8

1.继续往下执行

config_ht_link 在 ls3a7a_setup_ht_link.S 文件的前半部分:

1.1 先看这个文件的注释吧

//************************************
// setup_ht_link
// author: chenxk
// date: 2017.11.14
// set up the link between CPU and PCH include two steps:    设置这个连接包括两个步骤
// 1. config_ht_link(set link parameters)           1.配置ht的连接参数
// 2. reset_ht_link(reset to make new configure effect) 2.重启ht的连接
//
// for CPU: LS3A2000/LS3A3000
// for PCH: LS7A1000
//************************************
#include "ht.h"

    .global config_ht_link
    .ent    config_ht_link
    .set    noreorder
    .set    mips3
//input:
//a0: HT address base(full address base, like: 0x90001e0000000000)  ht的基地址
//a1: HT bus and hard freq mode related setting:    总线频率关系如下
//[15:12]: 7A freq-0: 200M; 2: 400M; 5: 800M; 9: 1600M;  传入参数是9
//[11: 8]: 3A freq-0: 200M; 2: 400M; 5: 800M; 9: 1600M;  传入参数是9
//[ 7: 4]: GENx-1/3;                                     传入参数是3
//[    1]: width-0: 8bit; 1: 16bits;                     传入参数是1,16位宽度
//[    0]: reconnect, 0: not reconnect; 1: reconnect     传入参数是1,重新连接 
//a2: HT soft configure pll setting:
//[63:32]: 7A side ht_pllcfg[31:0]            //高32位表示7A的PLL设置
//[31: 0]: 3A side ht_pllcfg[31:0]            //低32位表示3A的PLL设置

//register usage:
//t0: 3A HT cntl register base address         //t0表示3A的ht控制器基地址
//t1: 7A HT cntl register base address        //t1表示7A的ht控制器基地址
//t5, t6: tmp variable                     //临时变量
//t2: store a1                          //t2保存传入参数2
//t3: store a2                          //t2保存传入参数3
//s1: store ra                          //s1保存返回地址。有可能中间有调用其他函数

1.2 进入代码,分成几段吧,比较长。 

config_ht_link:

    move    s1, ra    /* 函数返回在483行 */

    dli     t0, 0xfdfb000000    //3A
    dli     t1, 0xfdfe000000    //7A
    daddu   t0, t0, a0          //a0 = 0x90000e0000000000
    daddu   t1, t1, a0
    move    t2, a1
    move    t3, a2

//中间有些宏定义控制,没有定义的部分,就省略了。

#ifdef  CHECK_HT_PLL_LOCK    //宏定义有效
    //check HT PLL lock
    move    t5, $0
    lw      a0, LS3A_HT_PLL_CONF(t0)
    srl     a0, a0, 3
    and     a0, a0, 0x1
    bnez    a0, 2f
    nop
    PRINTSTR("\r\nError: After reconfigure, 3A HT PLL not locked!!!")
    add     t5, t5, 1
2:
#ifdef  CHECK_7A_HT_PLL_LOCK     //宏定义有效
    lw      a0, 0x1F4(t1)
    srl     a0, a0, 3
    and     a0, a0, 0x1
    bnez    a0, 2f
    nop
    PRINTSTR("\r\nError: After reconfigure, 7A HT PLL not locked!!!")
    add     t5, t5, 1
2:
#endif
    bnez    t5, 2b
    nop
    TTYDBG("\r\nPLL check success.")    //执行这句
#endif

1.2.1 代码最前面的7行。

1)保存ra到s1

2)t0为3A的ht控制器的基地址,t1为7A的HT控制器的基地址

3)参数2,参数3分别保存到 t2和t3中。

1.2.2 接下来

1)t5 的寄存器被清零。$0寄存器的值只有0,复制给t5

2)读3A的HT寄存器(0x9000,0efd,fb00,0178),判断位[3]是否为0,为0则出错,否则跳转继续执行

    文档显示第3位是保留,????0x178就是这个寄存器。参考7A的寄存器,两个有点像。

 3)读7A的HT寄存器(0x9000,0efd,fb00,01f4),判断位[3]是否为0,为0则出错,否则跳转继续执行

 

 这个寄存器与上面那个寄存器的分区很像,可能是上个寄存器的手册不完整。

 4)不为0,是不是表示PLL锁定了?唉,反正就是靠猜。。。

 

1.2.3 接下来

t5 不等于0,则表示刚刚执行的出错了,死循环。

等于0,则继续向下执行。打印成功的提示

1.3  继续看代码

    //wait until HT link up
    TTYDBG("\r\nWait HT bus up.")
    li      t5, 0x1f
1:
    lw      a0, 0x44(t0)
    bal     hexserial            //打印寄存器的值
    nop
    TTYDBG(">")
    addi    t5, t5, -1
    bnez    t5, 2f
    nop
    TTYDBG("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b=")
    li      t5, 0x1f
2:
    lw      a0, 0x44(t0)
    li      a1, 0x20        //[5] InitComplete 置1,表示初始化完成。
    and     a0, a0, a1      //与操作
    beqz    a0, 1b          //等于0,则往会跳,否则继续向下执行
    nop

    TTYDBG("\r\n")
    lw      a0, 0x44(t0)
    bal     hexserial       //打印寄存器的值
    nop
    TTYDBG("\r\n")

3A的HT寄存器(偏移地址0x44):

 

1.4 继续看代码

#if HT1_RECONNECT
    and     a0, t2, 0x1          //t2最低位是1
    beqz    a0, 8f               //8f 479行,程序结束返回
    nop

    TTYDBG("Set 7A side HT:\r\n")          //7A1000 手册.pdf
    TTYDBG("Set width\r\n")
    lw      a0, 0x44(t1)
    li      a1, (0xff<<24)    //注意是文档中46-47H寄存器的值
    not     a1, a1            //a1 = 00ff,ffff
    and     a0, a0, a1        //[31:24]被清零
    li      a1, HT_WIDTH_CTRL_8  //a1 = 0
    srl     t5, t2, 1        //t5 = t2 >> 1
    and     t5, t5, 0x1      //t2[1] = 1
    beqz    t5, 1f           //不等于0,不跳
    nop
    li      a1, HT_WIDTH_CTRL_16  //a1 = 0x11  
1:
    sll     a1, a1, 24           //a1 = 0x1100,0000
    or      a0, a0, a1			 //a0 的[28] [24] 置1 发送端和接收端 16位宽度设置
    sw      a0, 0x44(t1)         //写入寄存器

    lw      a0, 0x44(t1)       //信息打印,
    bal     hexserial
    nop
    TTYDBG("\r\n")

    TTYDBG("Set Freq\r\n")
    lw      a0, 0x4c(t1)        //链路频率配置寄存器 ,只有8-11位可写
    li      a1, (0xf<<8)  
    not     a1, a1             //a1 = 0xffff,f0ff
    and     a0, a0, a1         //[11:8] 清零
    srl     a1, t2, 12         //右移12位
    and     a1, a1, 0xf		   //剩下 9    HT总线工作频率配置
    sll     a1, a1, 8          //左移8位
    or      a0, a0, a1         //9 写入到[11:8]
    sw      a0, 0x4c(t1)       //偏移为4c的寄存器

    lw      a0, 0x4c(t1)       //打印出来[11:8] = 0; 打印值:0x82250060
    bal     hexserial
    nop
    TTYDBG("\r\n")

    TTYDBG("Set soft config\r\n")
    dsrl    a1, t3, 32               //右移32,取高32位
    sw      a1, 0x1F4(t1)
    lw      a0, 0x1F4(t1)          //HT PLL控制寄存器,配置时钟 频率的。  
    bal     hexserial
    nop
    TTYDBG("\r\n")

    srl     a1, t2, 4       //右移4
    and     a1, a1, 0xf    
    li      a0, 3
    bne     a0, a1, 4f        //相等,不跳转
    nop
    TTYDBG("Set Gen3 mode\r\n")
    lw      a0, 0x6c(t1)      //
    li      a1, (0xff<<16)    
    not     a1, a1            //a1 = 0xff00,ffff
    and     a0, a0, a1        //清零[23:16]
    li      a1, (0x60<<16)
    or      a0, a0, a1        //[23:16]= 0x60  
    sw      a0, 0x6c(t1)      //文档说明没找到!!!!!!!

    lw      a0, 0x6c(t1)
    bal     hexserial
    nop
    TTYDBG("\r\n")

    TTYDBG("Set retry mode\r\n")
    lw      a0, 0x64(t1)
    li      a1, (0xc1<<0)  
    not     a1, a1
    and     a0, a0, a1          //清零[7:6],[0]
    li      a1, (0x81<<0)
    or      a0, a0, a1
    sw      a0, 0x64(t1)       //文档说明没找到!!!!!!!
    lw      a0, 0x64(t1)
    bal     hexserial
    nop
    TTYDBG("\r\n")

    TTYDBG("Enable scrambling\r\n")
    lw      a0, 0xd0(t1)        
    li      a1, (0x78<<0)  
    not     a1, a1
    and     a0, a0, a1       //清零[6:4],[3]
    li      a1, (0x78<<0)
    or      a0, a0, a1       //[6:4] = 7 [3] = 1
    sw      a0, 0xd0(t1)     

    lw      a0, 0xd0(t1)
    bal     hexserial
    nop
    TTYDBG("\r\n")
4:
    TTYDBG("set buffer num\r\n")
    lw      a0, 0x1dc(t1)
    li      a1, 0xfffffff 
    or      a0, a0, a1
    sw      a0, 0x1dc(t1)

    lw      a0, 0x1dc(t1)
    bal     hexserial
    nop
    TTYDBG("\r\n")



    //Set CPU side HT
    TTYDBG("Set CPU side HT:\r\n")     //执行,3A文档部分。
    //HT bus width
    TTYDBG("Set width\r\n")
    li      a1, HT_WIDTH_CTRL_8
    srl     t5, t2, 1
    and     t5, t5, 0x1
    beqz    t5, 1f             //等于0跳转,实际不跳转
    nop
    li      a1, HT_WIDTH_CTRL_16  //0x11
1:
    sb      a1, 0x47(t0)    //0x44 [31:24] 高8位,使能相位选择,接收发送16位模式
    lw      a0, 0x44(t0)    //信息打印
    bal     hexserial
    nop
    TTYDBG("\r\n")

    //Set HT bus frequency
    TTYDBG("Set Freq\r\n")
    srl     a1, t2, 8           //9
    and     a1, a1, 0xf         //a1= 9
    sb      a1, (LS3A_HT_FREQ+1)(t0)   //0x4d这个字节   [11:8] = 9  文档中意义不明确
    lw      a0,  LS3A_HT_FREQ   (t0)   //0x4c ,信息打印

    bal     hexserial
    nop
    TTYDBG("\r\n")

    TTYDBG("Set soft config\r\n")
    move    a1, t3
    sw      a1, LS3A_HT_PLL_CONF(t0)   //0x178 ,100页,软件频率配置
    lw      a0, LS3A_HT_PLL_CONF(t0)   //信息打印
    bal     hexserial
    nop
    TTYDBG("\r\n")

    srl     a1, t2, 4          //逻辑右移
    and     a1, a1, 0xf        //3
    li      a0, 3
    bne     a0, a1, 4f         //相等,不跳转
    nop
    TTYDBG("Set GEN3 mode\r\n")
    li      a1, 0x88600000
    sw      a1, LS3A_HT_REVISION(t0)   //0x110  [23:16] = 0x60 表示HT3.0  其他位只读
    lw      a0, LS3A_HT_REVISION(t0)   //信息打印
    bal     hexserial
    nop
    TTYDBG("\r\n")

    TTYDBG("Set retry mode\r\n")
    li      a1, 0x81
    sb      a1, LS3A_HT_RETRY_CONTROL(t0)   //0x118 错误重传使能 [7:6]=2, 运行重传次数,[0]可能是使能位,文档中未给出
    lw      a0, LS3A_HT_RETRY_CONTROL(t0)   //信息打印
    bal     hexserial
    nop
    TTYDBG("\r\n")

    TTYDBG("Enable scrambling\r\n")
    li      a1, 0x78
    sb      a1, LS3A_HT_LINK_TRAIN(t0)   //0x130  文档97页。 注意设置的低8位0111,1000每一位的含义 使能scrambling(抢占)
    lw      a0, LS3A_HT_LINK_TRAIN(t0)    //信息打印  ,函数准备返回了,482行
    bal     hexserial
    nop
    TTYDBG("\r\n")
4:

//中间删掉了一些没有宏定义的代码

8:
#endif

    move    ra, s1      /* 函数返回 */
    jr      ra
    nop

1.4.1 t2(t2 = 9<<12 | 9<<8 | 3<<4 | 1<<1 | 1<<0;)是保存的传入的参数,最低位是1,不结束。继续执行

1.4.2   到“TTYDBG("Set Freq\r\n")”的前面,7A这边0x44-0x47寄存器,高31-24位(应该是0x47地址)被清零,[28],[24] 被置1,其他位保持不变

 1.4.3  到“TTYDBG("Set soft config\r\n")”代码前,配置0x4c寄存器,设置位[11-8]为9,1600MHz

 

1.4.4 接下来7句,到回车换行结束。

        设置7A的HTPLL寄存器  值为 2<<22 | 2<<18 | 2<<16 | 32*2<<9 | 8<<5 | 1<<1; 

 

 

 不知道它这个计算公式在哪?看下图,似乎是HT PHY自己产生时钟,跟5个PLL没什么关系????

 

 

 1.4.5 到“TTYDBG("Set retry mode\r\n")”代码前 ,这一段注释说明是配置GEN3.0 但是0x6c的寄存器并没有找到文档说明!!

         跳过吧,这也猜不出来啊!!!!

 

 

 1.4.6 到“TTYDBG("Enable scrambling\r\n")”代码前,0x64的寄存器并没有找到文档说明!!

         跳过吧,这也猜不出来啊!!!!

 1.4.7 到“TTYDBG("set buffer num\r\n")”代码前,0xd0的寄存器并没有找到文档说明!!

         跳过吧,这也猜不出来啊!!!!

 1.4.8 到“TTYDBG("Set CPU side HT:\r\n")”代码前,0x1dc的寄存器并没有找到文档说明!!

         跳过吧,这也猜不出来啊!!!!

1.5 截取其中cpu HT的代码下来,(跟1.4中后半截相同)

    //Set CPU side HT
    TTYDBG("Set CPU side HT:\r\n")     //执行,3A文档部分。
    //HT bus width
    TTYDBG("Set width\r\n")
    li      a1, HT_WIDTH_CTRL_8
    srl     t5, t2, 1
    and     t5, t5, 0x1
    beqz    t5, 1f             //等于0跳转,实际不跳转
    nop
    li      a1, HT_WIDTH_CTRL_16  //0x11
1:
    sb      a1, 0x47(t0)    //0x44 [31:24] 高8位,使能相位选择,接收发送16位模式
    lw      a0, 0x44(t0)    //信息打印
    bal     hexserial
    nop
    TTYDBG("\r\n")

    //Set HT bus frequency
    TTYDBG("Set Freq\r\n")
    srl     a1, t2, 8           //9
    and     a1, a1, 0xf         //a1= 9
    sb      a1, (LS3A_HT_FREQ+1)(t0)   //0x49这个字节   [11:8] = 9  文档中意义不明确
    lw      a0,  LS3A_HT_FREQ   (t0)   //0x48 ,信息打印

    bal     hexserial
    nop
    TTYDBG("\r\n")

    TTYDBG("Set soft config\r\n")
    move    a1, t3
    sw      a1, LS3A_HT_PLL_CONF(t0)   //0x178 ,100页,软件频率配置
    lw      a0, LS3A_HT_PLL_CONF(t0)   //信息打印
    bal     hexserial
    nop
    TTYDBG("\r\n")

    srl     a1, t2, 4          //逻辑右移
    and     a1, a1, 0xf        //3
    li      a0, 3
    bne     a0, a1, 4f         //相等,不跳转
    nop
    TTYDBG("Set GEN3 mode\r\n")
    li      a1, 0x88600000
    sw      a1, LS3A_HT_REVISION(t0)   //0x110  [23:16] = 0x60 表示HT3.0  其他位只读
    lw      a0, LS3A_HT_REVISION(t0)   //信息打印
    bal     hexserial
    nop
    TTYDBG("\r\n")

    TTYDBG("Set retry mode\r\n")
    li      a1, 0x81
    sb      a1, LS3A_HT_RETRY_CONTROL(t0)   //0x118 错误重传使能 [7:6]=2, 运行重传次数,[0]可能是使能位,文档中未给出
    lw      a0, LS3A_HT_RETRY_CONTROL(t0)   //信息打印
    bal     hexserial
    nop
    TTYDBG("\r\n")

    TTYDBG("Enable scrambling\r\n")
    li      a1, 0x78
    sb      a1, LS3A_HT_LINK_TRAIN(t0)   //0x130  文档97页。 注意设置的低8位0111,1000每一位的含义 使能scrambling(抢占)
    lw      a0, LS3A_HT_LINK_TRAIN(t0)    //信息打印  ,函数准备返回了,482行
    bal     hexserial
    nop
    TTYDBG("\r\n")

1.5.1  前面几句 a1 = 0x11

1.5.2 接着 赋值0x47字节0x11(即0x44的[31-24]),设置宽度为16位。

 1.5.3 对0x49寄存器进行字节操作,写入数字9

 

 

 

1.5.4 到“TTYDBG("Set soft config\r\n")”开始的7个语句,寄存器0x178

        设置HT的PLL频率 

 

 

 

 怎么感觉算出来不是1600M呢????

 

 1.5.5 配置0x110寄存器

  

1.5.6 配置0x118寄存器,配置为0x81,文档说明不全!!

 

 

 1.5.7 配置0x130寄存器,配置为0x78,只有[7-0]位有效

 

 然后函数就返回了。

2.总结:

1.这部分主要是HT的时钟配置1600MHz,16bits模式,HT3.0,使能scrambling(抢占),最大重试次数为2

2.配置之后并不能立马生效,还得重启HT控制器,这是下一步要干的事情。

3.文档的说明真的是很不详细,可能需要结合3A和7A的文档一起看才行,顺便也猜一猜吧。唉。。。。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大智兄

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值