uboot 或者 linux 下限制 sata speed

1、linux下通过  cmdline 实现

参考 :Documentation/admin-guide/kernel-parameters.txt

    libata.force=   [LIBATA] Force configurations.  The format is comma
        separated list of "[ID:]VAL" where ID is
        PORT[.DEVICE].  PORT and DEVICE are decimal numbers
        matching port, link or device.  Basically, it matches
        the ATA ID string printed on console by libata.  If
        the whole ID part is omitted, the last PORT and DEVICE
        values are used.  If ID hasn't been specified yet, the
        configuration applies to all ports, links and devices.

        If only DEVICE is omitted, the parameter applies to
        the port and all links and devices behind it.  DEVICE
        number of 0 either selects the first device or the
        first fan-out link behind PMP device.  It does not
        select the host link.  DEVICE number of 15 selects the
        host link and device attached to it.

        The VAL specifies the configuration to force.  As long
        as there's no ambiguity shortcut notation is allowed.
        For example, both 1.5 and 1.5G would work for 1.5Gbps.
        The following configurations can be forced.

        * Cable type: 40c, 80c, short40c, unk, ign or sata.
          Any ID with matching PORT is used.

        * SATA link speed limit: 1.5Gbps or 3.0Gbps.

        * Transfer mode: pio[0-7], mwdma[0-4] and udma[0-7].
          udma[/][16,25,33,44,66,100,133] notation is also
          allowed.

        * [no]ncq: Turn on or off NCQ.

        * nohrst, nosrst, norst: suppress hard, soft
                      and both resets.

        * dump_id: dump IDENTIFY data.

        If there are multiple matching configurations changing
        the same attribute, the last one is used.

可以将上面的参数加到 cmdline 中,从uboot传给内核的参数

 

如果要限制具体那个port  , 可以根据 dmesg 来看 

So, the tricky part is finding out which port X and device Y (dmesg ataX.YY) is which controller and drive. I think - that notation matches PORT[.DEVICE], but there's also the W:X:Y:Z notation. I'm guessing ataX.YY :)

libata.force=1:1.5G,2:1.5G,3:1.5G

2、uboot下 通过修改 sata controller 实现

我们在 linux 启动的log里经常看到如下信息,

ata2: SATA link up 1.5 Gbps (SStatus 113 SControl 300) .

ata1: SATA link up 3.0 Gbps (SStatus 123 SControl 300)

ata1: SATA link up 6.0 Gbps (SStatus 133 SControl 300)

从SStatus 就可以看出 sata link speed , 0x133 就是6.0Gbps的速度。从 SControl 就可以看到 sata phy 的设置,这个 sata phy register是 sata 控制器的组成部分,如果 sata 接口是 CPU的资源,需要参考cpu 的手册,不过 sata phy register是一个标准,基本所有的控制器设计的时候都按照这个规范来的。以NXP LS1046A  ARM64平台为例,就1个sata controller (可以查看serdes配置,0x3040, 0x5a59 还有dts查看sata控制器地址),下面是 SATA status register (PxSSTS) 。

SATA control register (PxSCTL)

# u-boot-ls $ grep PORT_SCR -nR include/
include/ahci.h:54:#define PORT_SCR		0x28 /* SATA phy register block */
include/ahci.h:55:#define PORT_SCR_STAT		0x28 /* SATA phy register: SStatus */
include/ahci.h:56:#define PORT_SCR_CTL		0x2c /* SATA phy register: SControl */
include/ahci.h:57:#define PORT_SCR_ERR		0x30 /* SATA phy register: SError */
include/ahci.h:58:#define PORT_SCR_ACT		0x34 /* SATA phy register: SActive */
include/ahci.h:93:/* PORT_SCR_STAT bits */
include/ahci.h:94:#define PORT_SCR_STAT_DET_MASK	0x3
include/ahci.h:95:#define PORT_SCR_STAT_DET_COMINIT 0x1
include/ahci.h:96:#define PORT_SCR_STAT_DET_PHYRDY 0x3

这里的设置 可以参考 u-boot/board/highbank/ahci.c 来实现

具体实现如下:

diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index 18b748a..f6078c0 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -251,6 +251,15 @@ static int ahci_host_init(struct ahci_uc_priv *uc_priv)
                sunxi_dma_init(port_mmio);
 #endif
 
+#ifdef CONFIG_TARGET_YY_XXXXXXXXXXX
+               /* limit sata speed 1.5Gbps */
+               writel(0x311, port_mmio + PORT_SCR_CTL);
+               udelay(1000);
+               writel(0x310, port_mmio + PORT_SCR_CTL);
+               udelay(1000);
+#endif
+
                /* Add the spinup command to whatever mode bits may
                 * already be on in the command register.
                 */
@@ -314,7 +323,7 @@ static int ahci_host_init(struct ahci_uc_priv *uc_priv)
 
                /* register linkup ports */
                tmp = readl(port_mmio + PORT_SCR_STAT);
-               debug("SATA port %d status: 0x%x\n", i, tmp);
+               printf("SATA port %d status: 0x%x\n", i, tmp);
                if ((tmp & PORT_SCR_STAT_DET_MASK) == PORT_SCR_STAT_DET_PHYRDY)
                        uc_priv->link_port_map |= (0x01 << i);
        }

 不过需要注意的是,这里修改过寄存器后,linux下的 sata speed 也被限制到了 gen2, 如果只想在 uboot下限制 speed ,加载硬盘里的内核之后,可以在  执行 bootm命令之前将寄存器修改回来。

diff --git a/cmd/bootm.c b/cmd/bootm.c
index c3a0634..7d1c292 100644
--- a/cmd/bootm.c
+++ b/cmd/bootm.c
@@ -8,6 +8,7 @@
  * Boot support
  */
 #include <common.h>
+#include <asm/io.h>
 #include <bootm.h>
 #include <command.h>
 #include <environment.h>
@@ -90,6 +91,14 @@ static int do_bootm_subcommand(cmd_tbl_t *cmdtp, int flag, int argc,
 
 int do_bootm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
+#ifdef CONFIG_TARGET_YY_XXXXXX
+               /* do not limit sata speed any more */
+               writel(0x301, 0x320012c);
+               udelay(1000);
+               writel(0x300, 0x320012c);
+               udelay(1000);
+#endif
+

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值