Skip to content

Commit

Permalink
drm/gma500: Refactor backlight support
Browse files Browse the repository at this point in the history
Refactor backlight support so that the gma_backlight_enable() /
gma_backlight_disable() / gma_backlight_set() functions used by
the Opregion handle will also work if no backlight_device gets
registered.

This is a preparation patch for not registering the gma500's own backlight
device when acpi_video should be used, since registering 2 backlight
devices for a single display really is undesirable.

Since the acpi-video interface often uses the OpRegion we need to keep
the OpRegion functional even when dev_priv->backlight_device is NULL.

As a result of this refactor the actual backlight_device_register()
call is moved to the shared backlight.c code and all #ifdefs related to
CONFIG_BACKLIGHT_CLASS_DEVICE are now also limited to backlight.c .

No functional changes intended.

This has been tested on a Packard Bell Dot SC (Intel Atom N2600, cedarview)
and a Sony Vaio vpc-x11s1e (Intel N540, poulsbo) laptop.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
  • Loading branch information
jwrdegoede committed Sep 6, 2022
1 parent e3c1ed7 commit 97a1dbb
Show file tree
Hide file tree
Showing 6 changed files with 84 additions and 220 deletions.
96 changes: 62 additions & 34 deletions drivers/gpu/drm/gma500/backlight.c
Expand Up @@ -13,69 +13,97 @@
#include "intel_bios.h"
#include "power.h"

#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
static void do_gma_backlight_set(struct drm_device *dev)
{
struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
backlight_update_status(dev_priv->backlight_device);
}
#endif

void gma_backlight_enable(struct drm_device *dev)
{
#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
struct drm_psb_private *dev_priv = to_drm_psb_private(dev);

dev_priv->backlight_enabled = true;
if (dev_priv->backlight_device) {
dev_priv->backlight_device->props.brightness = dev_priv->backlight_level;
do_gma_backlight_set(dev);
}
#endif
dev_priv->ops->backlight_set(dev, dev_priv->backlight_level);
}

void gma_backlight_disable(struct drm_device *dev)
{
#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
struct drm_psb_private *dev_priv = to_drm_psb_private(dev);

dev_priv->backlight_enabled = false;
if (dev_priv->backlight_device) {
dev_priv->backlight_device->props.brightness = 0;
do_gma_backlight_set(dev);
}
#endif
dev_priv->ops->backlight_set(dev, 0);
}

void gma_backlight_set(struct drm_device *dev, int v)
{
#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
struct drm_psb_private *dev_priv = to_drm_psb_private(dev);

dev_priv->backlight_level = v;
if (dev_priv->backlight_device && dev_priv->backlight_enabled) {
dev_priv->backlight_device->props.brightness = v;
do_gma_backlight_set(dev);
}
#endif
if (dev_priv->backlight_enabled)
dev_priv->ops->backlight_set(dev, v);
}

static int gma_backlight_get_brightness(struct backlight_device *bd)
{
struct drm_device *dev = bl_get_data(bd);
struct drm_psb_private *dev_priv = to_drm_psb_private(dev);

if (dev_priv->ops->backlight_get)
return dev_priv->ops->backlight_get(dev);

return dev_priv->backlight_level;
}

static int gma_backlight_update_status(struct backlight_device *bd)
{
struct drm_device *dev = bl_get_data(bd);
struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
int level = bd->props.brightness;

/* Percentage 1-100% being valid */
if (level < 1)
level = 1;

dev_priv->backlight_level = level;
dev_priv->ops->backlight_set(dev, level);
return 0;
}

static const struct backlight_ops gma_backlight_ops = {
.get_brightness = gma_backlight_get_brightness,
.update_status = gma_backlight_update_status,
};

int gma_backlight_init(struct drm_device *dev)
{
#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
struct backlight_properties props = {};
int ret;

dev_priv->backlight_enabled = true;
return dev_priv->ops->backlight_init(dev);
#else
return 0;
dev_priv->backlight_level = 100;

ret = dev_priv->ops->backlight_init(dev);
if (ret)
return ret;

#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
props.brightness = dev_priv->backlight_level;
props.max_brightness = 100;
props.type = BACKLIGHT_PLATFORM;

dev_priv->backlight_device =
backlight_device_register(dev_priv->ops->backlight_name,
dev->dev, dev,
&gma_backlight_ops, &props);
if (IS_ERR(dev_priv->backlight_device))
return PTR_ERR(dev_priv->backlight_device);
#endif

return 0;
}

