firefly-RK3288 Lubuntu 修改分辨率时钟无法正确设置的问题

本帖最后由 Mimosa 于 2016-1-27 02:17 编辑

你好,
我自己有个VGA的显示器,最佳分辨率是1440*900,本来以为直接接上我们的firefly RK3288 在LUbuntu就可以完美工作了,可是发现显示并不完美。这三周泡在firefly的论坛上,也搜索了所有相关分辨率改动的相关文章,都找不到合适的修改方法。因为我想把精力尽快投入到应用开发,这个显示都不对,后续根本没法进行!虽然说多学也有好处,但时间应该在最关键的地方发力。所以,我想请教贵公司的开发人员一些问题,希望尽快解决此问题。
我现在只能确定这么几点:

  1. 我使用的是firefly提供得Lubuntu系统,kernel git log最后的版本是:
    commit b8f71a62dc31c36d0c3563d1bc8537931b69b7aa
    Author: Firefly-RK3288 <service@t-firefly.com>
    Date: Thu Nov 26 14:20:38 2015 +0800

    Kernel->usb:fix usb can not work sometimes
    我接的显示器是VGA得,最佳分辨率是1440*900

  2. 根据论坛提示,先使用fbset查看当前设置:
    root@firefly:/home/firefly# fbset
    mode “1920x1080-48”

    D: 118.807 MHz, H: 54.003 kHz, V: 48.003 Hz

    timings 8417 148 88 36 4 44 5
    geometry 1920 1080 1920 1080 16
    nonstd 4
    rgba 5/11,6/5,5/0,0/0
    endmode
    验证分辨率和颜色位数,时序都不对。于是,我使用fbset修改颜色空间和分辨率
    service lightdm stop
    fbset -a -nonstd 5 -rgba 8/16,8/8,8/0,8/24 -g 1440 900 1440 900 32
    service lightdm start

    nonstd的5对应HAL_PIXEL_FORMAT_BGRA_8888
    // include/linux/rk_fb.h
    enum {

    HAL_PIXEL_FORMAT_RGBA_8888 = 1,

    HAL_PIXEL_FORMAT_RGBX_8888 = 2,

    HAL_PIXEL_FORMAT_RGB_888 = 3,

    HAL_PIXEL_FORMAT_RGB_565 = 4,

    HAL_PIXEL_FORMAT_BGRA_8888 = 5,


    };
    但是,显示发现还是异常,那只剩下最后的问题,时序问题。(使用fbset修改时序是没有用得,下面会提及)

  3. 我的VGA显示器是比较标准的。通过cvt命令可知:
    cvt 1440 900
    # 1440x900 59.89 Hz (CVT 1.30MA) hsync: 55.93 kHz; pclk: 106.50 MHz
    Modeline “1440x900_60.00” 106.50 1440 1528 1672 1904 900 903 909 934 -hsync +vsync
    获得标准的点时钟是: 106.50 MHz。
    然后,我找到drivers/video/rockchip/vga/sda7123_vga.c,sda7123_vga_mode已经添加了1440*900mode了。并且预设的点时钟也106500000也是对的。
    所以,最后其实就剩下timming的设置了。

  4. timming是在drivers/clk/rockchip目录处理的。
    //drivers/clk/rockchip/clk-pll.c文件
    static const struct clk_ops clk_pll_ops_3188plus = {
    .recalc_rate = clk_pll_recalc_rate_3188plus,
    .round_rate = clk_pll_round_rate_3188plus,
    .set_rate = clk_pll_set_rate_3188plus,
    };
    为了clk_pll_round_rate_3188plus函数可能找到对应分辨率的时钟,我在rk3188plus_pll_com_table添加了“852000”这个CLKS
    static const struct pll_clk_set rk3188plus_pll_com_table = {
    _RK3188PLUS_PLL_SET_CLKS(1250000, 12, 625, 1),
    _RK3188PLUS_PLL_SET_CLKS(1200000, 1, 50, 1),
    _RK3188PLUS_PLL_SET_CLKS(1188000, 2, 99, 1),
    _RK3188PLUS_PLL_SET_CLKS(891000, 8, 594, 2),
    //_RK3188PLUS_PLL_SET_CLKS(852000, 4, 284, 2), //1440900,是问别人的,他们公司产品用了这个参数,该VGA分辨率RK3188肯定工作。
    _RK3188PLUS_PLL_SET_CLKS(852000, 1, 71, 2), //1440
    900, 因为(24000*71)/2=852000, 并且852000/106500=8,是整除关系,可以分频
    _RK3188PLUS_PLL_SET_CLKS(768000, 1, 64, 2),

    }
    但是在函数“clk_pll_set_rate_3188plus”里,继续调用“_pll_clk_set_rate_3188plus”的时候,有写死的部分代码:
    if(!strcmp(__clk_get_name(hw->clk), “clk_cpll”)) {
    // cru_writel(0xffff000f, pll->reg + RK3188_PLL_CON(0));
    cru_writel(0xffff0007, pll->reg + RK3188_PLL_CON(0));
    cru_writel(0xffff00c5, pll->reg + RK3188_PLL_CON(1));
    }
    else {
    cru_writel(clk_set->pllcon0, pll->reg + RK3188_PLL_CON(0));
    cru_writel(clk_set->pllcon1, pll->reg + RK3188_PLL_CON(1));
    }

    if (pll->lock) {
    if(!strcmp(__clk_get_name(hw->clk), “clk_cpll”)) {
    cru_writel(0, pll->reg + RK3188_PLL_CON(2));
    }
    spin_unlock_irqrestore(pll->lock, flags);
    }
    这样写死那根本没法设置正确的时钟,于是,我改成如下:
    #ifdef USE_BOX
    if(!strcmp(__clk_get_name(hw->clk), “clk_cpll”)) {
    // cru_writel(0xffff000f, pll->reg + RK3188_PLL_CON(0));
    cru_writel(0xffff0007, pll->reg + RK3188_PLL_CON(0));
    cru_writel(0xffff00c5, pll->reg + RK3188_PLL_CON(1));
    }
    else {
    cru_writel(clk_set->pllcon0, pll->reg + RK3188_PLL_CON(0));
    cru_writel(clk_set->pllcon1, pll->reg + RK3188_PLL_CON(1));
    }
    #else
    cru_writel(clk_set->pllcon0, pll->reg + RK3188_PLL_CON(0));
    cru_writel(clk_set->pllcon1, pll->reg + RK3188_PLL_CON(1));
    #endif

    #ifdef USE_BOX
    if (pll->lock) {
    if(!strcmp(__clk_get_name(hw->clk), “clk_cpll”)) {
    cru_writel(0, pll->reg + RK3188_PLL_CON(2));
    }
    spin_unlock_irqrestore(pll->lock, flags);
    }
    #else
    if (pll->lock)
    spin_unlock_irqrestore(pll->lock, flags);
    #endif

    但改后,直接黑屏了…

    还有//drivers/clk/rockchip/clk-ops.c文件
    const struct clk_ops clkops_rate_3288_dclk_lcdc0 = {
    .determine_rate = clk_3288_dclk_lcdc0_determine_rate,
    .set_rate = clk_3288_dclk_lcdc0_set_rate,
    .round_rate = clk_3288_dclk_lcdc0_round_rate,
    .recalc_rate = clk_divider_recalc_rate,
    };
    函数clk_3288_dclk_lcdc0_determine_rate也是写死“594*MHZ”相关的时钟。

    最后,想问一下firefly的研发人员,有什么好建议?完善点得话,能不能给个1440*900分辨率的补丁。在这再次表达感谢。

