From 9c6401d89ddec1ea852a4a092531b390c6a4a7fc Mon Sep 17 00:00:00 2001 From: ChiHun Won Date: Mon, 4 Jun 2018 15:42:56 +0900 Subject: [PATCH] fbdev: dpu20: SoC dependent code is removed in DPU BTS code. AXI port number of each DPP channel, port count, DPP channel count and DECON count are different at each SoC. Previous DPU BTS code doesn't care another SoC. Because DPU BTS code supports only own SoC. This change of DPU BTS code supports common DPU driver. Change-Id: I2421da368f5222295c41191d01736ddc3b75ff8c Signed-off-by: ChiHun Won --- drivers/video/fbdev/exynos/dpu20/bts.c | 119 ++++++------------ drivers/video/fbdev/exynos/dpu20/decon.h | 1 + drivers/video/fbdev/exynos/dpu20/decon_core.c | 7 ++ drivers/video/fbdev/exynos/dpu20/dpp.h | 2 + drivers/video/fbdev/exynos/dpu20/dpp_drv.c | 6 + 5 files changed, 51 insertions(+), 84 deletions(-) diff --git a/drivers/video/fbdev/exynos/dpu20/bts.c b/drivers/video/fbdev/exynos/dpu20/bts.c index f93c51e6d0f9..7c2be5f0d5b6 100644 --- a/drivers/video/fbdev/exynos/dpu20/bts.c +++ b/drivers/video/fbdev/exynos/dpu20/bts.c @@ -10,6 +10,7 @@ */ #include "decon.h" +#include "dpp.h" #include #include @@ -21,7 +22,6 @@ #endif #define DISP_FACTOR 100UL -#define PPC 2UL #define LCD_REFRESH_RATE 63UL #define MULTI_FACTOR (1UL << 10) @@ -39,9 +39,9 @@ u64 dpu_bts_calc_aclk_disp(struct decon_device *decon, /* case for using dsc encoder 1ea at decon0 or decon1 */ if ((decon->id != 2) && (decon->lcd_info->dsc_cnt == 1)) - ppc = PPC / 2UL; + ppc = ((decon->bts.ppc / 2UL) >= 1UL) ? (decon->bts.ppc / 2UL) : 1UL; else - ppc = PPC; + ppc = decon->bts.ppc; aclk_disp = resol_clock * s_ratio_h * s_ratio_v * DISP_FACTOR / 100UL / ppc * (MULTI_FACTOR * (u64)dst->w / (u64)decon->lcd_info->xres) @@ -55,37 +55,22 @@ u64 dpu_bts_calc_aclk_disp(struct decon_device *decon, static void dpu_bts_sum_all_decon_bw(struct decon_device *decon, u32 ch_bw[]) { - int id = decon->id; - - /* store current bw for each channel */ - decon->bts.ch_bw[id][BTS_DPU0] = ch_bw[BTS_DPU0]; - decon->bts.ch_bw[id][BTS_DPU1] = ch_bw[BTS_DPU1]; - - switch (id) { - case 0: - /* sum with bw of other decons */ - ch_bw[BTS_DPU0] += decon->bts.ch_bw[1][BTS_DPU0] - + decon->bts.ch_bw[2][BTS_DPU0]; - ch_bw[BTS_DPU1] += decon->bts.ch_bw[1][BTS_DPU1] - + decon->bts.ch_bw[2][BTS_DPU1]; - break; - case 1: - /* sum with bw of other decons */ - ch_bw[BTS_DPU0] += decon->bts.ch_bw[0][BTS_DPU0] - + decon->bts.ch_bw[2][BTS_DPU0]; - ch_bw[BTS_DPU1] += decon->bts.ch_bw[0][BTS_DPU1] - + decon->bts.ch_bw[2][BTS_DPU1]; - break; - case 2: - /* sum with bw of other decons */ - ch_bw[BTS_DPU0] += decon->bts.ch_bw[0][BTS_DPU0] - + decon->bts.ch_bw[1][BTS_DPU0]; - ch_bw[BTS_DPU1] += decon->bts.ch_bw[0][BTS_DPU1] - + decon->bts.ch_bw[1][BTS_DPU1]; - break; - default: - decon_warn("[%s] undefined decon id(%d)!\n", __func__, id); - break; + int i, j; + + if (decon->id < 0 || decon->id >= MAX_DECON_CNT) { + decon_warn("[%s] undefined decon id(%d)!\n", __func__, decon->id); + return; + } + + for (i = 0; i < BTS_DPU_MAX; ++i) + decon->bts.ch_bw[decon->id][i] = ch_bw[i]; + + for (i = 0; i < MAX_DECON_CNT; ++i) { + if (decon->id == i) + continue; + + for (j = 0; j < BTS_DPU_MAX; ++j) + ch_bw[j] += decon->bts.ch_bw[i][j]; } } @@ -158,57 +143,18 @@ static void dpu_bts_find_max_disp_freq(struct decon_device *decon, static void dpu_bts_share_bw_info(int id) { - int i; + int i, j; struct decon_device *decon[3]; - for (i = 0; i < 3; i++) + for (i = 0; i < MAX_DECON_CNT; i++) decon[i] = get_decon_drvdata(i); - switch (id) { - case 0: - if (decon[1] != NULL) { - decon[1]->bts.ch_bw[id][BTS_DPU0] = - decon[id]->bts.ch_bw[id][BTS_DPU0]; - decon[1]->bts.ch_bw[id][BTS_DPU1] = - decon[id]->bts.ch_bw[id][BTS_DPU1]; - } - if (decon[2] != NULL) { - decon[2]->bts.ch_bw[id][BTS_DPU0] = - decon[id]->bts.ch_bw[id][BTS_DPU0]; - decon[2]->bts.ch_bw[id][BTS_DPU1] = - decon[id]->bts.ch_bw[id][BTS_DPU1]; - } - break; - case 1: - if (decon[0] != NULL) { - decon[0]->bts.ch_bw[id][BTS_DPU0] = - decon[id]->bts.ch_bw[id][BTS_DPU0]; - decon[0]->bts.ch_bw[id][BTS_DPU1] = - decon[id]->bts.ch_bw[id][BTS_DPU1]; - } - if (decon[2] != NULL) { - decon[2]->bts.ch_bw[id][BTS_DPU0] = - decon[id]->bts.ch_bw[id][BTS_DPU0]; - decon[2]->bts.ch_bw[id][BTS_DPU1] = - decon[id]->bts.ch_bw[id][BTS_DPU1]; - } - break; - case 2: - if (decon[0] != NULL) { - decon[0]->bts.ch_bw[id][BTS_DPU0] = - decon[id]->bts.ch_bw[id][BTS_DPU0]; - decon[0]->bts.ch_bw[id][BTS_DPU1] = - decon[id]->bts.ch_bw[id][BTS_DPU1]; - } - if (decon[1] != NULL) { - decon[1]->bts.ch_bw[id][BTS_DPU0] = - decon[id]->bts.ch_bw[id][BTS_DPU0]; - decon[1]->bts.ch_bw[id][BTS_DPU1] = - decon[id]->bts.ch_bw[id][BTS_DPU1]; - } - break; - default: - break; + for (i = 0; i < MAX_DECON_CNT; ++i) { + if (id == i || decon[i] == NULL) + continue; + + for (j = 0; j < BTS_DPU_MAX; ++j) + decon[i]->bts.ch_bw[id][j] = decon[id]->bts.ch_bw[id][j]; } } @@ -453,6 +399,7 @@ void dpu_bts_init(struct decon_device *decon) { int comp_ratio; int i; + struct v4l2_subdev *sd = NULL; DPU_DEBUG_BTS("%s +\n", __func__); @@ -505,9 +452,13 @@ void dpu_bts_init(struct decon_device *decon) pm_qos_add_request(&decon->bts.disp_qos, PM_QOS_DISPLAY_THROUGHPUT, 0); decon->bts.scen_updated = 0; - decon_init_bts_info(decon->bts.bw); - for (i = 0; i < BTS_DPP_MAX; ++i) - DPU_INFO_BTS("IDMA_TYPE(%d) -> BTS CH(%d)\n", i, decon->bts.bw[i].ch_num); + for (i = 0; i < BTS_DPP_MAX; ++i) { + sd = decon->dpp_sd[DPU_DMA2CH(i)]; + v4l2_subdev_call(sd, core, ioctl, DPP_GET_PORT_NUM, + &decon->bts.bw[i].ch_num); + DPU_INFO_BTS("IDMA_TYPE(%d) CH(%d) Port(%d)\n", i, + DPU_DMA2CH(i), decon->bts.bw[i].ch_num); + } decon->bts.enabled = true; diff --git a/drivers/video/fbdev/exynos/dpu20/decon.h b/drivers/video/fbdev/exynos/dpu20/decon.h index b91648480fb5..8fe35b4cf1c6 100644 --- a/drivers/video/fbdev/exynos/dpu20/decon.h +++ b/drivers/video/fbdev/exynos/dpu20/decon.h @@ -806,6 +806,7 @@ struct decon_bts { u32 prev_total_bw; u32 max_disp_freq; u32 prev_max_disp_freq; + u64 ppc; #if defined(CONFIG_EXYNOS9610_BTS) struct decon_bts_bw bw[BTS_DPP_MAX]; diff --git a/drivers/video/fbdev/exynos/dpu20/decon_core.c b/drivers/video/fbdev/exynos/dpu20/decon_core.c index 2e68d907bd3b..19385bcf821e 100644 --- a/drivers/video/fbdev/exynos/dpu20/decon_core.c +++ b/drivers/video/fbdev/exynos/dpu20/decon_core.c @@ -3348,6 +3348,13 @@ static void decon_parse_dt(struct decon_device *decon) decon_info("out type(%d). 0: DSI 1: DISPLAYPORT 2: HDMI 3: WB\n", decon->dt.out_type); + if (of_property_read_u32(dev->of_node, "ppc", (u32 *)&decon->bts.ppc)) { + decon_info("failed to get bts ppc, assigns a default of 2 to ppc\n"); + decon->bts.ppc = 2UL; + } + + decon_info("PPC(%d)\n", decon->bts.ppc); + if (decon->dt.out_type == DECON_OUT_DSI) { ret = of_property_read_u32_index(dev->of_node, "out_idx", 0, &decon->dt.out_idx[0]); diff --git a/drivers/video/fbdev/exynos/dpu20/dpp.h b/drivers/video/fbdev/exynos/dpu20/dpp.h index 7ab85f3e4b90..b30378514860 100644 --- a/drivers/video/fbdev/exynos/dpu20/dpp.h +++ b/drivers/video/fbdev/exynos/dpu20/dpp.h @@ -148,6 +148,7 @@ struct dpp_config { struct dpp_device { int id; + int port; unsigned long attr; enum dpp_state state; struct device *dev; @@ -282,5 +283,6 @@ void dpp_dump(struct dpp_device *dpp); #define DPP_WB_WAIT_FOR_FRAMEDONE _IOR('P', 3, u32) #define DPP_WAIT_IDLE _IOR('P', 4, unsigned long) #define DPP_SET_RECOVERY_NUM _IOR('P', 5, unsigned long) +#define DPP_GET_PORT_NUM _IOR('P', 7, unsigned long) #endif /* __SAMSUNG_DPP_H__ */ diff --git a/drivers/video/fbdev/exynos/dpu20/dpp_drv.c b/drivers/video/fbdev/exynos/dpu20/dpp_drv.c index 03f458132e93..662220e80eb7 100644 --- a/drivers/video/fbdev/exynos/dpu20/dpp_drv.c +++ b/drivers/video/fbdev/exynos/dpu20/dpp_drv.c @@ -567,6 +567,10 @@ static long dpp_subdev_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg ret = dpp_wb_wait_for_framedone(dpp); break; + case DPP_GET_PORT_NUM: + *(int *)arg = dpp->port; + break; + default: break; } @@ -599,6 +603,8 @@ static void dpp_parse_dt(struct dpp_device *dpp, struct device *dev) dpp_info("dpp(%d) probe start..\n", dpp->id); of_property_read_u32(dev->of_node, "attr", (u32 *)&dpp->attr); dpp_info("attributes = 0x%lx\n", dpp->attr); + of_property_read_u32(dev->of_node, "port", (u32 *)&dpp->port); + dpp_info("AXI port = %d\n", dpp->port); dpp->dev = dev; } -- 2.20.1