brintos

brintos / linux-shallow public Read only

0
0
Text · 7.4 KiB · 6dece8f Raw
294 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/**************************************************************************3 * Copyright (c) 2011, Intel Corporation.4 * All Rights Reserved.5 *6 **************************************************************************/7 8#include <drm/drm.h>9#include <drm/drm_crtc_helper.h>10 11#include "gma_device.h"12#include "intel_bios.h"13#include "psb_device.h"14#include "psb_drv.h"15#include "psb_intel_reg.h"16#include "psb_reg.h"17 18static int psb_output_init(struct drm_device *dev)19{20	struct drm_psb_private *dev_priv = to_drm_psb_private(dev);21	psb_intel_lvds_init(dev, &dev_priv->mode_dev);22	psb_intel_sdvo_init(dev, SDVOB);23	return 0;24}25 26/*27 *	Poulsbo Backlight Interfaces28 */29 30#define BLC_PWM_PRECISION_FACTOR 100	/* 10000000 */31#define BLC_PWM_FREQ_CALC_CONSTANT 3232#define MHz 100000033 34#define PSB_BLC_PWM_PRECISION_FACTOR    1035#define PSB_BLC_MAX_PWM_REG_FREQ        0xFFFE36#define PSB_BLC_MIN_PWM_REG_FREQ        0x237 38#define PSB_BACKLIGHT_PWM_POLARITY_BIT_CLEAR (0xFFFE)39#define PSB_BACKLIGHT_PWM_CTL_SHIFT	(16)40 41static int psb_backlight_setup(struct drm_device *dev)42{43	struct drm_psb_private *dev_priv = to_drm_psb_private(dev);44	unsigned long core_clock;45	/* u32 bl_max_freq; */46	/* unsigned long value; */47	u16 bl_max_freq;48	uint32_t value;49	uint32_t blc_pwm_precision_factor;50 51	/* get bl_max_freq and pol from dev_priv*/52	if (!dev_priv->lvds_bl) {53		dev_err(dev->dev, "Has no valid LVDS backlight info\n");54		return -ENOENT;55	}56	bl_max_freq = dev_priv->lvds_bl->freq;57	blc_pwm_precision_factor = PSB_BLC_PWM_PRECISION_FACTOR;58 59	core_clock = dev_priv->core_freq;60 61	value = (core_clock * MHz) / BLC_PWM_FREQ_CALC_CONSTANT;62	value *= blc_pwm_precision_factor;63	value /= bl_max_freq;64	value /= blc_pwm_precision_factor;65 66	if (value > (unsigned long long)PSB_BLC_MAX_PWM_REG_FREQ ||67		 value < (unsigned long long)PSB_BLC_MIN_PWM_REG_FREQ)68				return -ERANGE;69	else {70		value &= PSB_BACKLIGHT_PWM_POLARITY_BIT_CLEAR;71		REG_WRITE(BLC_PWM_CTL,72			(value << PSB_BACKLIGHT_PWM_CTL_SHIFT) | (value));73	}74 75	psb_intel_lvds_set_brightness(dev, PSB_MAX_BRIGHTNESS);76 77	return 0;78}79 80/*81 *	Provide the Poulsbo specific chip logic and low level methods82 *	for power management83 */84 85static void psb_init_pm(struct drm_device *dev)86{87	struct drm_psb_private *dev_priv = to_drm_psb_private(dev);88 89	u32 gating = PSB_RSGX32(PSB_CR_CLKGATECTL);90	gating &= ~3;	/* Disable 2D clock gating */91	gating |= 1;92	PSB_WSGX32(gating, PSB_CR_CLKGATECTL);93	PSB_RSGX32(PSB_CR_CLKGATECTL);94}95 96/**97 *	psb_save_display_registers	-	save registers lost on suspend98 *	@dev: our DRM device99 *100 *	Save the state we need in order to be able to restore the interface101 *	upon resume from suspend102 */103static int psb_save_display_registers(struct drm_device *dev)104{105	struct drm_psb_private *dev_priv = to_drm_psb_private(dev);106	struct gma_connector *gma_connector;107	struct drm_crtc *crtc;108	struct drm_connector_list_iter conn_iter;109	struct drm_connector *connector;110	struct psb_state *regs = &dev_priv->regs.psb;111 112	/* Display arbitration control + watermarks */113	regs->saveDSPARB = PSB_RVDC32(DSPARB);114	regs->saveDSPFW1 = PSB_RVDC32(DSPFW1);115	regs->saveDSPFW2 = PSB_RVDC32(DSPFW2);116	regs->saveDSPFW3 = PSB_RVDC32(DSPFW3);117	regs->saveDSPFW4 = PSB_RVDC32(DSPFW4);118	regs->saveDSPFW5 = PSB_RVDC32(DSPFW5);119	regs->saveDSPFW6 = PSB_RVDC32(DSPFW6);120	regs->saveCHICKENBIT = PSB_RVDC32(DSPCHICKENBIT);121 122	/* Save crtc and output state */123	drm_modeset_lock_all(dev);124	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {125		if (drm_helper_crtc_in_use(crtc))126			dev_priv->ops->save_crtc(crtc);127	}128 129	drm_connector_list_iter_begin(dev, &conn_iter);130	drm_for_each_connector_iter(connector, &conn_iter) {131		gma_connector = to_gma_connector(connector);132		if (gma_connector->save)133			gma_connector->save(connector);134	}135	drm_connector_list_iter_end(&conn_iter);136 137	drm_modeset_unlock_all(dev);138	return 0;139}140 141/**142 *	psb_restore_display_registers	-	restore lost register state143 *	@dev: our DRM device144 *145 *	Restore register state that was lost during suspend and resume.146 */147static int psb_restore_display_registers(struct drm_device *dev)148{149	struct drm_psb_private *dev_priv = to_drm_psb_private(dev);150	struct gma_connector *gma_connector;151	struct drm_crtc *crtc;152	struct drm_connector_list_iter conn_iter;153	struct drm_connector *connector;154	struct psb_state *regs = &dev_priv->regs.psb;155 156	/* Display arbitration + watermarks */157	PSB_WVDC32(regs->saveDSPARB, DSPARB);158	PSB_WVDC32(regs->saveDSPFW1, DSPFW1);159	PSB_WVDC32(regs->saveDSPFW2, DSPFW2);160	PSB_WVDC32(regs->saveDSPFW3, DSPFW3);161	PSB_WVDC32(regs->saveDSPFW4, DSPFW4);162	PSB_WVDC32(regs->saveDSPFW5, DSPFW5);163	PSB_WVDC32(regs->saveDSPFW6, DSPFW6);164	PSB_WVDC32(regs->saveCHICKENBIT, DSPCHICKENBIT);165 166	/*make sure VGA plane is off. it initializes to on after reset!*/167	PSB_WVDC32(0x80000000, VGACNTRL);168 169	drm_modeset_lock_all(dev);170	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)171		if (drm_helper_crtc_in_use(crtc))172			dev_priv->ops->restore_crtc(crtc);173 174	drm_connector_list_iter_begin(dev, &conn_iter);175	drm_for_each_connector_iter(connector, &conn_iter) {176		gma_connector = to_gma_connector(connector);177		if (gma_connector->restore)178			gma_connector->restore(connector);179	}180	drm_connector_list_iter_end(&conn_iter);181 182	drm_modeset_unlock_all(dev);183	return 0;184}185 186static int psb_power_down(struct drm_device *dev)187{188	return 0;189}190 191static int psb_power_up(struct drm_device *dev)192{193	return 0;194}195 196/* Poulsbo */197static const struct psb_offset psb_regmap[2] = {198	{199		.fp0 = FPA0,200		.fp1 = FPA1,201		.cntr = DSPACNTR,202		.conf = PIPEACONF,203		.src = PIPEASRC,204		.dpll = DPLL_A,205		.htotal = HTOTAL_A,206		.hblank = HBLANK_A,207		.hsync = HSYNC_A,208		.vtotal = VTOTAL_A,209		.vblank = VBLANK_A,210		.vsync = VSYNC_A,211		.stride = DSPASTRIDE,212		.size = DSPASIZE,213		.pos = DSPAPOS,214		.base = DSPABASE,215		.surf = DSPASURF,216		.addr = DSPABASE,217		.status = PIPEASTAT,218		.linoff = DSPALINOFF,219		.tileoff = DSPATILEOFF,220		.palette = PALETTE_A,221	},222	{223		.fp0 = FPB0,224		.fp1 = FPB1,225		.cntr = DSPBCNTR,226		.conf = PIPEBCONF,227		.src = PIPEBSRC,228		.dpll = DPLL_B,229		.htotal = HTOTAL_B,230		.hblank = HBLANK_B,231		.hsync = HSYNC_B,232		.vtotal = VTOTAL_B,233		.vblank = VBLANK_B,234		.vsync = VSYNC_B,235		.stride = DSPBSTRIDE,236		.size = DSPBSIZE,237		.pos = DSPBPOS,238		.base = DSPBBASE,239		.surf = DSPBSURF,240		.addr = DSPBBASE,241		.status = PIPEBSTAT,242		.linoff = DSPBLINOFF,243		.tileoff = DSPBTILEOFF,244		.palette = PALETTE_B,245	}246};247 248static int psb_chip_setup(struct drm_device *dev)249{250	struct drm_psb_private *dev_priv = to_drm_psb_private(dev);251	dev_priv->regmap = psb_regmap;252	gma_get_core_freq(dev);253	gma_intel_setup_gmbus(dev);254	psb_intel_opregion_init(dev);255	psb_intel_init_bios(dev);256	return 0;257}258 259static void psb_chip_teardown(struct drm_device *dev)260{261	gma_intel_teardown_gmbus(dev);262}263 264const struct psb_ops psb_chip_ops = {265	.name = "Poulsbo",266	.pipes = 2,267	.crtcs = 2,268	.hdmi_mask = (1 << 0),269	.lvds_mask = (1 << 1),270	.sdvo_mask = (1 << 0),271	.cursor_needs_phys = 1,272	.sgx_offset = PSB_SGX_OFFSET,273	.chip_setup = psb_chip_setup,274	.chip_teardown = psb_chip_teardown,275 276	.crtc_helper = &psb_intel_helper_funcs,277	.clock_funcs = &psb_clock_funcs,278 279	.output_init = psb_output_init,280 281	.backlight_init = psb_backlight_setup,282	.backlight_set = psb_intel_lvds_set_brightness,283	.backlight_name = "psb-bl",284 285	.init_pm = psb_init_pm,286	.save_regs = psb_save_display_registers,287	.restore_regs = psb_restore_display_registers,288	.save_crtc = gma_crtc_save,289	.restore_crtc = gma_crtc_restore,290	.power_down = psb_power_down,291	.power_up = psb_power_up,292};293 294