HDIM调试之模块初始化顺序

模块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] ===&gt;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] ===&gt;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] ===&gt;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] ===&gt;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] ===&gt;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] ===&gt;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初始化顺序正常了。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值