当前位置:   article > 正文

RK3566 linux系统硬件复位后无法重启_could not find baseparameter partition

could not find baseparameter partition

1.硬件复位后重启日志

  1. Bootdev(atags): mmc 0
  2. MMC0: HS200, 200Mhz
  3. PartType: EFI
  4. boot mode: None
  5. FIT: no signed, no conf required
  6. DTB: rk-kernel.dtb
  7. HASH(c): OK
  8. I2c0 speed: 100000Hz
  9. vsel-gpios- not found! Error: -2
  10. vdd_cpu init 900000 uV
  11. PMIC: RK8170 (on=0x10, off=0x00)
  12. vdd_logic init 900000 uV
  13. vdd_gpu init 900000 uV
  14. 4200000 uV is too high from LDO_REG5
  15. io-domain: OK
  16. Warn: can't find connect driver
  17. Could not find baseparameter partition
  18. Model: Rockchip RK3566 RK817 BDTTS402 LP4X Board
  19. rk8xx_read: read reg 0x4d failed, ret=-121
  20. rk8xx_write: write reg 0x4d failed, ret=-121
  21. __virq_enable: Clear status register 0x4d failed, ret=-121
  22. 此时液晶屏无logo显示。
  23. 停留1分钟
  24. 继续输出如下日志:
  25. Rockchip UBOOT DRM driver version: v1.0.1
  26. VOP have 1 active VP
  27. vp0 have layer nr:6[0 2 4 1 3 5 ], primary plane: 4
  28. vp1 have layer nr:0[], primary plane: 0
  29. vp2 have layer nr:0[], primary plane: 0
  30. Using display timing dts
  31. dsi@fe060000: detailed mode clock 29000 kHz, flags[8000000a]
  32. H: 0480 0508 0512 0540
  33. V: 0854 0882 0886 0914
  34. bus_format: 100e
  35. VOP update mode to: 480x854p0, type: MIPI0 for VP0
  36. VOP VP0 enable Smart0[480x854->480x854@0x0] fmt[1] addr[0x7df00036]
  37. final DSI-Link bandwidth: 384 Mbps x 2
  38. CLK: (sync kernel. arm: enter 816000 KHz, init 816000 KHz, kernel 0N/A)
  39. apll 1416000 KHz
  40. dpll 460000 KHz
  41. gpll 1188000 KHz
  42. cpll 1000000 KHz
  43. npll 1200000 KHz
  44. vpll 24000 KHz
  45. hpll 29000 KHz
  46. ppll 200000 KHz
  47. armclk 1416000 KHz
  48. aclk_bus 150000 KHz
  49. pclk_bus 100000 KHz
  50. aclk_top_high 500000 KHz
  51. aclk_top_low 400000 KHz
  52. hclk_top 150000 KHz
  53. pclk_top 100000 KHz
  54. aclk_perimid 300000 KHz
  55. hclk_perimid 150000 KHz
  56. pclk_pmu 100000 KHz
  57. Net: eth1: ethernet@fe010000
  58. Hit key to stop autoboot('CTRL+C'): 0
  59. ## Booting FIT Image at 0x7a317f80 with size 0x014dfc00
  60. Fdt Ramdisk skip relocation
  61. ## Loading kernel from FIT Image at 7a317f80 ...
  62. Using 'conf' configuration
  63. optee api revision: 2.0
  64. TEEC: Waring: Could not find security partition
  65. 此时液晶屏可以显示logo。

2.对比android镜像

烧写厂家提供的android镜像则不会存在此问题。把linux镜像中的uboot.img换为android下的uboot.img也不会存在此问题,不过会出现另一个问题,就是内核启动后液晶就无显示了,如果没有这个问题其实可以直接用android下的u-boot源码替换linux下的u-boot源码。也尝试对比两个u-boot源码的差异,发现很多文件都不同。

3.找出关键的问题

通过在..\x3566_linux_v1.2.0\u-boot\arch\arm\mach-rockchip\board.c文件的board_late_init()函数中加入一些日志,发现是执行setup_download_mode()函数返回的错误,屏蔽此函数后则硬件复位后系统能正常启动。不过android源码中也调用了此函数。屏蔽此函数后启动时无法通过按下recovery按键进入loader模式。

