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版本的,讯为官方也没支持,好在自己终于搞好了。