Loading drivers/gpu/drm/nouveau/nouveau_connector.c +23 −14 Original line number Diff line number Diff line Loading @@ -517,12 +517,16 @@ nouveau_connector_set_property(struct drm_connector *connector, } /* Dithering */ if (property == dev->mode_config.dithering_mode_property) { if (value == DRM_MODE_DITHERING_ON) nv_connector->use_dithering = true; else nv_connector->use_dithering = false; if (property == disp->dithering_mode) { nv_connector->dithering_mode = value; if (!nv_crtc || !nv_crtc->set_dither) return 0; return nv_crtc->set_dither(nv_crtc, true); } if (property == disp->dithering_depth) { nv_connector->dithering_depth = value; if (!nv_crtc || !nv_crtc->set_dither) return 0; Loading Loading @@ -918,7 +922,7 @@ nouveau_connector_create(struct drm_device *dev, int index) drm_connector_init(dev, connector, funcs, type); drm_connector_helper_add(connector, &nouveau_connector_helper_funcs); /* Check if we need dithering enabled */ /* parse lvds table now, we depend on bios->fp.* values later */ if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS) { bool dummy, is_24bit = false; Loading @@ -928,8 +932,6 @@ nouveau_connector_create(struct drm_device *dev, int index) "LVDS\n"); goto fail; } nv_connector->use_dithering = !is_24bit; } /* Init DVI-I specific properties */ Loading @@ -940,8 +942,7 @@ nouveau_connector_create(struct drm_device *dev, int index) } /* Add overscan compensation options to digital outputs */ if ((dev_priv->card_type == NV_50 || dev_priv->card_type == NV_C0) && if (disp->underscan_property && (dcb->type == DCB_CONNECTOR_DVI_D || dcb->type == DCB_CONNECTOR_DVI_I || dcb->type == DCB_CONNECTOR_HDMI_0 || Loading Loading @@ -977,10 +978,18 @@ nouveau_connector_create(struct drm_device *dev, int index) drm_connector_attach_property(connector, dev->mode_config.scaling_mode_property, nv_connector->scaling_mode); if (disp->dithering_mode) { nv_connector->dithering_mode = DITHERING_MODE_AUTO; drm_connector_attach_property(connector, dev->mode_config.dithering_mode_property, nv_connector->use_dithering ? DRM_MODE_DITHERING_ON : DRM_MODE_DITHERING_OFF); disp->dithering_mode, nv_connector->dithering_mode); } if (disp->dithering_depth) { nv_connector->dithering_depth = DITHERING_DEPTH_AUTO; drm_connector_attach_property(connector, disp->dithering_depth, nv_connector->dithering_depth); } break; } Loading drivers/gpu/drm/nouveau/nouveau_connector.h +26 −1 Original line number Diff line number Diff line Loading @@ -30,12 +30,37 @@ #include "drm_edid.h" #include "nouveau_i2c.h" enum nouveau_underscan_type { UNDERSCAN_OFF, UNDERSCAN_ON, UNDERSCAN_AUTO, }; /* the enum values specifically defined here match nv50/nvd0 hw values, and * the code relies on this */ enum nouveau_dithering_mode { DITHERING_MODE_OFF = 0x00, DITHERING_MODE_ON = 0x01, DITHERING_MODE_DYNAMIC2X2 = 0x10 | DITHERING_MODE_ON, DITHERING_MODE_STATIC2X2 = 0x18 | DITHERING_MODE_ON, DITHERING_MODE_TEMPORAL = 0x20 | DITHERING_MODE_ON, DITHERING_MODE_AUTO }; enum nouveau_dithering_depth { DITHERING_DEPTH_6BPC = 0x00, DITHERING_DEPTH_8BPC = 0x02, DITHERING_DEPTH_AUTO }; struct nouveau_connector { struct drm_connector base; struct dcb_connector_table_entry *dcb; bool use_dithering; int dithering_mode; int dithering_depth; int scaling_mode; enum nouveau_underscan_type underscan; u32 underscan_hborder; Loading drivers/gpu/drm/nouveau/nouveau_display.c +59 −15 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ #include "nouveau_hw.h" #include "nouveau_crtc.h" #include "nouveau_dma.h" #include "nouveau_connector.h" #include "nv50_display.h" static void Loading Loading @@ -154,35 +155,78 @@ static const struct drm_mode_config_funcs nouveau_mode_config_funcs = { struct drm_prop_enum_list { u8 gen_mask; int type; char *name; }; static struct drm_prop_enum_list nouveau_underscan_enum_list[] = { { UNDERSCAN_OFF, "off" }, { UNDERSCAN_ON, "on" }, { UNDERSCAN_AUTO, "auto" }, static struct drm_prop_enum_list underscan[] = { { 2, UNDERSCAN_AUTO, "auto" }, { 2, UNDERSCAN_OFF, "off" }, { 2, UNDERSCAN_ON, "on" }, {} }; static struct drm_prop_enum_list dither_mode[] = { { 7, DITHERING_MODE_AUTO, "auto" }, { 7, DITHERING_MODE_OFF, "off" }, { 1, DITHERING_MODE_ON, "on" }, { 6, DITHERING_MODE_STATIC2X2, "static 2x2" }, { 6, DITHERING_MODE_DYNAMIC2X2, "dynamic 2x2" }, { 4, DITHERING_MODE_TEMPORAL, "temporal" }, {} }; static struct drm_prop_enum_list dither_depth[] = { { 6, DITHERING_DEPTH_AUTO, "auto" }, { 6, DITHERING_DEPTH_6BPC, "6 bpc" }, { 6, DITHERING_DEPTH_8BPC, "8 bpc" }, {} }; #define PROP_ENUM(p,gen,n,list) do { \ struct drm_prop_enum_list *l = (list); \ int c = 0; \ while (l->gen_mask) { \ if (l->gen_mask & (1 << (gen))) \ c++; \ l++; \ } \ if (c) { \ p = drm_property_create(dev, DRM_MODE_PROP_ENUM, n, c); \ l = (list); \ c = 0; \ while (p && l->gen_mask) { \ if (l->gen_mask & (1 << (gen))) { \ drm_property_add_enum(p, c, l->type, l->name); \ c++; \ } \ l++; \ } \ } \ } while(0) int nouveau_display_create(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = dev->dev_private; struct nouveau_display_engine *disp = &dev_priv->engine.display; int ret, cnt, i; int ret, gen; drm_mode_config_init(dev); drm_mode_create_scaling_mode_property(dev); drm_mode_create_dithering_property(dev); cnt = ARRAY_SIZE(nouveau_underscan_enum_list); disp->underscan_property = drm_property_create(dev, DRM_MODE_PROP_ENUM, "underscan", cnt); for (i = 0; i < cnt; i++) { drm_property_add_enum(disp->underscan_property, i, nouveau_underscan_enum_list[i].type, nouveau_underscan_enum_list[i].name); } if (dev_priv->card_type < NV_50) gen = 0; else if (dev_priv->card_type < NV_D0) gen = 1; else gen = 2; PROP_ENUM(disp->dithering_mode, gen, "dithering mode", dither_mode); PROP_ENUM(disp->dithering_depth, gen, "dithering depth", dither_depth); PROP_ENUM(disp->underscan_property, gen, "underscan", underscan); disp->underscan_hborder_property = drm_property_create(dev, DRM_MODE_PROP_RANGE, Loading drivers/gpu/drm/nouveau/nouveau_drv.h +2 −6 Original line number Diff line number Diff line Loading @@ -391,12 +391,6 @@ struct nouveau_fifo_engine { void (*tlb_flush)(struct drm_device *dev); }; enum nouveau_underscan_type { UNDERSCAN_OFF, UNDERSCAN_ON, UNDERSCAN_AUTO, }; struct nouveau_display_engine { void *priv; int (*early_init)(struct drm_device *); Loading @@ -405,6 +399,8 @@ struct nouveau_display_engine { int (*init)(struct drm_device *); void (*destroy)(struct drm_device *); struct drm_property *dithering_mode; struct drm_property *dithering_depth; struct drm_property *underscan_property; struct drm_property *underscan_hborder_property; struct drm_property *underscan_vborder_property; Loading drivers/gpu/drm/nouveau/nv04_dfp.c +4 −1 Original line number Diff line number Diff line Loading @@ -289,6 +289,7 @@ static void nv04_dfp_mode_set(struct drm_encoder *encoder, struct nouveau_connector *nv_connector = nouveau_crtc_connector_get(nv_crtc); struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); struct drm_display_mode *output_mode = &nv_encoder->mode; struct drm_connector *connector = &nv_connector->base; uint32_t mode_ratio, panel_ratio; NV_DEBUG_KMS(dev, "Output mode on CRTC %d:\n", nv_crtc->index); Loading Loading @@ -407,7 +408,9 @@ static void nv04_dfp_mode_set(struct drm_encoder *encoder, } /* Output property. */ if (nv_connector->use_dithering) { if ((nv_connector->dithering_mode == DITHERING_MODE_ON) || (nv_connector->dithering_mode == DITHERING_MODE_AUTO && encoder->crtc->fb->depth > connector->display_info.bpc * 3)) { if (dev_priv->chipset == 0x11) regp->dither = savep->dither | 0x00010000; else { Loading Loading
drivers/gpu/drm/nouveau/nouveau_connector.c +23 −14 Original line number Diff line number Diff line Loading @@ -517,12 +517,16 @@ nouveau_connector_set_property(struct drm_connector *connector, } /* Dithering */ if (property == dev->mode_config.dithering_mode_property) { if (value == DRM_MODE_DITHERING_ON) nv_connector->use_dithering = true; else nv_connector->use_dithering = false; if (property == disp->dithering_mode) { nv_connector->dithering_mode = value; if (!nv_crtc || !nv_crtc->set_dither) return 0; return nv_crtc->set_dither(nv_crtc, true); } if (property == disp->dithering_depth) { nv_connector->dithering_depth = value; if (!nv_crtc || !nv_crtc->set_dither) return 0; Loading Loading @@ -918,7 +922,7 @@ nouveau_connector_create(struct drm_device *dev, int index) drm_connector_init(dev, connector, funcs, type); drm_connector_helper_add(connector, &nouveau_connector_helper_funcs); /* Check if we need dithering enabled */ /* parse lvds table now, we depend on bios->fp.* values later */ if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS) { bool dummy, is_24bit = false; Loading @@ -928,8 +932,6 @@ nouveau_connector_create(struct drm_device *dev, int index) "LVDS\n"); goto fail; } nv_connector->use_dithering = !is_24bit; } /* Init DVI-I specific properties */ Loading @@ -940,8 +942,7 @@ nouveau_connector_create(struct drm_device *dev, int index) } /* Add overscan compensation options to digital outputs */ if ((dev_priv->card_type == NV_50 || dev_priv->card_type == NV_C0) && if (disp->underscan_property && (dcb->type == DCB_CONNECTOR_DVI_D || dcb->type == DCB_CONNECTOR_DVI_I || dcb->type == DCB_CONNECTOR_HDMI_0 || Loading Loading @@ -977,10 +978,18 @@ nouveau_connector_create(struct drm_device *dev, int index) drm_connector_attach_property(connector, dev->mode_config.scaling_mode_property, nv_connector->scaling_mode); if (disp->dithering_mode) { nv_connector->dithering_mode = DITHERING_MODE_AUTO; drm_connector_attach_property(connector, dev->mode_config.dithering_mode_property, nv_connector->use_dithering ? DRM_MODE_DITHERING_ON : DRM_MODE_DITHERING_OFF); disp->dithering_mode, nv_connector->dithering_mode); } if (disp->dithering_depth) { nv_connector->dithering_depth = DITHERING_DEPTH_AUTO; drm_connector_attach_property(connector, disp->dithering_depth, nv_connector->dithering_depth); } break; } Loading
drivers/gpu/drm/nouveau/nouveau_connector.h +26 −1 Original line number Diff line number Diff line Loading @@ -30,12 +30,37 @@ #include "drm_edid.h" #include "nouveau_i2c.h" enum nouveau_underscan_type { UNDERSCAN_OFF, UNDERSCAN_ON, UNDERSCAN_AUTO, }; /* the enum values specifically defined here match nv50/nvd0 hw values, and * the code relies on this */ enum nouveau_dithering_mode { DITHERING_MODE_OFF = 0x00, DITHERING_MODE_ON = 0x01, DITHERING_MODE_DYNAMIC2X2 = 0x10 | DITHERING_MODE_ON, DITHERING_MODE_STATIC2X2 = 0x18 | DITHERING_MODE_ON, DITHERING_MODE_TEMPORAL = 0x20 | DITHERING_MODE_ON, DITHERING_MODE_AUTO }; enum nouveau_dithering_depth { DITHERING_DEPTH_6BPC = 0x00, DITHERING_DEPTH_8BPC = 0x02, DITHERING_DEPTH_AUTO }; struct nouveau_connector { struct drm_connector base; struct dcb_connector_table_entry *dcb; bool use_dithering; int dithering_mode; int dithering_depth; int scaling_mode; enum nouveau_underscan_type underscan; u32 underscan_hborder; Loading
drivers/gpu/drm/nouveau/nouveau_display.c +59 −15 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ #include "nouveau_hw.h" #include "nouveau_crtc.h" #include "nouveau_dma.h" #include "nouveau_connector.h" #include "nv50_display.h" static void Loading Loading @@ -154,35 +155,78 @@ static const struct drm_mode_config_funcs nouveau_mode_config_funcs = { struct drm_prop_enum_list { u8 gen_mask; int type; char *name; }; static struct drm_prop_enum_list nouveau_underscan_enum_list[] = { { UNDERSCAN_OFF, "off" }, { UNDERSCAN_ON, "on" }, { UNDERSCAN_AUTO, "auto" }, static struct drm_prop_enum_list underscan[] = { { 2, UNDERSCAN_AUTO, "auto" }, { 2, UNDERSCAN_OFF, "off" }, { 2, UNDERSCAN_ON, "on" }, {} }; static struct drm_prop_enum_list dither_mode[] = { { 7, DITHERING_MODE_AUTO, "auto" }, { 7, DITHERING_MODE_OFF, "off" }, { 1, DITHERING_MODE_ON, "on" }, { 6, DITHERING_MODE_STATIC2X2, "static 2x2" }, { 6, DITHERING_MODE_DYNAMIC2X2, "dynamic 2x2" }, { 4, DITHERING_MODE_TEMPORAL, "temporal" }, {} }; static struct drm_prop_enum_list dither_depth[] = { { 6, DITHERING_DEPTH_AUTO, "auto" }, { 6, DITHERING_DEPTH_6BPC, "6 bpc" }, { 6, DITHERING_DEPTH_8BPC, "8 bpc" }, {} }; #define PROP_ENUM(p,gen,n,list) do { \ struct drm_prop_enum_list *l = (list); \ int c = 0; \ while (l->gen_mask) { \ if (l->gen_mask & (1 << (gen))) \ c++; \ l++; \ } \ if (c) { \ p = drm_property_create(dev, DRM_MODE_PROP_ENUM, n, c); \ l = (list); \ c = 0; \ while (p && l->gen_mask) { \ if (l->gen_mask & (1 << (gen))) { \ drm_property_add_enum(p, c, l->type, l->name); \ c++; \ } \ l++; \ } \ } \ } while(0) int nouveau_display_create(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = dev->dev_private; struct nouveau_display_engine *disp = &dev_priv->engine.display; int ret, cnt, i; int ret, gen; drm_mode_config_init(dev); drm_mode_create_scaling_mode_property(dev); drm_mode_create_dithering_property(dev); cnt = ARRAY_SIZE(nouveau_underscan_enum_list); disp->underscan_property = drm_property_create(dev, DRM_MODE_PROP_ENUM, "underscan", cnt); for (i = 0; i < cnt; i++) { drm_property_add_enum(disp->underscan_property, i, nouveau_underscan_enum_list[i].type, nouveau_underscan_enum_list[i].name); } if (dev_priv->card_type < NV_50) gen = 0; else if (dev_priv->card_type < NV_D0) gen = 1; else gen = 2; PROP_ENUM(disp->dithering_mode, gen, "dithering mode", dither_mode); PROP_ENUM(disp->dithering_depth, gen, "dithering depth", dither_depth); PROP_ENUM(disp->underscan_property, gen, "underscan", underscan); disp->underscan_hborder_property = drm_property_create(dev, DRM_MODE_PROP_RANGE, Loading
drivers/gpu/drm/nouveau/nouveau_drv.h +2 −6 Original line number Diff line number Diff line Loading @@ -391,12 +391,6 @@ struct nouveau_fifo_engine { void (*tlb_flush)(struct drm_device *dev); }; enum nouveau_underscan_type { UNDERSCAN_OFF, UNDERSCAN_ON, UNDERSCAN_AUTO, }; struct nouveau_display_engine { void *priv; int (*early_init)(struct drm_device *); Loading @@ -405,6 +399,8 @@ struct nouveau_display_engine { int (*init)(struct drm_device *); void (*destroy)(struct drm_device *); struct drm_property *dithering_mode; struct drm_property *dithering_depth; struct drm_property *underscan_property; struct drm_property *underscan_hborder_property; struct drm_property *underscan_vborder_property; Loading
drivers/gpu/drm/nouveau/nv04_dfp.c +4 −1 Original line number Diff line number Diff line Loading @@ -289,6 +289,7 @@ static void nv04_dfp_mode_set(struct drm_encoder *encoder, struct nouveau_connector *nv_connector = nouveau_crtc_connector_get(nv_crtc); struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); struct drm_display_mode *output_mode = &nv_encoder->mode; struct drm_connector *connector = &nv_connector->base; uint32_t mode_ratio, panel_ratio; NV_DEBUG_KMS(dev, "Output mode on CRTC %d:\n", nv_crtc->index); Loading Loading @@ -407,7 +408,9 @@ static void nv04_dfp_mode_set(struct drm_encoder *encoder, } /* Output property. */ if (nv_connector->use_dithering) { if ((nv_connector->dithering_mode == DITHERING_MODE_ON) || (nv_connector->dithering_mode == DITHERING_MODE_AUTO && encoder->crtc->fb->depth > connector->display_info.bpc * 3)) { if (dev_priv->chipset == 0x11) regp->dither = savep->dither | 0x00010000; else { Loading