(上面作为邮件也已经发给fn.service@t-firefly.com)

不完美,具体是什么现象?

本帖最后由 Mimosa 于 2016-1-28 00:45 编辑

具体就是,可以显示,但是显示的时候字体模糊,拖动时有残影等。下面几张图是我经过命令后拍的
fbset -a -nonstd 5 -rgba 8/16,8/8,8/0,8/24 -g 1440 900 1440 900 32

图片:

第一张图Move下面本来有一行字的,模糊到没有
第二张图图标也是有字的。用鼠标划过去,就恢复不回来了
第三张图,刷新率是有问题的,我想得到60,但因为kernel内部时钟写死,所以不可能获得正确的刷新率

本帖最后由 Mimosa 于 2016-1-28 00:45 编辑

因为就是点时钟设置的问题,是被固定死为“594MHZ"的。我想请教firefly的技术人员和大家怎么正确的修改这个时钟,论坛上基本都是让你可以改一下这个那个,都是点到为止,基本上没有具体的实现,希望回答的具体些,具体到1440900这个时钟设置OK,正常显示,再次万分感谢。还有几天快过年了,希望在这几天能解决掉。

zhansb 发表于 2016-1-27 16:53
不完美,具体是什么现象?

@zhansb 能否帮我分析下

@zhansb 继续顶起,没人回答

zhansb 发表于 2016-1-27 16:53
不完美,具体是什么现象?

@zhansb 不知道能不能给点提示?