diff options
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/pci/drm/drm_crtc.c | 23 | ||||
-rw-r--r-- | sys/dev/pci/drm/drm_crtc.h | 5 | ||||
-rw-r--r-- | sys/dev/pci/drm/drm_linux.c | 16 | ||||
-rw-r--r-- | sys/dev/pci/drm/drm_linux.h | 10 | ||||
-rw-r--r-- | sys/dev/pci/drm/i915/i915_drv.c | 120 |
5 files changed, 157 insertions, 17 deletions
diff --git a/sys/dev/pci/drm/drm_crtc.c b/sys/dev/pci/drm/drm_crtc.c index db3ececb00c..874388fdd23 100644 --- a/sys/dev/pci/drm/drm_crtc.c +++ b/sys/dev/pci/drm/drm_crtc.c @@ -4049,6 +4049,23 @@ int drm_object_property_get_value(struct drm_mode_object *obj, { int i; +#ifdef __OpenBSD__ + if (obj->type == DRM_MODE_OBJECT_CONNECTOR) { + struct drm_connector *connector = obj_to_connector(obj); + + if (property == connector->backlight_property) { + struct backlight_device *bd = + connector->backlight_device; + + if (bd->props.type == BACKLIGHT_FIRMWARE) + *val = bd->ops->get_brightness(bd); + else + *val = bd->props.brightness; + return 0; + } + } +#endif + /* read-only properties bypass atomic mechanism and still store * their value in obj->properties->values[].. mostly to avoid * having to deal w/ EDID and similar props in atomic paths: @@ -4840,6 +4857,12 @@ static int drm_mode_connector_set_obj_prop(struct drm_mode_object *obj, ret = 0; if (connector->funcs->dpms) ret = (*connector->funcs->dpms)(connector, (int)value); +#ifdef __OpenBSD__ + } else if (property == connector->backlight_property) { + ret = 0; + connector->backlight_device->props.brightness = value; + backlight_schedule_update_status(connector->backlight_device); +#endif } else if (connector->funcs->set_property) ret = connector->funcs->set_property(connector, property, value); diff --git a/sys/dev/pci/drm/drm_crtc.h b/sys/dev/pci/drm/drm_crtc.h index 978643ad1e5..bc5474cb422 100644 --- a/sys/dev/pci/drm/drm_crtc.h +++ b/sys/dev/pci/drm/drm_crtc.h @@ -741,6 +741,11 @@ struct drm_connector { uint8_t num_h_tile, num_v_tile; uint8_t tile_h_loc, tile_v_loc; uint16_t tile_h_size, tile_v_size; + +#ifdef __OpenBSD__ + struct backlight_device *backlight_device; + struct drm_property *backlight_property; +#endif }; /** diff --git a/sys/dev/pci/drm/drm_linux.c b/sys/dev/pci/drm/drm_linux.c index 6cf08ca251f..03ada0f9750 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.14 2017/07/05 20:30:13 kettenis Exp $ */ +/* $OpenBSD: drm_linux.c,v 1.15 2017/07/12 20:12:19 kettenis Exp $ */ /* * Copyright (c) 2013 Jonathan Gray <jsg@openbsd.org> * Copyright (c) 2015, 2016 Mark Kettenis <kettenis@openbsd.org> @@ -697,6 +697,12 @@ acpi_get_table_with_size(const char *sig, int instance, #endif +void +backlight_do_update_status(void *arg) +{ + backlight_update_status(arg); +} + struct backlight_device * backlight_device_register(const char *name, void *kdev, void *data, const struct backlight_ops *ops, struct backlight_properties *props) @@ -707,6 +713,8 @@ backlight_device_register(const char *name, void *kdev, void *data, bd->ops = ops; bd->props = *props; bd->data = data; + + task_set(&bd->task, backlight_do_update_status, bd); return bd; } @@ -716,3 +724,9 @@ backlight_device_unregister(struct backlight_device *bd) { free(bd, M_DRM, sizeof(*bd)); } + +void +backlight_schedule_update_status(struct backlight_device *bd) +{ + task_add(systq, &bd->task); +} diff --git a/sys/dev/pci/drm/drm_linux.h b/sys/dev/pci/drm/drm_linux.h index 099d4710788..1d6c739b151 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.54 2017/07/07 18:06:51 kettenis Exp $ */ +/* $OpenBSD: drm_linux.h,v 1.55 2017/07/12 20:12:19 kettenis Exp $ */ /* * Copyright (c) 2013, 2014, 2015 Mark Kettenis * @@ -1917,12 +1917,14 @@ struct backlight_ops { struct backlight_device { const struct backlight_ops *ops; struct backlight_properties props; + struct task task; void *data; }; #define bl_get_data(bd) (bd)->data -#define BACKLIGHT_RAW 0 +#define BACKLIGHT_RAW 0 +#define BACKLIGHT_FIRMWARE 1 struct backlight_device *backlight_device_register(const char *, void *, void *, const struct backlight_ops *, struct backlight_properties *); @@ -1932,7 +1934,9 @@ static inline void backlight_update_status(struct backlight_device *bd) { bd->ops->update_status(bd); -}; +} + +void backlight_schedule_update_status(struct backlight_device *); #define MIPI_DSI_V_SYNC_START 0x01 #define MIPI_DSI_V_SYNC_END 0x11 diff --git a/sys/dev/pci/drm/i915/i915_drv.c b/sys/dev/pci/drm/i915/i915_drv.c index 1e51de3a754..327b17e7737 100644 --- a/sys/dev/pci/drm/i915/i915_drv.c +++ b/sys/dev/pci/drm/i915/i915_drv.c @@ -2092,6 +2092,32 @@ inteldrm_burner_cb(void *arg1) drm_fb_helper_blank(dev_priv->burner_fblank, helper->fbdev); } +int +inteldrm_backlight_update_status(struct backlight_device *bd) +{ + struct wsdisplay_param dp; + + dp.param = WSDISPLAYIO_PARAM_BRIGHTNESS; + dp.curval = bd->props.brightness; + ws_set_param(&dp); + return 0; +} + +int +inteldrm_backlight_get_brightness(struct backlight_device *bd) +{ + struct wsdisplay_param dp; + + dp.param = WSDISPLAYIO_PARAM_BRIGHTNESS; + ws_get_param(&dp); + return dp.curval; +} + +const struct backlight_ops inteldrm_backlight_ops = { + .update_status = inteldrm_backlight_update_status, + .get_brightness = inteldrm_backlight_get_brightness +}; + int inteldrm_match(struct device *, void *, void *); void inteldrm_attach(struct device *, struct device *, void *); int inteldrm_detach(struct device *, int); @@ -2106,6 +2132,7 @@ struct cfdriver inteldrm_cd = { 0, "inteldrm", DV_DULL }; +void inteldrm_init_backlight(struct inteldrm_softc *); int inteldrm_intr(void *); int @@ -2126,7 +2153,6 @@ 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; @@ -2242,18 +2268,7 @@ 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); + inteldrm_init_backlight(dev_priv); ri->ri_flg = RI_CENTER | RI_WRONLY | RI_VCONS | RI_CLEAR; ri->ri_hw = dev_priv; @@ -2329,6 +2344,85 @@ inteldrm_activate(struct device *self, int act) return (rv); } +void +inteldrm_native_backlight(struct inteldrm_softc *dev_priv) +{ + struct drm_device *dev = dev_priv->dev; + struct intel_connector *intel_connector; + + list_for_each_entry(intel_connector, + &dev->mode_config.connector_list, base.head) { + struct drm_connector *connector = &intel_connector->base; + struct intel_panel *panel = &intel_connector->panel; + struct backlight_device *bd = panel->backlight.device; + + if (!panel->backlight.present) + continue; + + connector->backlight_device = bd; + connector->backlight_property = drm_property_create_range(dev, + 0, "Backlight", 0, bd->props.max_brightness); + drm_object_attach_property(&connector->base, + connector->backlight_property, bd->props.brightness); + + /* + * Use backlight from the first connector that has one + * for wscons(4). + */ + if (dev_priv->backlight == NULL) + dev_priv->backlight = bd; + } +} + +void +inteldrm_firmware_backlight(struct inteldrm_softc *dev_priv, + struct wsdisplay_param *dp) +{ + struct drm_device *dev = dev_priv->dev; + struct intel_connector *intel_connector; + struct backlight_properties props; + struct backlight_device *bd; + + memset(&props, 0, sizeof(props)); + props.type = BACKLIGHT_FIRMWARE; + props.brightness = dp->curval; + bd = backlight_device_register(dev->device.dv_xname, NULL, NULL, + &inteldrm_backlight_ops, &props); + + list_for_each_entry(intel_connector, + &dev->mode_config.connector_list, base.head) { + struct drm_connector *connector = &intel_connector->base; + + if (connector->connector_type != DRM_MODE_CONNECTOR_LVDS && + connector->connector_type != DRM_MODE_CONNECTOR_eDP && + connector->connector_type != DRM_MODE_CONNECTOR_DSI) + continue; + + connector->backlight_device = bd; + connector->backlight_property = drm_property_create_range(dev, + 0, "Backlight", dp->min, dp->max); + drm_object_attach_property(&connector->base, + connector->backlight_property, dp->curval); + } +} + +void +inteldrm_init_backlight(struct inteldrm_softc *dev_priv) +{ + struct drm_device *dev = dev_priv->dev; + struct wsdisplay_param dp; + + drm_modeset_lock(&dev->mode_config.connection_mutex, NULL); + + dp.param = WSDISPLAYIO_PARAM_BRIGHTNESS; + if (ws_get_param && ws_get_param(&dp) == 0) + inteldrm_firmware_backlight(dev_priv, &dp); + else + inteldrm_native_backlight(dev_priv); + + drm_modeset_unlock(&dev->mode_config.connection_mutex); +} + int inteldrm_intr(void *arg) { |