From e12511f5643b8f98e7bd17fc6857d8a65e25d964 Mon Sep 17 00:00:00 2001 From: kettenis Date: Wed, 5 Jul 2017 20:30:13 +0000 Subject: [PATCH] Fix native/raw backlight support in inteldrm(4). --- sys/dev/pci/drm/drmP.h | 5 +-- sys/dev/pci/drm/drm_linux.c | 22 +++++++++++- sys/dev/pci/drm/drm_linux.h | 36 ++++++++++++++++++- sys/dev/pci/drm/i915/i915_drv.c | 31 ++++++++++------ sys/dev/pci/drm/i915/i915_drv.h | 11 ++---- sys/dev/pci/drm/i915/intel_panel.c | 6 ---- sys/dev/pci/drm/radeon/atombios_encoders.c | 4 ++- .../pci/drm/radeon/radeon_legacy_encoders.c | 9 ++--- 8 files changed, 88 insertions(+), 36 deletions(-) diff --git a/sys/dev/pci/drm/drmP.h b/sys/dev/pci/drm/drmP.h index 3e2b9127d12..2eebfe58e0a 100644 --- a/sys/dev/pci/drm/drmP.h +++ b/sys/dev/pci/drm/drmP.h @@ -1,4 +1,4 @@ -/* $OpenBSD: drmP.h,v 1.212 2017/07/01 16:00:25 kettenis Exp $ */ +/* $OpenBSD: drmP.h,v 1.213 2017/07/05 20:30:13 kettenis Exp $ */ /* drmP.h -- Private header for Direct Rendering Manager -*- linux-c -*- * Created: Mon Jan 4 10:05:05 1999 by faith@precisioninsight.com */ @@ -67,7 +67,8 @@ #include #include -#define CONFIG_DRM_FBDEV_EMULATION +#define CONFIG_DRM_FBDEV_EMULATION 1 +#define CONFIG_BACKLIGHT_CLASS_DEVICE 1 #include "drm_linux.h" #include "drm_linux_list.h" diff --git a/sys/dev/pci/drm/drm_linux.c b/sys/dev/pci/drm/drm_linux.c index 1c713a60f70..6cf08ca251f 100644 --- a/sys/dev/pci/drm/drm_linux.c +++ b/sys/dev/pci/drm/drm_linux.c @@ -1,4 +1,4 @@ -/* $OpenBSD: drm_linux.c,v 1.13 2017/07/01 16:14:10 kettenis Exp $ */ +/* $OpenBSD: drm_linux.c,v 1.14 2017/07/05 20:30:13 kettenis Exp $ */ /* * Copyright (c) 2013 Jonathan Gray * Copyright (c) 2015, 2016 Mark Kettenis @@ -696,3 +696,23 @@ acpi_get_table_with_size(const char *sig, int instance, } #endif + +struct backlight_device * +backlight_device_register(const char *name, void *kdev, void *data, + const struct backlight_ops *ops, struct backlight_properties *props) +{ + struct backlight_device *bd; + + bd = malloc(sizeof(*bd), M_DRM, M_WAITOK); + bd->ops = ops; + bd->props = *props; + bd->data = data; + + return bd; +} + +void +backlight_device_unregister(struct backlight_device *bd) +{ + free(bd, M_DRM, sizeof(*bd)); +} diff --git a/sys/dev/pci/drm/drm_linux.h b/sys/dev/pci/drm/drm_linux.h index 82910492e11..46069445fc7 100644 --- a/sys/dev/pci/drm/drm_linux.h +++ b/sys/dev/pci/drm/drm_linux.h @@ -1,4 +1,4 @@ -/* $OpenBSD: drm_linux.h,v 1.52 2017/07/02 20:58:55 kettenis Exp $ */ +/* $OpenBSD: drm_linux.h,v 1.53 2017/07/05 20:30:13 kettenis Exp $ */ /* * Copyright (c) 2013, 2014, 2015 Mark Kettenis * @@ -1900,6 +1900,40 @@ acpi_status acpi_get_table_with_size(const char *, int, struct acpi_table_header #define acpi_video_register() #define acpi_video_unregister() +struct backlight_device; + +struct backlight_properties { + int type; + int max_brightness; + int brightness; + int power; +}; + +struct backlight_ops { + int (*update_status)(struct backlight_device *); + int (*get_brightness)(struct backlight_device *); +}; + +struct backlight_device { + const struct backlight_ops *ops; + struct backlight_properties props; + void *data; +}; + +#define bl_get_data(bd) (bd)->data + +#define BACKLIGHT_RAW 0 + +struct backlight_device *backlight_device_register(const char *, void *, + void *, const struct backlight_ops *, struct backlight_properties *); +void backlight_device_unregister(struct backlight_device *); + +static inline void +backlight_update_status(struct backlight_device *bd) +{ + bd->ops->update_status(bd); +}; + #define MIPI_DSI_V_SYNC_START 0x01 #define MIPI_DSI_V_SYNC_END 0x11 #define MIPI_DSI_H_SYNC_START 0x21 diff --git a/sys/dev/pci/drm/i915/i915_drv.c b/sys/dev/pci/drm/i915/i915_drv.c index a34396f623e..1e51de3a754 100644 --- a/sys/dev/pci/drm/i915/i915_drv.c +++ b/sys/dev/pci/drm/i915/i915_drv.c @@ -1921,7 +1921,7 @@ int inteldrm_wsioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p) { struct inteldrm_softc *dev_priv = v; - struct drm_device *dev = dev_priv->dev; + struct backlight_device *bd = dev_priv->backlight; struct rasops_info *ri = &dev_priv->ro; struct wsdisplay_fbinfo *wdf; struct wsdisplay_param *dp = (struct wsdisplay_param *)data; @@ -1941,14 +1941,14 @@ inteldrm_wsioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p) if (ws_get_param && ws_get_param(dp) == 0) return 0; - if (dev_priv->backlight.connector == NULL) + if (bd == NULL) return -1; switch (dp->param) { case WSDISPLAYIO_PARAM_BRIGHTNESS: dp->min = 0; - dp->max = dev_priv->backlight.props.max_brightness; - dp->curval = dev_priv->backlight.props.brightness; + dp->max = bd->props.max_brightness; + dp->curval = bd->ops->get_brightness(bd); return (dp->max > dp->min) ? 0 : -1; } break; @@ -1956,16 +1956,13 @@ inteldrm_wsioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p) if (ws_set_param && ws_set_param(dp) == 0) return 0; - if (dev_priv->backlight.connector == NULL || - dp->curval > dev_priv->backlight.props.max_brightness) + if (bd == NULL || dp->curval > bd->props.max_brightness) return -1; switch (dp->param) { case WSDISPLAYIO_PARAM_BRIGHTNESS: - mutex_lock(&dev->mode_config.mutex); - intel_panel_set_backlight_acpi(dev_priv->backlight.connector, - dp->curval, dev_priv->backlight.props.max_brightness); - mutex_unlock(&dev->mode_config.mutex); + bd->props.brightness = dp->curval; + backlight_update_status(bd); return 0; } break; @@ -2129,6 +2126,7 @@ inteldrm_attach(struct device *parent, struct device *self, void *aux) struct pci_attach_args *pa = aux; const struct drm_pcidev *id; struct intel_device_info *info, *device_info; + struct intel_connector *intel_connector; struct rasops_info *ri = &dev_priv->ro; struct wsemuldisplaydev_attach_args aa; extern int vga_console_attached; @@ -2244,6 +2242,19 @@ inteldrm_attach(struct device *parent, struct device *self, void *aux) intel_fbdev_restore_mode(dev); + /* Grab backlight from the first connector that has one. */ + drm_modeset_lock(&dev->mode_config.connection_mutex, NULL); + list_for_each_entry(intel_connector, &dev->mode_config.connector_list, + base.head) { + struct intel_panel *panel = &intel_connector->panel; + + if (panel->backlight.present) { + dev_priv->backlight = panel->backlight.device; + break; + } + } + drm_modeset_unlock(&dev->mode_config.connection_mutex); + ri->ri_flg = RI_CENTER | RI_WRONLY | RI_VCONS | RI_CLEAR; ri->ri_hw = dev_priv; rasops_init(ri, 160, 160); diff --git a/sys/dev/pci/drm/i915/i915_drv.h b/sys/dev/pci/drm/i915/i915_drv.h index a688d55247c..4b8168028bb 100644 --- a/sys/dev/pci/drm/i915/i915_drv.h +++ b/sys/dev/pci/drm/i915/i915_drv.h @@ -1,4 +1,4 @@ -/* $OpenBSD: i915_drv.h,v 1.75 2017/07/01 16:14:10 kettenis Exp $ */ +/* $OpenBSD: i915_drv.h,v 1.76 2017/07/05 20:30:13 kettenis Exp $ */ /* i915_drv.h -- Private header for the I915 driver -*- linux-c -*- */ /* @@ -1817,14 +1817,7 @@ struct inteldrm_softc { struct task burner_task; int burner_fblank; - struct backlight_device { - struct intel_connector *connector; - struct { - uint32_t brightness; - uint32_t max_brightness; - uint32_t power; - } props; - } backlight; + struct backlight_device *backlight; struct intel_uncore uncore; diff --git a/sys/dev/pci/drm/i915/intel_panel.c b/sys/dev/pci/drm/i915/intel_panel.c index 838eb81ecf2..2ffd76489d6 100644 --- a/sys/dev/pci/drm/i915/intel_panel.c +++ b/sys/dev/pci/drm/i915/intel_panel.c @@ -553,7 +553,6 @@ static u32 pwm_get_backlight(struct intel_connector *connector) return DIV_ROUND_UP(duty_ns * 100, CRC_PMIC_PWM_PERIOD_NS); } -#ifdef __linux__ static u32 intel_panel_get_backlight(struct intel_connector *connector) { struct drm_device *dev = connector->base.dev; @@ -573,7 +572,6 @@ static u32 intel_panel_get_backlight(struct intel_connector *connector) DRM_DEBUG_DRIVER("get backlight PWM = %d\n", val); return val; } -#endif static void lpt_set_backlight(struct intel_connector *connector, u32 level) { @@ -663,8 +661,6 @@ intel_panel_actually_set_backlight(struct intel_connector *connector, u32 level) panel->backlight.set(connector, level); } -#ifdef __linux__ - /* set backlight brightness to level in range [0..max], scaling wrt hw min */ static void intel_panel_set_backlight(struct intel_connector *connector, u32 user_level, u32 user_max) @@ -690,8 +686,6 @@ static void intel_panel_set_backlight(struct intel_connector *connector, mutex_unlock(&dev_priv->backlight_lock); } -#endif - /* set backlight brightness to level in range [0..max], assuming hw min is * respected. */ diff --git a/sys/dev/pci/drm/radeon/atombios_encoders.c b/sys/dev/pci/drm/radeon/atombios_encoders.c index 4d0cbe811c0..e4cb31aa172 100644 --- a/sys/dev/pci/drm/radeon/atombios_encoders.c +++ b/sys/dev/pci/drm/radeon/atombios_encoders.c @@ -1,4 +1,4 @@ -/* $OpenBSD: atombios_encoders.c,v 1.9 2015/04/18 14:47:34 jsg Exp $ */ +/* $OpenBSD: atombios_encoders.c,v 1.10 2017/07/05 20:30:13 kettenis Exp $ */ /* * Copyright 2007-11 Advanced Micro Devices, Inc. * Copyright 2008 Red Hat Inc. @@ -204,8 +204,10 @@ void radeon_atom_backlight_init(struct radeon_encoder *radeon_encoder, memset(&props, 0, sizeof(props)); props.max_brightness = RADEON_MAX_BL_LEVEL; props.type = BACKLIGHT_RAW; +#ifdef __linux__ snprintf(bl_name, sizeof(bl_name), "radeon_bl%d", dev->primary->index); +#endif bd = backlight_device_register(bl_name, &drm_connector->kdev, pdata, &radeon_atom_backlight_ops, &props); if (IS_ERR(bd)) { diff --git a/sys/dev/pci/drm/radeon/radeon_legacy_encoders.c b/sys/dev/pci/drm/radeon/radeon_legacy_encoders.c index 3f26f128451..0e36ccab358 100644 --- a/sys/dev/pci/drm/radeon/radeon_legacy_encoders.c +++ b/sys/dev/pci/drm/radeon/radeon_legacy_encoders.c @@ -1,4 +1,4 @@ -/* $OpenBSD: radeon_legacy_encoders.c,v 1.5 2017/07/01 16:14:10 kettenis Exp $ */ +/* $OpenBSD: radeon_legacy_encoders.c,v 1.6 2017/07/05 20:30:13 kettenis Exp $ */ /* * Copyright 2007-8 Advanced Micro Devices, Inc. * Copyright 2008 Red Hat Inc. @@ -30,11 +30,6 @@ #include "radeon.h" #include "atom.h" -u8 radeon_legacy_get_backlight_level(struct radeon_encoder *); -void radeon_legacy_set_backlight_level(struct radeon_encoder *, u8); -void radeon_legacy_backlight_init(struct radeon_encoder *); -void radeon_add_legacy_encoder(struct drm_device *, uint32_t, uint32_t); - static void radeon_legacy_encoder_disable(struct drm_encoder *encoder) { struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); @@ -392,8 +387,10 @@ void radeon_legacy_backlight_init(struct radeon_encoder *radeon_encoder, memset(&props, 0, sizeof(props)); props.max_brightness = RADEON_MAX_BL_LEVEL; props.type = BACKLIGHT_RAW; +#ifdef __linux__ snprintf(bl_name, sizeof(bl_name), "radeon_bl%d", dev->primary->index); +#endif bd = backlight_device_register(bl_name, &drm_connector->kdev, pdata, &radeon_backlight_ops, &props); if (IS_ERR(bd)) { -- 2.20.1