Re: [v4 6/7] drm/mediatek: change the dsi phytiming calculate method

2019-06-03 Thread Nicolas Boichat
On Sat, Jun 1, 2019 at 5:26 PM Jitao Shi  wrote:
>
> Change the method of frame rate calc which can get more accurate
> frame rate.
>
> data rate = pixel_clock * bit_per_pixel / lanes
> Adjust hfp_wc to adapt the additional phy_data
>
> if MIPI_DSI_MODE_VIDEO_BURST
> hfp_wc = hfp * bpp - data_phy_cycles * lanes - 12 - 6;
> else
> hfp_wc = hfp * bpp - data_phy_cycles * lanes - 12;
>
> Note:
> //(2: 1 for sync, 1 for phy idle)
> data_phy_cycles = T_hs_exit + T_lpx + T_hs_prepare + T_hs_zero + 2;
>
> bpp: bit per pixel
>
> Signed-off-by: Jitao Shi 
> Tested-by: Ryan Case 
> ---
>  drivers/gpu/drm/mediatek/mtk_dsi.c | 122 -
>  1 file changed, 83 insertions(+), 39 deletions(-)
>
> diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c 
> b/drivers/gpu/drm/mediatek/mtk_dsi.c
> index abf6ddec5db6..558727c60ba3 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dsi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
> @@ -144,12 +144,6 @@
>  #define DATA_0 (0xff << 16)
>  #define DATA_1 (0xff << 24)
>
> -#define T_LPX  5
> -#define T_HS_PREP  6
> -#define T_HS_TRAIL 8
> -#define T_HS_EXIT  7
> -#define T_HS_ZERO  10
> -
>  #define NS_TO_CYCLE(n, c)((n) / (c) + (((n) % (c)) ? 1 : 0))
>
>  #define MTK_DSI_HOST_IS_READ(type) \
> @@ -158,6 +152,25 @@
> (type == MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM) || \
> (type == MIPI_DSI_DCS_READ))
>
> +struct mtk_phy_timing {
> +   u32 lpx;
> +   u32 da_hs_prepare;
> +   u32 da_hs_zero;
> +   u32 da_hs_trail;
> +
> +   u32 ta_go;
> +   u32 ta_sure;
> +   u32 ta_get;
> +   u32 da_hs_exit;
> +
> +   u32 clk_hs_zero;
> +   u32 clk_hs_trail;
> +
> +   u32 clk_hs_prepare;
> +   u32 clk_hs_post;
> +   u32 clk_hs_exit;
> +};
> +
>  struct phy;
>
>  struct mtk_dsi_driver_data {
> @@ -182,12 +195,13 @@ struct mtk_dsi {
> struct clk *digital_clk;
> struct clk *hs_clk;
>
> -   u32 data_rate;
> +   u64 data_rate;

As highlighted in
https://patchwork.kernel.org/patch/10949323/#22673829, this change
causes issues on 32-bit platforms.

>
> unsigned long mode_flags;
> enum mipi_dsi_pixel_format format;
> unsigned int lanes;
> struct videomode vm;
> +   struct mtk_phy_timing phy_timing;
> int refcount;
> bool enabled;
> u32 irq_data;
> @@ -221,17 +235,36 @@ static void mtk_dsi_phy_timconfig(struct mtk_dsi *dsi)
>  {
> u32 timcon0, timcon1, timcon2, timcon3;
> u32 ui, cycle_time;
> +   struct mtk_phy_timing *timing = >phy_timing;
> +
> +   ui = 10 / dsi->data_rate;
> +   cycle_time = 80 / dsi->data_rate;
> +
> +   timing->lpx = NS_TO_CYCLE(60, cycle_time);
> +   timing->da_hs_prepare = NS_TO_CYCLE(40 + 5 * ui, cycle_time);
> +   timing->da_hs_zero = NS_TO_CYCLE(110 + 6 * ui, cycle_time);
> +   timing->da_hs_trail = NS_TO_CYCLE(80 + 4 * ui, cycle_time);
>
> -   ui = 1000 / dsi->data_rate + 0x01;
> -   cycle_time = 8000 / dsi->data_rate + 0x01;
> +   timing->ta_go = 4 * timing->lpx;
> +   timing->ta_sure = 3 * timing->lpx / 2;
> +   timing->ta_get = 5 * timing->lpx;
> +   timing->da_hs_exit = 2 * timing->lpx;
>
> -   timcon0 = T_LPX | T_HS_PREP << 8 | T_HS_ZERO << 16 | T_HS_TRAIL << 24;
> -   timcon1 = 4 * T_LPX | (3 * T_LPX / 2) << 8 | 5 * T_LPX << 16 |
> - T_HS_EXIT << 24;
> -   timcon2 = ((NS_TO_CYCLE(0x64, cycle_time) + 0xa) << 24) |
> - (NS_TO_CYCLE(0x150, cycle_time) << 16);
> -   timcon3 = NS_TO_CYCLE(0x40, cycle_time) | (2 * T_LPX) << 16 |
> - NS_TO_CYCLE(80 + 52 * ui, cycle_time) << 8;
> +   timing->clk_hs_zero = NS_TO_CYCLE(336, cycle_time);
> +   timing->clk_hs_trail = NS_TO_CYCLE(100, cycle_time) + 10;
> +
> +   timing->clk_hs_prepare = NS_TO_CYCLE(64, cycle_time);
> +   timing->clk_hs_post = NS_TO_CYCLE(80 + 52 * ui, cycle_time);
> +   timing->clk_hs_exit = 2 * timing->lpx;
> +
> +   timcon0 = timing->lpx | timing->da_hs_prepare << 8 |
> + timing->da_hs_zero << 16 | timing->da_hs_trail << 24;
> +   timcon1 = timing->ta_go | timing->ta_sure << 8 |
> + timing->ta_get << 16 | timing->da_hs_exit << 24;
> +   timcon2 = 1 << 8 | timing->clk_hs_zero << 16 |
> + timing->clk_hs_trail << 24;
> +   timcon3 = timing->clk_hs_prepare | timing->clk_hs_post << 8 |
> + timing->clk_hs_exit << 16;
>
> writel(timcon0, dsi->regs + DSI_PHY_TIMECON0);
> writel(timcon1, dsi->regs + DSI_PHY_TIMECON1);
> @@ -418,7 +451,8 @@ static void mtk_dsi_config_vdo_timing(struct mtk_dsi *dsi)
> u32 horizontal_sync_active_byte;
> u32 horizontal_backporch_byte;
> u32 horizontal_frontporch_byte;
> -   u32 dsi_tmp_buf_bpp;
> +   u32 dsi_tmp_buf_bpp, data_phy_cycles;
> +   struct 

Re: [v4 6/7] drm/mediatek: change the dsi phytiming calculate method

2019-06-02 Thread CK Hu
Hi, Jitao:

On Sat, 2019-06-01 at 17:26 +0800, Jitao Shi wrote:
> Change the method of frame rate calc which can get more accurate
> frame rate.
> 
> data rate = pixel_clock * bit_per_pixel / lanes
> Adjust hfp_wc to adapt the additional phy_data
> 
> if MIPI_DSI_MODE_VIDEO_BURST
>   hfp_wc = hfp * bpp - data_phy_cycles * lanes - 12 - 6;
> else
>   hfp_wc = hfp * bpp - data_phy_cycles * lanes - 12;
> 
> Note:
> //(2: 1 for sync, 1 for phy idle)
> data_phy_cycles = T_hs_exit + T_lpx + T_hs_prepare + T_hs_zero + 2;
> 
> bpp: bit per pixel
> 
> Signed-off-by: Jitao Shi 
> Tested-by: Ryan Case 
> ---
>  drivers/gpu/drm/mediatek/mtk_dsi.c | 122 -
>  1 file changed, 83 insertions(+), 39 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c 
> b/drivers/gpu/drm/mediatek/mtk_dsi.c
> index abf6ddec5db6..558727c60ba3 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dsi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
> @@ -144,12 +144,6 @@
>  #define DATA_0   (0xff << 16)
>  #define DATA_1   (0xff << 24)
>  
> -#define T_LPX5
> -#define T_HS_PREP6
> -#define T_HS_TRAIL   8
> -#define T_HS_EXIT7
> -#define T_HS_ZERO10
> -
>  #define NS_TO_CYCLE(n, c)((n) / (c) + (((n) % (c)) ? 1 : 0))
>  
>  #define MTK_DSI_HOST_IS_READ(type) \
> @@ -158,6 +152,25 @@
>   (type == MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM) || \
>   (type == MIPI_DSI_DCS_READ))
>  
> +struct mtk_phy_timing {
> + u32 lpx;
> + u32 da_hs_prepare;
> + u32 da_hs_zero;
> + u32 da_hs_trail;
> +
> + u32 ta_go;
> + u32 ta_sure;
> + u32 ta_get;
> + u32 da_hs_exit;
> +
> + u32 clk_hs_zero;
> + u32 clk_hs_trail;
> +
> + u32 clk_hs_prepare;
> + u32 clk_hs_post;
> + u32 clk_hs_exit;
> +};
> +
>  struct phy;
>  
>  struct mtk_dsi_driver_data {
> @@ -182,12 +195,13 @@ struct mtk_dsi {
>   struct clk *digital_clk;
>   struct clk *hs_clk;
>  
> - u32 data_rate;
> + u64 data_rate;
>  
>   unsigned long mode_flags;
>   enum mipi_dsi_pixel_format format;
>   unsigned int lanes;
>   struct videomode vm;
> + struct mtk_phy_timing phy_timing;
>   int refcount;
>   bool enabled;
>   u32 irq_data;
> @@ -221,17 +235,36 @@ static void mtk_dsi_phy_timconfig(struct mtk_dsi *dsi)
>  {
>   u32 timcon0, timcon1, timcon2, timcon3;
>   u32 ui, cycle_time;
> + struct mtk_phy_timing *timing = >phy_timing;
> +
> + ui = 10 / dsi->data_rate;
> + cycle_time = 80 / dsi->data_rate;
> +
> + timing->lpx = NS_TO_CYCLE(60, cycle_time);
> + timing->da_hs_prepare = NS_TO_CYCLE(40 + 5 * ui, cycle_time);
> + timing->da_hs_zero = NS_TO_CYCLE(110 + 6 * ui, cycle_time);
> + timing->da_hs_trail = NS_TO_CYCLE(80 + 4 * ui, cycle_time);
>  
> - ui = 1000 / dsi->data_rate + 0x01;
> - cycle_time = 8000 / dsi->data_rate + 0x01;
> + timing->ta_go = 4 * timing->lpx;
> + timing->ta_sure = 3 * timing->lpx / 2;
> + timing->ta_get = 5 * timing->lpx;
> + timing->da_hs_exit = 2 * timing->lpx;
>  
> - timcon0 = T_LPX | T_HS_PREP << 8 | T_HS_ZERO << 16 | T_HS_TRAIL << 24;
> - timcon1 = 4 * T_LPX | (3 * T_LPX / 2) << 8 | 5 * T_LPX << 16 |
> -   T_HS_EXIT << 24;
> - timcon2 = ((NS_TO_CYCLE(0x64, cycle_time) + 0xa) << 24) |
> -   (NS_TO_CYCLE(0x150, cycle_time) << 16);
> - timcon3 = NS_TO_CYCLE(0x40, cycle_time) | (2 * T_LPX) << 16 |
> -   NS_TO_CYCLE(80 + 52 * ui, cycle_time) << 8;
> + timing->clk_hs_zero = NS_TO_CYCLE(336, cycle_time);
> + timing->clk_hs_trail = NS_TO_CYCLE(100, cycle_time) + 10;
> +
> + timing->clk_hs_prepare = NS_TO_CYCLE(64, cycle_time);
> + timing->clk_hs_post = NS_TO_CYCLE(80 + 52 * ui, cycle_time);
> + timing->clk_hs_exit = 2 * timing->lpx;
> +
> + timcon0 = timing->lpx | timing->da_hs_prepare << 8 |
> +   timing->da_hs_zero << 16 | timing->da_hs_trail << 24;
> + timcon1 = timing->ta_go | timing->ta_sure << 8 |
> +   timing->ta_get << 16 | timing->da_hs_exit << 24;
> + timcon2 = 1 << 8 | timing->clk_hs_zero << 16 |
> +   timing->clk_hs_trail << 24;
> + timcon3 = timing->clk_hs_prepare | timing->clk_hs_post << 8 |
> +   timing->clk_hs_exit << 16;
>  
>   writel(timcon0, dsi->regs + DSI_PHY_TIMECON0);
>   writel(timcon1, dsi->regs + DSI_PHY_TIMECON1);
> @@ -418,7 +451,8 @@ static void mtk_dsi_config_vdo_timing(struct mtk_dsi *dsi)
>   u32 horizontal_sync_active_byte;
>   u32 horizontal_backporch_byte;
>   u32 horizontal_frontporch_byte;
> - u32 dsi_tmp_buf_bpp;
> + u32 dsi_tmp_buf_bpp, data_phy_cycles;
> + struct mtk_phy_timing *timing = >phy_timing;
>  
>   struct videomode *vm = >vm;
>  
> @@ -433,7 +467,8 @@ static void mtk_dsi_config_vdo_timing(struct mtk_dsi *dsi)
>   writel(vm->vactive, dsi->regs + DSI_VACT_NL);
>  
> 

[v4 6/7] drm/mediatek: change the dsi phytiming calculate method

2019-06-01 Thread Jitao Shi
Change the method of frame rate calc which can get more accurate
frame rate.

data rate = pixel_clock * bit_per_pixel / lanes
Adjust hfp_wc to adapt the additional phy_data

if MIPI_DSI_MODE_VIDEO_BURST
hfp_wc = hfp * bpp - data_phy_cycles * lanes - 12 - 6;
else
hfp_wc = hfp * bpp - data_phy_cycles * lanes - 12;

Note:
//(2: 1 for sync, 1 for phy idle)
data_phy_cycles = T_hs_exit + T_lpx + T_hs_prepare + T_hs_zero + 2;

bpp: bit per pixel

Signed-off-by: Jitao Shi 
Tested-by: Ryan Case 
---
 drivers/gpu/drm/mediatek/mtk_dsi.c | 122 -
 1 file changed, 83 insertions(+), 39 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c 
b/drivers/gpu/drm/mediatek/mtk_dsi.c
index abf6ddec5db6..558727c60ba3 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -144,12 +144,6 @@
 #define DATA_0 (0xff << 16)
 #define DATA_1 (0xff << 24)
 
-#define T_LPX  5
-#define T_HS_PREP  6
-#define T_HS_TRAIL 8
-#define T_HS_EXIT  7
-#define T_HS_ZERO  10
-
 #define NS_TO_CYCLE(n, c)((n) / (c) + (((n) % (c)) ? 1 : 0))
 
 #define MTK_DSI_HOST_IS_READ(type) \
@@ -158,6 +152,25 @@
(type == MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM) || \
(type == MIPI_DSI_DCS_READ))
 
+struct mtk_phy_timing {
+   u32 lpx;
+   u32 da_hs_prepare;
+   u32 da_hs_zero;
+   u32 da_hs_trail;
+
+   u32 ta_go;
+   u32 ta_sure;
+   u32 ta_get;
+   u32 da_hs_exit;
+
+   u32 clk_hs_zero;
+   u32 clk_hs_trail;
+
+   u32 clk_hs_prepare;
+   u32 clk_hs_post;
+   u32 clk_hs_exit;
+};
+
 struct phy;
 
 struct mtk_dsi_driver_data {
@@ -182,12 +195,13 @@ struct mtk_dsi {
struct clk *digital_clk;
struct clk *hs_clk;
 
-   u32 data_rate;
+   u64 data_rate;
 
unsigned long mode_flags;
enum mipi_dsi_pixel_format format;
unsigned int lanes;
struct videomode vm;
+   struct mtk_phy_timing phy_timing;
int refcount;
bool enabled;
u32 irq_data;
@@ -221,17 +235,36 @@ static void mtk_dsi_phy_timconfig(struct mtk_dsi *dsi)
 {
u32 timcon0, timcon1, timcon2, timcon3;
u32 ui, cycle_time;
+   struct mtk_phy_timing *timing = >phy_timing;
+
+   ui = 10 / dsi->data_rate;
+   cycle_time = 80 / dsi->data_rate;
+
+   timing->lpx = NS_TO_CYCLE(60, cycle_time);
+   timing->da_hs_prepare = NS_TO_CYCLE(40 + 5 * ui, cycle_time);
+   timing->da_hs_zero = NS_TO_CYCLE(110 + 6 * ui, cycle_time);
+   timing->da_hs_trail = NS_TO_CYCLE(80 + 4 * ui, cycle_time);
 
-   ui = 1000 / dsi->data_rate + 0x01;
-   cycle_time = 8000 / dsi->data_rate + 0x01;
+   timing->ta_go = 4 * timing->lpx;
+   timing->ta_sure = 3 * timing->lpx / 2;
+   timing->ta_get = 5 * timing->lpx;
+   timing->da_hs_exit = 2 * timing->lpx;
 
-   timcon0 = T_LPX | T_HS_PREP << 8 | T_HS_ZERO << 16 | T_HS_TRAIL << 24;
-   timcon1 = 4 * T_LPX | (3 * T_LPX / 2) << 8 | 5 * T_LPX << 16 |
- T_HS_EXIT << 24;
-   timcon2 = ((NS_TO_CYCLE(0x64, cycle_time) + 0xa) << 24) |
- (NS_TO_CYCLE(0x150, cycle_time) << 16);
-   timcon3 = NS_TO_CYCLE(0x40, cycle_time) | (2 * T_LPX) << 16 |
- NS_TO_CYCLE(80 + 52 * ui, cycle_time) << 8;
+   timing->clk_hs_zero = NS_TO_CYCLE(336, cycle_time);
+   timing->clk_hs_trail = NS_TO_CYCLE(100, cycle_time) + 10;
+
+   timing->clk_hs_prepare = NS_TO_CYCLE(64, cycle_time);
+   timing->clk_hs_post = NS_TO_CYCLE(80 + 52 * ui, cycle_time);
+   timing->clk_hs_exit = 2 * timing->lpx;
+
+   timcon0 = timing->lpx | timing->da_hs_prepare << 8 |
+ timing->da_hs_zero << 16 | timing->da_hs_trail << 24;
+   timcon1 = timing->ta_go | timing->ta_sure << 8 |
+ timing->ta_get << 16 | timing->da_hs_exit << 24;
+   timcon2 = 1 << 8 | timing->clk_hs_zero << 16 |
+ timing->clk_hs_trail << 24;
+   timcon3 = timing->clk_hs_prepare | timing->clk_hs_post << 8 |
+ timing->clk_hs_exit << 16;
 
writel(timcon0, dsi->regs + DSI_PHY_TIMECON0);
writel(timcon1, dsi->regs + DSI_PHY_TIMECON1);
@@ -418,7 +451,8 @@ static void mtk_dsi_config_vdo_timing(struct mtk_dsi *dsi)
u32 horizontal_sync_active_byte;
u32 horizontal_backporch_byte;
u32 horizontal_frontporch_byte;
-   u32 dsi_tmp_buf_bpp;
+   u32 dsi_tmp_buf_bpp, data_phy_cycles;
+   struct mtk_phy_timing *timing = >phy_timing;
 
struct videomode *vm = >vm;
 
@@ -433,7 +467,8 @@ static void mtk_dsi_config_vdo_timing(struct mtk_dsi *dsi)
writel(vm->vactive, dsi->regs + DSI_VACT_NL);
 
if (dsi->driver_data->has_size_ctl)
-   writel(vm->vactive << 16 | vm->hactive, dsi->regs + 
DSI_SIZE_CON);
+   writel(vm->vactive << 16 | vm->hactive,
+