通过搜索setup_download_mode()函数的实现在..\x3566_linux_v1.2.0\u-boot\arch\arm\mach-rockchip\boot_rkimg.c文件中:

  1. void setup_download_mode(void)
  2. {
  3. int vbus = 1; /* Assumed 1 in case of no rockusb */
  4. boot_devtype_init();
  5. /*
  6. * rockchip_dnl_key_pressed():
  7. *
  8. * (1) volume-up key (default)
  9. * (2) menu key (If no rockusb)
  10. *
  11. * It's possible that USB is disabled due to developer needs
  12. * a critial size of u-boot.bin.
  13. *
  14. * Disabling USB makes vbus can't be detected any more, so that
  15. * we add menu key. The events trigger are changed:
  16. *
  17. * - rockusb mode(actually fallback to bootrom mode):
  18. * "volume-up pressed + vbus=1" replaced with "menu pressed"
  19. * - recovery mode:
  20. * "volume-up pressed + vbus=0" replaced with "volume-up pressed"
  21. *
  22. * At the most time, USB is enabled and this feature is not applied.
  23. */
  24. if (rockchip_dnl_key_pressed() || is_hotkey(HK_ROCKUSB_DNL)) {
  25. printf("download %skey pressed... ",
  26. is_hotkey(HK_ROCKUSB_DNL) ? "hot" : "");
  27. #ifdef CONFIG_CMD_ROCKUSB
  28. vbus = rockchip_u2phy_vbus_detect();
  29. #endif
  30. if (vbus > 0) {
  31. printf("%sentering download mode...\n",
  32. IS_ENABLED(CONFIG_CMD_ROCKUSB) ?
  33. "" : "no rockusb, ");
  34. /* try rockusb download and brom download */
  35. run_command("download", 0);
  36. } else {
  37. printf("entering recovery mode!\n");
  38. env_set("reboot_mode", "recovery-key");
  39. }
  40. } else if (is_hotkey(HK_FASTBOOT)) {
  41. env_set("reboot_mode", "fastboot");
  42. }
  43. }

进一步探索,发现是uboot卡死在rockchip_dnl_key_pressed()函数的return key_is_pressed(key_read(KEY_VOLUMEUP));语句中:

  1. __weak int rockchip_dnl_key_pressed(void)
  2. {
  3. #if defined(CONFIG_DM_KEY)
  4. #ifdef CONFIG_CMD_ROCKUSB
  5. printf("key_is_pressed VOLUMEUP\n");
  6. return key_is_pressed(key_read(KEY_VOLUMEUP));
  7. #else
  8. printf("key_is_pressed MENU\n");
  9. return key_is_pressed(key_read(KEY_MENU));
  10. #endif
  11. #elif defined(CONFIG_ADC)
  12. const void *blob = gd->fdt_blob;
  13. int node, ret, channel = 1;
  14. u32 val, chns[2];
  15. node = fdt_node_offset_by_compatible(blob, 0, "adc-keys");
  16. printf("fdt_node_offset_by_compatible\n");
  17. if (node >= 0) {
  18. if (!fdtdec_get_int_array(blob, node, "io-channels", chns, 2))
  19. channel = chns[1];
  20. }
  21. ret = adc_channel_single_shot("saradc", channel, &val);
  22. if (ret) {
  23. printf("%s: Failed to read saradc, ret=%d\n", __func__, ret);
  24. return 0;
  25. }
  26. printf("adc_channel_single_shot\n");
  27. return ((val >= KEY_DOWN_MIN_VAL) && (val <= KEY_DOWN_MAX_VAL));
  28. #endif
  29. return 0;
  30. }

