diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c index 41a6513410e8db9fa3a5c02f6b2da92f26b0a7b2..3a0c0c650eed636e903cce7468a202597a528caf 100644 --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c @@ -39,6 +39,7 @@ struct hibmc_dislay_pll_config { }; static const struct hibmc_dislay_pll_config hibmc_pll_table[] = { + {640, 480, CRT_PLL1_HS_25MHZ, CRT_PLL2_HS_25MHZ}, {800, 600, CRT_PLL1_HS_40MHZ, CRT_PLL2_HS_40MHZ}, {1024, 768, CRT_PLL1_HS_65MHZ, CRT_PLL2_HS_65MHZ}, {1152, 864, CRT_PLL1_HS_80MHZ_1152, CRT_PLL2_HS_80MHZ}, @@ -46,6 +47,8 @@ static const struct hibmc_dislay_pll_config hibmc_pll_table[] = { {1280, 720, CRT_PLL1_HS_74MHZ, CRT_PLL2_HS_74MHZ}, {1280, 960, CRT_PLL1_HS_108MHZ, CRT_PLL2_HS_108MHZ}, {1280, 1024, CRT_PLL1_HS_108MHZ, CRT_PLL2_HS_108MHZ}, + {1440, 900, CRT_PLL1_HS_106MHZ, CRT_PLL2_HS_106MHZ}, + {1600, 900, CRT_PLL1_HS_108MHZ, CRT_PLL2_HS_108MHZ}, {1600, 1200, CRT_PLL1_HS_162MHZ, CRT_PLL2_HS_162MHZ}, {1920, 1080, CRT_PLL1_HS_148MHZ, CRT_PLL2_HS_148MHZ}, {1920, 1200, CRT_PLL1_HS_193MHZ, CRT_PLL2_HS_193MHZ}, diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c index ac97166ff696c6545d1f6bfeafdf957b7c2a51a9..e08655aaf14a771c0ccb977a2ddcd95608a4cc70 100644 --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c @@ -119,7 +119,7 @@ static int hibmc_kms_init(struct hibmc_drm_private *priv) priv->dev->mode_config.fb_base = priv->fb_base; priv->dev->mode_config.preferred_depth = 24; - priv->dev->mode_config.prefer_shadow = 0; + priv->dev->mode_config.prefer_shadow = 1; priv->dev->mode_config.funcs = (void *)&hibmc_mode_funcs; diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_fbdev.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_fbdev.c index ba23db0e770bf39c38f0be7a7892982adfcb2cc1..6217962c12892144e46e64ae6cb63ee9e562bda7 100644 --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_fbdev.c +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_fbdev.c @@ -71,7 +71,6 @@ static int hibmc_drm_fb_create(struct drm_fb_helper *helper, DRM_DEBUG_DRIVER("surface width(%d), height(%d) and bpp(%d)\n", sizes->surface_width, sizes->surface_height, sizes->surface_bpp); - sizes->surface_depth = 32; bytes_per_pixel = DIV_ROUND_UP(sizes->surface_bpp, 8); diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_regs.h b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_regs.h index f7035bf3ec1fa689696b08d3f6fbdbbfd47560c3..e2c6155152f8151002bdedf4d96974fd87090e72 100644 --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_regs.h +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_regs.h @@ -174,11 +174,12 @@ #define CRT_PLL1_HS_78MHZ 0x23540F82 #define CRT_PLL1_HS_74MHZ 0x23941dc2 #define CRT_PLL1_HS_80MHZ 0x23941001 -#define CRT_PLL1_HS_80MHZ_1152 0x23540fc2 +#define CRT_PLL1_HS_80MHZ_1152 0x23540fc2 #define CRT_PLL1_HS_108MHZ 0x23b41b01 #define CRT_PLL1_HS_162MHZ 0x23480681 #define CRT_PLL1_HS_148MHZ 0x23541dc2 #define CRT_PLL1_HS_193MHZ 0x234807c1 +#define CRT_PLL1_HS_106MHZ 0x237C1641 #define CRT_PLL2_HS 0x802ac #define CRT_PLL2_HS_25MHZ 0x206B851E @@ -191,6 +192,7 @@ #define CRT_PLL2_HS_162MHZ 0xA0000000 #define CRT_PLL2_HS_148MHZ 0xB0CCCCCD #define CRT_PLL2_HS_193MHZ 0xC0872B02 +#define CRT_PLL2_HS_106MHZ 0x0075c28f #define HIBMC_FIELD(field, value) (field(value) & field##_MASK) #endif diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c index 744956cea7496afd8ec2672bd953eaf67ef661c3..879ffb8c2413ad9fd05507e3e5fe5735ab292044 100644 --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c @@ -22,15 +22,62 @@ #include "hibmc_drm_drv.h" #include "hibmc_drm_regs.h" +struct hibmc_resolution { + int w; + int h; +}; + +static const struct hibmc_resolution hibmc_modetables[] = { + {640, 480}, + {800, 600}, + {1024, 768}, + {1152, 864}, + {1280, 768}, + {1280, 720}, + {1280, 960}, + {1280, 1024}, + {1440, 900}, + {1600, 900}, + {1600, 1200}, + {1920, 1080}, + {1920, 1200} +}; + +static int hibmc_valid_mode(int w, int h) +{ + int i; + + for (i = 0; i < sizeof(hibmc_modetables) / + sizeof(struct hibmc_resolution); i++) { + if (hibmc_modetables[i].w == w && hibmc_modetables[i].h == h) + return 0; + } + + return -1; +} + static int hibmc_connector_get_modes(struct drm_connector *connector) { - return drm_add_modes_noedid(connector, 800, 600); + int count; + + drm_connector_update_edid_property(connector, NULL); + count = drm_add_modes_noedid(connector, 1920, 1200); + drm_set_preferred_mode(connector, 1024, 768); + + return count; } static enum drm_mode_status hibmc_connector_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode) { - return MODE_OK; + int vrefresh = drm_mode_vrefresh(mode); + + if (vrefresh < 59 || vrefresh > 61) + return MODE_NOMODE; + else if (hibmc_valid_mode(mode->hdisplay, mode->vdisplay) != 0) + return MODE_NOMODE; + else + return MODE_OK; } static struct drm_encoder *