模块hdmi依赖模块disp,初始化过程中hdmi模块先于disp模块完成初始化,导致hdmi初始化失败。

- 猜想1:是否是模块初始化优先级设置问题,查看两个模块的初始化优先级:
drivers/video/fbdev/sunxi/disp2/hdmi2/hdmi_tx.c
late_initcall(hdmi_module_init);
module_exit(hdmi_module_exit);
drivers/video/fbdev/sunxi/disp2/disp/dev_disp.c
module_init(disp_module_init);
module_exit(disp_module_exit);
结论:从两个模块初始化代码可以看出hdmi使用late_initcall,初始化顺序应该在disp模块之后,所以初始化代码没问题。
猜想2:disp模块依赖某个模块,这个模块初始化靠后。打开disp调试信息:
==[ 1.572214] [DISP]disp_module_init
[ 1.580377] [DISP]disp_module_init finish==
[ 1.764033] sunxi_sid_init()784 - insmod ok
[ 2.867478] Serial: 8250/16550 driver, 4 ports, IRQ sharing disabled
[ 2.944259] [drm] radeon kernel modesetting enabled.
....
[ 3.440915] sit: IPv6, IPv4 and MPLS over IPv4 tunneling driver
[ 3.452526] NET: Registered protocol family 17
[ 3.456787] 9pnet: Installing 9P2000 support
[ 3.459837] Key type dns_resolver registered
[ 3.470616] debug_vm_pgtable: [debug_vm_pgtable ]: Validating architecture page table helpers
==[ 3.485199] HDMI 2.0 driver init start!
[ 3.486005] boot_hdmi=false
[ 3.486719] ERROR: pinctrl_get for HDMI2.0 DDC fail
[ 3.490211] [DISP] disp_hdmi_get_priv,line:77:
[ 3.490308] NULL hdl!
[ 3.490473] can NOT get hdmis!
[ 3.492913] NO hdmi funcs to registered!!!
[ 3.496238] HDMI2.0 module init end==
[ 3.805141] sun4i-usb-phy 4100400.phy: Couldn't request ID GPIO
==[ 3.975644] sun20i-d1-pinctrl 2000000.pinctrl: initialized sunXi PIO driver==
==[ 3.981266] disp 5000000.disp: Adding to iommu group 0
[ 3.992007] [DISP] disp_sys_script_get_item,line:205:==
[ 3.992108] of_find_compatible_node allwinner,sunxi-lcd0 fail
查看高亮部分日志,disp初始化优先于hdmi,但probe函数探测靠后了,查看日志“[ 3.975644] sun20i-d1-pinctrl 2000000.pinctrl: initialized sunXi PIO driver”是在drivers/pinctrl/sunxi/pinctrl-sunxi.c文件中,pinctrl添加打印日志,查看pinctrl模块初始化日志:
==[ 0.944004] ===>sun20i_d1_pinctrl_probe(909)==
[ 1.156035] NET: Registered protocol family 2
[ 1.159434] IP idents hash table entries: 8192 (order: 4, 65536 bytes, linear)
.....
[ 3.490956] HDMI 2.0 driver init start!
[ 3.491194] boot_hdmi=false
[ 3.491859] ERROR: pinctrl_get for HDMI2.0 DDC fail
[ 3.495990] [DISP] disp_hdmi_get_priv,line:77:
[ 3.496083] NULL hdl!
[ 3.496255] can NOT get hdmis!
[ 3.499055] NO hdmi funcs to registered!!!
[ 3.502233] HDMI2.0 module init end
==[ 3.814548] ===>sun20i_d1_pinctrl_probe(909)
[ 3.978943] sun20i-d1-pinctrl 2000000.pinctrl: initialized sunXi PIO driver==
从log可以看出pinctrl probe两次,第一次没有成功,第二次成功但是比较靠后。查看pinctrl probe函数调用,sun20i_d1_pinctrl_probe-->sunxi_pinctrl_init-->sunxi_pinctrl_init_with_variant;给sunxi_pinctrl_init_with_variant函数体添加打印信息,看到那一步失败:
int sunxi_pinctrl_init_with_variant(struct platform_device *pdev,
const struct sunxi_pinctrl_desc *desc,
unsigned long variant)
{
struct device_node *node = pdev->dev.of_node;
struct pinctrl_desc *pctrl_desc;
struct pinctrl_pin_desc *pins;
struct sunxi_pinctrl *pctl;
struct pinmux_ops *pmxops;
int i, ret, last_pin, pin_idx;
struct clk *clk;
printk("===>%s(%d)\n", __func__, __LINE__);
pctl = devm_kzalloc(&pdev->dev, sizeof(*pctl), GFP_KERNEL);
if (!pctl)
return -ENOMEM;
platform_set_drvdata(pdev, pctl);
printk("===>%s(%d)\n", __func__, __LINE__);
raw_spin_lock_init(&pctl->lock);
printk("===>%s(%d)\n", __func__, __LINE__);
pctl->membase = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(pctl->membase))
return PTR_ERR(pctl->membase);
printk("===>%s(%d)\n", __func__, __LINE__);
pctl->dev = &pdev->dev;
pctl->desc = desc;
pctl->variant = variant;
printk("===>%s(%d)\n", __func__, __LINE__);
pctl->irq_array = devm_kcalloc(&pdev->dev,
IRQ_PER_BANK * pctl->desc->irq_banks,
sizeof(*pctl->irq_array),
GFP_KERNEL);
if (!pctl->irq_array)
return -ENOMEM;
printk("===>%s(%d)\n", __func__, __LINE__);
ret = sunxi_pinctrl_build_state(pdev);
if (ret) {
dev_err(&pdev->dev, "dt probe failed: %d\n", ret);
return ret;
}
printk("===>%s(%d)\n", __func__, __LINE__);
pins = devm_kcalloc(&pdev->dev,
pctl->desc->npins, sizeof(*pins),
GFP_KERNEL);
if (!pins)
return -ENOMEM;
printk("===>%s(%d)\n", __func__, __LINE__);
for (i = 0, pin_idx = 0; i < pctl->desc->npins; i++) {
const struct sunxi_desc_pin *pin = pctl->desc->pins + i;
if (pin->variant && !(pctl->variant & pin->variant))
continue;
pins[pin_idx++] = pin->pin;
}
printk("===>%s(%d)\n", __func__, __LINE__);
pctrl_desc = devm_kzalloc(&pdev->dev,
sizeof(*pctrl_desc),
GFP_KERNEL);
if (!pctrl_desc)
return -ENOMEM;
printk("===>%s(%d)\n", __func__, __LINE__);
pctrl_desc->name = dev_name(&pdev->dev);
pctrl_desc->owner = THIS_MODULE;
pctrl_desc->pins = pins;
pctrl_desc->npins = pctl->ngroups;
pctrl_desc->confops = &sunxi_pconf_ops;
pctrl_desc->pctlops = &sunxi_pctrl_ops;
pmxops = devm_kmemdup(&pdev->dev, &sunxi_pmx_ops, sizeof(sunxi_pmx_ops),
GFP_KERNEL);
if (!pmxops)
return -ENOMEM;
printk("===>%s(%d)\n", __func__, __LINE__);
if (desc->disable_strict_mode)
pmxops->strict = false;
printk("===>%s(%d)\n", __func__, __LINE__);
pctrl_desc->pmxops = pmxops;
pctl->pctl_dev = devm_pinctrl_register(&pdev->dev, pctrl_desc, pctl);
if (IS_ERR(pctl->pctl_dev)) {
dev_err(&pdev->dev, "couldn't register pinctrl driver\n");
return PTR_ERR(pctl->pctl_dev);
}
printk("===>%s(%d)\n", __func__, __LINE__);
pctl->chip = devm_kzalloc(&pdev->dev, sizeof(*pctl->chip), GFP_KERNEL);
if (!pctl->chip)
return -ENOMEM;
last_pin = pctl->desc->pins[pctl->desc->npins - 1].pin.number;
pctl->chip->owner = THIS_MODULE;
pctl->chip->request = gpiochip_generic_request;
pctl->chip->free = gpiochip_generic_free;
pctl->chip->set_config = gpiochip_generic_config;
pctl->chip->direction_input = sunxi_pinctrl_gpio_direction_input;
pctl->chip->direction_output = sunxi_pinctrl_gpio_direction_output;
pctl->chip->get = sunxi_pinctrl_gpio_get;
pctl->chip->set = sunxi_pinctrl_gpio_set;
pctl->chip->of_xlate = sunxi_pinctrl_gpio_of_xlate;
pctl->chip->to_irq = sunxi_pinctrl_gpio_to_irq;
pctl->chip->of_gpio_n_cells = 3;
pctl->chip->can_sleep = false;
pctl->chip->ngpio = round_up(last_pin, PINS_PER_BANK) -
pctl->desc->pin_base;
pctl->chip->label = dev_name(&pdev->dev);
pctl->chip->parent = &pdev->dev;
pctl->chip->base = pctl->desc->pin_base;
printk("===>%s(%d)\n", __func__, __LINE__);
ret = gpiochip_add_data(pctl->chip, pctl);
if (ret)
return ret;
printk("===>%s(%d)\n", __func__, __LINE__);
for (i = 0; i < pctl->desc->npins; i++) {
const struct sunxi_desc_pin *pin = pctl->desc->pins + i;
ret = gpiochip_add_pin_range(pctl->chip, dev_name(&pdev->dev),
pin->pin.number - pctl->desc->pin_base,
pin->pin.number, 1);
if (ret)
goto gpiochip_error;
}
printk("===>%s(%d)\n", __func__, __LINE__);
ret = of_clk_get_parent_count(node);
clk = devm_clk_get(&pdev->dev, ret == 1 ? NULL : "apb");
if (IS_ERR(clk)) {
ret = PTR_ERR(clk);
goto gpiochip_error;
}
printk("===>%s(%d)\n", __func__, __LINE__);
ret = clk_prepare_enable(clk);
if (ret)
goto gpiochip_error;
printk("===>%s(%d)\n", __func__, __LINE__);
pctl->irq = devm_kcalloc(&pdev->dev,
pctl->desc->irq_banks,
sizeof(*pctl->irq),
GFP_KERNEL);
if (!pctl->irq) {
ret = -ENOMEM;
goto clk_error;
}
printk("===>%s(%d)\n", __func__, __LINE__);
for (i = 0; i < pctl->desc->irq_banks; i++) {
pctl->irq[i] = platform_get_irq(pdev, i);
if (pctl->irq[i] < 0) {
ret = pctl->irq[i];
goto clk_error;
}
}
printk("===>%s(%d)\n", __func__, __LINE__);
pctl->domain = irq_domain_add_linear(node,
pctl->desc->irq_banks * IRQ_PER_BANK,
&sunxi_pinctrl_irq_domain_ops,
pctl);
if (!pctl->domain) {
dev_err(&pdev->dev, "Couldn't register IRQ domain\n");
ret = -ENOMEM;
goto clk_error;
}
printk("===>%s(%d)\n", __func__, __LINE__);
for (i = 0; i < (pctl->desc->irq_banks * IRQ_PER_BANK); i++) {
int irqno = irq_create_mapping(pctl->domain, i);
irq_set_lockdep_class(irqno, &sunxi_pinctrl_irq_lock_class,
&sunxi_pinctrl_irq_request_class);
irq_set_chip_and_handler(irqno, &sunxi_pinctrl_edge_irq_chip,
handle_edge_irq);
irq_set_chip_data(irqno, pctl);
}
printk("===>%s(%d)\n", __func__, __LINE__);
for (i = 0; i < pctl->desc->irq_banks; i++) {
/* Mask and clear all IRQs before registering a handler */
writel(0, pctl->membase +
sunxi_irq_ctrl_reg_from_bank(pctl->desc, i));
writel(0xffffffff,
pctl->membase +
sunxi_irq_status_reg_from_bank(pctl->desc, i));
irq_set_chained_handler_and_data(pctl->irq[i],
sunxi_pinctrl_irq_handler,
pctl);
}
printk("===>%s(%d)\n", __func__, __LINE__);
sunxi_pinctrl_setup_debounce(pctl, node);
printk("===>%s(%d)\n", __func__, __LINE__);
dev_info(&pdev->dev, "initialized sunXi PIO driver\n");
return 0;
clk_error:
clk_disable_unprepare(clk);
gpiochip_error:
gpiochip_remove(pctl->chip);
return ret;
}
查看系统启动日志:
[ 0.947039] ===>sun20i_d1_pio_init(930)
[ 0.948589] ===>sun20i_d1_pinctrl_probe(909)
[ 0.948772] ===>sunxi_pinctrl_init_with_variant(1414)
[ 0.949468] ===>sunxi_pinctrl_init_with_variant(1419)
[ 0.949598] ===>sunxi_pinctrl_init_with_variant(1421)
[ 0.949953] ===>sunxi_pinctrl_init_with_variant(1425)
[ 0.950082] ===>sunxi_pinctrl_init_with_variant(1429)
[ 0.950231] ===>sunxi_pinctrl_init_with_variant(1436)
[ 0.970564] ===>sunxi_pinctrl_init_with_variant(1442)
[ 0.970774] ===>sunxi_pinctrl_init_with_variant(1448)
[ 0.970975] ===>sunxi_pinctrl_init_with_variant(1457)
[ 0.971115] ===>sunxi_pinctrl_init_with_variant(1463)
[ 0.971261] ===>sunxi_pinctrl_init_with_variant(1475)
[ 0.971374] ===>sunxi_pinctrl_init_with_variant(1478)
[ 0.974509] ===>sunxi_pinctrl_init_with_variant(1486)
[ 0.974739] ===>sunxi_pinctrl_init_with_variant(1509)
[ 0.982499] ===>sunxi_pinctrl_init_with_variant(1513)
==[ 0.984683] ===>sunxi_pinctrl_init_with_variant(1523)==
[ 1.171994] NET: Registered protocol family 2
[ 1.175479] IP idents hash table entries: 8192 (order: 4, 65536 bytes, linear)
....
[ 3.502102] debug_vm_pgtable: [debug_vm_pgtable ]: Validating architecture page table helpers
[ 3.515873] HDMI 2.0 driver init start!
[ 3.516115] boot_hdmi=false
[ 3.517354] ERROR: pinctrl_get for HDMI2.0 DDC fail
[ 3.521357] [DISP] disp_hdmi_get_priv,line:77:
[ 3.521451] NULL hdl!
[ 3.521619] can NOT get hdmis!
[ 3.524069] NO hdmi funcs to registered!!!
[ 3.527515] HDMI2.0 module init end
[ 3.830809] ===>sun20i_d1_pinctrl_probe(909)
[ 3.830992] ===>sunxi_pinctrl_init_with_variant(1414)
[ 3.831160] ===>sunxi_pinctrl_init_with_variant(1419)
[ 3.831283] ===>sunxi_pinctrl_init_with_variant(1421)
[ 3.831637] ===>sunxi_pinctrl_init_with_variant(1425)
[ 3.831765] ===>sunxi_pinctrl_init_with_variant(1429)
[ 3.831916] ===>sunxi_pinctrl_init_with_variant(1436)
[ 3.852166] ===>sunxi_pinctrl_init_with_variant(1442)
[ 3.852383] ===>sunxi_pinctrl_init_with_variant(1448)
[ 3.852589] ===>sunxi_pinctrl_init_with_variant(1457)
[ 3.852744] ===>sunxi_pinctrl_init_with_variant(1463)
[ 3.853344] ===>sunxi_pinctrl_init_with_variant(1475)
[ 3.853466] ===>sunxi_pinctrl_init_with_variant(1478)
[ 3.855906] ===>sunxi_pinctrl_init_with_variant(1486)
[ 3.856110] ===>sunxi_pinctrl_init_with_variant(1509)
[ 3.864442] ===>sunxi_pinctrl_init_with_variant(1513)
[ 3.867229] ===>sunxi_pinctrl_init_with_variant(1523)
[ 3.867650] ===>sunxi_pinctrl_init_with_variant(1530)
[ 3.867801] ===>sunxi_pinctrl_init_with_variant(1534)
[ 3.867940] ===>sunxi_pinctrl_init_with_variant(1543)
[ 3.869405] ===>sunxi_pinctrl_init_with_variant(1551)
[ 3.869785] ===>sunxi_pinctrl_init_with_variant(1561)
[ 4.003831] ===>sunxi_pinctrl_init_with_variant(1571)
[ 4.004314] ===>sunxi_pinctrl_init_with_variant(1584)
[ 4.004555] ===>sunxi_pinctrl_init_with_variant(1586)
[ 4.004759] sun20i-d1-pinctrl 2000000.pinctrl: initialized sunXi PIO driver
第一次调用sunxi_pinctrl_init_with_variant函数代码走到clk = devm_clk_get(&pdev->dev, ret == 1 ? NULL : "apb");处出错返回,这里是解析设备树获取pinctrl apb时钟,查看设备节点:
pio: pinctrl@2000000 {
compatible = "allwinner,sun20i-d1-pinctrl";
reg = <0x0 0x02000000 0x0 0x500>;
interrupts-extended = <&intc 85 IRQ_TYPE_LEVEL_HIGH>,
<&intc 87 IRQ_TYPE_LEVEL_HIGH>,
<&intc 89 IRQ_TYPE_LEVEL_HIGH>,
<&intc 91 IRQ_TYPE_LEVEL_HIGH>,
<&intc 93 IRQ_TYPE_LEVEL_HIGH>,
<&intc 95 IRQ_TYPE_LEVEL_HIGH>;
device_type = "pio";
clocks = <&ccu CLK_APB0>, <&dcxo24M>;
clock-names = "apb", "hosc";
gpio-controller;
#gpio-cells = <3>;
interrupt-controller;
#interrupt-cells = <3>;
#size-cells = <0>;
uart0_pins: uart0@0 {
pins = "PB8", "PB9";
function = "uart0";
};
mmc0_pins: mmc0@0 {
pins = "PF0", "PF1", "PF2",
"PF3", "PF4", "PF5";
function = "sdc0";
drive-strength = <40>;
bias-pull-up;
power-source = <3300>;
};
/omit-if-no-ref/
uart1_pg6_pins: uart1-pg6-pins {
pins = "PG6", "PG7";
function = "uart1";
};
};
apb对应ccu节点
ccu: clock@2001000 {
compatible = "allwinner,sun20i-d1-ccu";
reg = <0x0 0x02001000 0x0 0x1000>;
clocks = <&dcxo24M>, <&osc32k>, <&iosc>;
clock-names = "hosc", "losc", "iosc";
#clock-cells = <1>;
#reset-cells = <1>;
};
查看ccu初始化情况,drivers/clk/sunxi-ng/ccu-sun20i-d1.c文件中sun20i_d1_ccu_probe函数添加打印信息:
static int sun20i_d1_ccu_probe(struct platform_device *pdev)
{
void __iomem *reg;
u32 val;
int i, ret;
printk("===>%s(%d)\n", __func__, __LINE__);
reg = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(reg))
return PTR_ERR(reg);
/* Enable the lock bits on all PLLs */
for (i = 0; i < ARRAY_SIZE(sun20i_d1_pll_regs); i++) {
val = readl(reg + sun20i_d1_pll_regs[i]);
val |= BIT(29);
writel(val, reg + sun20i_d1_pll_regs[i]);
}
/*
* Force the output divider of video PLLs to 0.
*
* See the comment before pll-video0 definition for the reason.
*/
for (i = 0; i < ARRAY_SIZE(sun20i_d1_pll_video_regs); i++) {
val = readl(reg + sun20i_d1_pll_video_regs[i]);
val &= ~BIT(0);
writel(val, reg + sun20i_d1_pll_video_regs[i]);
}
/* Enforce m1 = 0, m0 = 1 for Audio0 PLL */
val = readl(reg + SUN20I_D1_PLL_AUDIO0_REG);
val &= ~BIT(1);
val |= BIT(0);
writel(val, reg + SUN20I_D1_PLL_AUDIO0_REG);
/*
* Force OHCI 12M clock sources to 00 (12MHz divided from 48MHz)
*
* This clock mux is still mysterious, and the code just enforces
* it to have a valid clock parent.
*/
for (i = 0; i < ARRAY_SIZE(sun20i_d1_usb2_clk_regs); i++) {
val = readl(reg + sun20i_d1_usb2_clk_regs[i]);
val &= ~GENMASK(25, 24);
writel(val, reg + sun20i_d1_usb2_clk_regs[i]);
}
ret = sunxi_ccu_probe(pdev->dev.of_node, reg, &sun20i_d1_ccu_desc);
if (ret)
return ret;
/* Gate then ungate PLL CPU after any rate changes */
ccu_pll_notifier_register(&sun20i_d1_pll_cpu_nb);
/* riscv:Reparent CPU during PLL CPU rate changes */
ccu_mux_notifier_register(pll_cpux_clk.common.hw.clk,
&sun20i_d1_cpu_nb);
return 0;
}
查看日志:
[ 0.943796] ===>sun20i_d1_pio_init(930)
[ 0.945322] ===>sun20i_d1_pinctrl_probe(909)
[ 0.945472] ===>sunxi_pinctrl_init_with_variant(1414)
[ 0.945626] ===>sunxi_pinctrl_init_with_variant(1419)
[ 0.945742] ===>sunxi_pinctrl_init_with_variant(1421)
[ 0.946571] ===>sunxi_pinctrl_init_with_variant(1425)
[ 0.946737] ===>sunxi_pinctrl_init_with_variant(1429)
[ 0.946881] ===>sunxi_pinctrl_init_with_variant(1436)
[ 0.967251] ===>sunxi_pinctrl_init_with_variant(1442)
[ 0.967469] ===>sunxi_pinctrl_init_with_variant(1448)
[ 0.967664] ===>sunxi_pinctrl_init_with_variant(1457)
[ 0.967792] ===>sunxi_pinctrl_init_with_variant(1463)
[ 0.967929] ===>sunxi_pinctrl_init_with_variant(1475)
[ 0.968039] ===>sunxi_pinctrl_init_with_variant(1478)
[ 0.971195] ===>sunxi_pinctrl_init_with_variant(1486)
[ 0.971418] ===>sunxi_pinctrl_init_with_variant(1509)
[ 0.979272] ===>sunxi_pinctrl_init_with_variant(1513)
[ 0.981350] ===>sunxi_pinctrl_init_with_variant(1523)
[ 1.170984] NET: Registered protocol family 2
....
[ 1.583169] [DISP]disp_module_init
[ 1.591132] [DISP]disp_module_init finish
==[ 1.600632] ===>sun20i_d1_ccu_probe(1107)==
[ 1.774039] sunxi_sid_init()784 - insmod ok
.....
[ 3.522671] boot_hdmi=false
[ 3.523429] ERROR: pinctrl_get for HDMI2.0 DDC fail
[ 3.526980] [DISP] disp_hdmi_get_priv,line:77:
[ 3.527064] NULL hdl!
[ 3.527230] can NOT get hdmis!
[ 3.529712] NO hdmi funcs to registered!!!
[ 3.533016] HDMI2.0 module init end
[ 3.835122] ===>sun20i_d1_pinctrl_probe(909)
[ 3.835298] ===>sunxi_pinctrl_init_with_variant(1414)
[ 3.835459] ===>sunxi_pinctrl_init_with_variant(1419)
[ 3.835574] ===>sunxi_pinctrl_init_with_variant(1421)
[ 3.835927] ===>sunxi_pinctrl_init_with_variant(1425)
[ 3.836053] ===>sunxi_pinctrl_init_with_variant(1429)
[ 3.836192] ===>sunxi_pinctrl_init_with_variant(1436)
[ 3.856300] ===>sunxi_pinctrl_init_with_variant(1442)
[ 3.856509] ===>sunxi_pinctrl_init_with_variant(1448)
[ 3.856705] ===>sunxi_pinctrl_init_with_variant(1457)
[ 3.856842] ===>sunxi_pinctrl_init_with_variant(1463)
[ 3.856977] ===>sunxi_pinctrl_init_with_variant(1475)
[ 3.857087] ===>sunxi_pinctrl_init_with_variant(1478)
[ 3.859977] ===>sunxi_pinctrl_init_with_variant(1486)
[ 3.860185] ===>sunxi_pinctrl_init_with_variant(1509)
[ 3.868730] ===>sunxi_pinctrl_init_with_variant(1513)
[ 3.871429] ===>sunxi_pinctrl_init_with_variant(1523)
[ 3.871848] ===>sunxi_pinctrl_init_with_variant(1530)
[ 3.872002] ===>sunxi_pinctrl_init_with_variant(1534)
[ 3.872133] ===>sunxi_pinctrl_init_with_variant(1543)
[ 3.872940] ===>sunxi_pinctrl_init_with_variant(1551)
[ 3.873287] ===>sunxi_pinctrl_init_with_variant(1561)
[ 4.008821] ===>sunxi_pinctrl_init_with_variant(1571)
[ 4.009301] ===>sunxi_pinctrl_init_with_variant(1584)
[ 4.009527] ===>sunxi_pinctrl_init_with_variant(1586)
[ 4.009708] sun20i-d1-pinctrl 2000000.pinctrl: initialized sunXi PIO driver
发现在两次pinctrl初始化之间,说明第一次初始化pinctrl时ccu未能及时初始化,需要将ccu初始化提前,修改源码:

