brintos

brintos / linux-shallow public Read only

0
0
Text · 47.8 KiB · 37927bd Raw
1845 lines · c
1// SPDX-License-Identifier: GPL-2.02/* Copyright (c) 2017-2019 The Linux Foundation. All rights reserved. */3 4#include <linux/bitfield.h>5#include <linux/clk.h>6#include <linux/interconnect.h>7#include <linux/of_platform.h>8#include <linux/platform_device.h>9#include <linux/pm_domain.h>10#include <linux/pm_opp.h>11#include <soc/qcom/cmd-db.h>12#include <drm/drm_gem.h>13 14#include "a6xx_gpu.h"15#include "a6xx_gmu.xml.h"16#include "msm_gem.h"17#include "msm_gpu_trace.h"18#include "msm_mmu.h"19 20static void a6xx_gmu_fault(struct a6xx_gmu *gmu)21{22	struct a6xx_gpu *a6xx_gpu = container_of(gmu, struct a6xx_gpu, gmu);23	struct adreno_gpu *adreno_gpu = &a6xx_gpu->base;24	struct msm_gpu *gpu = &adreno_gpu->base;25 26	/* FIXME: add a banner here */27	gmu->hung = true;28 29	/* Turn off the hangcheck timer while we are resetting */30	del_timer(&gpu->hangcheck_timer);31 32	/* Queue the GPU handler because we need to treat this as a recovery */33	kthread_queue_work(gpu->worker, &gpu->recover_work);34}35 36static irqreturn_t a6xx_gmu_irq(int irq, void *data)37{38	struct a6xx_gmu *gmu = data;39	u32 status;40 41	status = gmu_read(gmu, REG_A6XX_GMU_AO_HOST_INTERRUPT_STATUS);42	gmu_write(gmu, REG_A6XX_GMU_AO_HOST_INTERRUPT_CLR, status);43 44	if (status & A6XX_GMU_AO_HOST_INTERRUPT_STATUS_WDOG_BITE) {45		dev_err_ratelimited(gmu->dev, "GMU watchdog expired\n");46 47		a6xx_gmu_fault(gmu);48	}49 50	if (status &  A6XX_GMU_AO_HOST_INTERRUPT_STATUS_HOST_AHB_BUS_ERROR)51		dev_err_ratelimited(gmu->dev, "GMU AHB bus error\n");52 53	if (status & A6XX_GMU_AO_HOST_INTERRUPT_STATUS_FENCE_ERR)54		dev_err_ratelimited(gmu->dev, "GMU fence error: 0x%x\n",55			gmu_read(gmu, REG_A6XX_GMU_AHB_FENCE_STATUS));56 57	return IRQ_HANDLED;58}59 60static irqreturn_t a6xx_hfi_irq(int irq, void *data)61{62	struct a6xx_gmu *gmu = data;63	u32 status;64 65	status = gmu_read(gmu, REG_A6XX_GMU_GMU2HOST_INTR_INFO);66	gmu_write(gmu, REG_A6XX_GMU_GMU2HOST_INTR_CLR, status);67 68	if (status & A6XX_GMU_GMU2HOST_INTR_INFO_CM3_FAULT) {69		dev_err_ratelimited(gmu->dev, "GMU firmware fault\n");70 71		a6xx_gmu_fault(gmu);72	}73 74	return IRQ_HANDLED;75}76 77bool a6xx_gmu_sptprac_is_on(struct a6xx_gmu *gmu)78{79	u32 val;80 81	/* This can be called from gpu state code so make sure GMU is valid */82	if (!gmu->initialized)83		return false;84 85	val = gmu_read(gmu, REG_A6XX_GMU_SPTPRAC_PWR_CLK_STATUS);86 87	return !(val &88		(A6XX_GMU_SPTPRAC_PWR_CLK_STATUS_SPTPRAC_GDSC_POWER_OFF |89		A6XX_GMU_SPTPRAC_PWR_CLK_STATUS_SP_CLOCK_OFF));90}91 92/* Check to see if the GX rail is still powered */93bool a6xx_gmu_gx_is_on(struct a6xx_gmu *gmu)94{95	u32 val;96 97	/* This can be called from gpu state code so make sure GMU is valid */98	if (!gmu->initialized)99		return false;100 101	val = gmu_read(gmu, REG_A6XX_GMU_SPTPRAC_PWR_CLK_STATUS);102 103	return !(val &104		(A6XX_GMU_SPTPRAC_PWR_CLK_STATUS_GX_HM_GDSC_POWER_OFF |105		A6XX_GMU_SPTPRAC_PWR_CLK_STATUS_GX_HM_CLK_OFF));106}107 108void a6xx_gmu_set_freq(struct msm_gpu *gpu, struct dev_pm_opp *opp,109		       bool suspended)110{111	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);112	struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);113	struct a6xx_gmu *gmu = &a6xx_gpu->gmu;114	u32 perf_index;115	unsigned long gpu_freq;116	int ret = 0;117 118	gpu_freq = dev_pm_opp_get_freq(opp);119 120	if (gpu_freq == gmu->freq)121		return;122 123	for (perf_index = 0; perf_index < gmu->nr_gpu_freqs - 1; perf_index++)124		if (gpu_freq == gmu->gpu_freqs[perf_index])125			break;126 127	gmu->current_perf_index = perf_index;128	gmu->freq = gmu->gpu_freqs[perf_index];129 130	trace_msm_gmu_freq_change(gmu->freq, perf_index);131 132	/*133	 * This can get called from devfreq while the hardware is idle. Don't134	 * bring up the power if it isn't already active. All we're doing here135	 * is updating the frequency so that when we come back online we're at136	 * the right rate.137	 */138	if (suspended)139		return;140 141	if (!gmu->legacy) {142		a6xx_hfi_set_freq(gmu, perf_index);143		dev_pm_opp_set_opp(&gpu->pdev->dev, opp);144		return;145	}146 147	gmu_write(gmu, REG_A6XX_GMU_DCVS_ACK_OPTION, 0);148 149	gmu_write(gmu, REG_A6XX_GMU_DCVS_PERF_SETTING,150			((3 & 0xf) << 28) | perf_index);151 152	/*153	 * Send an invalid index as a vote for the bus bandwidth and let the154	 * firmware decide on the right vote155	 */156	gmu_write(gmu, REG_A6XX_GMU_DCVS_BW_SETTING, 0xff);157 158	/* Set and clear the OOB for DCVS to trigger the GMU */159	a6xx_gmu_set_oob(gmu, GMU_OOB_DCVS_SET);160	a6xx_gmu_clear_oob(gmu, GMU_OOB_DCVS_SET);161 162	ret = gmu_read(gmu, REG_A6XX_GMU_DCVS_RETURN);163	if (ret)164		dev_err(gmu->dev, "GMU set GPU frequency error: %d\n", ret);165 166	dev_pm_opp_set_opp(&gpu->pdev->dev, opp);167}168 169unsigned long a6xx_gmu_get_freq(struct msm_gpu *gpu)170{171	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);172	struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);173	struct a6xx_gmu *gmu = &a6xx_gpu->gmu;174 175	return  gmu->freq;176}177 178static bool a6xx_gmu_check_idle_level(struct a6xx_gmu *gmu)179{180	u32 val;181	int local = gmu->idle_level;182 183	/* SPTP and IFPC both report as IFPC */184	if (gmu->idle_level == GMU_IDLE_STATE_SPTP)185		local = GMU_IDLE_STATE_IFPC;186 187	val = gmu_read(gmu, REG_A6XX_GPU_GMU_CX_GMU_RPMH_POWER_STATE);188 189	if (val == local) {190		if (gmu->idle_level != GMU_IDLE_STATE_IFPC ||191			!a6xx_gmu_gx_is_on(gmu))192			return true;193	}194 195	return false;196}197 198/* Wait for the GMU to get to its most idle state */199int a6xx_gmu_wait_for_idle(struct a6xx_gmu *gmu)200{201	return spin_until(a6xx_gmu_check_idle_level(gmu));202}203 204static int a6xx_gmu_start(struct a6xx_gmu *gmu)205{206	struct a6xx_gpu *a6xx_gpu = container_of(gmu, struct a6xx_gpu, gmu);207	struct adreno_gpu *adreno_gpu = &a6xx_gpu->base;208	u32 mask, reset_val, val;209	int ret;210 211	val = gmu_read(gmu, REG_A6XX_GMU_CM3_DTCM_START + 0xff8);212	if (val <= 0x20010004) {213		mask = 0xffffffff;214		reset_val = 0xbabeface;215	} else {216		mask = 0x1ff;217		reset_val = 0x100;218	}219 220	gmu_write(gmu, REG_A6XX_GMU_CM3_SYSRESET, 1);221 222	/* Set the log wptr index223	 * note: downstream saves the value in poweroff and restores it here224	 */225	if (adreno_is_a7xx(adreno_gpu))226		gmu_write(gmu, REG_A7XX_GMU_GENERAL_9, 0);227	else228		gmu_write(gmu, REG_A6XX_GPU_GMU_CX_GMU_PWR_COL_CP_RESP, 0);229 230 231	gmu_write(gmu, REG_A6XX_GMU_CM3_SYSRESET, 0);232 233	ret = gmu_poll_timeout(gmu, REG_A6XX_GMU_CM3_FW_INIT_RESULT, val,234		(val & mask) == reset_val, 100, 10000);235 236	if (ret)237		DRM_DEV_ERROR(gmu->dev, "GMU firmware initialization timed out\n");238 239	return ret;240}241 242static int a6xx_gmu_hfi_start(struct a6xx_gmu *gmu)243{244	u32 val;245	int ret;246 247	gmu_write(gmu, REG_A6XX_GMU_HFI_CTRL_INIT, 1);248 249	ret = gmu_poll_timeout(gmu, REG_A6XX_GMU_HFI_CTRL_STATUS, val,250		val & 1, 100, 10000);251	if (ret)252		DRM_DEV_ERROR(gmu->dev, "Unable to start the HFI queues\n");253 254	return ret;255}256 257struct a6xx_gmu_oob_bits {258	int set, ack, set_new, ack_new, clear, clear_new;259	const char *name;260};261 262/* These are the interrupt / ack bits for each OOB request that are set263 * in a6xx_gmu_set_oob and a6xx_clear_oob264 */265static const struct a6xx_gmu_oob_bits a6xx_gmu_oob_bits[] = {266	[GMU_OOB_GPU_SET] = {267		.name = "GPU_SET",268		.set = 16,269		.ack = 24,270		.set_new = 30,271		.ack_new = 31,272		.clear = 24,273		.clear_new = 31,274	},275 276	[GMU_OOB_PERFCOUNTER_SET] = {277		.name = "PERFCOUNTER",278		.set = 17,279		.ack = 25,280		.set_new = 28,281		.ack_new = 30,282		.clear = 25,283		.clear_new = 29,284	},285 286	[GMU_OOB_BOOT_SLUMBER] = {287		.name = "BOOT_SLUMBER",288		.set = 22,289		.ack = 30,290		.clear = 30,291	},292 293	[GMU_OOB_DCVS_SET] = {294		.name = "GPU_DCVS",295		.set = 23,296		.ack = 31,297		.clear = 31,298	},299};300 301/* Trigger a OOB (out of band) request to the GMU */302int a6xx_gmu_set_oob(struct a6xx_gmu *gmu, enum a6xx_gmu_oob_state state)303{304	int ret;305	u32 val;306	int request, ack;307 308	WARN_ON_ONCE(!mutex_is_locked(&gmu->lock));309 310	if (state >= ARRAY_SIZE(a6xx_gmu_oob_bits))311		return -EINVAL;312 313	if (gmu->legacy) {314		request = a6xx_gmu_oob_bits[state].set;315		ack = a6xx_gmu_oob_bits[state].ack;316	} else {317		request = a6xx_gmu_oob_bits[state].set_new;318		ack = a6xx_gmu_oob_bits[state].ack_new;319		if (!request || !ack) {320			DRM_DEV_ERROR(gmu->dev,321				      "Invalid non-legacy GMU request %s\n",322				      a6xx_gmu_oob_bits[state].name);323			return -EINVAL;324		}325	}326 327	/* Trigger the equested OOB operation */328	gmu_write(gmu, REG_A6XX_GMU_HOST2GMU_INTR_SET, 1 << request);329 330	/* Wait for the acknowledge interrupt */331	ret = gmu_poll_timeout(gmu, REG_A6XX_GMU_GMU2HOST_INTR_INFO, val,332		val & (1 << ack), 100, 10000);333 334	if (ret)335		DRM_DEV_ERROR(gmu->dev,336			"Timeout waiting for GMU OOB set %s: 0x%x\n",337				a6xx_gmu_oob_bits[state].name,338				gmu_read(gmu, REG_A6XX_GMU_GMU2HOST_INTR_INFO));339 340	/* Clear the acknowledge interrupt */341	gmu_write(gmu, REG_A6XX_GMU_GMU2HOST_INTR_CLR, 1 << ack);342 343	return ret;344}345 346/* Clear a pending OOB state in the GMU */347void a6xx_gmu_clear_oob(struct a6xx_gmu *gmu, enum a6xx_gmu_oob_state state)348{349	int bit;350 351	WARN_ON_ONCE(!mutex_is_locked(&gmu->lock));352 353	if (state >= ARRAY_SIZE(a6xx_gmu_oob_bits))354		return;355 356	if (gmu->legacy)357		bit = a6xx_gmu_oob_bits[state].clear;358	else359		bit = a6xx_gmu_oob_bits[state].clear_new;360 361	gmu_write(gmu, REG_A6XX_GMU_HOST2GMU_INTR_SET, 1 << bit);362}363 364/* Enable CPU control of SPTP power power collapse */365int a6xx_sptprac_enable(struct a6xx_gmu *gmu)366{367	int ret;368	u32 val;369 370	if (!gmu->legacy)371		return 0;372 373	gmu_write(gmu, REG_A6XX_GMU_GX_SPTPRAC_POWER_CONTROL, 0x778000);374 375	ret = gmu_poll_timeout(gmu, REG_A6XX_GMU_SPTPRAC_PWR_CLK_STATUS, val,376		(val & 0x38) == 0x28, 1, 100);377 378	if (ret) {379		DRM_DEV_ERROR(gmu->dev, "Unable to power on SPTPRAC: 0x%x\n",380			gmu_read(gmu, REG_A6XX_GMU_SPTPRAC_PWR_CLK_STATUS));381	}382 383	return 0;384}385 386/* Disable CPU control of SPTP power power collapse */387void a6xx_sptprac_disable(struct a6xx_gmu *gmu)388{389	u32 val;390	int ret;391 392	if (!gmu->legacy)393		return;394 395	/* Make sure retention is on */396	gmu_rmw(gmu, REG_A6XX_GPU_CC_GX_GDSCR, 0, (1 << 11));397 398	gmu_write(gmu, REG_A6XX_GMU_GX_SPTPRAC_POWER_CONTROL, 0x778001);399 400	ret = gmu_poll_timeout(gmu, REG_A6XX_GMU_SPTPRAC_PWR_CLK_STATUS, val,401		(val & 0x04), 100, 10000);402 403	if (ret)404		DRM_DEV_ERROR(gmu->dev, "failed to power off SPTPRAC: 0x%x\n",405			gmu_read(gmu, REG_A6XX_GMU_SPTPRAC_PWR_CLK_STATUS));406}407 408/* Let the GMU know we are starting a boot sequence */409static int a6xx_gmu_gfx_rail_on(struct a6xx_gmu *gmu)410{411	u32 vote;412 413	/* Let the GMU know we are getting ready for boot */414	gmu_write(gmu, REG_A6XX_GMU_BOOT_SLUMBER_OPTION, 0);415 416	/* Choose the "default" power level as the highest available */417	vote = gmu->gx_arc_votes[gmu->nr_gpu_freqs - 1];418 419	gmu_write(gmu, REG_A6XX_GMU_GX_VOTE_IDX, vote & 0xff);420	gmu_write(gmu, REG_A6XX_GMU_MX_VOTE_IDX, (vote >> 8) & 0xff);421 422	/* Let the GMU know the boot sequence has started */423	return a6xx_gmu_set_oob(gmu, GMU_OOB_BOOT_SLUMBER);424}425 426static void a6xx_gemnoc_workaround(struct a6xx_gmu *gmu)427{428	struct a6xx_gpu *a6xx_gpu = container_of(gmu, struct a6xx_gpu, gmu);429	struct adreno_gpu *adreno_gpu = &a6xx_gpu->base;430 431	/*432	 * GEMNoC can power collapse whilst the GPU is being powered down, resulting433	 * in the power down sequence not being fully executed. That in turn can434	 * prevent CX_GDSC from collapsing. Assert Qactive to avoid this.435	 */436	if (adreno_is_a621(adreno_gpu) || adreno_is_7c3(adreno_gpu))437		gmu_write(gmu, REG_A6XX_GMU_AO_AHB_FENCE_CTRL, BIT(0));438}439 440/* Let the GMU know that we are about to go into slumber */441static int a6xx_gmu_notify_slumber(struct a6xx_gmu *gmu)442{443	int ret;444 445	/* Disable the power counter so the GMU isn't busy */446	gmu_write(gmu, REG_A6XX_GMU_CX_GMU_POWER_COUNTER_ENABLE, 0);447 448	/* Disable SPTP_PC if the CPU is responsible for it */449	if (gmu->idle_level < GMU_IDLE_STATE_SPTP)450		a6xx_sptprac_disable(gmu);451 452	if (!gmu->legacy) {453		ret = a6xx_hfi_send_prep_slumber(gmu);454		goto out;455	}456 457	/* Tell the GMU to get ready to slumber */458	gmu_write(gmu, REG_A6XX_GMU_BOOT_SLUMBER_OPTION, 1);459 460	ret = a6xx_gmu_set_oob(gmu, GMU_OOB_BOOT_SLUMBER);461	a6xx_gmu_clear_oob(gmu, GMU_OOB_BOOT_SLUMBER);462 463	if (!ret) {464		/* Check to see if the GMU really did slumber */465		if (gmu_read(gmu, REG_A6XX_GPU_GMU_CX_GMU_RPMH_POWER_STATE)466			!= 0x0f) {467			DRM_DEV_ERROR(gmu->dev, "The GMU did not go into slumber\n");468			ret = -ETIMEDOUT;469		}470	}471 472out:473	a6xx_gemnoc_workaround(gmu);474 475	/* Put fence into allow mode */476	gmu_write(gmu, REG_A6XX_GMU_AO_AHB_FENCE_CTRL, 0);477	return ret;478}479 480static int a6xx_rpmh_start(struct a6xx_gmu *gmu)481{482	int ret;483	u32 val;484 485	gmu_write(gmu, REG_A6XX_GMU_RSCC_CONTROL_REQ, BIT(1));486 487	ret = gmu_poll_timeout(gmu, REG_A6XX_GMU_RSCC_CONTROL_ACK, val,488		val & (1 << 1), 100, 10000);489	if (ret) {490		DRM_DEV_ERROR(gmu->dev, "Unable to power on the GPU RSC\n");491		return ret;492	}493 494	ret = gmu_poll_timeout_rscc(gmu, REG_A6XX_RSCC_SEQ_BUSY_DRV0, val,495		!val, 100, 10000);496 497	if (ret) {498		DRM_DEV_ERROR(gmu->dev, "GPU RSC sequence stuck while waking up the GPU\n");499		return ret;500	}501 502	gmu_write(gmu, REG_A6XX_GMU_RSCC_CONTROL_REQ, 0);503 504	return 0;505}506 507static void a6xx_rpmh_stop(struct a6xx_gmu *gmu)508{509	int ret;510	u32 val;511 512	gmu_write(gmu, REG_A6XX_GMU_RSCC_CONTROL_REQ, 1);513 514	ret = gmu_poll_timeout_rscc(gmu, REG_A6XX_GPU_RSCC_RSC_STATUS0_DRV0,515		val, val & (1 << 16), 100, 10000);516	if (ret)517		DRM_DEV_ERROR(gmu->dev, "Unable to power off the GPU RSC\n");518 519	gmu_write(gmu, REG_A6XX_GMU_RSCC_CONTROL_REQ, 0);520}521 522static inline void pdc_write(void __iomem *ptr, u32 offset, u32 value)523{524	writel(value, ptr + (offset << 2));525}526 527static void __iomem *a6xx_gmu_get_mmio(struct platform_device *pdev,528		const char *name);529 530static void a6xx_gmu_rpmh_init(struct a6xx_gmu *gmu)531{532	struct a6xx_gpu *a6xx_gpu = container_of(gmu, struct a6xx_gpu, gmu);533	struct adreno_gpu *adreno_gpu = &a6xx_gpu->base;534	struct platform_device *pdev = to_platform_device(gmu->dev);535	void __iomem *pdcptr = a6xx_gmu_get_mmio(pdev, "gmu_pdc");536	u32 seqmem0_drv0_reg = REG_A6XX_RSCC_SEQ_MEM_0_DRV0;537	void __iomem *seqptr = NULL;538	uint32_t pdc_address_offset;539	bool pdc_in_aop = false;540 541	if (IS_ERR(pdcptr))542		goto err;543 544	if (adreno_is_a650_family(adreno_gpu) ||545	    adreno_is_a7xx(adreno_gpu))546		pdc_in_aop = true;547	else if (adreno_is_a618(adreno_gpu) || adreno_is_a640_family(adreno_gpu))548		pdc_address_offset = 0x30090;549	else if (adreno_is_a619(adreno_gpu))550		pdc_address_offset = 0x300a0;551	else552		pdc_address_offset = 0x30080;553 554	if (!pdc_in_aop) {555		seqptr = a6xx_gmu_get_mmio(pdev, "gmu_pdc_seq");556		if (IS_ERR(seqptr))557			goto err;558	}559 560	/* Disable SDE clock gating */561	gmu_write_rscc(gmu, REG_A6XX_GPU_RSCC_RSC_STATUS0_DRV0, BIT(24));562 563	/* Setup RSC PDC handshake for sleep and wakeup */564	gmu_write_rscc(gmu, REG_A6XX_RSCC_PDC_SLAVE_ID_DRV0, 1);565	gmu_write_rscc(gmu, REG_A6XX_RSCC_HIDDEN_TCS_CMD0_DATA, 0);566	gmu_write_rscc(gmu, REG_A6XX_RSCC_HIDDEN_TCS_CMD0_ADDR, 0);567	gmu_write_rscc(gmu, REG_A6XX_RSCC_HIDDEN_TCS_CMD0_DATA + 2, 0);568	gmu_write_rscc(gmu, REG_A6XX_RSCC_HIDDEN_TCS_CMD0_ADDR + 2, 0);569	gmu_write_rscc(gmu, REG_A6XX_RSCC_HIDDEN_TCS_CMD0_DATA + 4,570		       adreno_is_a740_family(adreno_gpu) ? 0x80000021 : 0x80000000);571	gmu_write_rscc(gmu, REG_A6XX_RSCC_HIDDEN_TCS_CMD0_ADDR + 4, 0);572	gmu_write_rscc(gmu, REG_A6XX_RSCC_OVERRIDE_START_ADDR, 0);573	gmu_write_rscc(gmu, REG_A6XX_RSCC_PDC_SEQ_START_ADDR, 0x4520);574	gmu_write_rscc(gmu, REG_A6XX_RSCC_PDC_MATCH_VALUE_LO, 0x4510);575	gmu_write_rscc(gmu, REG_A6XX_RSCC_PDC_MATCH_VALUE_HI, 0x4514);576 577	/* The second spin of A7xx GPUs messed with some register offsets.. */578	if (adreno_is_a740_family(adreno_gpu))579		seqmem0_drv0_reg = REG_A7XX_RSCC_SEQ_MEM_0_DRV0_A740;580 581	/* Load RSC sequencer uCode for sleep and wakeup */582	if (adreno_is_a650_family(adreno_gpu) ||583	    adreno_is_a7xx(adreno_gpu)) {584		gmu_write_rscc(gmu, seqmem0_drv0_reg, 0xeaaae5a0);585		gmu_write_rscc(gmu, seqmem0_drv0_reg + 1, 0xe1a1ebab);586		gmu_write_rscc(gmu, seqmem0_drv0_reg + 2, 0xa2e0a581);587		gmu_write_rscc(gmu, seqmem0_drv0_reg + 3, 0xecac82e2);588		gmu_write_rscc(gmu, seqmem0_drv0_reg + 4, 0x0020edad);589	} else {590		gmu_write_rscc(gmu, REG_A6XX_RSCC_SEQ_MEM_0_DRV0, 0xa7a506a0);591		gmu_write_rscc(gmu, REG_A6XX_RSCC_SEQ_MEM_0_DRV0 + 1, 0xa1e6a6e7);592		gmu_write_rscc(gmu, REG_A6XX_RSCC_SEQ_MEM_0_DRV0 + 2, 0xa2e081e1);593		gmu_write_rscc(gmu, REG_A6XX_RSCC_SEQ_MEM_0_DRV0 + 3, 0xe9a982e2);594		gmu_write_rscc(gmu, REG_A6XX_RSCC_SEQ_MEM_0_DRV0 + 4, 0x0020e8a8);595	}596 597	if (pdc_in_aop)598		goto setup_pdc;599 600	/* Load PDC sequencer uCode for power up and power down sequence */601	pdc_write(seqptr, REG_A6XX_PDC_GPU_SEQ_MEM_0, 0xfebea1e1);602	pdc_write(seqptr, REG_A6XX_PDC_GPU_SEQ_MEM_0 + 1, 0xa5a4a3a2);603	pdc_write(seqptr, REG_A6XX_PDC_GPU_SEQ_MEM_0 + 2, 0x8382a6e0);604	pdc_write(seqptr, REG_A6XX_PDC_GPU_SEQ_MEM_0 + 3, 0xbce3e284);605	pdc_write(seqptr, REG_A6XX_PDC_GPU_SEQ_MEM_0 + 4, 0x002081fc);606 607	/* Set TCS commands used by PDC sequence for low power modes */608	pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS1_CMD_ENABLE_BANK, 7);609	pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS1_CMD_WAIT_FOR_CMPL_BANK, 0);610	pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS1_CONTROL, 0);611	pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS1_CMD0_MSGID, 0x10108);612	pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS1_CMD0_ADDR, 0x30010);613	pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS1_CMD0_DATA, 1);614	pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS1_CMD0_MSGID + 4, 0x10108);615	pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS1_CMD0_ADDR + 4, 0x30000);616	pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS1_CMD0_DATA + 4, 0x0);617 618	pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS1_CMD0_MSGID + 8, 0x10108);619	pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS1_CMD0_ADDR + 8, pdc_address_offset);620	pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS1_CMD0_DATA + 8, 0x0);621 622	pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS3_CMD_ENABLE_BANK, 7);623	pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS3_CMD_WAIT_FOR_CMPL_BANK, 0);624	pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS3_CONTROL, 0);625	pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS3_CMD0_MSGID, 0x10108);626	pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS3_CMD0_ADDR, 0x30010);627	pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS3_CMD0_DATA, 2);628 629	pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS3_CMD0_MSGID + 4, 0x10108);630	pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS3_CMD0_ADDR + 4, 0x30000);631	if (adreno_is_a618(adreno_gpu) || adreno_is_a619(adreno_gpu) ||632			adreno_is_a650_family(adreno_gpu))633		pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS3_CMD0_DATA + 4, 0x2);634	else635		pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS3_CMD0_DATA + 4, 0x3);636	pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS3_CMD0_MSGID + 8, 0x10108);637	pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS3_CMD0_ADDR + 8, pdc_address_offset);638	pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS3_CMD0_DATA + 8, 0x3);639 640	/* Setup GPU PDC */641setup_pdc:642	pdc_write(pdcptr, REG_A6XX_PDC_GPU_SEQ_START_ADDR, 0);643	pdc_write(pdcptr, REG_A6XX_PDC_GPU_ENABLE_PDC, 0x80000001);644 645	/* ensure no writes happen before the uCode is fully written */646	wmb();647 648	a6xx_rpmh_stop(gmu);649 650err:651	if (!IS_ERR_OR_NULL(pdcptr))652		iounmap(pdcptr);653	if (!IS_ERR_OR_NULL(seqptr))654		iounmap(seqptr);655}656 657/*658 * The lowest 16 bits of this value are the number of XO clock cycles for main659 * hysteresis which is set at 0x1680 cycles (300 us).  The higher 16 bits are660 * for the shorter hysteresis that happens after main - this is 0xa (.5 us)661 */662 663#define GMU_PWR_COL_HYST 0x000a1680664 665/* Set up the idle state for the GMU */666static void a6xx_gmu_power_config(struct a6xx_gmu *gmu)667{668	struct a6xx_gpu *a6xx_gpu = container_of(gmu, struct a6xx_gpu, gmu);669	struct adreno_gpu *adreno_gpu = &a6xx_gpu->base;670 671	/* Disable GMU WB/RB buffer */672	gmu_write(gmu, REG_A6XX_GMU_SYS_BUS_CONFIG, 0x1);673	gmu_write(gmu, REG_A6XX_GMU_ICACHE_CONFIG, 0x1);674	gmu_write(gmu, REG_A6XX_GMU_DCACHE_CONFIG, 0x1);675 676	/* A7xx knows better by default! */677	if (adreno_is_a7xx(adreno_gpu))678		return;679 680	gmu_write(gmu, REG_A6XX_GMU_PWR_COL_INTER_FRAME_CTRL, 0x9c40400);681 682	switch (gmu->idle_level) {683	case GMU_IDLE_STATE_IFPC:684		gmu_write(gmu, REG_A6XX_GMU_PWR_COL_INTER_FRAME_HYST,685			GMU_PWR_COL_HYST);686		gmu_rmw(gmu, REG_A6XX_GMU_PWR_COL_INTER_FRAME_CTRL, 0,687			A6XX_GMU_PWR_COL_INTER_FRAME_CTRL_IFPC_ENABLE |688			A6XX_GMU_PWR_COL_INTER_FRAME_CTRL_HM_POWER_COLLAPSE_ENABLE);689		fallthrough;690	case GMU_IDLE_STATE_SPTP:691		gmu_write(gmu, REG_A6XX_GMU_PWR_COL_SPTPRAC_HYST,692			GMU_PWR_COL_HYST);693		gmu_rmw(gmu, REG_A6XX_GMU_PWR_COL_INTER_FRAME_CTRL, 0,694			A6XX_GMU_PWR_COL_INTER_FRAME_CTRL_IFPC_ENABLE |695			A6XX_GMU_PWR_COL_INTER_FRAME_CTRL_SPTPRAC_POWER_CONTROL_ENABLE);696	}697 698	/* Enable RPMh GPU client */699	gmu_rmw(gmu, REG_A6XX_GMU_RPMH_CTRL, 0,700		A6XX_GMU_RPMH_CTRL_RPMH_INTERFACE_ENABLE |701		A6XX_GMU_RPMH_CTRL_LLC_VOTE_ENABLE |702		A6XX_GMU_RPMH_CTRL_DDR_VOTE_ENABLE |703		A6XX_GMU_RPMH_CTRL_MX_VOTE_ENABLE |704		A6XX_GMU_RPMH_CTRL_CX_VOTE_ENABLE |705		A6XX_GMU_RPMH_CTRL_GFX_VOTE_ENABLE);706}707 708struct block_header {709	u32 addr;710	u32 size;711	u32 type;712	u32 value;713	u32 data[];714};715 716static bool fw_block_mem(struct a6xx_gmu_bo *bo, const struct block_header *blk)717{718	if (!in_range(blk->addr, bo->iova, bo->size))719		return false;720 721	memcpy(bo->virt + blk->addr - bo->iova, blk->data, blk->size);722	return true;723}724 725static int a6xx_gmu_fw_load(struct a6xx_gmu *gmu)726{727	struct a6xx_gpu *a6xx_gpu = container_of(gmu, struct a6xx_gpu, gmu);728	struct adreno_gpu *adreno_gpu = &a6xx_gpu->base;729	const struct firmware *fw_image = adreno_gpu->fw[ADRENO_FW_GMU];730	const struct block_header *blk;731	u32 reg_offset;732 733	u32 itcm_base = 0x00000000;734	u32 dtcm_base = 0x00040000;735 736	if (adreno_is_a650_family(adreno_gpu) || adreno_is_a7xx(adreno_gpu))737		dtcm_base = 0x10004000;738 739	if (gmu->legacy) {740		/* Sanity check the size of the firmware that was loaded */741		if (fw_image->size > 0x8000) {742			DRM_DEV_ERROR(gmu->dev,743				"GMU firmware is bigger than the available region\n");744			return -EINVAL;745		}746 747		gmu_write_bulk(gmu, REG_A6XX_GMU_CM3_ITCM_START,748			       (u32*) fw_image->data, fw_image->size);749		return 0;750	}751 752 753	for (blk = (const struct block_header *) fw_image->data;754	     (const u8*) blk < fw_image->data + fw_image->size;755	     blk = (const struct block_header *) &blk->data[blk->size >> 2]) {756		if (blk->size == 0)757			continue;758 759		if (in_range(blk->addr, itcm_base, SZ_16K)) {760			reg_offset = (blk->addr - itcm_base) >> 2;761			gmu_write_bulk(gmu,762				REG_A6XX_GMU_CM3_ITCM_START + reg_offset,763				blk->data, blk->size);764		} else if (in_range(blk->addr, dtcm_base, SZ_16K)) {765			reg_offset = (blk->addr - dtcm_base) >> 2;766			gmu_write_bulk(gmu,767				REG_A6XX_GMU_CM3_DTCM_START + reg_offset,768				blk->data, blk->size);769		} else if (!fw_block_mem(&gmu->icache, blk) &&770			   !fw_block_mem(&gmu->dcache, blk) &&771			   !fw_block_mem(&gmu->dummy, blk)) {772			DRM_DEV_ERROR(gmu->dev,773				"failed to match fw block (addr=%.8x size=%d data[0]=%.8x)\n",774				blk->addr, blk->size, blk->data[0]);775		}776	}777 778	return 0;779}780 781static int a6xx_gmu_fw_start(struct a6xx_gmu *gmu, unsigned int state)782{783	struct a6xx_gpu *a6xx_gpu = container_of(gmu, struct a6xx_gpu, gmu);784	struct adreno_gpu *adreno_gpu = &a6xx_gpu->base;785	const struct a6xx_info *a6xx_info = adreno_gpu->info->a6xx;786	u32 fence_range_lower, fence_range_upper;787	u32 chipid = 0;788	int ret;789 790	/* Vote veto for FAL10 */791	if (adreno_is_a650_family(adreno_gpu) || adreno_is_a7xx(adreno_gpu)) {792		gmu_write(gmu, REG_A6XX_GPU_GMU_CX_GMU_CX_FALNEXT_INTF, 1);793		gmu_write(gmu, REG_A6XX_GPU_GMU_CX_GMU_CX_FAL_INTF, 1);794	}795 796	/* Turn on TCM (Tightly Coupled Memory) retention */797	if (adreno_is_a7xx(adreno_gpu))798		a6xx_llc_write(a6xx_gpu, REG_A7XX_CX_MISC_TCM_RET_CNTL, 1);799	else800		gmu_write(gmu, REG_A6XX_GMU_GENERAL_7, 1);801 802	if (state == GMU_WARM_BOOT) {803		ret = a6xx_rpmh_start(gmu);804		if (ret)805			return ret;806	} else {807		if (WARN(!adreno_gpu->fw[ADRENO_FW_GMU],808			"GMU firmware is not loaded\n"))809			return -ENOENT;810 811		ret = a6xx_rpmh_start(gmu);812		if (ret)813			return ret;814 815		ret = a6xx_gmu_fw_load(gmu);816		if (ret)817			return ret;818	}819 820	/* Clear init result to make sure we are getting a fresh value */821	gmu_write(gmu, REG_A6XX_GMU_CM3_FW_INIT_RESULT, 0);822	gmu_write(gmu, REG_A6XX_GMU_CM3_BOOT_CONFIG, 0x02);823 824	/* Write the iova of the HFI table */825	gmu_write(gmu, REG_A6XX_GMU_HFI_QTBL_ADDR, gmu->hfi.iova);826	gmu_write(gmu, REG_A6XX_GMU_HFI_QTBL_INFO, 1);827 828	if (adreno_is_a7xx(adreno_gpu)) {829		fence_range_upper = 0x32;830		fence_range_lower = 0x8a0;831	} else {832		fence_range_upper = 0xa;833		fence_range_lower = 0xa0;834	}835 836	gmu_write(gmu, REG_A6XX_GMU_AHB_FENCE_RANGE_0,837		  BIT(31) |838		  FIELD_PREP(GENMASK(30, 18), fence_range_upper) |839		  FIELD_PREP(GENMASK(17, 0), fence_range_lower));840 841	/*842	 * Snapshots toggle the NMI bit which will result in a jump to the NMI843	 * handler instead of __main. Set the M3 config value to avoid that.844	 */845	gmu_write(gmu, REG_A6XX_GMU_CM3_CFG, 0x4052);846 847	if (a6xx_info->gmu_chipid) {848		chipid = a6xx_info->gmu_chipid;849	} else {850		/*851		 * Note that the GMU has a slightly different layout for852		 * chip_id, for whatever reason, so a bit of massaging853		 * is needed.  The upper 16b are the same, but minor and854		 * patchid are packed in four bits each with the lower855		 * 8b unused:856		 */857		chipid  = adreno_gpu->chip_id & 0xffff0000;858		chipid |= (adreno_gpu->chip_id << 4) & 0xf000; /* minor */859		chipid |= (adreno_gpu->chip_id << 8) & 0x0f00; /* patchid */860	}861 862	if (adreno_is_a7xx(adreno_gpu)) {863		gmu_write(gmu, REG_A7XX_GMU_GENERAL_10, chipid);864		gmu_write(gmu, REG_A7XX_GMU_GENERAL_8,865			  (gmu->log.iova & GENMASK(31, 12)) |866			  ((gmu->log.size / SZ_4K - 1) & GENMASK(7, 0)));867	} else {868		gmu_write(gmu, REG_A6XX_GMU_HFI_SFR_ADDR, chipid);869 870		gmu_write(gmu, REG_A6XX_GPU_GMU_CX_GMU_PWR_COL_CP_MSG,871			  gmu->log.iova | (gmu->log.size / SZ_4K - 1));872	}873 874	/* Set up the lowest idle level on the GMU */875	a6xx_gmu_power_config(gmu);876 877	ret = a6xx_gmu_start(gmu);878	if (ret)879		return ret;880 881	if (gmu->legacy) {882		ret = a6xx_gmu_gfx_rail_on(gmu);883		if (ret)884			return ret;885	}886 887	/* Enable SPTP_PC if the CPU is responsible for it */888	if (gmu->idle_level < GMU_IDLE_STATE_SPTP) {889		ret = a6xx_sptprac_enable(gmu);890		if (ret)891			return ret;892	}893 894	ret = a6xx_gmu_hfi_start(gmu);895	if (ret)896		return ret;897 898	/* FIXME: Do we need this wmb() here? */899	wmb();900 901	return 0;902}903 904#define A6XX_HFI_IRQ_MASK \905	(A6XX_GMU_GMU2HOST_INTR_INFO_CM3_FAULT)906 907#define A6XX_GMU_IRQ_MASK \908	(A6XX_GMU_AO_HOST_INTERRUPT_STATUS_WDOG_BITE | \909	 A6XX_GMU_AO_HOST_INTERRUPT_STATUS_HOST_AHB_BUS_ERROR | \910	 A6XX_GMU_AO_HOST_INTERRUPT_STATUS_FENCE_ERR)911 912static void a6xx_gmu_irq_disable(struct a6xx_gmu *gmu)913{914	disable_irq(gmu->gmu_irq);915	disable_irq(gmu->hfi_irq);916 917	gmu_write(gmu, REG_A6XX_GMU_AO_HOST_INTERRUPT_MASK, ~0);918	gmu_write(gmu, REG_A6XX_GMU_GMU2HOST_INTR_MASK, ~0);919}920 921static void a6xx_gmu_rpmh_off(struct a6xx_gmu *gmu)922{923	struct a6xx_gpu *a6xx_gpu = container_of(gmu, struct a6xx_gpu, gmu);924	struct adreno_gpu *adreno_gpu = &a6xx_gpu->base;925	u32 val, seqmem_off = 0;926 927	/* The second spin of A7xx GPUs messed with some register offsets.. */928	if (adreno_is_a740_family(adreno_gpu))929		seqmem_off = 4;930 931	/* Make sure there are no outstanding RPMh votes */932	gmu_poll_timeout_rscc(gmu, REG_A6XX_RSCC_TCS0_DRV0_STATUS + seqmem_off,933		val, (val & 1), 100, 10000);934	gmu_poll_timeout_rscc(gmu, REG_A6XX_RSCC_TCS1_DRV0_STATUS + seqmem_off,935		val, (val & 1), 100, 10000);936	gmu_poll_timeout_rscc(gmu, REG_A6XX_RSCC_TCS2_DRV0_STATUS + seqmem_off,937		val, (val & 1), 100, 10000);938	gmu_poll_timeout_rscc(gmu, REG_A6XX_RSCC_TCS3_DRV0_STATUS + seqmem_off,939		val, (val & 1), 100, 1000);940}941 942/* Force the GMU off in case it isn't responsive */943static void a6xx_gmu_force_off(struct a6xx_gmu *gmu)944{945	struct a6xx_gpu *a6xx_gpu = container_of(gmu, struct a6xx_gpu, gmu);946	struct adreno_gpu *adreno_gpu = &a6xx_gpu->base;947	struct msm_gpu *gpu = &adreno_gpu->base;948 949	/*950	 * Turn off keep alive that might have been enabled by the hang951	 * interrupt952	 */953	gmu_write(&a6xx_gpu->gmu, REG_A6XX_GMU_GMU_PWR_COL_KEEPALIVE, 0);954 955	/* Flush all the queues */956	a6xx_hfi_stop(gmu);957 958	/* Stop the interrupts */959	a6xx_gmu_irq_disable(gmu);960 961	/* Force off SPTP in case the GMU is managing it */962	a6xx_sptprac_disable(gmu);963 964	a6xx_gemnoc_workaround(gmu);965 966	/* Make sure there are no outstanding RPMh votes */967	a6xx_gmu_rpmh_off(gmu);968 969	/* Clear the WRITEDROPPED fields and put fence into allow mode */970	gmu_write(gmu, REG_A6XX_GMU_AHB_FENCE_STATUS_CLR, 0x7);971	gmu_write(gmu, REG_A6XX_GMU_AO_AHB_FENCE_CTRL, 0);972 973	/* Make sure the above writes go through */974	wmb();975 976	/* Halt the gmu cm3 core */977	gmu_write(gmu, REG_A6XX_GMU_CM3_SYSRESET, 1);978 979	a6xx_bus_clear_pending_transactions(adreno_gpu, true);980 981	/* Reset GPU core blocks */982	a6xx_gpu_sw_reset(gpu, true);983}984 985static void a6xx_gmu_set_initial_freq(struct msm_gpu *gpu, struct a6xx_gmu *gmu)986{987	struct dev_pm_opp *gpu_opp;988	unsigned long gpu_freq = gmu->gpu_freqs[gmu->current_perf_index];989 990	gpu_opp = dev_pm_opp_find_freq_exact(&gpu->pdev->dev, gpu_freq, true);991	if (IS_ERR(gpu_opp))992		return;993 994	gmu->freq = 0; /* so a6xx_gmu_set_freq() doesn't exit early */995	a6xx_gmu_set_freq(gpu, gpu_opp, false);996	dev_pm_opp_put(gpu_opp);997}998 999static void a6xx_gmu_set_initial_bw(struct msm_gpu *gpu, struct a6xx_gmu *gmu)1000{1001	struct dev_pm_opp *gpu_opp;1002	unsigned long gpu_freq = gmu->gpu_freqs[gmu->current_perf_index];1003 1004	gpu_opp = dev_pm_opp_find_freq_exact(&gpu->pdev->dev, gpu_freq, true);1005	if (IS_ERR(gpu_opp))1006		return;1007 1008	dev_pm_opp_set_opp(&gpu->pdev->dev, gpu_opp);1009	dev_pm_opp_put(gpu_opp);1010}1011 1012int a6xx_gmu_resume(struct a6xx_gpu *a6xx_gpu)1013{1014	struct adreno_gpu *adreno_gpu = &a6xx_gpu->base;1015	struct msm_gpu *gpu = &adreno_gpu->base;1016	struct a6xx_gmu *gmu = &a6xx_gpu->gmu;1017	int status, ret;1018 1019	if (WARN(!gmu->initialized, "The GMU is not set up yet\n"))1020		return -EINVAL;1021 1022	gmu->hung = false;1023 1024	/* Notify AOSS about the ACD state (unimplemented for now => disable it) */1025	if (!IS_ERR(gmu->qmp)) {1026		ret = qmp_send(gmu->qmp, "{class: gpu, res: acd, val: %d}",1027			       0 /* Hardcode ACD to be disabled for now */);1028		if (ret)1029			dev_err(gmu->dev, "failed to send GPU ACD state\n");1030	}1031 1032	/* Turn on the resources */1033	pm_runtime_get_sync(gmu->dev);1034 1035	/*1036	 * "enable" the GX power domain which won't actually do anything but it1037	 * will make sure that the refcounting is correct in case we need to1038	 * bring down the GX after a GMU failure1039	 */1040	if (!IS_ERR_OR_NULL(gmu->gxpd))1041		pm_runtime_get_sync(gmu->gxpd);1042 1043	/* Use a known rate to bring up the GMU */1044	clk_set_rate(gmu->core_clk, 200000000);1045	clk_set_rate(gmu->hub_clk, adreno_is_a740_family(adreno_gpu) ?1046		     200000000 : 150000000);1047	ret = clk_bulk_prepare_enable(gmu->nr_clocks, gmu->clocks);1048	if (ret) {1049		pm_runtime_put(gmu->gxpd);1050		pm_runtime_put(gmu->dev);1051		return ret;1052	}1053 1054	/* Set the bus quota to a reasonable value for boot */1055	a6xx_gmu_set_initial_bw(gpu, gmu);1056 1057	/* Enable the GMU interrupt */1058	gmu_write(gmu, REG_A6XX_GMU_AO_HOST_INTERRUPT_CLR, ~0);1059	gmu_write(gmu, REG_A6XX_GMU_AO_HOST_INTERRUPT_MASK, ~A6XX_GMU_IRQ_MASK);1060	enable_irq(gmu->gmu_irq);1061 1062	/* Check to see if we are doing a cold or warm boot */1063	if (adreno_is_a7xx(adreno_gpu)) {1064		status = a6xx_llc_read(a6xx_gpu, REG_A7XX_CX_MISC_TCM_RET_CNTL) == 1 ?1065			GMU_WARM_BOOT : GMU_COLD_BOOT;1066	} else if (gmu->legacy) {1067		status = gmu_read(gmu, REG_A6XX_GMU_GENERAL_7) == 1 ?1068			GMU_WARM_BOOT : GMU_COLD_BOOT;1069	} else {1070		/*1071		 * Warm boot path does not work on newer A6xx GPUs1072		 * Presumably this is because icache/dcache regions must be restored1073		 */1074		status = GMU_COLD_BOOT;1075	}1076 1077	ret = a6xx_gmu_fw_start(gmu, status);1078	if (ret)1079		goto out;1080 1081	ret = a6xx_hfi_start(gmu, status);1082	if (ret)1083		goto out;1084 1085	/*1086	 * Turn on the GMU firmware fault interrupt after we know the boot1087	 * sequence is successful1088	 */1089	gmu_write(gmu, REG_A6XX_GMU_GMU2HOST_INTR_CLR, ~0);1090	gmu_write(gmu, REG_A6XX_GMU_GMU2HOST_INTR_MASK, ~A6XX_HFI_IRQ_MASK);1091	enable_irq(gmu->hfi_irq);1092 1093	/* Set the GPU to the current freq */1094	a6xx_gmu_set_initial_freq(gpu, gmu);1095 1096out:1097	/* On failure, shut down the GMU to leave it in a good state */1098	if (ret) {1099		disable_irq(gmu->gmu_irq);1100		a6xx_rpmh_stop(gmu);1101		pm_runtime_put(gmu->gxpd);1102		pm_runtime_put(gmu->dev);1103	}1104 1105	return ret;1106}1107 1108bool a6xx_gmu_isidle(struct a6xx_gmu *gmu)1109{1110	u32 reg;1111 1112	if (!gmu->initialized)1113		return true;1114 1115	reg = gmu_read(gmu, REG_A6XX_GPU_GMU_AO_GPU_CX_BUSY_STATUS);1116 1117	if (reg &  A6XX_GPU_GMU_AO_GPU_CX_BUSY_STATUS_GPUBUSYIGNAHB)1118		return false;1119 1120	return true;1121}1122 1123/* Gracefully try to shut down the GMU and by extension the GPU */1124static void a6xx_gmu_shutdown(struct a6xx_gmu *gmu)1125{1126	struct a6xx_gpu *a6xx_gpu = container_of(gmu, struct a6xx_gpu, gmu);1127	struct adreno_gpu *adreno_gpu = &a6xx_gpu->base;1128	u32 val;1129 1130	/*1131	 * The GMU may still be in slumber unless the GPU started so check and1132	 * skip putting it back into slumber if so1133	 */1134	val = gmu_read(gmu, REG_A6XX_GPU_GMU_CX_GMU_RPMH_POWER_STATE);1135 1136	if (val != 0xf) {1137		int ret = a6xx_gmu_wait_for_idle(gmu);1138 1139		/* If the GMU isn't responding assume it is hung */1140		if (ret) {1141			a6xx_gmu_force_off(gmu);1142			return;1143		}1144 1145		a6xx_bus_clear_pending_transactions(adreno_gpu, a6xx_gpu->hung);1146 1147		/* tell the GMU we want to slumber */1148		ret = a6xx_gmu_notify_slumber(gmu);1149		if (ret) {1150			a6xx_gmu_force_off(gmu);1151			return;1152		}1153 1154		ret = gmu_poll_timeout(gmu,1155			REG_A6XX_GPU_GMU_AO_GPU_CX_BUSY_STATUS, val,1156			!(val & A6XX_GPU_GMU_AO_GPU_CX_BUSY_STATUS_GPUBUSYIGNAHB),1157			100, 10000);1158 1159		/*1160		 * Let the user know we failed to slumber but don't worry too1161		 * much because we are powering down anyway1162		 */1163 1164		if (ret)1165			DRM_DEV_ERROR(gmu->dev,1166				"Unable to slumber GMU: status = 0%x/0%x\n",1167				gmu_read(gmu,1168					REG_A6XX_GPU_GMU_AO_GPU_CX_BUSY_STATUS),1169				gmu_read(gmu,1170					REG_A6XX_GPU_GMU_AO_GPU_CX_BUSY_STATUS2));1171	}1172 1173	/* Turn off HFI */1174	a6xx_hfi_stop(gmu);1175 1176	/* Stop the interrupts and mask the hardware */1177	a6xx_gmu_irq_disable(gmu);1178 1179	/* Tell RPMh to power off the GPU */1180	a6xx_rpmh_stop(gmu);1181}1182 1183 1184int a6xx_gmu_stop(struct a6xx_gpu *a6xx_gpu)1185{1186	struct a6xx_gmu *gmu = &a6xx_gpu->gmu;1187	struct msm_gpu *gpu = &a6xx_gpu->base.base;1188 1189	if (!pm_runtime_active(gmu->dev))1190		return 0;1191 1192	/*1193	 * Force the GMU off if we detected a hang, otherwise try to shut it1194	 * down gracefully1195	 */1196	if (gmu->hung)1197		a6xx_gmu_force_off(gmu);1198	else1199		a6xx_gmu_shutdown(gmu);1200 1201	/* Remove the bus vote */1202	dev_pm_opp_set_opp(&gpu->pdev->dev, NULL);1203 1204	/*1205	 * Make sure the GX domain is off before turning off the GMU (CX)1206	 * domain. Usually the GMU does this but only if the shutdown sequence1207	 * was successful1208	 */1209	if (!IS_ERR_OR_NULL(gmu->gxpd))1210		pm_runtime_put_sync(gmu->gxpd);1211 1212	clk_bulk_disable_unprepare(gmu->nr_clocks, gmu->clocks);1213 1214	pm_runtime_put_sync(gmu->dev);1215 1216	return 0;1217}1218 1219static void a6xx_gmu_memory_free(struct a6xx_gmu *gmu)1220{1221	msm_gem_kernel_put(gmu->hfi.obj, gmu->aspace);1222	msm_gem_kernel_put(gmu->debug.obj, gmu->aspace);1223	msm_gem_kernel_put(gmu->icache.obj, gmu->aspace);1224	msm_gem_kernel_put(gmu->dcache.obj, gmu->aspace);1225	msm_gem_kernel_put(gmu->dummy.obj, gmu->aspace);1226	msm_gem_kernel_put(gmu->log.obj, gmu->aspace);1227 1228	gmu->aspace->mmu->funcs->detach(gmu->aspace->mmu);1229	msm_gem_address_space_put(gmu->aspace);1230}1231 1232static int a6xx_gmu_memory_alloc(struct a6xx_gmu *gmu, struct a6xx_gmu_bo *bo,1233		size_t size, u64 iova, const char *name)1234{1235	struct a6xx_gpu *a6xx_gpu = container_of(gmu, struct a6xx_gpu, gmu);1236	struct drm_device *dev = a6xx_gpu->base.base.dev;1237	uint32_t flags = MSM_BO_WC;1238	u64 range_start, range_end;1239	int ret;1240 1241	size = PAGE_ALIGN(size);1242	if (!iova) {1243		/* no fixed address - use GMU's uncached range */1244		range_start = 0x60000000 + PAGE_SIZE; /* skip dummy page */1245		range_end = 0x80000000;1246	} else {1247		/* range for fixed address */1248		range_start = iova;1249		range_end = iova + size;1250		/* use IOMMU_PRIV for icache/dcache */1251		flags |= MSM_BO_MAP_PRIV;1252	}1253 1254	bo->obj = msm_gem_new(dev, size, flags);1255	if (IS_ERR(bo->obj))1256		return PTR_ERR(bo->obj);1257 1258	ret = msm_gem_get_and_pin_iova_range(bo->obj, gmu->aspace, &bo->iova,1259					     range_start, range_end);1260	if (ret) {1261		drm_gem_object_put(bo->obj);1262		return ret;1263	}1264 1265	bo->virt = msm_gem_get_vaddr(bo->obj);1266	bo->size = size;1267 1268	msm_gem_object_set_name(bo->obj, name);1269 1270	return 0;1271}1272 1273static int a6xx_gmu_memory_probe(struct a6xx_gmu *gmu)1274{1275	struct msm_mmu *mmu;1276 1277	mmu = msm_iommu_new(gmu->dev, 0);1278	if (!mmu)1279		return -ENODEV;1280	if (IS_ERR(mmu))1281		return PTR_ERR(mmu);1282 1283	gmu->aspace = msm_gem_address_space_create(mmu, "gmu", 0x0, 0x80000000);1284	if (IS_ERR(gmu->aspace))1285		return PTR_ERR(gmu->aspace);1286 1287	return 0;1288}1289 1290/* Return the 'arc-level' for the given frequency */1291static unsigned int a6xx_gmu_get_arc_level(struct device *dev,1292					   unsigned long freq)1293{1294	struct dev_pm_opp *opp;1295	unsigned int val;1296 1297	if (!freq)1298		return 0;1299 1300	opp = dev_pm_opp_find_freq_exact(dev, freq, true);1301	if (IS_ERR(opp))1302		return 0;1303 1304	val = dev_pm_opp_get_level(opp);1305 1306	dev_pm_opp_put(opp);1307 1308	return val;1309}1310 1311static int a6xx_gmu_rpmh_arc_votes_init(struct device *dev, u32 *votes,1312		unsigned long *freqs, int freqs_count, const char *id)1313{1314	int i, j;1315	const u16 *pri, *sec;1316	size_t pri_count, sec_count;1317 1318	pri = cmd_db_read_aux_data(id, &pri_count);1319	if (IS_ERR(pri))1320		return PTR_ERR(pri);1321	/*1322	 * The data comes back as an array of unsigned shorts so adjust the1323	 * count accordingly1324	 */1325	pri_count >>= 1;1326	if (!pri_count)1327		return -EINVAL;1328 1329	/*1330	 * Some targets have a separate gfx mxc rail. So try to read that first and then fall back1331	 * to regular mx rail if it is missing1332	 */1333	sec = cmd_db_read_aux_data("gmxc.lvl", &sec_count);1334	if (IS_ERR(sec) && sec != ERR_PTR(-EPROBE_DEFER))1335		sec = cmd_db_read_aux_data("mx.lvl", &sec_count);1336	if (IS_ERR(sec))1337		return PTR_ERR(sec);1338 1339	sec_count >>= 1;1340	if (!sec_count)1341		return -EINVAL;1342 1343	/* Construct a vote for each frequency */1344	for (i = 0; i < freqs_count; i++) {1345		u8 pindex = 0, sindex = 0;1346		unsigned int level = a6xx_gmu_get_arc_level(dev, freqs[i]);1347 1348		/* Get the primary index that matches the arc level */1349		for (j = 0; j < pri_count; j++) {1350			if (pri[j] >= level) {1351				pindex = j;1352				break;1353			}1354		}1355 1356		if (j == pri_count) {1357			DRM_DEV_ERROR(dev,1358				      "Level %u not found in the RPMh list\n",1359				      level);1360			DRM_DEV_ERROR(dev, "Available levels:\n");1361			for (j = 0; j < pri_count; j++)1362				DRM_DEV_ERROR(dev, "  %u\n", pri[j]);1363 1364			return -EINVAL;1365		}1366 1367		/*1368		 * Look for a level in in the secondary list that matches. If1369		 * nothing fits, use the maximum non zero vote1370		 */1371 1372		for (j = 0; j < sec_count; j++) {1373			if (sec[j] >= level) {1374				sindex = j;1375				break;1376			} else if (sec[j]) {1377				sindex = j;1378			}1379		}1380 1381		/* Construct the vote */1382		votes[i] = ((pri[pindex] & 0xffff) << 16) |1383			(sindex << 8) | pindex;1384	}1385 1386	return 0;1387}1388 1389/*1390 * The GMU votes with the RPMh for itself and on behalf of the GPU but we need1391 * to construct the list of votes on the CPU and send it over. Query the RPMh1392 * voltage levels and build the votes1393 */1394 1395static int a6xx_gmu_rpmh_votes_init(struct a6xx_gmu *gmu)1396{1397	struct a6xx_gpu *a6xx_gpu = container_of(gmu, struct a6xx_gpu, gmu);1398	struct adreno_gpu *adreno_gpu = &a6xx_gpu->base;1399	struct msm_gpu *gpu = &adreno_gpu->base;1400	int ret;1401 1402	/* Build the GX votes */1403	ret = a6xx_gmu_rpmh_arc_votes_init(&gpu->pdev->dev, gmu->gx_arc_votes,1404		gmu->gpu_freqs, gmu->nr_gpu_freqs, "gfx.lvl");1405 1406	/* Build the CX votes */1407	ret |= a6xx_gmu_rpmh_arc_votes_init(gmu->dev, gmu->cx_arc_votes,1408		gmu->gmu_freqs, gmu->nr_gmu_freqs, "cx.lvl");1409 1410	return ret;1411}1412 1413static int a6xx_gmu_build_freq_table(struct device *dev, unsigned long *freqs,1414		u32 size)1415{1416	int count = dev_pm_opp_get_opp_count(dev);1417	struct dev_pm_opp *opp;1418	int i, index = 0;1419	unsigned long freq = 1;1420 1421	/*1422	 * The OPP table doesn't contain the "off" frequency level so we need to1423	 * add 1 to the table size to account for it1424	 */1425 1426	if (WARN(count + 1 > size,1427		"The GMU frequency table is being truncated\n"))1428		count = size - 1;1429 1430	/* Set the "off" frequency */1431	freqs[index++] = 0;1432 1433	for (i = 0; i < count; i++) {1434		opp = dev_pm_opp_find_freq_ceil(dev, &freq);1435		if (IS_ERR(opp))1436			break;1437 1438		dev_pm_opp_put(opp);1439		freqs[index++] = freq++;1440	}1441 1442	return index;1443}1444 1445static int a6xx_gmu_pwrlevels_probe(struct a6xx_gmu *gmu)1446{1447	struct a6xx_gpu *a6xx_gpu = container_of(gmu, struct a6xx_gpu, gmu);1448	struct adreno_gpu *adreno_gpu = &a6xx_gpu->base;1449	struct msm_gpu *gpu = &adreno_gpu->base;1450 1451	int ret = 0;1452 1453	/*1454	 * The GMU handles its own frequency switching so build a list of1455	 * available frequencies to send during initialization1456	 */1457	ret = devm_pm_opp_of_add_table(gmu->dev);1458	if (ret) {1459		DRM_DEV_ERROR(gmu->dev, "Unable to set the OPP table for the GMU\n");1460		return ret;1461	}1462 1463	gmu->nr_gmu_freqs = a6xx_gmu_build_freq_table(gmu->dev,1464		gmu->gmu_freqs, ARRAY_SIZE(gmu->gmu_freqs));1465 1466	/*1467	 * The GMU also handles GPU frequency switching so build a list1468	 * from the GPU OPP table1469	 */1470	gmu->nr_gpu_freqs = a6xx_gmu_build_freq_table(&gpu->pdev->dev,1471		gmu->gpu_freqs, ARRAY_SIZE(gmu->gpu_freqs));1472 1473	gmu->current_perf_index = gmu->nr_gpu_freqs - 1;1474 1475	/* Build the list of RPMh votes that we'll send to the GMU */1476	return a6xx_gmu_rpmh_votes_init(gmu);1477}1478 1479static int a6xx_gmu_clocks_probe(struct a6xx_gmu *gmu)1480{1481	int ret = devm_clk_bulk_get_all(gmu->dev, &gmu->clocks);1482 1483	if (ret < 1)1484		return ret;1485 1486	gmu->nr_clocks = ret;1487 1488	gmu->core_clk = msm_clk_bulk_get_clock(gmu->clocks,1489		gmu->nr_clocks, "gmu");1490 1491	gmu->hub_clk = msm_clk_bulk_get_clock(gmu->clocks,1492		gmu->nr_clocks, "hub");1493 1494	return 0;1495}1496 1497static void __iomem *a6xx_gmu_get_mmio(struct platform_device *pdev,1498		const char *name)1499{1500	void __iomem *ret;1501	struct resource *res = platform_get_resource_byname(pdev,1502			IORESOURCE_MEM, name);1503 1504	if (!res) {1505		DRM_DEV_ERROR(&pdev->dev, "Unable to find the %s registers\n", name);1506		return ERR_PTR(-EINVAL);1507	}1508 1509	ret = ioremap(res->start, resource_size(res));1510	if (!ret) {1511		DRM_DEV_ERROR(&pdev->dev, "Unable to map the %s registers\n", name);1512		return ERR_PTR(-EINVAL);1513	}1514 1515	return ret;1516}1517 1518static int a6xx_gmu_get_irq(struct a6xx_gmu *gmu, struct platform_device *pdev,1519		const char *name, irq_handler_t handler)1520{1521	int irq, ret;1522 1523	irq = platform_get_irq_byname(pdev, name);1524 1525	ret = request_irq(irq, handler, IRQF_TRIGGER_HIGH, name, gmu);1526	if (ret) {1527		DRM_DEV_ERROR(&pdev->dev, "Unable to get interrupt %s %d\n",1528			      name, ret);1529		return ret;1530	}1531 1532	disable_irq(irq);1533 1534	return irq;1535}1536 1537void a6xx_gmu_remove(struct a6xx_gpu *a6xx_gpu)1538{1539	struct adreno_gpu *adreno_gpu = &a6xx_gpu->base;1540	struct a6xx_gmu *gmu = &a6xx_gpu->gmu;1541	struct platform_device *pdev = to_platform_device(gmu->dev);1542 1543	mutex_lock(&gmu->lock);1544	if (!gmu->initialized) {1545		mutex_unlock(&gmu->lock);1546		return;1547	}1548 1549	gmu->initialized = false;1550 1551	mutex_unlock(&gmu->lock);1552 1553	pm_runtime_force_suspend(gmu->dev);1554 1555	/*1556	 * Since cxpd is a virt device, the devlink with gmu-dev will be removed1557	 * automatically when we do detach1558	 */1559	dev_pm_domain_detach(gmu->cxpd, false);1560 1561	if (!IS_ERR_OR_NULL(gmu->gxpd)) {1562		pm_runtime_disable(gmu->gxpd);1563		dev_pm_domain_detach(gmu->gxpd, false);1564	}1565 1566	if (!IS_ERR_OR_NULL(gmu->qmp))1567		qmp_put(gmu->qmp);1568 1569	iounmap(gmu->mmio);1570	if (platform_get_resource_byname(pdev, IORESOURCE_MEM, "rscc"))1571		iounmap(gmu->rscc);1572	gmu->mmio = NULL;1573	gmu->rscc = NULL;1574 1575	if (!adreno_has_gmu_wrapper(adreno_gpu)) {1576		a6xx_gmu_memory_free(gmu);1577 1578		free_irq(gmu->gmu_irq, gmu);1579		free_irq(gmu->hfi_irq, gmu);1580	}1581 1582	/* Drop reference taken in of_find_device_by_node */1583	put_device(gmu->dev);1584}1585 1586static int cxpd_notifier_cb(struct notifier_block *nb,1587			unsigned long action, void *data)1588{1589	struct a6xx_gmu *gmu = container_of(nb, struct a6xx_gmu, pd_nb);1590 1591	if (action == GENPD_NOTIFY_OFF)1592		complete_all(&gmu->pd_gate);1593 1594	return 0;1595}1596 1597int a6xx_gmu_wrapper_init(struct a6xx_gpu *a6xx_gpu, struct device_node *node)1598{1599	struct platform_device *pdev = of_find_device_by_node(node);1600	struct a6xx_gmu *gmu = &a6xx_gpu->gmu;1601	int ret;1602 1603	if (!pdev)1604		return -ENODEV;1605 1606	gmu->dev = &pdev->dev;1607 1608	of_dma_configure(gmu->dev, node, true);1609 1610	pm_runtime_enable(gmu->dev);1611 1612	/* Mark legacy for manual SPTPRAC control */1613	gmu->legacy = true;1614 1615	/* Map the GMU registers */1616	gmu->mmio = a6xx_gmu_get_mmio(pdev, "gmu");1617	if (IS_ERR(gmu->mmio)) {1618		ret = PTR_ERR(gmu->mmio);1619		goto err_mmio;1620	}1621 1622	gmu->cxpd = dev_pm_domain_attach_by_name(gmu->dev, "cx");1623	if (IS_ERR(gmu->cxpd)) {1624		ret = PTR_ERR(gmu->cxpd);1625		goto err_mmio;1626	}1627 1628	if (!device_link_add(gmu->dev, gmu->cxpd, DL_FLAG_PM_RUNTIME)) {1629		ret = -ENODEV;1630		goto detach_cxpd;1631	}1632 1633	init_completion(&gmu->pd_gate);1634	complete_all(&gmu->pd_gate);1635	gmu->pd_nb.notifier_call = cxpd_notifier_cb;1636 1637	/* Get a link to the GX power domain to reset the GPU */1638	gmu->gxpd = dev_pm_domain_attach_by_name(gmu->dev, "gx");1639	if (IS_ERR(gmu->gxpd)) {1640		ret = PTR_ERR(gmu->gxpd);1641		goto err_mmio;1642	}1643 1644	gmu->initialized = true;1645 1646	return 0;1647 1648detach_cxpd:1649	dev_pm_domain_detach(gmu->cxpd, false);1650 1651err_mmio:1652	iounmap(gmu->mmio);1653 1654	/* Drop reference taken in of_find_device_by_node */1655	put_device(gmu->dev);1656 1657	return ret;1658}1659 1660int a6xx_gmu_init(struct a6xx_gpu *a6xx_gpu, struct device_node *node)1661{1662	struct adreno_gpu *adreno_gpu = &a6xx_gpu->base;1663	struct a6xx_gmu *gmu = &a6xx_gpu->gmu;1664	struct platform_device *pdev = of_find_device_by_node(node);1665	struct device_link *link;1666	int ret;1667 1668	if (!pdev)1669		return -ENODEV;1670 1671	gmu->dev = &pdev->dev;1672 1673	of_dma_configure(gmu->dev, node, true);1674 1675	/* Fow now, don't do anything fancy until we get our feet under us */1676	gmu->idle_level = GMU_IDLE_STATE_ACTIVE;1677 1678	pm_runtime_enable(gmu->dev);1679 1680	/* Get the list of clocks */1681	ret = a6xx_gmu_clocks_probe(gmu);1682	if (ret)1683		goto err_put_device;1684 1685	ret = a6xx_gmu_memory_probe(gmu);1686	if (ret)1687		goto err_put_device;1688 1689 1690	/* A660 now requires handling "prealloc requests" in GMU firmware1691	 * For now just hardcode allocations based on the known firmware.1692	 * note: there is no indication that these correspond to "dummy" or1693	 * "debug" regions, but this "guess" allows reusing these BOs which1694	 * are otherwise unused by a660.1695	 */1696	gmu->dummy.size = SZ_4K;1697	if (adreno_is_a660_family(adreno_gpu) ||1698	    adreno_is_a7xx(adreno_gpu)) {1699		ret = a6xx_gmu_memory_alloc(gmu, &gmu->debug, SZ_4K * 7,1700					    0x60400000, "debug");1701		if (ret)1702			goto err_memory;1703 1704		gmu->dummy.size = SZ_8K;1705	}1706 1707	/* Allocate memory for the GMU dummy page */1708	ret = a6xx_gmu_memory_alloc(gmu, &gmu->dummy, gmu->dummy.size,1709				    0x60000000, "dummy");1710	if (ret)1711		goto err_memory;1712 1713	/* Note that a650 family also includes a660 family: */1714	if (adreno_is_a650_family(adreno_gpu) ||1715	    adreno_is_a7xx(adreno_gpu)) {1716		ret = a6xx_gmu_memory_alloc(gmu, &gmu->icache,1717			SZ_16M - SZ_16K, 0x04000, "icache");1718		if (ret)1719			goto err_memory;1720	/*1721	 * NOTE: when porting legacy ("pre-650-family") GPUs you may be tempted to add a condition1722	 * to allocate icache/dcache here, as per downstream code flow, but it may not actually be1723	 * necessary. If you omit this step and you don't get random pagefaults, you are likely1724	 * good to go without this!1725	 */1726	} else if (adreno_is_a640_family(adreno_gpu)) {1727		ret = a6xx_gmu_memory_alloc(gmu, &gmu->icache,1728			SZ_256K - SZ_16K, 0x04000, "icache");1729		if (ret)1730			goto err_memory;1731 1732		ret = a6xx_gmu_memory_alloc(gmu, &gmu->dcache,1733			SZ_256K - SZ_16K, 0x44000, "dcache");1734		if (ret)1735			goto err_memory;1736	} else if (adreno_is_a630_family(adreno_gpu)) {1737		/* HFI v1, has sptprac */1738		gmu->legacy = true;1739 1740		/* Allocate memory for the GMU debug region */1741		ret = a6xx_gmu_memory_alloc(gmu, &gmu->debug, SZ_16K, 0, "debug");1742		if (ret)1743			goto err_memory;1744	}1745 1746	/* Allocate memory for the GMU log region */1747	ret = a6xx_gmu_memory_alloc(gmu, &gmu->log, SZ_16K, 0, "log");1748	if (ret)1749		goto err_memory;1750 1751	/* Allocate memory for for the HFI queues */1752	ret = a6xx_gmu_memory_alloc(gmu, &gmu->hfi, SZ_16K, 0, "hfi");1753	if (ret)1754		goto err_memory;1755 1756	/* Map the GMU registers */1757	gmu->mmio = a6xx_gmu_get_mmio(pdev, "gmu");1758	if (IS_ERR(gmu->mmio)) {1759		ret = PTR_ERR(gmu->mmio);1760		goto err_memory;1761	}1762 1763	if (adreno_is_a650_family(adreno_gpu) ||1764	    adreno_is_a7xx(adreno_gpu)) {1765		gmu->rscc = a6xx_gmu_get_mmio(pdev, "rscc");1766		if (IS_ERR(gmu->rscc)) {1767			ret = -ENODEV;1768			goto err_mmio;1769		}1770	} else {1771		gmu->rscc = gmu->mmio + 0x23000;1772	}1773 1774	/* Get the HFI and GMU interrupts */1775	gmu->hfi_irq = a6xx_gmu_get_irq(gmu, pdev, "hfi", a6xx_hfi_irq);1776	gmu->gmu_irq = a6xx_gmu_get_irq(gmu, pdev, "gmu", a6xx_gmu_irq);1777 1778	if (gmu->hfi_irq < 0 || gmu->gmu_irq < 0) {1779		ret = -ENODEV;1780		goto err_mmio;1781	}1782 1783	gmu->cxpd = dev_pm_domain_attach_by_name(gmu->dev, "cx");1784	if (IS_ERR(gmu->cxpd)) {1785		ret = PTR_ERR(gmu->cxpd);1786		goto err_mmio;1787	}1788 1789	link = device_link_add(gmu->dev, gmu->cxpd, DL_FLAG_PM_RUNTIME);1790	if (!link) {1791		ret = -ENODEV;1792		goto detach_cxpd;1793	}1794 1795	gmu->qmp = qmp_get(gmu->dev);1796	if (IS_ERR(gmu->qmp) && adreno_is_a7xx(adreno_gpu)) {1797		ret = PTR_ERR(gmu->qmp);1798		goto remove_device_link;1799	}1800 1801	init_completion(&gmu->pd_gate);1802	complete_all(&gmu->pd_gate);1803	gmu->pd_nb.notifier_call = cxpd_notifier_cb;1804 1805	/*1806	 * Get a link to the GX power domain to reset the GPU in case of GMU1807	 * crash1808	 */1809	gmu->gxpd = dev_pm_domain_attach_by_name(gmu->dev, "gx");1810 1811	/* Get the power levels for the GMU and GPU */1812	a6xx_gmu_pwrlevels_probe(gmu);1813 1814	/* Set up the HFI queues */1815	a6xx_hfi_init(gmu);1816 1817	/* Initialize RPMh */1818	a6xx_gmu_rpmh_init(gmu);1819 1820	gmu->initialized = true;1821 1822	return 0;1823 1824remove_device_link:1825	device_link_del(link);1826 1827detach_cxpd:1828	dev_pm_domain_detach(gmu->cxpd, false);1829 1830err_mmio:1831	iounmap(gmu->mmio);1832	if (platform_get_resource_byname(pdev, IORESOURCE_MEM, "rscc"))1833		iounmap(gmu->rscc);1834	free_irq(gmu->gmu_irq, gmu);1835	free_irq(gmu->hfi_irq, gmu);1836 1837err_memory:1838	a6xx_gmu_memory_free(gmu);1839err_put_device:1840	/* Drop reference taken in of_find_device_by_node */1841	put_device(gmu->dev);1842 1843	return ret;1844}1845