1 // SPDX-License-Identifier: GPL-2.0-only
2 /**************************************************************************
3 * Copyright (c) 2011, Intel Corporation.
6 **************************************************************************/
8 #include <linux/backlight.h>
12 #include "gma_device.h"
13 #include "intel_bios.h"
14 #include "psb_device.h"
16 #include "psb_intel_reg.h"
19 static int psb_output_init(struct drm_device
*dev
)
21 struct drm_psb_private
*dev_priv
= dev
->dev_private
;
22 psb_intel_lvds_init(dev
, &dev_priv
->mode_dev
);
23 psb_intel_sdvo_init(dev
, SDVOB
);
27 #ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
30 * Poulsbo Backlight Interfaces
33 #define BLC_PWM_PRECISION_FACTOR 100 /* 10000000 */
34 #define BLC_PWM_FREQ_CALC_CONSTANT 32
37 #define PSB_BLC_PWM_PRECISION_FACTOR 10
38 #define PSB_BLC_MAX_PWM_REG_FREQ 0xFFFE
39 #define PSB_BLC_MIN_PWM_REG_FREQ 0x2
41 #define PSB_BACKLIGHT_PWM_POLARITY_BIT_CLEAR (0xFFFE)
42 #define PSB_BACKLIGHT_PWM_CTL_SHIFT (16)
44 static int psb_brightness
;
45 static struct backlight_device
*psb_backlight_device
;
47 static int psb_get_brightness(struct backlight_device
*bd
)
49 /* return locally cached var instead of HW read (due to DPST etc.) */
50 /* FIXME: ideally return actual value in case firmware fiddled with
52 return psb_brightness
;
56 static int psb_backlight_setup(struct drm_device
*dev
)
58 struct drm_psb_private
*dev_priv
= dev
->dev_private
;
59 unsigned long core_clock
;
60 /* u32 bl_max_freq; */
61 /* unsigned long value; */
64 uint32_t blc_pwm_precision_factor
;
66 /* get bl_max_freq and pol from dev_priv*/
67 if (!dev_priv
->lvds_bl
) {
68 dev_err(dev
->dev
, "Has no valid LVDS backlight info\n");
71 bl_max_freq
= dev_priv
->lvds_bl
->freq
;
72 blc_pwm_precision_factor
= PSB_BLC_PWM_PRECISION_FACTOR
;
74 core_clock
= dev_priv
->core_freq
;
76 value
= (core_clock
* MHz
) / BLC_PWM_FREQ_CALC_CONSTANT
;
77 value
*= blc_pwm_precision_factor
;
79 value
/= blc_pwm_precision_factor
;
81 if (value
> (unsigned long long)PSB_BLC_MAX_PWM_REG_FREQ
||
82 value
< (unsigned long long)PSB_BLC_MIN_PWM_REG_FREQ
)
85 value
&= PSB_BACKLIGHT_PWM_POLARITY_BIT_CLEAR
;
86 REG_WRITE(BLC_PWM_CTL
,
87 (value
<< PSB_BACKLIGHT_PWM_CTL_SHIFT
) | (value
));
92 static int psb_set_brightness(struct backlight_device
*bd
)
94 struct drm_device
*dev
= bl_get_data(psb_backlight_device
);
95 int level
= bd
->props
.brightness
;
97 /* Percentage 1-100% being valid */
101 psb_intel_lvds_set_brightness(dev
, level
);
102 psb_brightness
= level
;
106 static const struct backlight_ops psb_ops
= {
107 .get_brightness
= psb_get_brightness
,
108 .update_status
= psb_set_brightness
,
111 static int psb_backlight_init(struct drm_device
*dev
)
113 struct drm_psb_private
*dev_priv
= dev
->dev_private
;
115 struct backlight_properties props
;
117 memset(&props
, 0, sizeof(struct backlight_properties
));
118 props
.max_brightness
= 100;
119 props
.type
= BACKLIGHT_PLATFORM
;
121 psb_backlight_device
= backlight_device_register("psb-bl",
122 NULL
, (void *)dev
, &psb_ops
, &props
);
123 if (IS_ERR(psb_backlight_device
))
124 return PTR_ERR(psb_backlight_device
);
126 ret
= psb_backlight_setup(dev
);
128 backlight_device_unregister(psb_backlight_device
);
129 psb_backlight_device
= NULL
;
132 psb_backlight_device
->props
.brightness
= 100;
133 psb_backlight_device
->props
.max_brightness
= 100;
134 backlight_update_status(psb_backlight_device
);
135 dev_priv
->backlight_device
= psb_backlight_device
;
137 /* This must occur after the backlight is properly initialised */
138 psb_lid_timer_init(dev_priv
);
146 * Provide the Poulsbo specific chip logic and low level methods
147 * for power management
150 static void psb_init_pm(struct drm_device
*dev
)
152 struct drm_psb_private
*dev_priv
= dev
->dev_private
;
154 u32 gating
= PSB_RSGX32(PSB_CR_CLKGATECTL
);
155 gating
&= ~3; /* Disable 2D clock gating */
157 PSB_WSGX32(gating
, PSB_CR_CLKGATECTL
);
158 PSB_RSGX32(PSB_CR_CLKGATECTL
);
162 * psb_save_display_registers - save registers lost on suspend
163 * @dev: our DRM device
165 * Save the state we need in order to be able to restore the interface
166 * upon resume from suspend
168 static int psb_save_display_registers(struct drm_device
*dev
)
170 struct drm_psb_private
*dev_priv
= dev
->dev_private
;
171 struct drm_crtc
*crtc
;
172 struct gma_connector
*connector
;
173 struct psb_state
*regs
= &dev_priv
->regs
.psb
;
175 /* Display arbitration control + watermarks */
176 regs
->saveDSPARB
= PSB_RVDC32(DSPARB
);
177 regs
->saveDSPFW1
= PSB_RVDC32(DSPFW1
);
178 regs
->saveDSPFW2
= PSB_RVDC32(DSPFW2
);
179 regs
->saveDSPFW3
= PSB_RVDC32(DSPFW3
);
180 regs
->saveDSPFW4
= PSB_RVDC32(DSPFW4
);
181 regs
->saveDSPFW5
= PSB_RVDC32(DSPFW5
);
182 regs
->saveDSPFW6
= PSB_RVDC32(DSPFW6
);
183 regs
->saveCHICKENBIT
= PSB_RVDC32(DSPCHICKENBIT
);
185 /* Save crtc and output state */
186 drm_modeset_lock_all(dev
);
187 list_for_each_entry(crtc
, &dev
->mode_config
.crtc_list
, head
) {
188 if (drm_helper_crtc_in_use(crtc
))
189 dev_priv
->ops
->save_crtc(crtc
);
192 list_for_each_entry(connector
, &dev
->mode_config
.connector_list
, base
.head
)
194 connector
->save(&connector
->base
);
196 drm_modeset_unlock_all(dev
);
201 * psb_restore_display_registers - restore lost register state
202 * @dev: our DRM device
204 * Restore register state that was lost during suspend and resume.
206 static int psb_restore_display_registers(struct drm_device
*dev
)
208 struct drm_psb_private
*dev_priv
= dev
->dev_private
;
209 struct drm_crtc
*crtc
;
210 struct gma_connector
*connector
;
211 struct psb_state
*regs
= &dev_priv
->regs
.psb
;
213 /* Display arbitration + watermarks */
214 PSB_WVDC32(regs
->saveDSPARB
, DSPARB
);
215 PSB_WVDC32(regs
->saveDSPFW1
, DSPFW1
);
216 PSB_WVDC32(regs
->saveDSPFW2
, DSPFW2
);
217 PSB_WVDC32(regs
->saveDSPFW3
, DSPFW3
);
218 PSB_WVDC32(regs
->saveDSPFW4
, DSPFW4
);
219 PSB_WVDC32(regs
->saveDSPFW5
, DSPFW5
);
220 PSB_WVDC32(regs
->saveDSPFW6
, DSPFW6
);
221 PSB_WVDC32(regs
->saveCHICKENBIT
, DSPCHICKENBIT
);
223 /*make sure VGA plane is off. it initializes to on after reset!*/
224 PSB_WVDC32(0x80000000, VGACNTRL
);
226 drm_modeset_lock_all(dev
);
227 list_for_each_entry(crtc
, &dev
->mode_config
.crtc_list
, head
)
228 if (drm_helper_crtc_in_use(crtc
))
229 dev_priv
->ops
->restore_crtc(crtc
);
231 list_for_each_entry(connector
, &dev
->mode_config
.connector_list
, base
.head
)
232 if (connector
->restore
)
233 connector
->restore(&connector
->base
);
235 drm_modeset_unlock_all(dev
);
239 static int psb_power_down(struct drm_device
*dev
)
244 static int psb_power_up(struct drm_device
*dev
)
250 static const struct psb_offset psb_regmap
[2] = {
264 .stride
= DSPASTRIDE
,
271 .linoff
= DSPALINOFF
,
272 .tileoff
= DSPATILEOFF
,
273 .palette
= PALETTE_A
,
288 .stride
= DSPBSTRIDE
,
295 .linoff
= DSPBLINOFF
,
296 .tileoff
= DSPBTILEOFF
,
297 .palette
= PALETTE_B
,
301 static int psb_chip_setup(struct drm_device
*dev
)
303 struct drm_psb_private
*dev_priv
= dev
->dev_private
;
304 dev_priv
->regmap
= psb_regmap
;
305 gma_get_core_freq(dev
);
306 gma_intel_setup_gmbus(dev
);
307 psb_intel_opregion_init(dev
);
308 psb_intel_init_bios(dev
);
312 static void psb_chip_teardown(struct drm_device
*dev
)
314 struct drm_psb_private
*dev_priv
= dev
->dev_private
;
315 psb_lid_timer_takedown(dev_priv
);
316 gma_intel_teardown_gmbus(dev
);
319 const struct psb_ops psb_chip_ops
= {
323 .hdmi_mask
= (1 << 0),
324 .lvds_mask
= (1 << 1),
325 .sdvo_mask
= (1 << 0),
326 .cursor_needs_phys
= 1,
327 .sgx_offset
= PSB_SGX_OFFSET
,
328 .chip_setup
= psb_chip_setup
,
329 .chip_teardown
= psb_chip_teardown
,
331 .crtc_helper
= &psb_intel_helper_funcs
,
332 .crtc_funcs
= &psb_intel_crtc_funcs
,
333 .clock_funcs
= &psb_clock_funcs
,
335 .output_init
= psb_output_init
,
337 #ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
338 .backlight_init
= psb_backlight_init
,
341 .init_pm
= psb_init_pm
,
342 .save_regs
= psb_save_display_registers
,
343 .restore_regs
= psb_restore_display_registers
,
344 .save_crtc
= gma_crtc_save
,
345 .restore_crtc
= gma_crtc_restore
,
346 .power_down
= psb_power_down
,
347 .power_up
= psb_power_up
,