2021-10-14 13:28:58 +03:00
// SPDX-License-Identifier: MIT
2013-05-22 15:36:16 +03:00
/*
2021-10-14 13:28:58 +03:00
* Copyright © 2013 - 2021 Intel Corporation
2013-05-22 15:36:16 +03:00
*
2021-10-14 13:28:58 +03:00
* LPT / WPT IOSF sideband .
2013-05-22 15:36:16 +03:00
*/
# include "i915_drv.h"
2021-10-14 13:28:58 +03:00
# include "intel_sbi.h"
2013-05-22 15:36:16 +03:00
/* SBI access */
2019-04-26 09:17:23 +01:00
static int intel_sbi_rw ( struct drm_i915_private * i915 , u16 reg ,
enum intel_sbi_destination destination ,
u32 * val , bool is_read )
2013-05-22 15:36:16 +03:00
{
2019-04-26 09:17:23 +01:00
struct intel_uncore * uncore = & i915 - > uncore ;
u32 cmd ;
2019-04-26 09:17:19 +01:00
2019-04-26 09:17:23 +01:00
lockdep_assert_held ( & i915 - > sb_lock ) ;
2013-05-22 15:36:16 +03:00
2019-04-26 09:17:23 +01:00
if ( intel_wait_for_register_fw ( uncore ,
SBI_CTL_STAT , SBI_BUSY , 0 ,
100 ) ) {
2020-01-07 18:13:32 +03:00
drm_err ( & i915 - > drm ,
" timeout waiting for SBI to become ready \n " ) ;
2019-04-26 09:17:23 +01:00
return - EBUSY ;
2013-05-22 15:36:16 +03:00
}
2019-04-26 09:17:23 +01:00
intel_uncore_write_fw ( uncore , SBI_ADDR , ( u32 ) reg < < 16 ) ;
intel_uncore_write_fw ( uncore , SBI_DATA , is_read ? 0 : * val ) ;
2013-05-22 15:36:16 +03:00
if ( destination = = SBI_ICLK )
2019-04-26 09:17:23 +01:00
cmd = SBI_CTL_DEST_ICLK | SBI_CTL_OP_CRRD ;
2013-05-22 15:36:16 +03:00
else
2019-04-26 09:17:23 +01:00
cmd = SBI_CTL_DEST_MPHY | SBI_CTL_OP_IORD ;
if ( ! is_read )
cmd | = BIT ( 8 ) ;
intel_uncore_write_fw ( uncore , SBI_CTL_STAT , cmd | SBI_BUSY ) ;
if ( __intel_wait_for_register_fw ( uncore ,
SBI_CTL_STAT , SBI_BUSY , 0 ,
100 , 100 , & cmd ) ) {
2020-01-07 18:13:32 +03:00
drm_err ( & i915 - > drm ,
" timeout waiting for SBI to complete read \n " ) ;
2019-04-26 09:17:23 +01:00
return - ETIMEDOUT ;
2017-02-23 14:10:20 +00:00
}
2019-04-26 09:17:23 +01:00
if ( cmd & SBI_RESPONSE_FAIL ) {
2020-01-07 18:13:32 +03:00
drm_err ( & i915 - > drm , " error during SBI read of reg %x \n " , reg ) ;
2019-04-26 09:17:23 +01:00
return - ENXIO ;
2013-05-22 15:36:16 +03:00
}
2019-04-26 09:17:23 +01:00
if ( is_read )
* val = intel_uncore_read_fw ( uncore , SBI_DATA ) ;
return 0 ;
2013-05-22 15:36:16 +03:00
}
2019-04-26 09:17:23 +01:00
u32 intel_sbi_read ( struct drm_i915_private * i915 , u16 reg ,
enum intel_sbi_destination destination )
2013-05-22 15:36:16 +03:00
{
2019-04-26 09:17:23 +01:00
u32 result = 0 ;
2013-05-22 15:36:16 +03:00
2019-04-26 09:17:23 +01:00
intel_sbi_rw ( i915 , reg , destination , & result , true ) ;
2013-05-22 15:36:16 +03:00
2019-04-26 09:17:23 +01:00
return result ;
}
2017-02-23 14:10:20 +00:00
2019-04-26 09:17:23 +01:00
void intel_sbi_write ( struct drm_i915_private * i915 , u16 reg , u32 value ,
enum intel_sbi_destination destination )
{
intel_sbi_rw ( i915 , reg , destination , & value , false ) ;
2013-05-22 15:36:16 +03:00
}