1*7fb3a1f7SJani Nikula // SPDX-License-Identifier: MIT 2*7fb3a1f7SJani Nikula /* 3*7fb3a1f7SJani Nikula * Copyright © 2013-2021 Intel Corporation 4*7fb3a1f7SJani Nikula * 5*7fb3a1f7SJani Nikula * LPT/WPT IOSF sideband. 6*7fb3a1f7SJani Nikula */ 7*7fb3a1f7SJani Nikula 8*7fb3a1f7SJani Nikula #include "i915_drv.h" 9*7fb3a1f7SJani Nikula #include "intel_sbi.h" 10*7fb3a1f7SJani Nikula #include "i915_reg.h" 11*7fb3a1f7SJani Nikula 12*7fb3a1f7SJani Nikula /* SBI access */ 13*7fb3a1f7SJani Nikula static int intel_sbi_rw(struct drm_i915_private *i915, u16 reg, 14*7fb3a1f7SJani Nikula enum intel_sbi_destination destination, 15*7fb3a1f7SJani Nikula u32 *val, bool is_read) 16*7fb3a1f7SJani Nikula { 17*7fb3a1f7SJani Nikula struct intel_uncore *uncore = &i915->uncore; 18*7fb3a1f7SJani Nikula u32 cmd; 19*7fb3a1f7SJani Nikula 20*7fb3a1f7SJani Nikula lockdep_assert_held(&i915->sbi_lock); 21*7fb3a1f7SJani Nikula 22*7fb3a1f7SJani Nikula if (intel_wait_for_register_fw(uncore, 23*7fb3a1f7SJani Nikula SBI_CTL_STAT, SBI_BUSY, 0, 24*7fb3a1f7SJani Nikula 100)) { 25*7fb3a1f7SJani Nikula drm_err(&i915->drm, 26*7fb3a1f7SJani Nikula "timeout waiting for SBI to become ready\n"); 27*7fb3a1f7SJani Nikula return -EBUSY; 28*7fb3a1f7SJani Nikula } 29*7fb3a1f7SJani Nikula 30*7fb3a1f7SJani Nikula intel_uncore_write_fw(uncore, SBI_ADDR, (u32)reg << 16); 31*7fb3a1f7SJani Nikula intel_uncore_write_fw(uncore, SBI_DATA, is_read ? 0 : *val); 32*7fb3a1f7SJani Nikula 33*7fb3a1f7SJani Nikula if (destination == SBI_ICLK) 34*7fb3a1f7SJani Nikula cmd = SBI_CTL_DEST_ICLK | SBI_CTL_OP_CRRD; 35*7fb3a1f7SJani Nikula else 36*7fb3a1f7SJani Nikula cmd = SBI_CTL_DEST_MPHY | SBI_CTL_OP_IORD; 37*7fb3a1f7SJani Nikula if (!is_read) 38*7fb3a1f7SJani Nikula cmd |= BIT(8); 39*7fb3a1f7SJani Nikula intel_uncore_write_fw(uncore, SBI_CTL_STAT, cmd | SBI_BUSY); 40*7fb3a1f7SJani Nikula 41*7fb3a1f7SJani Nikula if (__intel_wait_for_register_fw(uncore, 42*7fb3a1f7SJani Nikula SBI_CTL_STAT, SBI_BUSY, 0, 43*7fb3a1f7SJani Nikula 100, 100, &cmd)) { 44*7fb3a1f7SJani Nikula drm_err(&i915->drm, 45*7fb3a1f7SJani Nikula "timeout waiting for SBI to complete read\n"); 46*7fb3a1f7SJani Nikula return -ETIMEDOUT; 47*7fb3a1f7SJani Nikula } 48*7fb3a1f7SJani Nikula 49*7fb3a1f7SJani Nikula if (cmd & SBI_RESPONSE_FAIL) { 50*7fb3a1f7SJani Nikula drm_err(&i915->drm, "error during SBI read of reg %x\n", reg); 51*7fb3a1f7SJani Nikula return -ENXIO; 52*7fb3a1f7SJani Nikula } 53*7fb3a1f7SJani Nikula 54*7fb3a1f7SJani Nikula if (is_read) 55*7fb3a1f7SJani Nikula *val = intel_uncore_read_fw(uncore, SBI_DATA); 56*7fb3a1f7SJani Nikula 57*7fb3a1f7SJani Nikula return 0; 58*7fb3a1f7SJani Nikula } 59*7fb3a1f7SJani Nikula 60*7fb3a1f7SJani Nikula void intel_sbi_lock(struct drm_i915_private *i915) 61*7fb3a1f7SJani Nikula { 62*7fb3a1f7SJani Nikula mutex_lock(&i915->sbi_lock); 63*7fb3a1f7SJani Nikula } 64*7fb3a1f7SJani Nikula 65*7fb3a1f7SJani Nikula void intel_sbi_unlock(struct drm_i915_private *i915) 66*7fb3a1f7SJani Nikula { 67*7fb3a1f7SJani Nikula mutex_unlock(&i915->sbi_lock); 68*7fb3a1f7SJani Nikula } 69*7fb3a1f7SJani Nikula 70*7fb3a1f7SJani Nikula u32 intel_sbi_read(struct drm_i915_private *i915, u16 reg, 71*7fb3a1f7SJani Nikula enum intel_sbi_destination destination) 72*7fb3a1f7SJani Nikula { 73*7fb3a1f7SJani Nikula u32 result = 0; 74*7fb3a1f7SJani Nikula 75*7fb3a1f7SJani Nikula intel_sbi_rw(i915, reg, destination, &result, true); 76*7fb3a1f7SJani Nikula 77*7fb3a1f7SJani Nikula return result; 78*7fb3a1f7SJani Nikula } 79*7fb3a1f7SJani Nikula 80*7fb3a1f7SJani Nikula void intel_sbi_write(struct drm_i915_private *i915, u16 reg, u32 value, 81*7fb3a1f7SJani Nikula enum intel_sbi_destination destination) 82*7fb3a1f7SJani Nikula { 83*7fb3a1f7SJani Nikula intel_sbi_rw(i915, reg, destination, &value, false); 84*7fb3a1f7SJani Nikula } 85*7fb3a1f7SJani Nikula 86*7fb3a1f7SJani Nikula void intel_sbi_init(struct drm_i915_private *i915) 87*7fb3a1f7SJani Nikula { 88*7fb3a1f7SJani Nikula mutex_init(&i915->sbi_lock); 89*7fb3a1f7SJani Nikula } 90*7fb3a1f7SJani Nikula 91*7fb3a1f7SJani Nikula void intel_sbi_fini(struct drm_i915_private *i915) 92*7fb3a1f7SJani Nikula { 93*7fb3a1f7SJani Nikula mutex_destroy(&i915->sbi_lock); 94*7fb3a1f7SJani Nikula } 95