void gma_backlight_exit(struct drm_device *dev)
{
#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
if (dev_priv->backlight_device) {
dev_priv->backlight_device->props.brightness = 0;
backlight_update_status(dev_priv->backlight_device);

if (dev_priv->backlight_device)
backlight_device_unregister(dev_priv->backlight_device);
}
#endif
}
50 changes: 9 additions & 41 deletions drivers/gpu/drm/gma500/cdv_device.c
Expand Up @@ -5,7 +5,6 @@
*
**************************************************************************/

#include <linux/backlight.h>
#include <linux/delay.h>

#include <drm/drm.h>
Expand Down Expand Up @@ -62,14 +61,10 @@ static int cdv_output_init(struct drm_device *dev)
return 0;
}

#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE

/*
* Cedartrail Backlght Interfaces
*/

static struct backlight_device *cdv_backlight_device;

static int cdv_backlight_combination_mode(struct drm_device *dev)
{
return REG_READ(BLC_PWM_CTL2) & PWM_LEGACY_MODE;
Expand All @@ -92,9 +87,8 @@ static u32 cdv_get_max_backlight(struct drm_device *dev)
return max;
}

static int cdv_get_brightness(struct backlight_device *bd)
static int cdv_get_brightness(struct drm_device *dev)
{
struct drm_device *dev = bl_get_data(bd);
struct pci_dev *pdev = to_pci_dev(dev->dev);
u32 val = REG_READ(BLC_PWM_CTL) & BACKLIGHT_DUTY_CYCLE_MASK;

Expand All @@ -106,20 +100,13 @@ static int cdv_get_brightness(struct backlight_device *bd)
val *= lbpc;
}
return (val * 100)/cdv_get_max_backlight(dev);

}

static int cdv_set_brightness(struct backlight_device *bd)
static void cdv_set_brightness(struct drm_device *dev, int level)
{
struct drm_device *dev = bl_get_data(bd);
struct pci_dev *pdev = to_pci_dev(dev->dev);
int level = bd->props.brightness;
u32 blc_pwm_ctl;

/* Percentage 1-100% being valid */
if (level < 1)
level = 1;

level *= cdv_get_max_backlight(dev);
level /= 100;

Expand All @@ -136,38 +123,18 @@ static int cdv_set_brightness(struct backlight_device *bd)
blc_pwm_ctl = REG_READ(BLC_PWM_CTL) & ~BACKLIGHT_DUTY_CYCLE_MASK;
REG_WRITE(BLC_PWM_CTL, (blc_pwm_ctl |
(level << BACKLIGHT_DUTY_CYCLE_SHIFT)));
return 0;
}

static const struct backlight_ops cdv_ops = {
.get_brightness = cdv_get_brightness,
.update_status = cdv_set_brightness,
};

static int cdv_backlight_init(struct drm_device *dev)
{
struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
struct backlight_properties props;

memset(&props, 0, sizeof(struct backlight_properties));
props.max_brightness = 100;
props.type = BACKLIGHT_PLATFORM;

cdv_backlight_device = backlight_device_register("psb-bl",
NULL, (void *)dev, &cdv_ops, &props);
if (IS_ERR(cdv_backlight_device))
return PTR_ERR(cdv_backlight_device);

cdv_backlight_device->props.brightness =
cdv_get_brightness(cdv_backlight_device);
backlight_update_status(cdv_backlight_device);
dev_priv->backlight_device = cdv_backlight_device;
dev_priv->backlight_enabled = true;

dev_priv->backlight_level = cdv_get_brightness(dev);
cdv_set_brightness(dev, dev_priv->backlight_level);

return 0;
}

#endif

/*
* Provide the Cedarview specific chip logic and low level methods
* for power management
Expand Down Expand Up @@ -613,9 +580,10 @@ const struct psb_ops cdv_chip_ops = {
.hotplug = cdv_hotplug_event,
.hotplug_enable = cdv_hotplug_enable,

#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
.backlight_init = cdv_backlight_init,
#endif
.backlight_get = cdv_get_brightness,
.backlight_set = cdv_set_brightness,
.backlight_name = "psb-bl",

.init_pm = cdv_init_pm,
.save_regs = cdv_save_display_registers,
Expand Down
64 changes: 4 additions & 60 deletions drivers/gpu/drm/gma500/oaktrail_device.c
Expand Up @@ -5,7 +5,6 @@
*
**************************************************************************/