使用core_initcall将模块初始化提前,查看日志:
[ 0.211089] thermal_sys: Registered thermal governor 'step_wise'
==[ 0.540515] ===>sun20i_d1_ccu_probe(1107)==
[ 0.895505] iommu: Default domain type: Translated
[ 0.898772] vgaarb: loaded
[ 0.906324] SCSI subsystem initialized
[ 0.917025] usbcore: registered new interface driver usbfs
[ 0.917985] usbcore: registered new interface driver hub
[ 0.919471] usbcore: registered new device driver usb
[ 0.947459] pwm module init!
[ 0.972084] clocksource: Switched to clocksource riscv_clocksource
[ 0.985253] ===>sun20i_d1_pio_init(930)
==[ 0.986626] ===>sun20i_d1_pinctrl_probe(909)==
[ 0.986774] ===>sunxi_pinctrl_init_with_variant(1414)
[ 0.986933] ===>sunxi_pinctrl_init_with_variant(1419)<br/>...<br/>[ 1.697487] io scheduler kyber registered
==[ 1.797712] [DISP]disp_module_init
[ 1.807565] [DISP]disp_module_init finish==
[ 1.960648] sunxi_sid_init()784 - insmod ok<br/>....<br/>[ 30.251629] debug_vm_pgtable: [debug_vm_pgtable ]: Validating architecture page table helpers
[ 30.359325] HDMI 2.0 driver init start!
[ 30.398804] boot_hdmi=false
[ 30.428317] ERROR: pinctrl_get for HDMI2.0 DDC fail
[ 30.481347] [DISP] disp_hdmi_get_priv,line:77:
[ 30.481434] NULL hdl!
[ 30.549246] can NOT get hdmis!
[ 30.585160] NO hdmi funcs to registered!!!
[ 30.630071] HDMI2.0 module init end
[ 30.988653] pcf857x 2-0038: probed
[ 31.025715] sunxi-i2c sunxi-i2c2: probe success
==[ 31.077582] disp 5000000.disp: Adding to iommu group 0==
[ 31.140844] [DISP] disp_sys_script_get_item,line:205:
[ 31.140948] of_find_compatible_node allwinner,sunxi-lcd0 fail
[ 31.266719] display_fb_request,fb_id:0
[ 31.305529] [DISP] display_fb_request,line:2006:
[ 31.305617] invalid paras xres(0), yres(0) bpp(32
发现ccu已经于pinctrl前初始化完成,但是disp仍然滞后,根据日志[ 31.077582] disp 5000000.disp: Adding to iommu group 0猜想iommu初始化靠后,在drivers/iommu/sun50i-iommu.c文件中添加打印信息:
static int sun50i_iommu_probe(struct platform_device *pdev)
{
struct sun50i_iommu *iommu;
int ret, irq;
printk("===>%s(%d)\n", __func__, __LINE__);
iommu = devm_kzalloc(&pdev->dev, sizeof(*iommu), GFP_KERNEL);
if (!iommu)
return -ENOMEM;
spin_lock_init(&iommu->iommu_lock);
platform_set_drvdata(pdev, iommu);
iommu->dev = &pdev->dev;
...
return ret;
}
==[ 1.784840] [DISP]disp_module_init
[ 1.795169] [DISP]disp_module_init finish==
[ 1.944643] sunxi_sid_init()784 - insmod ok
[ 3.049636] Serial: 8250/16550 driver, 4 ports, IRQ sharing disabled
[ 3.080615] printk: console [ttyS0] disabled
[ 3.103687] 2500000.serial: ttyS0 at MMIO 0x2500000 (irq = 1, base_baud = 1500000) is a 16550A
[ 10.181281] printk: console [ttyS0] enabled
[ 10.266159] 2500400.serial: ttyS1 at MMIO 0x2500400 (irq = 2, base_baud = 1500000) is a 16550A
==[ 10.407098] ===>sun50i_iommu_probe(938)==
[ 10.457022] [drm] radeon kernel modesetting enabled.
[ 10.678965] loop: module loaded
iommu_prob初始化靠后,修改源码:

使用subsys_initcall将iommu模块初始化优先级提高,查看日志:
[ 0.215249] thermal_sys: Registered thermal governor 'step_wise'
[ 0.893822] iommu: Default domain type: Translated
==[ 0.895559] ===>sun50i_iommu_probe(938)==
[ 0.910812] vgaarb: loaded
[ 0.917425] SCSI subsystem initialized
[ 0.928631] usbcore: registered new interface driver usbfs<br/>.....
[ 1.690906] io scheduler kyber registered
==[ 1.808119] [DISP]disp_module_init==
[ 1.816834] disp 5000000.disp: Adding to iommu group 0
[ 1.827574] [DISP] disp_sys_script_get_item,line:205:
[ 1.827682] of_find_compatible_node allwinner,sunxi-lcd0 fail
[ 1.835435] display_fb_request,fb_id:0
[ 1.835621] [DISP] display_fb_request,line:2006:
[ 1.835701] invalid paras xres(0), yres(0) bpp(32)
==[ 1.846117] [DISP]disp_module_init finish==
[ 1.994318] sunxi_sid_init()784 - insmod ok
[ 3.101823] Serial: 8250/16550 driver, 4 ports, IRQ sharing disabled<br/>....<br/>==[ 29.510467] HDMI 2.0 driver init start!==
[ 29.550173] boot_hdmi=false
[ 29.579299] ERROR: pinctrl_get for HDMI2.0 DDC fail
==[ 29.642256] HDMI2.0 module init end==
[ 30.010784] pcf857x 2-0038: probed
[ 30.047635] sunxi-i2c sunxi-i2c2: probe success
[ 30.144892] clk: Not disabling unused clocks
[ 30.204456] Waiting for root device /dev/mmcblk0p2...
[ 30.350473] mmc0: host does not support reading read-only switch, assuming write-enable
[ 30.432151] HDMI cable is connected
从日志可以看到,iommu,disp,hdmi初始化顺序正常了。
939

被折叠的 条评论
为什么被折叠?



