Fix native/raw backlight support in inteldrm(4).
authorkettenis <kettenis@openbsd.org>
Wed, 5 Jul 2017 20:30:13 +0000 (20:30 +0000)
committerkettenis <kettenis@openbsd.org>
Wed, 5 Jul 2017 20:30:13 +0000 (20:30 +0000)
sys/dev/pci/drm/drmP.h
sys/dev/pci/drm/drm_linux.c
sys/dev/pci/drm/drm_linux.h
sys/dev/pci/drm/i915/i915_drv.c
sys/dev/pci/drm/i915/i915_drv.h
sys/dev/pci/drm/i915/intel_panel.c
sys/dev/pci/drm/radeon/atombios_encoders.c
sys/dev/pci/drm/radeon/radeon_legacy_encoders.c

index 3e2b912..2eebfe5 100644 (file)
@@ -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 <dev/pci/agpvar.h>
 #include <machine/bus.h>
 
-#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"
index 1c713a6..6cf08ca 100644 (file)
@@ -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 <jsg@openbsd.org>
  * Copyright (c) 2015, 2016 Mark Kettenis <kettenis@openbsd.org>
@@ -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));
+}
index 8291049..4606944 100644 (file)
@@ -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
index a34396f..1e51de3 100644 (file)
@@ -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);
index a688d55..4b81680 100644 (file)
@@ -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;
 
index 838eb81..2ffd764 100644 (file)
@@ -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.
  */
index 4d0cbe8..e4cb31a 100644 (file)
@@ -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)) {
index 3f26f12..0e36cca 100644 (file)
@@ -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.
 #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)) {