【精选】全志D1/D1s芯片:芒果派麻雀点RGB屏填坑 | 您所在的位置:网站首页 › 瓜瓜在线填坑 › 【精选】全志D1/D1s芯片:芒果派麻雀点RGB屏填坑 |
前言
最近全志推出了D1处理器,搭载平头哥玄铁906 RISC-V的应用处理器。于是准备入手玩一下,买了芒果派做了基于D1s的麻雀板,D1s是D1内封64M DDR的版本,去掉了hdmi输出,号称点屏强芯,点个屏来玩玩。 先晒下小巧精致的麻雀: 手上正好有块480*272的rgb屏,可以用这个小板子来点一下。想来rgb屏幕应该很好适配,dts里改几个参数就完事了,不过多次调整怎么也没法让画面正常输出,这个问题应该有不少人遇到。先直入主题说一下如何修复问题吧,后面在详细记录填坑过程。 快速上手体验我修复的代码patch在这里 https://download.csdn.net/download/qq_34440409/66654101,下载下来后分别到kernel uboot 里打上patch即可。 然后屏幕参数DTS里根据自己的屏参配置下,可以参考我的配置,主要是以下几个参数: /* part 3 */ lcd_width = ; /* 随便写 */ lcd_height = ;/* 随便写 */ lcd_x = ; lcd_y = ; lcd_dclk_freq = ; lcd_hbp = ; lcd_ht = ; lcd_hspw = ; lcd_vbp = ; lcd_vt = ; lcd_vspw = ;另外屏幕起来后加载到kernel启动会明显感觉到颜色发生了变化,在kernel 的DTS里找到dmic,并关闭 &dmic { pinctrl-names = "default","sleep"; pinctrl-0 = ; pinctrl-1 = ; status = "disable"; };这个据网友反馈是屏引脚占用导致。 详细填坑过程记录 1.关闭uboot logo显示为了方便调试我们先针对内核修改,把uboot点屏给他关了。 打开文件 D1\lichee\brandy-2.0\u-boot-2018\configs\sun20iw1p1_defconfig 搜索 CONFIG_DISP2_SUNXI 并注释。重新编译烧录就不会在显示uboot logo了 2.确定屏参点RGB屏一般就是配一下几个参数的事,这些参数屏手册一般都会给出来,例如我的屏参手册 还剩下lcd_hspw,lcd_vspw hspw (HSYNC plus width)行同步脉宽 单位:像素时钟周期 vspw (VSYNC width)垂直同步脉宽 单位:显示一行的时间th 以水平方向为例说一下几个参数的关系: ht = h显示区域像素 + hbp + hfb + hspw 525 = 480 + 40 + 5 + 0 由此可以确定hspw与vspw 两项的值为0,按经验来说 spw这项一般不需要额外关注。 3.查看LCD显示调试信息但我照着手册填好后点屏画面总是糊的,调整一番参数多次尝试无果,确定参数应该是没有问题的,那只能翻手册查看调试信息排坑了。 关于D1/D1s芯片资料可以在这里获取https://whycan.com/t_6440.html 查看lcd调试指南,我们可以通过 cat /sys/class/disp/disp/attr/sys查看显示信息 查看显示信息 查看下lcd相关的时钟 cat /sys/kernel/debug/clk/clk_summary cat /sys/kernel/debug/clk/clk_summary | grep tcon
既然猜到了dclk有问题,那么可以去查下寄存器手册找到该值的地址,确定下问题。 最终查到的dclk寄存器描述如下: 把我们的设备烧录回480 * 272的DTS配置,写寄存器 devmem 0x05461044 32 0xF0000020 写完后立马看到屏幕显示正常了,确定是这个问题无疑。 DTS设置不生效就要去驱动源码里查问题了。 5.梳理屏幕显示驱动DTS里可知 lcd_driver_name = “default_lcd” 我们可以通过搜索"default_lcd"来找屏驱动文件,找到了drivers/video/fbdev/sunxi/disp2/disp/lcd/default_panel.c,查看文件发现只有上下电时序,初始化序列相关,没有我们需要的,那直接按解析参数来搜索好了。 进入到内核目录,执行 grep -rn "lcd_dclk_freq" 先来看下 lcd_clk_config 函数,时钟配置的代码在这里: lcd_clk_config(...) { ...//省略若干代码 disp_al_lcd_get_clk_info(lcd->hwdev_index, &clk_info, &lcdp->panel_info); dclk_rate = lcdp->panel_info.lcd_dclk_freq * 1000000; /* Mhz -> hz */ if (lcdp->panel_info.lcd_if == LCD_IF_DSI) { lcd_rate = dclk_rate * clk_info.dsi_div; pll_rate = lcd_rate * clk_info.lcd_div; } else { lcd_rate = dclk_rate * clk_info.tcon_div; pll_rate = lcd_rate * clk_info.lcd_div; } ... dclk_rate_set = lcd_rate_set / clk_info.tcon_div; if ((pll_rate_set != pll_rate) || (lcd_rate_set != lcd_rate) || (dclk_rate_set != dclk_rate)) { DE_WRN ("disp %d, clk: pll(%ld),clk(%ld),dclk(%ld) dsi_rate(%ld)\n clk real:pll(%ld),clk(%ld),dclk(%ld) dsi_rate(%ld)\n", lcd->disp, pll_rate, lcd_rate, dclk_rate, dsi_rate, pll_rate_set, lcd_rate_set, dclk_rate_set, dsi_rate_set); } return 0; }dclk_rate 就是我们DTS传入的9Mhz参数,通过该值计算得到两个时钟 lcd_rate 与 pll_rate ,根据代码可以得知 pll_rate = lcd_rate = dclk_rate * tcon_div; pll_rate、 lcd_rate、 dclk_rate 这些都是我们根据DTS得到的值,实际设置值为 pll_rate_set、 lcd_rate_set、dclk_rate_set。这个函数末尾已经加了打印,当计算值与实际设置值不一致时就会打印,查看下启动打印有没有: 查看打印: 这里我们就懒得再去追查pll_rate设置不生效原因了,我们先假设pll_rate最小值为288M或者他只能设置为288M。 然后找到DCLK_DIV设置的地方,去修改。 通过上面代码分析可以知道pll_rate 与 dclk_rate 的关系: pll_rate = lcd_rate = dclk_rate * tcon_div 那么这个tcon_div应当就是DCLK_DIV了 tcon_div的值来自函数disp_al_lcd_get_clk_info 搜索这个函数,找到源码: 从这里就知道了tcon_div值来自clk_tbl[]中,默认为6,这与我们之前寄存器查看得到值是对得上的。 6.动手修改上面已经找到了tcon_div值设置的位置,就在这下面添加代码好了 if(panel->lcd_dclk_freq lcd_dclk_freq >= 3){ tcon_div = 288/panel->lcd_dclk_freq; }意思是当DTS中设置的dclk在3到48M之间时自动计算tcon_div的值,要满足tcon_div小于128。 kernel修改完毕后编译测试显示正常,来看下显示调试信息 Uboot的修改也是同样的道理,UBoot显示驱动代码路径在D1\lichee\brandy-2.0\u-boot-2018\drivers\video\sunxi\disp2\disp\de\ 完成最后晒一下屏幕显示结果 |
CopyRight 2018-2019 实验室设备网 版权所有 |