858 lines
25 KiB
C
858 lines
25 KiB
C
/** @file
|
|
Touch Host Controller Private Lib for Driver usage
|
|
|
|
@copyright
|
|
INTEL CONFIDENTIAL
|
|
Copyright 2018 - 2021 Intel Corporation.
|
|
|
|
The source code contained or described herein and all documents related to the
|
|
source code ("Material") are owned by Intel Corporation or its suppliers or
|
|
licensors. Title to the Material remains with Intel Corporation or its suppliers
|
|
and licensors. The Material may contain trade secrets and proprietary and
|
|
confidential information of Intel Corporation and its suppliers and licensors,
|
|
and is protected by worldwide copyright and trade secret laws and treaty
|
|
provisions. No part of the Material may be used, copied, reproduced, modified,
|
|
published, uploaded, posted, transmitted, distributed, or disclosed in any way
|
|
without Intel's prior express written permission.
|
|
|
|
No license under any patent, copyright, trade secret or other intellectual
|
|
property right is granted to or conferred upon you by disclosure or delivery
|
|
of the Materials, either expressly, by implication, inducement, estoppel or
|
|
otherwise. Any license under such intellectual property rights must be
|
|
express and approved by Intel in writing.
|
|
|
|
Unless otherwise agreed by Intel in writing, you may not remove or alter
|
|
this notice or any other notice embedded in Materials by Intel or
|
|
Intel's suppliers or licensors in any way.
|
|
|
|
This file contains an 'Intel Peripheral Driver' and is uniquely identified as
|
|
"Intel Reference Module" and is licensed for Intel CPUs and chipsets under
|
|
the terms of your license agreement with Intel or your vendor. This file may
|
|
be modified by the user, subject to additional terms of the license agreement.
|
|
|
|
@par Specification Reference:
|
|
**/
|
|
|
|
#include "ThcPrivate.h"
|
|
|
|
/**
|
|
Sets TSSGO bit to start a cycle
|
|
|
|
@param[in] MmioBase Thc MMIO BAR0
|
|
|
|
**/
|
|
VOID
|
|
ThcLibGo (
|
|
IN UINT64 MmioBase
|
|
)
|
|
{
|
|
THC_LOCAL_DEBUG(L"ThcLibGo\n")
|
|
MmioOr32 ((UINTN)(MmioBase + R_THC_MEM_PORT_SW_SEQ_CNTRL), B_THC_MEM_PORT_SW_SEQ_CNTRL_TSSGO);
|
|
}
|
|
|
|
/**
|
|
Sets Edge Interrupt mode
|
|
|
|
@param[in] MmioBase Thc MMIO BAR0
|
|
|
|
**/
|
|
VOID
|
|
ThcLibSetEdgeInterrupts (
|
|
IN UINT64 MmioBase
|
|
)
|
|
{
|
|
MmioOr32 (MmioBase + R_THC_MEM_PORT_TSEQ_CNTRL_1, BIT31);
|
|
}
|
|
|
|
/**
|
|
Sets Ewog for Opcode in ICRRD will be used from
|
|
ICRRD_OPCODE[31:8], ICRRD_OPCODE[15:8]
|
|
|
|
@param[in] MmioBase Thc MMIO BAR0
|
|
|
|
**/
|
|
VOID
|
|
ThcLibSetEwog (
|
|
IN UINT64 MmioBase
|
|
)
|
|
{
|
|
MmioOr32 (MmioBase + R_THC_MEM_PORT_TSEQ_CNTRL_1, BIT5);
|
|
}
|
|
|
|
/**
|
|
Returns last received interrupt of THC_INTERRUPT_TYPE
|
|
|
|
@param[in] MmioBase Thc MMIO BAR0
|
|
|
|
@retval One of THC_INTERRUPT_TYPE
|
|
**/
|
|
UINT8
|
|
ThcLibInterruptStatus (
|
|
IN UINT64 MmioBase
|
|
)
|
|
{
|
|
return (UINT8)(MmioRead32 ((UINTN)(MmioBase + R_THC_MEM_PORT_DEV_INT_CAUSE_REG_VAL)) & (BIT0|BIT1|BIT2|BIT3));
|
|
}
|
|
|
|
/**
|
|
Waits for SPI_IO_RDY BIT after it was moved to D0
|
|
|
|
@param[in] MmioBase Thc MMIO BAR0
|
|
@param[in] Timeout [MILLISECONDS] Indicates how long driver waits for device to become ready
|
|
|
|
@retval EFI_SUCCESS Device is ready
|
|
@retval EFI_DEVICE_ERROR Timeout reached - error during initialization
|
|
**/
|
|
EFI_STATUS
|
|
ThcLibIoReady (
|
|
IN UINT64 MmioBase,
|
|
IN UINT32 Timeout
|
|
)
|
|
{
|
|
while (Timeout > 0) {
|
|
if (MmioRead32 (MmioBase + R_THC_MEM_PORT_CONTROL) & B_THC_MEM_PORT_CONTROL_PORT_SPI_IO_RDY) {
|
|
return EFI_SUCCESS;
|
|
}
|
|
gBS->Stall (THC_DELAY_PERIOD_1MS);
|
|
Timeout--;
|
|
}
|
|
return EFI_DEVICE_ERROR;
|
|
}
|
|
|
|
/**
|
|
Start Quiesce to de-initialize THC
|
|
|
|
@param[in] MmioBase Thc MMIO BAR0
|
|
@param[in] Timeout [MILLISECONDS] Indicates how long driver waits for HW Sts bit to be 1
|
|
|
|
@retval EFI_SUCCESS Quiesce Enabled
|
|
@retval EFI_DEVICE_ERROR Timeout reached - error during initialization
|
|
**/
|
|
EFI_STATUS
|
|
ThcLibStartQuiesce (
|
|
IN UINT64 MmioBase,
|
|
IN UINT32 Timeout
|
|
)
|
|
{
|
|
//
|
|
// Set THC_DEVINT_QUIESCE_EN to 1
|
|
//
|
|
MmioOr32 (MmioBase + R_THC_MEM_PORT_CONTROL, B_THC_MEM_PORT_CONTROL_THC_DEVINT_QUIESCE_EN);
|
|
|
|
//
|
|
// Poll on Quiesce HW Sts bit to be 1
|
|
//
|
|
while (Timeout > 0) {
|
|
THC_LOCAL_DEBUG(L"ThcLibStartQuiesce HW_STS: 0x%X | Timeout: %d\n", MmioRead32 (MmioBase + R_THC_MEM_PORT_CONTROL), Timeout)
|
|
if (MmioRead32 (MmioBase + R_THC_MEM_PORT_CONTROL) & B_THC_MEM_PORT_CONTROL_THC_DEVINT_QUIESCE_HW_STS) {
|
|
return EFI_SUCCESS;
|
|
}
|
|
gBS->Stall (THC_DELAY_PERIOD_1MS);
|
|
Timeout--;
|
|
}
|
|
return EFI_DEVICE_ERROR;
|
|
}
|
|
|
|
/**
|
|
Ends Quiesce
|
|
|
|
@param[in] MmioBase Thc MMIO BAR0
|
|
@param[in] Timeout [MILLISECONDS] Indicates how long driver waits for HW STS response
|
|
|
|
@retval EFI_SUCCESS Quiesce Disabled
|
|
@retval EFI_DEVICE_ERROR Timeout reached - error during initialization
|
|
**/
|
|
EFI_STATUS
|
|
ThcLibEndQuiesce (
|
|
IN UINT64 MmioBase,
|
|
IN UINT32 Timeout
|
|
)
|
|
{
|
|
THC_LOCAL_DEBUG(L"ThcLibEndQuiesce R_THC_MEM_PORT_SPI_CONFIG 0x%X, VAL: 0x%X\n", R_THC_MEM_PORT_CONTROL, MmioRead32 (MmioBase + R_THC_MEM_PORT_CONTROL))
|
|
MmioAnd32 (MmioBase + R_THC_MEM_PORT_CONTROL, (UINT32) ~(B_THC_MEM_PORT_CONTROL_THC_DEVINT_QUIESCE_EN));
|
|
THC_LOCAL_DEBUG(L"ThcLibEndQuiesce R_THC_MEM_PORT_SPI_CONFIG 0x%X, VAL: 0x%X\n", R_THC_MEM_PORT_CONTROL, MmioRead32 (MmioBase + R_THC_MEM_PORT_CONTROL))
|
|
|
|
//
|
|
// Poll on Quiesce HW Sts bit to be 0
|
|
//
|
|
while (Timeout > 0) {
|
|
if ( MmioRead32 (MmioBase + R_THC_MEM_PORT_CONTROL) & B_THC_MEM_PORT_CONTROL_THC_DEVINT_QUIESCE_HW_STS) {
|
|
gBS->Stall (THC_DELAY_PERIOD_1MS);
|
|
Timeout--;
|
|
} else {
|
|
return EFI_SUCCESS;
|
|
}
|
|
}
|
|
return EFI_DEVICE_ERROR;
|
|
}
|
|
|
|
/**
|
|
Check if Quiesce is disabled
|
|
|
|
@param[in] MmioBase Thc MMIO BAR0
|
|
|
|
@retval TRUE Quiesce is Disabled
|
|
@retval FALSE Quiesce is Enabled
|
|
**/
|
|
BOOLEAN
|
|
ThcLibIsQuiesceDisabled (
|
|
IN UINT64 MmioBase
|
|
)
|
|
{
|
|
if (MmioRead32 (MmioBase + R_THC_MEM_PORT_CONTROL) & (B_THC_MEM_PORT_CONTROL_THC_DEVINT_QUIESCE_EN | B_THC_MEM_PORT_CONTROL_THC_DEVINT_QUIESCE_HW_STS)) {
|
|
return FALSE;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
/**
|
|
Sets Port Frequency
|
|
|
|
@param[in] MmioBase Thc MMIO BAR0
|
|
@param[in] TypeShift Frequency shift value for read or write
|
|
@param[in] Frequency Frequency value
|
|
|
|
**/
|
|
VOID
|
|
ThcLibSetPortFrequency (
|
|
IN UINT64 MmioBase,
|
|
IN UINT32 TypeShift,
|
|
IN THC_PORT_FREQUENCY Frequency
|
|
)
|
|
{
|
|
UINT32 Data32;
|
|
|
|
Data32 = 0x0;
|
|
|
|
if (Frequency <= ThcFreqLow15MHz) {
|
|
Data32 |= B_THC_MEM_PORT_SPI_CONFIG_LOW_FREQ_EN;
|
|
}
|
|
|
|
switch (Frequency) {
|
|
case ThcFreqLow2p1MHz:
|
|
Data32 |= (V_THC_MEM_PORT_SPI_CONFIG_LOW_FREQ_2P1MHZ << TypeShift);
|
|
break;
|
|
case ThcFreqLow2p5MHz:
|
|
Data32 |= (V_THC_MEM_PORT_SPI_CONFIG_LOW_FREQ_2P5MHZ << TypeShift);
|
|
break;
|
|
case ThcFreqLow3MHz:
|
|
Data32 |= (V_THC_MEM_PORT_SPI_CONFIG_LOW_FREQ_3MHZ << TypeShift);
|
|
break;
|
|
case ThcFreqLow3p75MHz:
|
|
Data32 |= (V_THC_MEM_PORT_SPI_CONFIG_LOW_FREQ_3P75MHZ << TypeShift);
|
|
break;
|
|
case ThcFreqLow5MHz:
|
|
Data32 |= (V_THC_MEM_PORT_SPI_CONFIG_LOW_FREQ_5MHZ << TypeShift);
|
|
break;
|
|
case ThcFreqLow7p5MHz:
|
|
Data32 |= (V_THC_MEM_PORT_SPI_CONFIG_LOW_FREQ_7P5MHZ << TypeShift);
|
|
break;
|
|
case ThcFreqLow15MHz:
|
|
Data32 |= (V_THC_MEM_PORT_SPI_CONFIG_LOW_FREQ_15MHZ << TypeShift);
|
|
break;
|
|
case ThcFreqHigh17MHz:
|
|
Data32 |= (V_THC_MEM_PORT_SPI_CONFIG_HIGH_FREQ_17MHZ << TypeShift);
|
|
break;
|
|
case ThcFreqHigh20MHz:
|
|
Data32 |= (V_THC_MEM_PORT_SPI_CONFIG_HIGH_FREQ_20MHZ << TypeShift);
|
|
break;
|
|
case ThcFreqHigh24MHz:
|
|
Data32 |= (V_THC_MEM_PORT_SPI_CONFIG_HIGH_FREQ_24MHZ << TypeShift);
|
|
break;
|
|
case ThcFreqHigh30MHz:
|
|
Data32 |= (V_THC_MEM_PORT_SPI_CONFIG_HIGH_FREQ_30MHZ << TypeShift);
|
|
break;
|
|
case ThcFreqHigh40MHz:
|
|
Data32 |= (V_THC_MEM_PORT_SPI_CONFIG_HIGH_FREQ_40MHZ << TypeShift);
|
|
break;
|
|
default:
|
|
case ThcFreqInvalid:
|
|
ASSERT (FALSE);
|
|
return;
|
|
}
|
|
|
|
MmioAndThenOr32 (MmioBase + R_THC_MEM_PORT_SPI_CONFIG,
|
|
(UINT32) ~(B_THC_MEM_PORT_SPI_CONFIG_LOW_FREQ_EN | (B_THC_MEM_PORT_SPI_CONFIG_FREQUENCY << TypeShift)),
|
|
Data32);
|
|
}
|
|
|
|
/**
|
|
Sets Single IO mode for both read and write
|
|
|
|
@param[in] MmioBase Thc MMIO BAR0
|
|
|
|
**/
|
|
VOID
|
|
ThcLibSetSingleIoMode (
|
|
IN UINT64 MmioBase
|
|
)
|
|
{
|
|
UINT32 Data32;
|
|
|
|
Data32 = V_THC_MEM_PORT_SPI_CONFIG_SINLGE_IO;
|
|
|
|
MmioAndThenOr32 (MmioBase + R_THC_MEM_PORT_SPI_CONFIG,
|
|
(UINT32) ~((B_THC_MEM_PORT_SPI_CONFIG_MODE << N_THC_MEM_PORT_SPI_CONFIG_TRMODE)),
|
|
Data32);
|
|
MmioAndThenOr32 (MmioBase + R_THC_MEM_PORT_SPI_CONFIG,
|
|
(UINT32) ~((B_THC_MEM_PORT_SPI_CONFIG_MODE << N_THC_MEM_PORT_SPI_CONFIG_TWMODE)),
|
|
Data32);
|
|
}
|
|
|
|
/**
|
|
Power down device through GPIO
|
|
|
|
@param[in] MmioBase Thc MMIO BAR0
|
|
|
|
**/
|
|
VOID
|
|
ThcLibReset (
|
|
IN UINT64 MmioBase
|
|
)
|
|
{
|
|
//
|
|
// Reset Assert
|
|
//
|
|
MmioAndThenOr32 (MmioBase + R_THC_MEM_PORT_CONTROL, (UINT32) ~ (B_THC_MEM_PORT_CONTROL_THC_DEVINT_DEVRST), 0);
|
|
THC_LOCAL_DEBUG(L"ThcLibReset R_THC_MEM_PORT_CONTROL 0x%X, VAL: 0x%X\n", R_THC_MEM_PORT_CONTROL, MmioRead32 (MmioBase + R_THC_MEM_PORT_CONTROL))
|
|
}
|
|
|
|
/**
|
|
Power up device through RST GPIO
|
|
|
|
@param[in] MmioBase Thc MMIO BAR0
|
|
@param[in] Timeout [MILLISECONDS] Indicates how long driver waits for device to power up
|
|
|
|
**/
|
|
VOID
|
|
ThcLibGetOutOfReset (
|
|
IN UINT64 MmioBase,
|
|
IN UINT32 Timeout
|
|
)
|
|
{
|
|
//
|
|
// Check If THC is already In Reset state
|
|
//
|
|
THC_LOCAL_DEBUG(L"ThcLibGetOutOfReset R_THC_MEM_PORT_CONTROL 0x%X, VAL: 0x%X\n", R_THC_MEM_PORT_CONTROL, MmioRead32 (MmioBase + R_THC_MEM_PORT_CONTROL))
|
|
if ((MmioRead32 (MmioBase + R_THC_MEM_PORT_CONTROL) & B_THC_MEM_PORT_CONTROL_THC_DEVINT_DEVRST)) {
|
|
ThcLibReset (MmioBase);
|
|
gBS->Stall (EFI_TIMER_PERIOD_MILLISECONDS(Timeout));
|
|
}
|
|
//
|
|
// Reset DeAssert
|
|
//
|
|
MmioOr32 (MmioBase + R_THC_MEM_PORT_CONTROL, B_THC_MEM_PORT_CONTROL_THC_DEVINT_DEVRST);
|
|
THC_LOCAL_DEBUG(L"ThcLibGetOutOfReset R_THC_MEM_PORT_CONTROL 0x%X, VAL: 0x%X\n", R_THC_MEM_PORT_CONTROL, MmioRead32 (MmioBase + R_THC_MEM_PORT_CONTROL))
|
|
}
|
|
|
|
/**
|
|
Waits for TOUCH_INT_CAUSE to return ResetOccurred
|
|
|
|
@param[in] MmioBase Thc MMIO BAR0
|
|
@param[in] Timeout [MILLISECONDS] Indicates how long driver waits for device to become ready
|
|
|
|
@retval EFI_SUCCESS Reset was successful
|
|
@retval EFI_TIMEOUT Timeout reached - might be expected
|
|
**/
|
|
EFI_STATUS
|
|
ThcLibWaitForResetOccured (
|
|
IN UINT64 MmioBase,
|
|
IN UINT32 Timeout
|
|
)
|
|
{
|
|
while (Timeout > 0) {
|
|
if (ThcLibInterruptStatus (MmioBase) == ResetOccurred) {
|
|
return EFI_SUCCESS;
|
|
}
|
|
gBS->Stall (THC_DELAY_PERIOD_1MS);
|
|
Timeout--;
|
|
if (Timeout % 100 == 0) {
|
|
THC_LOCAL_DEBUG(L"ThcLibWaitForResetOccured Timeout %d InterruptStatus %d \n", Timeout, ThcLibInterruptStatus (MmioBase))
|
|
DEBUG ((DEBUG_INFO, "ThcLibWaitForResetOccured Timeout %d\n", Timeout));
|
|
}
|
|
}
|
|
return EFI_TIMEOUT;
|
|
}
|
|
|
|
/**
|
|
Waits for TOUCH_INT_CAUSE to return ConfigChange
|
|
|
|
@param[in] MmioBase Thc MMIO BAR0
|
|
@param[in] Timeout [MILLISECONDS] Indicates how long driver waits for device to become ready
|
|
|
|
@retval EFI_SUCCESS Reset was successful
|
|
@retval EFI_TIMEOUT Timeout reached - might be expected
|
|
**/
|
|
EFI_STATUS
|
|
ThcLibWaitForConfigChange (
|
|
IN UINT64 MmioBase,
|
|
IN UINT32 Timeout
|
|
)
|
|
{
|
|
while (Timeout > 0) {
|
|
if (ThcLibInterruptStatus (MmioBase) == ConfigChange) {
|
|
return EFI_SUCCESS;
|
|
}
|
|
gBS->Stall (THC_DELAY_PERIOD_1MS);
|
|
Timeout--;
|
|
if (Timeout % 100 == 0) {
|
|
THC_LOCAL_DEBUG(L"ThcLibWaitForConfigChange Timeout %d InterruptStatus %d \n", Timeout, ThcLibInterruptStatus (MmioBase))
|
|
DEBUG ((DEBUG_INFO, "ThcLibWaitForConfigChange Timeout %d\n", Timeout));
|
|
}
|
|
}
|
|
return EFI_TIMEOUT;
|
|
}
|
|
|
|
/**
|
|
Checks if any cycle is currently being served by THC
|
|
|
|
@param[in] MmioBase Thc MMIO BAR0
|
|
|
|
@retval TRUE Cycle is in progress
|
|
@retval FALSE No cycles running
|
|
**/
|
|
BOOLEAN
|
|
ThcLibCycleInProgress (
|
|
IN UINT64 MmioBase
|
|
)
|
|
{
|
|
if (MmioRead32 (MmioBase + R_THC_MEM_PORT_SW_SEQ_STS) & B_THC_MEM_PORT_SW_SEQ_STS_THC_CIP) {
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
/**
|
|
Waits until cycle is completed
|
|
|
|
@param[in] MmioBase Thc MMIO BAR0
|
|
@param[in] Timeout [MILLISECONDS] Indicates how long driver waits for device to become ready
|
|
|
|
@retval EFI_SUCCESS Cycle completed
|
|
@retval EFI_DEVICE_ERROR TSSDONE not set or ERR set
|
|
@retval EFI_TIMEOUT Timeout
|
|
**/
|
|
EFI_STATUS
|
|
ThcLibWaitCycleCompleted (
|
|
IN UINT64 MmioBase,
|
|
IN UINT32 Timeout
|
|
)
|
|
{
|
|
while (Timeout > 0) {
|
|
if (ThcLibCycleInProgress (MmioBase)) {
|
|
gBS->Stall (THC_DELAY_PERIOD_1MS);
|
|
Timeout--;
|
|
if (Timeout % 100 == 0) {
|
|
THC_LOCAL_DEBUG(L"ThcLibWaitCycleCompleted Cycle is still in progress\n")
|
|
DEBUG ((DEBUG_INFO, "ThcLibWaitCycleCompleted Cycle is still in progress\n"));
|
|
}
|
|
} else {
|
|
break;
|
|
}
|
|
}
|
|
if (Timeout == 0) {
|
|
return EFI_TIMEOUT;
|
|
}
|
|
|
|
if ((MmioRead32 ((UINTN)(MmioBase + R_THC_MEM_PORT_SW_SEQ_STS)) & (UINT32)(B_THC_MEM_PORT_SW_SEQ_STS_THC_SS_ERR))) { // ERR set
|
|
return EFI_DEVICE_ERROR;
|
|
}
|
|
if (!(MmioRead32 ((UINTN)(MmioBase + R_THC_MEM_PORT_SW_SEQ_STS)) & (UINT32)(B_THC_MEM_PORT_SW_SEQ_STS_TSSDONE))) { // DONE not set
|
|
return EFI_DEVICE_ERROR;
|
|
}
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
Checks if no cycles are pending
|
|
|
|
@param[in] MmioBase Thc MMIO BAR0
|
|
@param[in] Timeout [MILLISECONDS] Indicates how long driver waits for device to become ready
|
|
|
|
@retval EFI_SUCCESS No Cycles running
|
|
@retval EFI_TIMEOUT Timeout
|
|
**/
|
|
EFI_STATUS
|
|
ThcLibNoCyclesPending (
|
|
IN UINT64 MmioBase,
|
|
IN UINT32 Timeout
|
|
)
|
|
{
|
|
while (Timeout > 0) {
|
|
if (ThcLibCycleInProgress (MmioBase)) {
|
|
gBS->Stall (THC_DELAY_PERIOD_1MS);
|
|
Timeout--;
|
|
if (Timeout % 100 == 0) {
|
|
THC_LOCAL_DEBUG(L"ThcLibNoCyclesPending, Cycle is still in progress\n")
|
|
DEBUG ((DEBUG_INFO, "ThcLibNoCyclesPending, Cycle is still in progress\n"));
|
|
}
|
|
} else {
|
|
return EFI_SUCCESS;
|
|
}
|
|
}
|
|
return EFI_TIMEOUT;
|
|
}
|
|
|
|
/**
|
|
Prepares THC to return its configuration
|
|
|
|
@param[in] MmioBase Thc MMIO BAR0
|
|
|
|
**/
|
|
VOID
|
|
ThcLibPrepareReadDevRegCmd (
|
|
IN UINT64 MmioBase
|
|
)
|
|
{
|
|
THC_M_PRT_SW_SEQ_CNTRL SwSeqCntrl;
|
|
|
|
THC_LOCAL_DEBUG(L"ThcLibPrepareReadDevRegCmd\n")
|
|
|
|
MmioOr32 ((UINTN)(MmioBase + R_THC_MEM_PORT_SW_SEQ_STS), (UINT32) (B_THC_MEM_PORT_SW_SEQ_STS_TSSDONE | B_THC_MEM_PORT_SW_SEQ_STS_THC_SS_ERR));
|
|
SwSeqCntrl.Data = MmioRead32 ((UINTN)(MmioBase + R_THC_MEM_PORT_SW_SEQ_CNTRL));
|
|
|
|
SwSeqCntrl.Fields.ThcSsBc = sizeof (THC_DEVICE_REGISTERS); // 64 bytes
|
|
SwSeqCntrl.Fields.ThcSsCmd = ThcPioRead;
|
|
|
|
MmioWrite32 ((UINTN)(MmioBase + R_THC_MEM_PORT_SW_SEQ_CNTRL), SwSeqCntrl.Data);
|
|
|
|
// Read all defined Touch IC registers. Start from 0 till 64 bytes
|
|
MmioWrite32 ((UINTN)(MmioBase + R_THC_MEM_PORT_SW_SEQ_DATA0_ADDR), R_THC_DEV_TOUCH_INT_CAUSE);
|
|
|
|
}
|
|
|
|
/**
|
|
Prepares THC to change Touch Panels TOUCH_CONFIG fields
|
|
|
|
@param[in] MmioBase Thc MMIO BAR0
|
|
|
|
**/
|
|
VOID
|
|
ThcLibPrepareWriteConfigCmd (
|
|
IN UINT64 MmioBase
|
|
)
|
|
{
|
|
THC_M_PRT_SW_SEQ_CNTRL SwSeqCntrl;
|
|
|
|
THC_LOCAL_DEBUG(L"ThcLibPrepareWriteConfigCmd\n")
|
|
|
|
MmioOr32 ((UINTN)(MmioBase + R_THC_MEM_PORT_SW_SEQ_STS), (UINT32) (B_THC_MEM_PORT_SW_SEQ_STS_TSSDONE | B_THC_MEM_PORT_SW_SEQ_STS_THC_SS_ERR));
|
|
SwSeqCntrl.Data = MmioRead32 ((UINTN)(MmioBase + R_THC_MEM_PORT_SW_SEQ_CNTRL));
|
|
|
|
SwSeqCntrl.Fields.ThcSsBc = sizeof (TOUCH_CONFIG); // 4 bytes
|
|
SwSeqCntrl.Fields.ThcSsCmd = ThcPioWrite;
|
|
|
|
MmioWrite32 ((UINTN)(MmioBase + R_THC_MEM_PORT_SW_SEQ_CNTRL), SwSeqCntrl.Data);
|
|
THC_LOCAL_DEBUG(L"ThcLibPrepareWriteConfigCmd R_THC_MEM_PORT_SW_SEQ_CNTRL 0x%X Data: 0x%X \n", R_THC_MEM_PORT_SW_SEQ_CNTRL, MmioRead32 ((UINTN)(MmioBase + R_THC_MEM_PORT_SW_SEQ_CNTRL)))
|
|
|
|
MmioWrite32 ((UINTN)(MmioBase + R_THC_MEM_PORT_SW_SEQ_DATA0_ADDR), R_THC_DEV_TOUCH_CFG);
|
|
THC_LOCAL_DEBUG(L"ThcLibPrepareWriteConfigCmd R_THC_MEM_PORT_SW_SEQ_DATA0_ADDR 0x%X Data: 0x%X \n", R_THC_MEM_PORT_SW_SEQ_DATA0_ADDR, MmioRead32 ((UINTN)(MmioBase + R_THC_MEM_PORT_SW_SEQ_DATA0_ADDR)))
|
|
}
|
|
|
|
/**
|
|
Reads THC device registers
|
|
|
|
@param[in] MmioBase Thc MMIO BAR0
|
|
@param[in/out] DeviceRegisters Pointer to the device registers
|
|
|
|
@retval EFI_SUCCESS Cycle completed
|
|
@retval EFI_DEVICE_ERROR Returned Byte Count is too big or empty
|
|
**/
|
|
EFI_STATUS
|
|
ThcLibReadDeviceRegisters (
|
|
IN UINT64 MmioBase,
|
|
IN OUT UINT32 *DeviceRegisters
|
|
)
|
|
{
|
|
THC_M_PRT_SW_SEQ_CNTRL SwSeqCntrl;
|
|
UINT32 Index;
|
|
UINT32 DWordCount;
|
|
|
|
THC_LOCAL_DEBUG(L"ThcLibReadDeviceRegisters Start ()\n")
|
|
|
|
SwSeqCntrl.Data = MmioRead32 ((UINTN)(MmioBase + R_THC_MEM_PORT_SW_SEQ_CNTRL));
|
|
if ((SwSeqCntrl.Fields.ThcSsBc > 64) || (SwSeqCntrl.Fields.ThcSsBc == 0)) {
|
|
return EFI_DEVICE_ERROR;
|
|
}
|
|
|
|
DWordCount = SwSeqCntrl.Fields.ThcSsBc / sizeof (UINT32);
|
|
// Go through every DATAx register and read it's content
|
|
for (Index = 0; Index < DWordCount; Index++) {
|
|
THC_LOCAL_DEBUG(L"ThcLibReadDeviceRegisters Offset 0x%X Data: 0x%X\n", (R_THC_MEM_PORT_SW_SEQ_DATA1 + (Index * sizeof (UINT32))), MmioRead32 (MmioBase + R_THC_MEM_PORT_SW_SEQ_DATA1 + (Index * sizeof (UINT32))))
|
|
DeviceRegisters[Index] = MmioRead32 (MmioBase + R_THC_MEM_PORT_SW_SEQ_DATA1 + (Index * sizeof (UINT32)));
|
|
}
|
|
|
|
MmioOr32 ((UINTN)(MmioBase + R_THC_MEM_PORT_SW_SEQ_STS), (UINT32) (B_THC_MEM_PORT_SW_SEQ_STS_TSSDONE | B_THC_MEM_PORT_SW_SEQ_STS_THC_SS_ERR));
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
Write to sequencing Data 1
|
|
|
|
@param[in] MmioBase Thc MMIO BAR0
|
|
@param[in] Data Data
|
|
|
|
**/
|
|
VOID
|
|
ThcLibWriteSeqData1 (
|
|
IN UINT64 MmioBase,
|
|
IN UINT32 Data
|
|
)
|
|
{
|
|
MmioWrite32 ((UINTN)(MmioBase + R_THC_MEM_PORT_SW_SEQ_DATA1), Data);
|
|
}
|
|
|
|
/**
|
|
Sets Prd Tables Adddress in THC MMIO
|
|
|
|
@param[in] MmioBase Thc MMIO BAR0
|
|
@param[in] WriteAddr Write Prd Address
|
|
@param[in] Read2Addr Read2 Prd Address
|
|
|
|
@retval EFI_SUCCESS Cycle completed
|
|
@retval EFI_INVALID_PARAMETER Returned Byte Count is too big or empty
|
|
**/
|
|
EFI_STATUS
|
|
ThcLibSetPrdTablesAddress (
|
|
IN UINT64 MmioBase,
|
|
IN UINT64 WriteAddr,
|
|
IN UINT64 Read2Addr
|
|
)
|
|
{
|
|
THC_LOCAL_DEBUG(L"ThcLibSetPrdTablesAddress Read2Addr: 0x%X Write: 0x%X \n", Read2Addr, WriteAddr)
|
|
if ((Read2Addr & EFI_PAGE_MASK) || (WriteAddr & EFI_PAGE_MASK)) {
|
|
THC_LOCAL_DEBUG(L"ThcLibSetPrdTablesAddress WriteRead Address not 4K alligned first 12 bits should be 0. Read2Addr: 0x%X Write: 0x%X \n", Read2Addr, WriteAddr)
|
|
DEBUG ((DEBUG_ERROR, "ThcLibSetPrdTablesAddress WriteRead Address not 4K alligned first 12 bits should be 0. Read2Addr: 0x%X Write: 0x%X \n", Read2Addr, WriteAddr));
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
MmioWrite32 (MmioBase + R_THC_MEM_PORT_WPRD_BA_LOW, WriteAddr & 0xFFFFF000);
|
|
MmioWrite32 (MmioBase + R_THC_MEM_PORT_WPRD_BA_HI, (UINT32) RShiftU64 ((UINTN) WriteAddr, 32));
|
|
|
|
MmioWrite32 (MmioBase + R_THC_MEM_PORT_RPRD_BA_LOW_2, Read2Addr & 0xFFFFF000);
|
|
MmioWrite32 (MmioBase + R_THC_MEM_PORT_RPRD_BA_HI_2, (UINT32) RShiftU64 ((UINTN) Read2Addr, 32));
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
Sets PrdTable/CircullarBuffer length
|
|
|
|
@param[in] MmioBase Thc MMIO BAR0
|
|
@param[in] ReadEntryCount Number Of Read Entries
|
|
@param[in] ReadCBDepth Read Circullar Buffer Depth
|
|
@param[in] WriteEntryCount Number of Write Entries
|
|
|
|
**/
|
|
VOID
|
|
ThcLibSetLengthInPrd (
|
|
IN UINT64 MmioBase,
|
|
IN UINT8 ReadEntryCount,
|
|
IN UINT8 ReadCBDepth,
|
|
IN UINT8 WriteEntryCount
|
|
)
|
|
{
|
|
THC_M_PRT_RPRD_CNTRL_2 ReadRprdCntrl2;
|
|
THC_M_PRT_WRITE_DMA_CNTRL WriteDmaCntrl;
|
|
|
|
THC_LOCAL_DEBUG(L"ThcLibSetLengthInPrd ReadEntryCount: %d WriteEntryCount: %d ReadCBDepth %d\n", ReadEntryCount, WriteEntryCount, ReadCBDepth)
|
|
|
|
ReadRprdCntrl2.Data = MmioRead32 (MmioBase + R_THC_MEM_PORT_RPRD_CNTRL_2);
|
|
ReadRprdCntrl2.Fields.Ptec = ReadEntryCount - 1; // 0 MmioBased
|
|
ReadRprdCntrl2.Fields.Pcd = ReadCBDepth - 1; // 0 MmioBased
|
|
MmioWrite32 (MmioBase + R_THC_MEM_PORT_RPRD_CNTRL_2, ReadRprdCntrl2.Data);
|
|
|
|
WriteDmaCntrl.Data = MmioRead32 (MmioBase + R_THC_MEM_PORT_WRITE_DMA_CNTRL);
|
|
WriteDmaCntrl.Fields.ThcWrDmaPtec = WriteEntryCount - 1;
|
|
MmioWrite32 (MmioBase + R_THC_MEM_PORT_WRITE_DMA_CNTRL, WriteDmaCntrl.Data);
|
|
}
|
|
|
|
/**
|
|
Sets Write DMA start bit
|
|
|
|
@param[in] MmioBase Thc MMIO BAR0
|
|
|
|
**/
|
|
VOID
|
|
ThcLibSetWriteStartBit (
|
|
IN UINT64 MmioBase
|
|
)
|
|
{
|
|
THC_LOCAL_DEBUG(L"ThcLibSetWriteStartBit ()\n")
|
|
|
|
THC_M_PRT_WRITE_DMA_CNTRL WriteDmaCntrl;
|
|
WriteDmaCntrl.Data = MmioRead32 (MmioBase + R_THC_MEM_PORT_WRITE_DMA_CNTRL);
|
|
WriteDmaCntrl.Fields.ThcWrDmaIeDmaCpl = 1;
|
|
WriteDmaCntrl.Fields.ThcWrDmaStart = 1;
|
|
MmioWrite32 (MmioBase + R_THC_MEM_PORT_WRITE_DMA_CNTRL, WriteDmaCntrl.Data);
|
|
}
|
|
|
|
/**
|
|
Polls until DMA Complete bit is set
|
|
|
|
@param[in] MmioBase Thc MMIO BAR0
|
|
@param[in] Timeout [MILLISECONDS] Indicates how long polling lasts
|
|
|
|
@retval EFI_SUCCESS DMA transfer is complete
|
|
@retval EFI_TIMEOUT Timeout reached
|
|
**/
|
|
EFI_STATUS
|
|
ThcLibPollDmaComplete (
|
|
IN UINT64 MmioBase,
|
|
IN UINT32 Timeout
|
|
)
|
|
{
|
|
THC_M_PRT_WRITE_DMA_CNTRL WriteDmaCntrl;
|
|
THC_M_PRT_DMA_INT_STS WriteDmaIntSts;
|
|
|
|
THC_LOCAL_DEBUG(L"ThcLibPollDmaComplete ()\n")
|
|
|
|
while (Timeout > 0) {
|
|
WriteDmaCntrl.Data = MmioRead32 (MmioBase + R_THC_MEM_PORT_WRITE_DMA_CNTRL);
|
|
if (WriteDmaCntrl.Fields.ThcWrDmaStart == 0) {
|
|
WriteDmaIntSts.Data = MmioRead32 (MmioBase + R_THC_MEM_PORT_WRITE_INT_STS);
|
|
WriteDmaIntSts.Fields.ThcWrDmaCmplStatus = 1;
|
|
MmioWrite32 (MmioBase + R_THC_MEM_PORT_WRITE_INT_STS, WriteDmaIntSts.Data);
|
|
return EFI_SUCCESS;
|
|
}
|
|
MicroSecondDelay (1);
|
|
Timeout--;
|
|
}
|
|
return EFI_TIMEOUT;
|
|
}
|
|
|
|
/**
|
|
Sets Read Rx2 DMA start bit
|
|
|
|
@param[in] MmioBase Thc MMIO BAR0
|
|
|
|
**/
|
|
VOID
|
|
ThcLibSetReadRx2StartBit (
|
|
IN UINT64 MmioBase
|
|
)
|
|
{
|
|
THC_LOCAL_DEBUG(L"ThcLibSetReadRx2StartBit ()\n")
|
|
|
|
THC_M_PRT_READ_DMA_CNTRL_2 ReadDmaCntrl2;
|
|
ReadDmaCntrl2.Data = MmioRead32 (MmioBase + R_THC_MEM_PORT_READ_DMA_CNTRL_2);
|
|
ReadDmaCntrl2.Fields.IeEof = 1;
|
|
ReadDmaCntrl2.Fields.ThcPrdCbWritePointer = POINTER_WRAPAROUND;
|
|
ReadDmaCntrl2.Fields.Start = 1;
|
|
MmioWrite32 (MmioBase + R_THC_MEM_PORT_READ_DMA_CNTRL_2, ReadDmaCntrl2.Data);
|
|
}
|
|
|
|
/**
|
|
Sets Read Rx2 DMA write pointer
|
|
|
|
@param[in] MmioBase Thc MMIO BAR0
|
|
@param[in] WritePointer PRD CB Write Pointer
|
|
|
|
**/
|
|
VOID
|
|
ThcLibSetReadRx2WritePointer (
|
|
IN UINT64 MmioBase,
|
|
IN UINT8 WritePointer
|
|
)
|
|
{
|
|
THC_M_PRT_READ_DMA_CNTRL_2 ReadDmaCntrl2;
|
|
ReadDmaCntrl2.Data = MmioRead32 (MmioBase + R_THC_MEM_PORT_READ_DMA_CNTRL_2);
|
|
ReadDmaCntrl2.Fields.ThcPrdCbWritePointer = WritePointer;
|
|
MmioWrite32 (MmioBase + R_THC_MEM_PORT_READ_DMA_CNTRL_2, ReadDmaCntrl2.Data);
|
|
}
|
|
|
|
/**
|
|
Sets Read Rx2 DMA write pointer
|
|
|
|
@param[in] MmioBase Thc MMIO BAR0
|
|
|
|
@retval Contents of Dma Control 2 register
|
|
**/
|
|
UINT32
|
|
ThcLibGetReadRx2Data (
|
|
IN UINT64 MmioBase
|
|
)
|
|
{
|
|
return MmioRead32 (MmioBase + R_THC_MEM_PORT_READ_DMA_CNTRL_2);
|
|
}
|
|
|
|
/**
|
|
Prepares Touch Panel and THC for OS hand off
|
|
|
|
@param[in] MmioBase Thc MMIO BAR0
|
|
|
|
**/
|
|
VOID
|
|
ThcLibCleanUp (
|
|
IN UINT64 MmioBase
|
|
)
|
|
{
|
|
THC_LOCAL_DEBUG(L"ThcLibCleanUp ()\n")
|
|
THC_M_PRT_READ_DMA_CNTRL_2 ReadDmaCntrl2;
|
|
THC_M_PRT_WRITE_DMA_CNTRL WriteDmaCntrl;
|
|
THC_M_PRT_DMA_INT_STS WriteDmaIntSts;
|
|
|
|
ReadDmaCntrl2.Data = MmioRead32 (MmioBase + R_THC_MEM_PORT_READ_DMA_CNTRL_2);
|
|
ReadDmaCntrl2.Fields.IeEof = 0;
|
|
ReadDmaCntrl2.Fields.ThcPrdCbWritePointer = 0;
|
|
ReadDmaCntrl2.Fields.Start = 0;
|
|
MmioWrite32 (MmioBase + R_THC_MEM_PORT_READ_DMA_CNTRL_2, ReadDmaCntrl2.Data);
|
|
|
|
WriteDmaCntrl.Data = MmioRead32 (MmioBase + R_THC_MEM_PORT_WRITE_DMA_CNTRL);
|
|
WriteDmaCntrl.Fields.ThcWrDmaIeDmaCpl = 0;
|
|
WriteDmaCntrl.Fields.ThcWrDmaStart = 0;
|
|
WriteDmaCntrl.Fields.ThcWrDmaPtec = 0;
|
|
MmioWrite32 (MmioBase + R_THC_MEM_PORT_WRITE_DMA_CNTRL, WriteDmaCntrl.Data);
|
|
|
|
WriteDmaIntSts.Data = MmioRead32 (MmioBase + R_THC_MEM_PORT_WRITE_INT_STS);
|
|
WriteDmaIntSts.Fields.ThcWrDmaCmplStatus = 1;
|
|
MmioWrite32 (MmioBase + R_THC_MEM_PORT_WRITE_INT_STS, WriteDmaIntSts.Data);
|
|
|
|
ThcLibSetReadRx2WritePointer (MmioBase, 0);
|
|
|
|
ThcLibSetPrdTablesAddress (MmioBase, 0, 0);
|
|
ThcLibSetLengthInPrd (MmioBase, 1, 1, 1);
|
|
|
|
ThcLibStartQuiesce (MmioBase, StartQuiesceTimeout);
|
|
|
|
ThcLibReset (MmioBase);
|
|
}
|
|
|
|
/**
|
|
Read Int Cause Register in PIO mode.
|
|
|
|
@param[in] MmioBase Thc MMIO BAR0
|
|
|
|
**/
|
|
VOID
|
|
ThcLibPioReadIntCause (
|
|
IN UINT64 MmioBase
|
|
)
|
|
{
|
|
THC_M_PRT_SW_SEQ_CNTRL SwSeqCntrl;
|
|
|
|
THC_LOCAL_DEBUG(L"ThcLibPioReadIntCause\n")
|
|
|
|
MmioOr32 ((UINTN)(MmioBase + R_THC_MEM_PORT_SW_SEQ_STS), (UINT32) (B_THC_MEM_PORT_SW_SEQ_STS_TSSDONE | B_THC_MEM_PORT_SW_SEQ_STS_THC_SS_ERR));
|
|
SwSeqCntrl.Data = MmioRead32 ((UINTN)(MmioBase + R_THC_MEM_PORT_SW_SEQ_CNTRL));
|
|
|
|
SwSeqCntrl.Fields.ThcSsBc = 4; // 4 bytes
|
|
SwSeqCntrl.Fields.ThcSsCmd = ThcPioRead;
|
|
|
|
MmioWrite32 ((UINTN)(MmioBase + R_THC_MEM_PORT_SW_SEQ_CNTRL), SwSeqCntrl.Data);
|
|
|
|
ThcLibGo (MmioBase);
|
|
|
|
SwSeqCntrl.Data = MmioRead32 ((UINTN)(MmioBase + R_THC_MEM_PORT_SW_SEQ_CNTRL));
|
|
if ((SwSeqCntrl.Fields.ThcSsBc > 64) || (SwSeqCntrl.Fields.ThcSsBc == 0)) {
|
|
THC_LOCAL_DEBUG(L"Error. Wrong data size ThcSsBc = 0x%X.\n", SwSeqCntrl.Fields.ThcSsBc)
|
|
return;
|
|
}
|
|
|
|
THC_LOCAL_DEBUG(L"ThcLibPioReadIntCause Register Offset 0x%X Data: 0x%X\n", R_THC_MEM_PORT_SW_SEQ_DATA1, MmioRead32 (MmioBase + R_THC_MEM_PORT_SW_SEQ_DATA1))
|
|
|
|
MmioOr32 ((UINTN)(MmioBase + R_THC_MEM_PORT_SW_SEQ_STS), (UINT32) (B_THC_MEM_PORT_SW_SEQ_STS_TSSDONE | B_THC_MEM_PORT_SW_SEQ_STS_THC_SS_ERR));
|
|
}
|
|
|