mirror of https://gitee.com/openkylin/linux.git
drm/nv50/backlight: take the sor into account when bashing regs
I'm sure that out there somewhere, someone will need this. We currently haven't seen an example of LVDS being on a non-0 SOR so far though. Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
This commit is contained in:
parent
730764812d
commit
10b461e40a
|
@ -37,6 +37,7 @@
|
|||
#include "nouveau_drv.h"
|
||||
#include "nouveau_drm.h"
|
||||
#include "nouveau_reg.h"
|
||||
#include "nouveau_encoder.h"
|
||||
|
||||
static int
|
||||
nv40_get_intensity(struct backlight_device *bd)
|
||||
|
@ -96,18 +97,22 @@ nv40_backlight_init(struct drm_connector *connector)
|
|||
static int
|
||||
nv50_get_intensity(struct backlight_device *bd)
|
||||
{
|
||||
struct drm_device *dev = bl_get_data(bd);
|
||||
struct nouveau_encoder *nv_encoder = bl_get_data(bd);
|
||||
struct drm_device *dev = nv_encoder->base.base.dev;
|
||||
int or = nv_encoder->or;
|
||||
|
||||
return nv_rd32(dev, NV50_PDISPLAY_SOR_BACKLIGHT);
|
||||
return nv_rd32(dev, NV50_PDISPLAY_SOR_BACKLIGHT + (or * 0x800));
|
||||
}
|
||||
|
||||
static int
|
||||
nv50_set_intensity(struct backlight_device *bd)
|
||||
{
|
||||
struct drm_device *dev = bl_get_data(bd);
|
||||
struct nouveau_encoder *nv_encoder = bl_get_data(bd);
|
||||
struct drm_device *dev = nv_encoder->base.base.dev;
|
||||
int val = bd->props.brightness;
|
||||
int or = nv_encoder->or;
|
||||
|
||||
nv_wr32(dev, NV50_PDISPLAY_SOR_BACKLIGHT,
|
||||
nv_wr32(dev, NV50_PDISPLAY_SOR_BACKLIGHT + (or * 0x800),
|
||||
val | NV50_PDISPLAY_SOR_BACKLIGHT_ENABLE);
|
||||
return 0;
|
||||
}
|
||||
|
@ -123,17 +128,28 @@ nv50_backlight_init(struct drm_connector *connector)
|
|||
{
|
||||
struct drm_device *dev = connector->dev;
|
||||
struct drm_nouveau_private *dev_priv = dev->dev_private;
|
||||
struct nouveau_encoder *nv_encoder;
|
||||
struct backlight_properties props;
|
||||
struct backlight_device *bd;
|
||||
int or;
|
||||
|
||||
if (!nv_rd32(dev, NV50_PDISPLAY_SOR_BACKLIGHT))
|
||||
nv_encoder = find_encoder(connector, OUTPUT_LVDS);
|
||||
if (!nv_encoder) {
|
||||
nv_encoder = find_encoder(connector, OUTPUT_DP);
|
||||
if (!nv_encoder)
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
or = nv_encoder->or;
|
||||
|
||||
if (!nv_rd32(dev, NV50_PDISPLAY_SOR_BACKLIGHT + (or * 0x800)))
|
||||
return 0;
|
||||
|
||||
memset(&props, 0, sizeof(struct backlight_properties));
|
||||
props.type = BACKLIGHT_RAW;
|
||||
props.max_brightness = 1025;
|
||||
bd = backlight_device_register("nv_backlight", &connector->kdev, dev,
|
||||
&nv50_bl_ops, &props);
|
||||
bd = backlight_device_register("nv_backlight", &connector->kdev,
|
||||
nv_encoder, &nv50_bl_ops, &props);
|
||||
if (IS_ERR(bd))
|
||||
return PTR_ERR(bd);
|
||||
|
||||
|
@ -144,10 +160,10 @@ nv50_backlight_init(struct drm_connector *connector)
|
|||
}
|
||||
|
||||
int
|
||||
nouveau_backlight_init(struct drm_connector *connector)
|
||||
nouveau_backlight_init(struct drm_device *dev)
|
||||
{
|
||||
struct drm_device *dev = connector->dev;
|
||||
struct drm_nouveau_private *dev_priv = dev->dev_private;
|
||||
struct drm_connector *connector;
|
||||
|
||||
#ifdef CONFIG_ACPI
|
||||
if (acpi_video_backlight_support()) {
|
||||
|
@ -157,22 +173,28 @@ nouveau_backlight_init(struct drm_connector *connector)
|
|||
}
|
||||
#endif
|
||||
|
||||
switch (dev_priv->card_type) {
|
||||
case NV_40:
|
||||
return nv40_backlight_init(connector);
|
||||
case NV_50:
|
||||
return nv50_backlight_init(connector);
|
||||
default:
|
||||
break;
|
||||
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
|
||||
if (connector->connector_type != DRM_MODE_CONNECTOR_LVDS &&
|
||||
connector->connector_type != DRM_MODE_CONNECTOR_eDP)
|
||||
continue;
|
||||
|
||||
switch (dev_priv->card_type) {
|
||||
case NV_40:
|
||||
return nv40_backlight_init(connector);
|
||||
case NV_50:
|
||||
return nv50_backlight_init(connector);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
nouveau_backlight_exit(struct drm_connector *connector)
|
||||
nouveau_backlight_exit(struct drm_device *dev)
|
||||
{
|
||||
struct drm_device *dev = connector->dev;
|
||||
struct drm_nouveau_private *dev_priv = dev->dev_private;
|
||||
|
||||
if (dev_priv->backlight) {
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
|
||||
static void nouveau_connector_hotplug(void *, int);
|
||||
|
||||
static struct nouveau_encoder *
|
||||
struct nouveau_encoder *
|
||||
find_encoder(struct drm_connector *connector, int type)
|
||||
{
|
||||
struct drm_device *dev = connector->dev;
|
||||
|
@ -116,10 +116,6 @@ nouveau_connector_destroy(struct drm_connector *connector)
|
|||
nouveau_connector_hotplug, connector);
|
||||
}
|
||||
|
||||
if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS ||
|
||||
connector->connector_type == DRM_MODE_CONNECTOR_eDP)
|
||||
nouveau_backlight_exit(connector);
|
||||
|
||||
kfree(nv_connector->edid);
|
||||
drm_sysfs_connector_remove(connector);
|
||||
drm_connector_cleanup(connector);
|
||||
|
@ -901,10 +897,6 @@ nouveau_connector_create(struct drm_device *dev, int index)
|
|||
|
||||
drm_sysfs_connector_add(connector);
|
||||
|
||||
if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS ||
|
||||
connector->connector_type == DRM_MODE_CONNECTOR_eDP)
|
||||
nouveau_backlight_init(connector);
|
||||
|
||||
dcb->drm = connector;
|
||||
return dcb->drm;
|
||||
|
||||
|
|
|
@ -1054,15 +1054,15 @@ static inline int nouveau_acpi_edid(struct drm_device *dev, struct drm_connector
|
|||
|
||||
/* nouveau_backlight.c */
|
||||
#ifdef CONFIG_DRM_NOUVEAU_BACKLIGHT
|
||||
extern int nouveau_backlight_init(struct drm_connector *);
|
||||
extern void nouveau_backlight_exit(struct drm_connector *);
|
||||
extern int nouveau_backlight_init(struct drm_device *);
|
||||
extern void nouveau_backlight_exit(struct drm_device *);
|
||||
#else
|
||||
static inline int nouveau_backlight_init(struct drm_connector *dev)
|
||||
static inline int nouveau_backlight_init(struct drm_device *dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void nouveau_backlight_exit(struct drm_connector *dev) { }
|
||||
static inline void nouveau_backlight_exit(struct drm_device *dev) { }
|
||||
#endif
|
||||
|
||||
/* nouveau_bios.c */
|
||||
|
|
|
@ -57,6 +57,9 @@ struct nouveau_encoder {
|
|||
};
|
||||
};
|
||||
|
||||
struct nouveau_encoder *
|
||||
find_encoder(struct drm_connector *connector, int type);
|
||||
|
||||
static inline struct nouveau_encoder *nouveau_encoder(struct drm_encoder *enc)
|
||||
{
|
||||
struct drm_encoder_slave *slave = to_encoder_slave(enc);
|
||||
|
|
|
@ -728,6 +728,8 @@ nouveau_card_init(struct drm_device *dev)
|
|||
if (ret)
|
||||
goto out_irq;
|
||||
|
||||
nouveau_backlight_init(dev);
|
||||
|
||||
if (dev_priv->eng[NVOBJ_ENGINE_GR]) {
|
||||
ret = nouveau_fence_init(dev);
|
||||
if (ret)
|
||||
|
@ -757,6 +759,7 @@ nouveau_card_init(struct drm_device *dev)
|
|||
out_fence:
|
||||
nouveau_fence_fini(dev);
|
||||
out_disp:
|
||||
nouveau_backlight_exit(dev);
|
||||
engine->display.destroy(dev);
|
||||
out_irq:
|
||||
nouveau_irq_fini(dev);
|
||||
|
@ -817,6 +820,7 @@ static void nouveau_card_takedown(struct drm_device *dev)
|
|||
nouveau_fence_fini(dev);
|
||||
}
|
||||
|
||||
nouveau_backlight_exit(dev);
|
||||
engine->display.destroy(dev);
|
||||
drm_mode_config_cleanup(dev);
|
||||
|
||||
|
|
Loading…
Reference in New Issue