展讯平台lcd频率计算

 展讯平台点屏时要配置两个时钟(phy_freq和pixel_clk),那这两个参数要怎么配置呢,我们可以找到展讯的这份文档,输入屏的参数,即可计算出相应的时钟。如

展讯平台lcd频率计算_第1张图片

 然后将相应的参数填到屏的配置文件中,如

Android9.0以前,
uboot配置

.phy_freq = 1105000
.pixel_clk = 153600000

kernel配置

pixel_clk:由uboot传参到cmdline(在uboot)
clock-frequency = <1105000>;对应uboot的phy_freq

Android10.0
uboot配置

.phy_freq = 1105000
.pixel_clk = 153600000


kernel配置

sprd,phy-bit-clock = <1105000>;//phy-freq
clock-frequency = <153600000>;//pixel_clk

当然,这不是重点,之前一直不了解其中的运算规则,excel隐藏了其中的运算规则,今天看代码有了一些了解,分享下

pixel_clk计算

从下面的程序中可以窥见一二,如果配置是时钟源是dpi_clk_src中一个,直接使用,然后根据ROUND(a, b)计算分配分配系数

static const u32 dpi_clk_src[] = {
	96000000,
	128000000,
	153600000,
	192000000
};

static u32 calc_dpi_clk_src(u32 pclk)
{
	int i;

	for (i = 0; i < ARRAY_SIZE(dpi_clk_src); i++) {
		if ((dpi_clk_src[i] % pclk) == 0)
			return dpi_clk_src[i];
	}

	pr_err("calc DPI_CLK_SRC failed, use default\n");
	return 96000000;
}
#define ROUND(a, b) (((a) + (b) / 2) / (b))  

static int calc_dpi_clk(struct sprd_dispc *dispc,
			       u32 *new_pclk, u32 pclk_src,
			       u32 new_val, int type)
{
	switch (type) {
	case SPRD_FORCE_FPS:
	case SPRD_DYNAMIC_FPS:
		if (new_val < LCD_MIN_FPS || new_val > LCD_MAX_FPS) {
			pr_err
			    ("Unsupported FPS. fps range should be [%d, %d]\n",
			     LCD_MIN_FPS, LCD_MAX_FPS);
			return -EINVAL;
		}
		pclk = hpixels * vlines * new_val;
		divider = ROUND(pclk_src, pclk);
		*new_pclk = pclk_src / divider;
		if (pclk_src % divider)
			*new_pclk += 1;
		panel->fps = new_val;
		break;

}

 fps计算 

static ssize_t actual_fps_show(struct device *dev,
                        struct device_attribute *attr,
                        char *buf)
{
        struct sprd_dpu *dpu = dev_get_drvdata(dev);
        struct videomode vm = dpu->ctx.vm;
        uint32_t act_fps_int, act_fps_frac;
        uint32_t total_pixels;
        int ret;

        total_pixels = (vm.hsync_len + vm.hback_porch +
                        vm.hfront_porch + vm.hactive) *
                        (vm.vsync_len + vm.vback_porch +
                        vm.vfront_porch + vm.vactive);

        act_fps_int = vm.pixelclock / total_pixels;
        act_fps_frac = vm.pixelclock % total_pixels;
        act_fps_frac = act_fps_frac * 100 / total_pixels;

        ret = snprintf(buf, PAGE_SIZE, "%u.%u\n", act_fps_int, act_fps_frac);

        return ret;
}
static DEVICE_ATTR_RO(actual_fps);

kernel4.14/drivers/gpu/drm/sprd/dpu/dpu_r3p0.c 

static void dpu_dpi_init(struct dpu_context *ctx)
{
	if (ctx->vm.vsync_len + ctx->vm.vback_porch < 32)
		pr_warn("Warning: (vsync + vbp) < 32, ""underflow risk!\n");
}

如上面的那组参数

1206*2138*60=154705680
ROUND(a, b)=1,分频系数为1,那时钟就是153600000

fps≈153600000/(1206*2138)≈60,满足要求

 如这组参数,

1547*688*60=63860160

ROUND(a, b)=2,频率就是153600000/2=76800000,

fps≈76800000/(1547*688)≈72fps,,不满足要求

但更换64000000时钟源,

ROUND(a, b)=2,频率就是128000000/2=64000000,

fps≈64000000/(1547*688)≈60fps,满足要求

展讯给的公式为

1.need_clock = (width+hfp+hbp+hsync)*(height+vfp+vbp+vsync)*fps  
2.dividor = dpi_clock_src/need_clock;
3.if((dpi_clock_src - dividor*need_clock) > (need_clock/2)){
    dividor += 1;
}

 

展讯平台lcd频率计算_第2张图片

phy_freq的计算

展讯给的公式为

(DPI_CLK_SRC/DIVIDOR)x 3x 8 bit < phy_feq x lane_num x 0.9
考虑到MIPI传输过程中可能会出现传输错误,实际设置的值可以再加大10%

对于下面屏的配置算出来的是
(153600000*3*8)/(4*0.9)*1.1=1126400000,表格算处理的是1105*1000kbs,差不多。

展讯平台lcd频率计算_第3张图片

你可能感兴趣的:(LCD)