brintos

brintos / linux-shallow public Read only

0
0
Text · 12.7 KiB · 7bbb79b Raw
494 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/**************************************************************************3 * Copyright (c) 2007, Intel Corporation.4 * All Rights Reserved.5 *6 * Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to7 * develop this driver.8 *9 **************************************************************************/10 11#include <drm/drm_drv.h>12#include <drm/drm_vblank.h>13 14#include "power.h"15#include "psb_drv.h"16#include "psb_intel_reg.h"17#include "psb_irq.h"18#include "psb_reg.h"19 20/*21 * inline functions22 */23 24static inline u32 gma_pipestat(int pipe)25{26	if (pipe == 0)27		return PIPEASTAT;28	if (pipe == 1)29		return PIPEBSTAT;30	if (pipe == 2)31		return PIPECSTAT;32	BUG();33}34 35static inline u32 gma_pipeconf(int pipe)36{37	if (pipe == 0)38		return PIPEACONF;39	if (pipe == 1)40		return PIPEBCONF;41	if (pipe == 2)42		return PIPECCONF;43	BUG();44}45 46void gma_enable_pipestat(struct drm_psb_private *dev_priv, int pipe, u32 mask)47{48	if ((dev_priv->pipestat[pipe] & mask) != mask) {49		u32 reg = gma_pipestat(pipe);50		dev_priv->pipestat[pipe] |= mask;51		/* Enable the interrupt, clear any pending status */52		if (gma_power_begin(&dev_priv->dev, false)) {53			u32 writeVal = PSB_RVDC32(reg);54			writeVal |= (mask | (mask >> 16));55			PSB_WVDC32(writeVal, reg);56			(void) PSB_RVDC32(reg);57			gma_power_end(&dev_priv->dev);58		}59	}60}61 62void gma_disable_pipestat(struct drm_psb_private *dev_priv, int pipe, u32 mask)63{64	if ((dev_priv->pipestat[pipe] & mask) != 0) {65		u32 reg = gma_pipestat(pipe);66		dev_priv->pipestat[pipe] &= ~mask;67		if (gma_power_begin(&dev_priv->dev, false)) {68			u32 writeVal = PSB_RVDC32(reg);69			writeVal &= ~mask;70			PSB_WVDC32(writeVal, reg);71			(void) PSB_RVDC32(reg);72			gma_power_end(&dev_priv->dev);73		}74	}75}76 77/*78 * Display controller interrupt handler for pipe event.79 */80static void gma_pipe_event_handler(struct drm_device *dev, int pipe)81{82	struct drm_psb_private *dev_priv = to_drm_psb_private(dev);83 84	uint32_t pipe_stat_val = 0;85	uint32_t pipe_stat_reg = gma_pipestat(pipe);86	uint32_t pipe_enable = dev_priv->pipestat[pipe];87	uint32_t pipe_status = dev_priv->pipestat[pipe] >> 16;88	uint32_t pipe_clear;89	uint32_t i = 0;90 91	spin_lock(&dev_priv->irqmask_lock);92 93	pipe_stat_val = PSB_RVDC32(pipe_stat_reg);94	pipe_stat_val &= pipe_enable | pipe_status;95	pipe_stat_val &= pipe_stat_val >> 16;96 97	spin_unlock(&dev_priv->irqmask_lock);98 99	/* Clear the 2nd level interrupt status bits100	 * Sometimes the bits are very sticky so we repeat until they unstick */101	for (i = 0; i < 0xffff; i++) {102		PSB_WVDC32(PSB_RVDC32(pipe_stat_reg), pipe_stat_reg);103		pipe_clear = PSB_RVDC32(pipe_stat_reg) & pipe_status;104 105		if (pipe_clear == 0)106			break;107	}108 109	if (pipe_clear)110		dev_err(dev->dev,111		"%s, can't clear status bits for pipe %d, its value = 0x%x.\n",112		__func__, pipe, PSB_RVDC32(pipe_stat_reg));113 114	if (pipe_stat_val & PIPE_VBLANK_STATUS) {115		struct drm_crtc *crtc = drm_crtc_from_index(dev, pipe);116		struct gma_crtc *gma_crtc = to_gma_crtc(crtc);117		unsigned long flags;118 119		drm_handle_vblank(dev, pipe);120 121		spin_lock_irqsave(&dev->event_lock, flags);122		if (gma_crtc->page_flip_event) {123			drm_crtc_send_vblank_event(crtc,124						   gma_crtc->page_flip_event);125			gma_crtc->page_flip_event = NULL;126			drm_crtc_vblank_put(crtc);127		}128		spin_unlock_irqrestore(&dev->event_lock, flags);129	}130}131 132/*133 * Display controller interrupt handler.134 */135static void gma_vdc_interrupt(struct drm_device *dev, uint32_t vdc_stat)136{137	if (vdc_stat & _PSB_IRQ_ASLE)138		psb_intel_opregion_asle_intr(dev);139 140	if (vdc_stat & _PSB_VSYNC_PIPEA_FLAG)141		gma_pipe_event_handler(dev, 0);142 143	if (vdc_stat & _PSB_VSYNC_PIPEB_FLAG)144		gma_pipe_event_handler(dev, 1);145}146 147/*148 * SGX interrupt handler149 */150static void gma_sgx_interrupt(struct drm_device *dev, u32 stat_1, u32 stat_2)151{152	struct drm_psb_private *dev_priv = to_drm_psb_private(dev);153	u32 val, addr;154 155	if (stat_1 & _PSB_CE_TWOD_COMPLETE)156		val = PSB_RSGX32(PSB_CR_2D_BLIT_STATUS);157 158	if (stat_2 & _PSB_CE2_BIF_REQUESTER_FAULT) {159		val = PSB_RSGX32(PSB_CR_BIF_INT_STAT);160		addr = PSB_RSGX32(PSB_CR_BIF_FAULT);161		if (val) {162			if (val & _PSB_CBI_STAT_PF_N_RW)163				DRM_ERROR("SGX MMU page fault:");164			else165				DRM_ERROR("SGX MMU read / write protection fault:");166 167			if (val & _PSB_CBI_STAT_FAULT_CACHE)168				DRM_ERROR("\tCache requestor");169			if (val & _PSB_CBI_STAT_FAULT_TA)170				DRM_ERROR("\tTA requestor");171			if (val & _PSB_CBI_STAT_FAULT_VDM)172				DRM_ERROR("\tVDM requestor");173			if (val & _PSB_CBI_STAT_FAULT_2D)174				DRM_ERROR("\t2D requestor");175			if (val & _PSB_CBI_STAT_FAULT_PBE)176				DRM_ERROR("\tPBE requestor");177			if (val & _PSB_CBI_STAT_FAULT_TSP)178				DRM_ERROR("\tTSP requestor");179			if (val & _PSB_CBI_STAT_FAULT_ISP)180				DRM_ERROR("\tISP requestor");181			if (val & _PSB_CBI_STAT_FAULT_USSEPDS)182				DRM_ERROR("\tUSSEPDS requestor");183			if (val & _PSB_CBI_STAT_FAULT_HOST)184				DRM_ERROR("\tHost requestor");185 186			DRM_ERROR("\tMMU failing address is 0x%08x.\n",187				  (unsigned int)addr);188		}189	}190 191	/* Clear bits */192	PSB_WSGX32(stat_1, PSB_CR_EVENT_HOST_CLEAR);193	PSB_WSGX32(stat_2, PSB_CR_EVENT_HOST_CLEAR2);194	PSB_RSGX32(PSB_CR_EVENT_HOST_CLEAR2);195}196 197static irqreturn_t gma_irq_handler(int irq, void *arg)198{199	struct drm_device *dev = arg;200	struct drm_psb_private *dev_priv = to_drm_psb_private(dev);201	uint32_t vdc_stat, dsp_int = 0, sgx_int = 0, hotplug_int = 0;202	u32 sgx_stat_1, sgx_stat_2;203	int handled = 0;204 205	spin_lock(&dev_priv->irqmask_lock);206 207	vdc_stat = PSB_RVDC32(PSB_INT_IDENTITY_R);208 209	if (vdc_stat & (_PSB_PIPE_EVENT_FLAG|_PSB_IRQ_ASLE))210		dsp_int = 1;211 212	if (vdc_stat & _PSB_IRQ_SGX_FLAG)213		sgx_int = 1;214	if (vdc_stat & _PSB_IRQ_DISP_HOTSYNC)215		hotplug_int = 1;216 217	vdc_stat &= dev_priv->vdc_irq_mask;218	spin_unlock(&dev_priv->irqmask_lock);219 220	if (dsp_int) {221		gma_vdc_interrupt(dev, vdc_stat);222		handled = 1;223	}224 225	if (sgx_int) {226		sgx_stat_1 = PSB_RSGX32(PSB_CR_EVENT_STATUS);227		sgx_stat_2 = PSB_RSGX32(PSB_CR_EVENT_STATUS2);228		gma_sgx_interrupt(dev, sgx_stat_1, sgx_stat_2);229		handled = 1;230	}231 232	/* Note: this bit has other meanings on some devices, so we will233	   need to address that later if it ever matters */234	if (hotplug_int && dev_priv->ops->hotplug) {235		handled = dev_priv->ops->hotplug(dev);236		REG_WRITE(PORT_HOTPLUG_STAT, REG_READ(PORT_HOTPLUG_STAT));237	}238 239	PSB_WVDC32(vdc_stat, PSB_INT_IDENTITY_R);240	(void) PSB_RVDC32(PSB_INT_IDENTITY_R);241	rmb();242 243	if (!handled)244		return IRQ_NONE;245 246	return IRQ_HANDLED;247}248 249void gma_irq_preinstall(struct drm_device *dev)250{251	struct drm_psb_private *dev_priv = to_drm_psb_private(dev);252	unsigned long irqflags;253 254	spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);255 256	PSB_WVDC32(0xFFFFFFFF, PSB_HWSTAM);257	PSB_WVDC32(0x00000000, PSB_INT_MASK_R);258	PSB_WVDC32(0x00000000, PSB_INT_ENABLE_R);259	PSB_WSGX32(0x00000000, PSB_CR_EVENT_HOST_ENABLE);260	PSB_RSGX32(PSB_CR_EVENT_HOST_ENABLE);261 262	if (dev->vblank[0].enabled)263		dev_priv->vdc_irq_mask |= _PSB_VSYNC_PIPEA_FLAG;264	if (dev->vblank[1].enabled)265		dev_priv->vdc_irq_mask |= _PSB_VSYNC_PIPEB_FLAG;266 267	/* Revisit this area - want per device masks ? */268	if (dev_priv->ops->hotplug)269		dev_priv->vdc_irq_mask |= _PSB_IRQ_DISP_HOTSYNC;270	dev_priv->vdc_irq_mask |= _PSB_IRQ_ASLE | _PSB_IRQ_SGX_FLAG;271 272	/* This register is safe even if display island is off */273	PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R);274	spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);275}276 277void gma_irq_postinstall(struct drm_device *dev)278{279	struct drm_psb_private *dev_priv = to_drm_psb_private(dev);280	unsigned long irqflags;281	unsigned int i;282 283	spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);284 285	/* Enable 2D and MMU fault interrupts */286	PSB_WSGX32(_PSB_CE2_BIF_REQUESTER_FAULT, PSB_CR_EVENT_HOST_ENABLE2);287	PSB_WSGX32(_PSB_CE_TWOD_COMPLETE, PSB_CR_EVENT_HOST_ENABLE);288	PSB_RSGX32(PSB_CR_EVENT_HOST_ENABLE); /* Post */289 290	/* This register is safe even if display island is off */291	PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R);292	PSB_WVDC32(0xFFFFFFFF, PSB_HWSTAM);293 294	for (i = 0; i < dev->num_crtcs; ++i) {295		if (dev->vblank[i].enabled)296			gma_enable_pipestat(dev_priv, i, PIPE_VBLANK_INTERRUPT_ENABLE);297		else298			gma_disable_pipestat(dev_priv, i, PIPE_VBLANK_INTERRUPT_ENABLE);299	}300 301	if (dev_priv->ops->hotplug_enable)302		dev_priv->ops->hotplug_enable(dev, true);303 304	spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);305}306 307int gma_irq_install(struct drm_device *dev)308{309	struct drm_psb_private *dev_priv = to_drm_psb_private(dev);310	struct pci_dev *pdev = to_pci_dev(dev->dev);311	int ret;312 313	if (dev_priv->use_msi && pci_enable_msi(pdev)) {314		dev_warn(dev->dev, "Enabling MSI failed!\n");315		dev_priv->use_msi = false;316	}317 318	if (pdev->irq == IRQ_NOTCONNECTED)319		return -ENOTCONN;320 321	gma_irq_preinstall(dev);322 323	/* PCI devices require shared interrupts. */324	ret = request_irq(pdev->irq, gma_irq_handler, IRQF_SHARED, dev->driver->name, dev);325	if (ret)326		return ret;327 328	gma_irq_postinstall(dev);329 330	dev_priv->irq_enabled = true;331 332	return 0;333}334 335void gma_irq_uninstall(struct drm_device *dev)336{337	struct drm_psb_private *dev_priv = to_drm_psb_private(dev);338	struct pci_dev *pdev = to_pci_dev(dev->dev);339	unsigned long irqflags;340	unsigned int i;341 342	if (!dev_priv->irq_enabled)343		return;344 345	spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);346 347	if (dev_priv->ops->hotplug_enable)348		dev_priv->ops->hotplug_enable(dev, false);349 350	PSB_WVDC32(0xFFFFFFFF, PSB_HWSTAM);351 352	for (i = 0; i < dev->num_crtcs; ++i) {353		if (dev->vblank[i].enabled)354			gma_disable_pipestat(dev_priv, i, PIPE_VBLANK_INTERRUPT_ENABLE);355	}356 357	dev_priv->vdc_irq_mask &= _PSB_IRQ_SGX_FLAG |358				  _PSB_IRQ_MSVDX_FLAG |359				  _LNC_IRQ_TOPAZ_FLAG;360 361	/* These two registers are safe even if display island is off */362	PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R);363	PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R);364 365	wmb();366 367	/* This register is safe even if display island is off */368	PSB_WVDC32(PSB_RVDC32(PSB_INT_IDENTITY_R), PSB_INT_IDENTITY_R);369	spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);370 371	free_irq(pdev->irq, dev);372	if (dev_priv->use_msi)373		pci_disable_msi(pdev);374}375 376int gma_crtc_enable_vblank(struct drm_crtc *crtc)377{378	struct drm_device *dev = crtc->dev;379	unsigned int pipe = crtc->index;380	struct drm_psb_private *dev_priv = to_drm_psb_private(dev);381	unsigned long irqflags;382	uint32_t reg_val = 0;383	uint32_t pipeconf_reg = gma_pipeconf(pipe);384 385	if (gma_power_begin(dev, false)) {386		reg_val = REG_READ(pipeconf_reg);387		gma_power_end(dev);388	}389 390	if (!(reg_val & PIPEACONF_ENABLE))391		return -EINVAL;392 393	spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);394 395	if (pipe == 0)396		dev_priv->vdc_irq_mask |= _PSB_VSYNC_PIPEA_FLAG;397	else if (pipe == 1)398		dev_priv->vdc_irq_mask |= _PSB_VSYNC_PIPEB_FLAG;399 400	PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R);401	PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R);402	gma_enable_pipestat(dev_priv, pipe, PIPE_VBLANK_INTERRUPT_ENABLE);403 404	spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);405 406	return 0;407}408 409void gma_crtc_disable_vblank(struct drm_crtc *crtc)410{411	struct drm_device *dev = crtc->dev;412	unsigned int pipe = crtc->index;413	struct drm_psb_private *dev_priv = to_drm_psb_private(dev);414	unsigned long irqflags;415 416	spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);417 418	if (pipe == 0)419		dev_priv->vdc_irq_mask &= ~_PSB_VSYNC_PIPEA_FLAG;420	else if (pipe == 1)421		dev_priv->vdc_irq_mask &= ~_PSB_VSYNC_PIPEB_FLAG;422 423	PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R);424	PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R);425	gma_disable_pipestat(dev_priv, pipe, PIPE_VBLANK_INTERRUPT_ENABLE);426 427	spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);428}429 430/* Called from drm generic code, passed a 'crtc', which431 * we use as a pipe index432 */433u32 gma_crtc_get_vblank_counter(struct drm_crtc *crtc)434{435	struct drm_device *dev = crtc->dev;436	unsigned int pipe = crtc->index;437	uint32_t high_frame = PIPEAFRAMEHIGH;438	uint32_t low_frame = PIPEAFRAMEPIXEL;439	uint32_t pipeconf_reg = PIPEACONF;440	uint32_t reg_val = 0;441	uint32_t high1 = 0, high2 = 0, low = 0, count = 0;442 443	switch (pipe) {444	case 0:445		break;446	case 1:447		high_frame = PIPEBFRAMEHIGH;448		low_frame = PIPEBFRAMEPIXEL;449		pipeconf_reg = PIPEBCONF;450		break;451	case 2:452		high_frame = PIPECFRAMEHIGH;453		low_frame = PIPECFRAMEPIXEL;454		pipeconf_reg = PIPECCONF;455		break;456	default:457		dev_err(dev->dev, "%s, invalid pipe.\n", __func__);458		return 0;459	}460 461	if (!gma_power_begin(dev, false))462		return 0;463 464	reg_val = REG_READ(pipeconf_reg);465 466	if (!(reg_val & PIPEACONF_ENABLE)) {467		dev_err(dev->dev, "trying to get vblank count for disabled pipe %u\n",468			pipe);469		goto err_gma_power_end;470	}471 472	/*473	 * High & low register fields aren't synchronized, so make sure474	 * we get a low value that's stable across two reads of the high475	 * register.476	 */477	do {478		high1 = ((REG_READ(high_frame) & PIPE_FRAME_HIGH_MASK) >>479			 PIPE_FRAME_HIGH_SHIFT);480		low =  ((REG_READ(low_frame) & PIPE_FRAME_LOW_MASK) >>481			PIPE_FRAME_LOW_SHIFT);482		high2 = ((REG_READ(high_frame) & PIPE_FRAME_HIGH_MASK) >>483			 PIPE_FRAME_HIGH_SHIFT);484	} while (high1 != high2);485 486	count = (high1 << 8) | low;487 488err_gma_power_end:489	gma_power_end(dev);490 491	return count;492}493 494