2016-11-25 18:59:35 +01:00
/*
* Copyright © 2016 Intel Corporation
*
* Permission is hereby granted , free of charge , to any person obtaining a
* copy of this software and associated documentation files ( the " Software " ) ,
* to deal in the Software without restriction , including without limitation
* the rights to use , copy , modify , merge , publish , distribute , sublicense ,
* and / or sell copies of the Software , and to permit persons to whom the
* Software is furnished to do so , subject to the following conditions :
*
* The above copyright notice and this permission notice ( including the next
* paragraph ) shall be included in all copies or substantial portions of the
* Software .
*
* THE SOFTWARE IS PROVIDED " AS IS " , WITHOUT WARRANTY OF ANY KIND , EXPRESS OR
* IMPLIED , INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY ,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT . IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM , DAMAGES OR OTHER
* LIABILITY , WHETHER IN AN ACTION OF CONTRACT , TORT OR OTHERWISE , ARISING
* FROM , OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE .
*
*/
# include "i915_drv.h"
# include "intel_uc.h"
2016-11-25 18:59:36 +01:00
void intel_uc_init_early ( struct drm_i915_private * dev_priv )
{
mutex_init ( & dev_priv - > guc . send_mutex ) ;
}
2016-11-25 18:59:35 +01:00
/*
* Read GuC command / status register ( SOFT_SCRATCH_0 )
* Return true if it contains a response rather than a command
*/
2016-12-20 11:55:31 +00:00
static bool intel_guc_recv ( struct intel_guc * guc , u32 * status )
2016-11-25 18:59:35 +01:00
{
2016-12-20 11:55:31 +00:00
struct drm_i915_private * dev_priv = guc_to_i915 ( guc ) ;
2016-11-25 18:59:35 +01:00
u32 val = I915_READ ( SOFT_SCRATCH ( 0 ) ) ;
* status = val ;
return INTEL_GUC_RECV_IS_RESPONSE ( val ) ;
}
int intel_guc_send ( struct intel_guc * guc , const u32 * action , u32 len )
{
struct drm_i915_private * dev_priv = guc_to_i915 ( guc ) ;
u32 status ;
int i ;
int ret ;
if ( WARN_ON ( len < 1 | | len > 15 ) )
return - EINVAL ;
mutex_lock ( & guc - > send_mutex ) ;
intel_uncore_forcewake_get ( dev_priv , FORCEWAKE_ALL ) ;
dev_priv - > guc . action_count + = 1 ;
dev_priv - > guc . action_cmd = action [ 0 ] ;
for ( i = 0 ; i < len ; i + + )
I915_WRITE ( SOFT_SCRATCH ( i ) , action [ i ] ) ;
POSTING_READ ( SOFT_SCRATCH ( i - 1 ) ) ;
I915_WRITE ( GUC_SEND_INTERRUPT , GUC_SEND_TRIGGER ) ;
/*
* Fast commands should complete in less than 10u s , so sample quickly
* up to that length of time , then switch to a slower sleep - wait loop .
* No inte_guc_send command should ever take longer than 10 ms .
*/
2016-12-20 11:55:31 +00:00
ret = wait_for_us ( intel_guc_recv ( guc , & status ) , 10 ) ;
2016-11-25 18:59:35 +01:00
if ( ret )
2016-12-20 11:55:31 +00:00
ret = wait_for ( intel_guc_recv ( guc , & status ) , 10 ) ;
2016-11-25 18:59:35 +01:00
if ( status ! = INTEL_GUC_STATUS_SUCCESS ) {
/*
* Either the GuC explicitly returned an error ( which
* we convert to - EIO here ) or no response at all was
* received within the timeout limit ( - ETIMEDOUT )
*/
if ( ret ! = - ETIMEDOUT )
ret = - EIO ;
DRM_WARN ( " INTEL_GUC_SEND: Action 0x%X failed; "
" ret=%d status=0x%08X response=0x%08X \n " ,
action [ 0 ] , ret , status , I915_READ ( SOFT_SCRATCH ( 15 ) ) ) ;
dev_priv - > guc . action_fail + = 1 ;
dev_priv - > guc . action_err = ret ;
}
dev_priv - > guc . action_status = status ;
intel_uncore_forcewake_put ( dev_priv , FORCEWAKE_ALL ) ;
mutex_unlock ( & guc - > send_mutex ) ;
return ret ;
}
int intel_guc_sample_forcewake ( struct intel_guc * guc )
{
struct drm_i915_private * dev_priv = guc_to_i915 ( guc ) ;
u32 action [ 2 ] ;
action [ 0 ] = INTEL_GUC_ACTION_SAMPLE_FORCEWAKE ;
/* WaRsDisableCoarsePowerGating:skl,bxt */
if ( ! intel_enable_rc6 ( ) | | NEEDS_WaRsDisableCoarsePowerGating ( dev_priv ) )
action [ 1 ] = 0 ;
else
/* bit 0 and 1 are for Render and Media domain separately */
action [ 1 ] = GUC_FORCEWAKE_RENDER | GUC_FORCEWAKE_MEDIA ;
return intel_guc_send ( guc , action , ARRAY_SIZE ( action ) ) ;
}