展訊平臺lcd頻率計算

 展訊平臺點屏時要配置兩個時鐘(phy_freq和pixel_clk),那這兩個參數要怎麼配置呢,我們可以找到展訊的這份文檔,輸入屏的參數,即可計算出相應的時鐘。如

 然後將相應的參數填到屏的配置文件中,如

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;
}

 

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,差不多。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章