#include <linux/backlight.h>
#include <linux/delay.h>
#include <linux/dmi.h>
#include <linux/module.h>
Expand Down Expand Up @@ -37,29 +36,18 @@ static int oaktrail_output_init(struct drm_device *dev)
* Provide the low level interfaces for the Moorestown backlight
*/

#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE

#define MRST_BLC_MAX_PWM_REG_FREQ 0xFFFF
#define BLC_PWM_PRECISION_FACTOR 100 /* 10000000 */
#define BLC_PWM_FREQ_CALC_CONSTANT 32
#define MHz 1000000
#define BLC_ADJUSTMENT_MAX 100

static struct backlight_device *oaktrail_backlight_device;
static int oaktrail_brightness;

static int oaktrail_set_brightness(struct backlight_device *bd)
static void oaktrail_set_brightness(struct drm_device *dev, int level)
{
struct drm_device *dev = bl_get_data(oaktrail_backlight_device);
struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
int level = bd->props.brightness;
u32 blc_pwm_ctl;
u32 max_pwm_blc;

/* Percentage 1-100% being valid */
if (level < 1)
level = 1;

if (gma_power_begin(dev, 0)) {
/* Calculate and set the brightness value */
max_pwm_blc = REG_READ(BLC_PWM_CTL) >> 16;
Expand All @@ -82,19 +70,9 @@ static int oaktrail_set_brightness(struct backlight_device *bd)
REG_WRITE(BLC_PWM_CTL, (max_pwm_blc << 16) | blc_pwm_ctl);
gma_power_end(dev);
}
oaktrail_brightness = level;
return 0;
}

static int oaktrail_get_brightness(struct backlight_device *bd)
{
/* return locally cached var instead of HW read (due to DPST etc.) */
/* FIXME: ideally return actual value in case firmware fiddled with
it */
return oaktrail_brightness;
}

static int device_backlight_init(struct drm_device *dev)
static int oaktrail_backlight_init(struct drm_device *dev)
{
struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
unsigned long core_clock;
Expand Down Expand Up @@ -123,44 +101,11 @@ static int device_backlight_init(struct drm_device *dev)
REG_WRITE(BLC_PWM_CTL, value | (value << 16));
gma_power_end(dev);
}
return 0;
}

static const struct backlight_ops oaktrail_ops = {
.get_brightness = oaktrail_get_brightness,
.update_status = oaktrail_set_brightness,
};

static int oaktrail_backlight_init(struct drm_device *dev)
{
struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
int ret;
struct backlight_properties props;

memset(&props, 0, sizeof(struct backlight_properties));
props.max_brightness = 100;
props.type = BACKLIGHT_PLATFORM;

oaktrail_backlight_device = backlight_device_register("oaktrail-bl",
NULL, (void *)dev, &oaktrail_ops, &props);

if (IS_ERR(oaktrail_backlight_device))
return PTR_ERR(oaktrail_backlight_device);

ret = device_backlight_init(dev);
if (ret < 0) {
backlight_device_unregister(oaktrail_backlight_device);
return ret;
}
oaktrail_backlight_device->props.brightness = 100;
oaktrail_backlight_device->props.max_brightness = 100;
backlight_update_status(oaktrail_backlight_device);
dev_priv->backlight_device = oaktrail_backlight_device;
oaktrail_set_brightness(dev, 100);
return 0;
}

#endif

/*
* Provide the Moorestown specific chip logic and low level methods
* for power management
Expand Down Expand Up @@ -545,9 +490,8 @@ const struct psb_ops oaktrail_chip_ops = {

.output_init = oaktrail_output_init,

#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
.backlight_init = oaktrail_backlight_init,
#endif
.backlight_set = oaktrail_set_brightness,

.save_regs = oaktrail_save_display_registers,
.restore_regs = oaktrail_restore_display_registers,
Expand Down

0 comments on commit 97a1dbb

Please sign in to comment.