xref: /linux/drivers/gpu/drm/i915/display/intel_sbi.c (revision 0b6d7dbf1813447e64a09ef3a831fa71bff43669)
17fb3a1f7SJani Nikula // SPDX-License-Identifier: MIT
27fb3a1f7SJani Nikula /*
37fb3a1f7SJani Nikula  * Copyright © 2013-2021 Intel Corporation
47fb3a1f7SJani Nikula  *
57fb3a1f7SJani Nikula  * LPT/WPT IOSF sideband.
67fb3a1f7SJani Nikula  */
77fb3a1f7SJani Nikula 
8ad3cfb65SJani Nikula #include <drm/drm_print.h>
9ad3cfb65SJani Nikula 
10ad3cfb65SJani Nikula #include "intel_de.h"
11a737ab4aSJani Nikula #include "intel_display_core.h"
12a737ab4aSJani Nikula #include "intel_sbi.h"
13*0b6d7dbfSJani Nikula #include "intel_sbi_regs.h"
147fb3a1f7SJani Nikula 
157fb3a1f7SJani Nikula /* SBI access */
16a737ab4aSJani Nikula static int intel_sbi_rw(struct intel_display *display, u16 reg,
177fb3a1f7SJani Nikula 			enum intel_sbi_destination destination,
187fb3a1f7SJani Nikula 			u32 *val, bool is_read)
197fb3a1f7SJani Nikula {
207fb3a1f7SJani Nikula 	u32 cmd;
217fb3a1f7SJani Nikula 
229ab17edeSJani Nikula 	lockdep_assert_held(&display->sbi.lock);
237fb3a1f7SJani Nikula 
24ad3cfb65SJani Nikula 	if (intel_de_wait_fw(display, SBI_CTL_STAT, SBI_BUSY, 0, 100, NULL)) {
25a737ab4aSJani Nikula 		drm_err(display->drm, "timeout waiting for SBI to become ready\n");
267fb3a1f7SJani Nikula 		return -EBUSY;
277fb3a1f7SJani Nikula 	}
287fb3a1f7SJani Nikula 
29ad3cfb65SJani Nikula 	intel_de_write_fw(display, SBI_ADDR, (u32)reg << 16);
30ad3cfb65SJani Nikula 	intel_de_write_fw(display, SBI_DATA, is_read ? 0 : *val);
317fb3a1f7SJani Nikula 
327fb3a1f7SJani Nikula 	if (destination == SBI_ICLK)
337fb3a1f7SJani Nikula 		cmd = SBI_CTL_DEST_ICLK | SBI_CTL_OP_CRRD;
347fb3a1f7SJani Nikula 	else
357fb3a1f7SJani Nikula 		cmd = SBI_CTL_DEST_MPHY | SBI_CTL_OP_IORD;
367fb3a1f7SJani Nikula 	if (!is_read)
377fb3a1f7SJani Nikula 		cmd |= BIT(8);
38ad3cfb65SJani Nikula 	intel_de_write_fw(display, SBI_CTL_STAT, cmd | SBI_BUSY);
397fb3a1f7SJani Nikula 
40ad3cfb65SJani Nikula 	if (intel_de_wait_fw(display, SBI_CTL_STAT, SBI_BUSY, 0, 100, &cmd)) {
41a737ab4aSJani Nikula 		drm_err(display->drm, "timeout waiting for SBI to complete read\n");
427fb3a1f7SJani Nikula 		return -ETIMEDOUT;
437fb3a1f7SJani Nikula 	}
447fb3a1f7SJani Nikula 
457fb3a1f7SJani Nikula 	if (cmd & SBI_RESPONSE_FAIL) {
46a737ab4aSJani Nikula 		drm_err(display->drm, "error during SBI read of reg %x\n", reg);
477fb3a1f7SJani Nikula 		return -ENXIO;
487fb3a1f7SJani Nikula 	}
497fb3a1f7SJani Nikula 
507fb3a1f7SJani Nikula 	if (is_read)
51ad3cfb65SJani Nikula 		*val = intel_de_read_fw(display, SBI_DATA);
527fb3a1f7SJani Nikula 
537fb3a1f7SJani Nikula 	return 0;
547fb3a1f7SJani Nikula }
557fb3a1f7SJani Nikula 
56a737ab4aSJani Nikula void intel_sbi_lock(struct intel_display *display)
577fb3a1f7SJani Nikula {
589ab17edeSJani Nikula 	mutex_lock(&display->sbi.lock);
597fb3a1f7SJani Nikula }
607fb3a1f7SJani Nikula 
61a737ab4aSJani Nikula void intel_sbi_unlock(struct intel_display *display)
627fb3a1f7SJani Nikula {
639ab17edeSJani Nikula 	mutex_unlock(&display->sbi.lock);
647fb3a1f7SJani Nikula }
657fb3a1f7SJani Nikula 
66a737ab4aSJani Nikula u32 intel_sbi_read(struct intel_display *display, u16 reg,
677fb3a1f7SJani Nikula 		   enum intel_sbi_destination destination)
687fb3a1f7SJani Nikula {
697fb3a1f7SJani Nikula 	u32 result = 0;
707fb3a1f7SJani Nikula 
71a737ab4aSJani Nikula 	intel_sbi_rw(display, reg, destination, &result, true);
727fb3a1f7SJani Nikula 
737fb3a1f7SJani Nikula 	return result;
747fb3a1f7SJani Nikula }
757fb3a1f7SJani Nikula 
76a737ab4aSJani Nikula void intel_sbi_write(struct intel_display *display, u16 reg, u32 value,
777fb3a1f7SJani Nikula 		     enum intel_sbi_destination destination)
787fb3a1f7SJani Nikula {
79a737ab4aSJani Nikula 	intel_sbi_rw(display, reg, destination, &value, false);
807fb3a1f7SJani Nikula }
817fb3a1f7SJani Nikula 
82a737ab4aSJani Nikula void intel_sbi_init(struct intel_display *display)
837fb3a1f7SJani Nikula {
849ab17edeSJani Nikula 	mutex_init(&display->sbi.lock);
857fb3a1f7SJani Nikula }
867fb3a1f7SJani Nikula 
87a737ab4aSJani Nikula void intel_sbi_fini(struct intel_display *display)
887fb3a1f7SJani Nikula {
899ab17edeSJani Nikula 	mutex_destroy(&display->sbi.lock);
907fb3a1f7SJani Nikula }
91