继续深入到..\x3566_linux_v1.2.0\u-boot\drivers\input\key-uclass.c文件,此文件实现了int key_read(int code)函数:

  1. int key_read(int code)
  2. {
  3. struct dm_key_uclass_platdata *uc_key;
  4. struct udevice *dev;
  5. struct uclass *uc;
  6. bool allow_pre_reloc = false;
  7. int ret, event = KEY_NOT_EXIST;
  8. ret = uclass_get(UCLASS_KEY, &uc);
  9. if (ret)
  10. return ret;
  11. try_again:
  12. for (uclass_first_device(UCLASS_KEY, &dev);
  13. dev;
  14. uclass_next_device(&dev)) {
  15. uc_key = dev_get_uclass_platdata(dev);
  16. if (!allow_pre_reloc && uc_key->pre_reloc)
  17. continue;
  18. if (uc_key->code != code)
  19. continue;
  20. event = key_core_read(uc_key);
  21. if (key_is_pressed(event))
  22. return event;
  23. }
  24. /* If not find valid key node from kernel, try from u-boot */
  25. if (event == KEY_NOT_EXIST && !allow_pre_reloc) {
  26. allow_pre_reloc = true;
  27. goto try_again;
  28. }
  29. return event;
  30. }

dev_get_uclass_platdata()函数的实现在..\x3566_linux_v1.2.0\u-boot\drivers\core\device.c文件中。

4.根据日志猜测问题在读取PMIC INT寄出器时出错

  1. rk8xx_read: read reg 0x4d failed, ret=-121
  2. rk8xx_write: write reg 0x4d failed, ret=-121
  3. __virq_enable: Clear status register 0x4d failed, ret=-121

根据以上日志,猜测应该是PMIC产生了中断事件,处理器读取PMIC INT寄存器时出错,也没有清除掉PMIC的中断,导致中断一直存在,程序卡死。

从日志看出当前是在读取0x04寄存器,而RK817的INT MASK寄存器为0xf9,RK805、RK808、RK818的INT MASK寄存器为0x4d。

怀疑是某个过程PMIC的ID传错了,通过加日志排查,int rk8xx_irq_chip_init(struct udevice *dev)函数中PMIC的ID为RK808,所以注册的中断相关的寄存器也是RK808的,导致读取错误。

修改int rk8xx_probe(struct udevice *dev)函数,给priv->variant赋值:

  1. static int rk8xx_probe(struct udevice *dev)
  2. {
  3. ...
  4. -- show_variant = ((msb << 8) | lsb) & RK8XX_ID_MSK;
  5. ++ priv->variant = ((msb << 8) | lsb) & RK8XX_ID_MSK;
  6. ++ show_variant = priv->variant;
  7. ...
  8. }

修改之后运行还是报错,只是寄存器变了: 

  1. rk8xx_read: read reg 0xf9 failed, ret=-121
  2. rk8xx_write: write reg 0xf9 failed, ret=-121
  3. __virq_enable: Clear status register 0xf9 failed, ret=-121

从此现象可以得出错误的主要原因不是寄存器配置错误,而是其它未知的原因。

5.解决方案

目前将rk8xx_pwrkey.c文件中的中断使能函数屏蔽,即可避免此问题:

  1. static int rk8xx_pwrkey_probe(struct udevice *dev)
  2. {
  3. printf("rk8xx_pwrkey_probe\n");
  4. struct rk8xx_priv *rk8xx = dev_get_priv(dev->parent);
  5. struct dm_key_uclass_platdata *key = dev_get_uclass_platdata(dev);
  6. int fall_irq, rise_irq;
  7. if (!rk8xx->irq_chip) {
  8. printf("Failed to get parent irq chip\n");
  9. return -ENOENT;
  10. }
  11. fall_irq = virq_to_irq(rk8xx->irq_chip, RK8XX_IRQ_PWRON_FALL);
  12. if (fall_irq < 0) {
  13. printf("Failed to register pwron fall irq, ret=%d\n", fall_irq);
  14. return fall_irq;
  15. }
  16. rise_irq = virq_to_irq(rk8xx->irq_chip, RK8XX_IRQ_PWRON_RISE);
  17. if (rise_irq < 0) {
  18. printf("Failed to register pwron rise irq, ret=%d\n", rise_irq);
  19. return rise_irq;
  20. }
  21. key->name = "rk8xx_pwr";
  22. key->type = GPIO_KEY;
  23. key->code = KEY_POWER;
  24. key->skip_irq_init = 1;
  25. irq_install_handler(fall_irq, rk8xx_pwron_fall_handler, dev);
  26. irq_install_handler(rise_irq, rk8xx_pwron_rise_handler, dev);
  27. // irq_handler_enable(fall_irq);
  28. // irq_handler_enable(rise_irq);
  29. return 0;
  30. }

本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号