itop4412 设备树 HDMI

itop4412 设备树 HDMI

目前进度

  • 2021.5.22

    • 学了设备树驱动半个多月了,因为我只有一块HDMI接口的屏幕,想在这个开发板上显示点图像,我一开始先去看了 Documentation/devicetree/bindings/display/exynos/exynos_hdmi.txt这个目录下面的文档,发现他让添加几个属性,我又去arch/arm/boot/dts/exynos4.dtsi 这个文件夹下面,看到了这个

      hdmi: hdmi@12D00000 {
      		compatible = "samsung,exynos4210-hdmi";
      		reg = <0x12D00000 0x70000>;
      		interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>;
      		clock-names = "hdmi", "sclk_hdmi", "sclk_pixel", "sclk_hdmiphy",
      			"mout_hdmi";
      		clocks = <&clock CLK_HDMI>, <&clock CLK_SCLK_HDMI>,
      			<&clock CLK_SCLK_PIXEL>, <&clock CLK_SCLK_HDMIPHY>,
      			<&clock CLK_MOUT_HDMI>;
      		phy = <&hdmi_i2c_phy>;
      		power-domains = <&pd_tv>;
      		samsung,syscon-phandle = <&pmu_system_controller>;
      		status = "disabled";
      	};
      

      当时想这,难度也没多少啊,我看文档中的属性,这里快包含完了,就非常简单的把status 的状态改成okay,也把phy相关的i2c的状态也修改成为okay,添加了一个 hpd-gpios = <&gpx3 7 1>;这个节点,下载进去,发现报错如下:

      [    1.636613] exynos-hdmi 12d00000.hdmi: 12d00000.hdmi supply vdd not found, using dummy regulator
      [    1.645082] exynos-hdmi 12d00000.hdmi: 12d00000.hdmi supply vdd_osc not found, using dummy regulator
      [    1.654173] exynos-hdmi 12d00000.hdmi: 12d00000.hdmi supply vdd_pll not found, using dummy regulator
      [    1.663288] OF: graph: no port node found in /hdmi@12D00000
      [    1.676701] [drm:exynos_drm_bind] *ERROR* no device found for DMA mapping ope     rations.
      [    1.683591] exynos-drm exynos-drm: master bind failed: -19
      

      我懵逼了,丝毫看不懂…

  • 2021.5.23

    • 第二天来了,我去查了电路图,我看到HDMI的接口用的是I2C0,但是exynos4.dtsi里面用的I2C是I2C8,而且经过电路图分析,我发现他还有个HDMI_IIC_EN,这个引脚,这个引脚貌似为1,I2C才可以通讯,于是我写了简单的设备驱动,把它编译到了内核,就是简单的让这个引脚为高电平。
      在这里插入图片描述

    • 经过我的修改我的设备树配置成这个样子了,我完全模仿i2c_8的功能特写写的,下面那个ddc我随便写的

      &i2c_0 {
      	samsung,i2c-sda-delay = <100>;
      	samsung,i2c-slave-addr = <0x10>;
      	samsung,i2c-max-bus-freq = <400000>;
      	compatible = "samsung,s3c2440-hdmiphy-i2c";
      	clocks = <&clock CLK_I2C_HDMI>;
      	pinctrl-names = "default";
      	pinctrl-0 = <&i2c0_bus>;
       	status = "okay";
      
      	hdmiphy: hdmiphy@38 {
      			compatible = "samsung,exynos4212-hdmiphy";
      			reg = <0x38>;
      	};
      
      	hdmiddc: hdmiddc@50 {
      		compatible = "samsung,exynos4210-hdmiddc";
      		reg = <0x50>;
      	};
      };
      
      &hdmi {
      	ddc = <&hdmiddc>;
      	phy = <&hdmiphy>;
      	hpd-gpios = <&gpx3 7 1>;
      	status = "okay";
      };
      

      结果很明显,还是报错了,跟上次的错误一毛一样,忙活了半天,一点收获都没有,而且这次,我花费的精力挺大的,我把某些错误,在内核中搜索,发现是drivers/gpu/drm/exynos/exynos_drm_drv.c,这个地方报错,就是三星的内核驱动报错,这个错误很麻烦,反正以我目前的实力,肯定不会,我还看不懂啥叫drm,于是我去百度搜了搜drm,结果出来了一大堆,看了几篇,发现头更晕了,可能我太菜了,我一直感觉是ddc那个节点的问题,我又去百度了ddc,在这个https://www.eefocus.com/ayayayaya/blog/16-02/377337_53619.html,博客中我看到了这样一句话:

      DDC 全文为 Display Data Channel,用于 HDMI 设备之间的协议沟通,Exynos4412 内部没有专用的 DDC 控制器,而是采用 I2C 总线完成这部分工作,驱动部分使用 I2C 传输控制命令到显示终端设备。

      我就看到了这一句,也没下文了,下面就是代码的分析。我感到很疑惑,ddc和phy这两个东西都用到了i2c,但是HDMI只有一个I2c接口,我也不知道它们有什么却别,在这个博客里面还有这样一句话:

      SCL,SDA 为 I2C 控制信号,用于 EDID 协议传输,主要用于板卡与 HDMI 显示设备之间进行协商,比如查询 HDMI 显示设备支持的最大分辨率,板卡设置 HDMI 输出分辨率等等均通过 I2C 总线传输,fs4412 开发平台采用 I2C0 传输 EDID。 I2C 作为 HDMI 的 DDC 通道,用于设备之间的沟通。
      我很想知道他说的这个是不是指向的同一个i2c控制器,对此我又去百度了 EDID和DDC之间的关系。

      DDC是数据显示的通道(采用I2C协议),EDID是DDC通讯显示的信息。

      那么让我疑惑的是 hdmiphy它包含的是啥?文档中也没有细说

  • 2021.5.24

    • 又过了一天,昨晚睡的格外不好,我又去看了看,那报错的信息,我尝试先去解决一两个报错,我把vdd_osc这关键字放进Linux内核中搜索,发现了巨大的猫腻,我在arch/arm/boot/dts/exynos4412-odroid-common.dtsi这个设备树文件下面,看到了这样的节点,我马上仿造它修改。

      &hdmi {
      	hpd-gpios = <&gpx3 7 GPIO_ACTIVE_HIGH>;
      	pinctrl-names = "default";
      	pinctrl-0 = <&hdmi_hpd>;
      	vdd-supply = <&ldo8_reg>;
      	vdd_osc-supply = <&ldo10_reg>;
      	vdd_pll-supply = <&ldo8_reg>;
      	ddc = <&i2c_2>;
      	status = "okay";
      };
      

      我兴奋极了,我以为我快要让我的HDMI屏幕点亮了呢,发现错误只少了三行.

      [    1.663288] OF: graph: no port node found in /hdmi@12D00000
      [    1.676701] [drm:exynos_drm_bind] *ERROR* no device found for DMA mapping ope     rations.
      [    1.683591] exynos-drm exynos-drm: master bind failed: -19
      

      从这个地方可以看到报错,就是没找到设备节点,我感觉还是我ddc节点,配置的不对,刚刚在想,ddc是通过i2c协议,跟设备通信交换数据,

      那么分辨率,厂家的信息,存在哪? 存在屏幕里面 还是自己写个,通过i2c协议,传输过去。

      假如数据是存在屏幕里面,那么ddc必然是挂载在i2c_0节点下面,可是我看上面那个设备树文件,它的ddc和phy不在一个i2c设备下,也就是可以说,它不是存在屏幕里面的??????啊啊啊啊,快被这搞疯了。

    • 2021.5.25

    哎,搞清楚了ddc,他就挂载在i2c0的节点下面,我TM板子坏了,电源不知道是不是抽风了?我一开始发现板子不亮了,电源指示灯也灭了,我以为是板子坏了,后来发现是充电器坏了,还发烫,后来借了个电源,指示灯亮了起来,但是核心板有滋滋滋的电流声,估计是核心板废了,我感觉是电压过高,击穿了核心板,真的是RTM,我的大洋啊…………………。
    这HDMI也没整出来,损失个板子。我TM裂开。
    完结。

  • 2021.5.28

    虚惊一场,,,,继续搞,换了根电源线,板子又好了,接着搞。。。。

    对报错的信息进行分析:

    • OF: graph: no port node found in /hdmi@12D00000
       这句话具体在drivers/gpu/drm/exynos/exynos_hdmi.c这个文件里面,
        static int hdmi_bridge_init(struct hdmi_context *hdata)在整函数里面,但是这个它返回为0,也就是可以默认他对。
      
      ERROR* no device found for DMA mapping ope     rations.
      

      这个报错,在drivers/gpu/drm/exynos/exynos_drm_drv.c这个目录下,

      /* the first real CRTC device is used for all dma mapping operations */
      	private->dma_dev = exynos_drm_get_dma_device();
      	if (!private->dma_dev) {
      		DRM_ERROR("no device found for DMA mapping operations.\n");
      		ret = -ENODEV;
      		goto err_free_private;
      	}
      

      可以看到他是去得到dma设备,他没有得到dma设备,那我们进去它的源码看看

      static struct exynos_drm_driver_info exynos_drm_drivers[] = {
      	{
      		DRV_PTR(fimd_driver, CONFIG_DRM_EXYNOS_FIMD),
      		DRM_COMPONENT_DRIVER | DRM_DMA_DEVICE
      	},
          ...
          {
      		DRV_PTR(mixer_driver, CONFIG_DRM_EXYNOS_MIXER),
      		DRM_COMPONENT_DRIVER | DRM_DMA_DEVICE
      	}
          ...
          {
      		DRV_PTR(hdmi_driver, CONFIG_DRM_EXYNOS_HDMI),
      		DRM_COMPONENT_DRIVER
      	}
          ...
      };
      
      static struct device *exynos_drm_get_dma_device(void)
      {
      	int i;
      
          // 循环15次 遍历exynos_drm_drivers 这个数组,这个数组中装的是exynos的各种驱动,
          // 这个数组我把部分数据放到上面了。
          // 可以看到每个数组第二行,他是一个flag,表示他是不是DMA设备,
      	for (i = 0; i < ARRAY_SIZE(exynos_drm_drivers); ++i) {
      		struct exynos_drm_driver_info *info = &exynos_drm_drivers[i];
      		struct device *dev;
      
      		if (!info->driver || !(info->flags & DRM_DMA_DEVICE))
      			continue;
      
      		while ((dev = bus_find_device(&platform_bus_type, NULL,
      					    &info->driver->driver,
      					    (void *)platform_bus_type.match))) {
      			put_device(dev);
      			return dev;
      		}
      	}
      	return NULL;
      }
      

      看到这,我想他这个不是玩人呢? HDMI没有 DRM_DMA_DEVICE这个宏定义,于是我手动在HDMI这个后面或了个DRM_DMA_DEVICE,结果烧录进去,又报错了,时间太晚了,今天先到这。

  • 2021.5.29

    昨晚回去又想了想,总感觉那个地方不对,三星的驱动框架肯定没问题,我去看了看Kconfig这个文件

    config DRM_EXYNOS_HDMI
    	bool "HDMI"
    	depends on DRM_EXYNOS_MIXER || DRM_EXYNOS5433_DECON
    	select CEC_CORE if CEC_NOTIFIER
    	help
    	  Choose this option if you want to use Exynos HDMI for DRM.
    

    我发现了,使能HDMI,要打开 DRM_EXYNOS_MIXER这个宏定义,那么使能这个宏,就肯定是HDMI要用上,那么它对应的驱动文件肯定会被HDMi加载,我在这个exynos_mixer.c中搜索了dma,果然里面有dma的适配器,那我岂不是在设备树中把它的状态设置为"okay",岂不是被加载进去了,我抱着试一试的心态,果然被加载成功了,屏幕上出现了那只小企鹅,就是分辨率有问题,我在想办法调教调教。。。

在这里插入图片描述

这几天被HDMI,这个屏幕折磨的死死的,现在终于解脱了,我搜索了好多文章,发现都没有关于4.x版本支持HDMI的博客,去都是3.0版本的,讯为官方也没支持,好在自己终于搞好了。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值