mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-02 11:10:54 +03:00
feat(usb_host): Add power and clock gating LL, HAL
- part of suspend/resume (remote wakeup) sequences
This commit is contained in:
@@ -1061,6 +1061,21 @@ FORCE_INLINE_ATTR bool usb_dwc_ll_get_stoppclk_st(usb_dwc_dev_t *hw)
|
|||||||
return hw->pcgcctl_reg.stoppclk;
|
return hw->pcgcctl_reg.stoppclk;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FORCE_INLINE_ATTR void usb_dwc_ll_set_gatehclk(usb_dwc_dev_t *hw, bool gate)
|
||||||
|
{
|
||||||
|
hw->pcgcctl_reg.gatehclk = gate;
|
||||||
|
}
|
||||||
|
|
||||||
|
FORCE_INLINE_ATTR bool usb_dwc_ll_get_gatehclk_st(usb_dwc_dev_t *hw)
|
||||||
|
{
|
||||||
|
return hw->pcgcctl_reg.gatehclk;
|
||||||
|
}
|
||||||
|
|
||||||
|
FORCE_INLINE_ATTR bool usb_dwc_ll_get_physleep_st(usb_dwc_dev_t *hw)
|
||||||
|
{
|
||||||
|
return hw->pcgcctl_reg.physleep;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include "esp_attr.h"
|
||||||
#include "soc/usb_dwc_struct.h"
|
#include "soc/usb_dwc_struct.h"
|
||||||
#include "soc/usb_dwc_cfg.h"
|
#include "soc/usb_dwc_cfg.h"
|
||||||
#include "hal/usb_dwc_types.h"
|
#include "hal/usb_dwc_types.h"
|
||||||
@@ -976,6 +977,32 @@ static inline void usb_dwc_ll_qtd_get_status(usb_dwc_ll_dma_qtd_t *qtd, int *rem
|
|||||||
qtd->buffer_status_val = 0;
|
qtd->buffer_status_val = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---------------------------- Power and Clock Gating Register --------------------------------
|
||||||
|
FORCE_INLINE_ATTR void usb_dwc_ll_set_stoppclk(usb_dwc_dev_t *hw, bool stop)
|
||||||
|
{
|
||||||
|
hw->pcgcctl_reg.stoppclk = stop;
|
||||||
|
}
|
||||||
|
|
||||||
|
FORCE_INLINE_ATTR bool usb_dwc_ll_get_stoppclk_st(usb_dwc_dev_t *hw)
|
||||||
|
{
|
||||||
|
return hw->pcgcctl_reg.stoppclk;
|
||||||
|
}
|
||||||
|
|
||||||
|
FORCE_INLINE_ATTR void usb_dwc_ll_set_gatehclk(usb_dwc_dev_t *hw, bool gate)
|
||||||
|
{
|
||||||
|
hw->pcgcctl_reg.gatehclk = gate;
|
||||||
|
}
|
||||||
|
|
||||||
|
FORCE_INLINE_ATTR bool usb_dwc_ll_get_gatehclk_st(usb_dwc_dev_t *hw)
|
||||||
|
{
|
||||||
|
return hw->pcgcctl_reg.gatehclk;
|
||||||
|
}
|
||||||
|
|
||||||
|
FORCE_INLINE_ATTR bool usb_dwc_ll_get_physleep_st(usb_dwc_dev_t *hw)
|
||||||
|
{
|
||||||
|
return hw->pcgcctl_reg.physleep;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include "esp_attr.h"
|
||||||
#include "soc/usb_dwc_struct.h"
|
#include "soc/usb_dwc_struct.h"
|
||||||
#include "soc/usb_dwc_cfg.h"
|
#include "soc/usb_dwc_cfg.h"
|
||||||
#include "hal/usb_dwc_types.h"
|
#include "hal/usb_dwc_types.h"
|
||||||
@@ -976,6 +977,32 @@ static inline void usb_dwc_ll_qtd_get_status(usb_dwc_ll_dma_qtd_t *qtd, int *rem
|
|||||||
qtd->buffer_status_val = 0;
|
qtd->buffer_status_val = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---------------------------- Power and Clock Gating Register --------------------------------
|
||||||
|
FORCE_INLINE_ATTR void usb_dwc_ll_set_stoppclk(usb_dwc_dev_t *hw, bool stop)
|
||||||
|
{
|
||||||
|
hw->pcgcctl_reg.stoppclk = stop;
|
||||||
|
}
|
||||||
|
|
||||||
|
FORCE_INLINE_ATTR bool usb_dwc_ll_get_stoppclk_st(usb_dwc_dev_t *hw)
|
||||||
|
{
|
||||||
|
return hw->pcgcctl_reg.stoppclk;
|
||||||
|
}
|
||||||
|
|
||||||
|
FORCE_INLINE_ATTR void usb_dwc_ll_set_gatehclk(usb_dwc_dev_t *hw, bool gate)
|
||||||
|
{
|
||||||
|
hw->pcgcctl_reg.gatehclk = gate;
|
||||||
|
}
|
||||||
|
|
||||||
|
FORCE_INLINE_ATTR bool usb_dwc_ll_get_gatehclk_st(usb_dwc_dev_t *hw)
|
||||||
|
{
|
||||||
|
return hw->pcgcctl_reg.gatehclk;
|
||||||
|
}
|
||||||
|
|
||||||
|
FORCE_INLINE_ATTR bool usb_dwc_ll_get_physleep_st(usb_dwc_dev_t *hw)
|
||||||
|
{
|
||||||
|
return hw->pcgcctl_reg.physleep;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -553,6 +553,66 @@ static inline bool usb_dwc_hal_port_check_if_suspended(usb_dwc_hal_context_t *ha
|
|||||||
return usb_dwc_ll_hprt_get_port_suspend(hal->dev);
|
return usb_dwc_ll_hprt_get_port_suspend(hal->dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------- Power and Clock gating ----------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gate internal clock of the DWC_OTG core
|
||||||
|
*
|
||||||
|
* This function gates the internal clock of the DWC_OTG core to reduce power consumption
|
||||||
|
*
|
||||||
|
* Internal clock gating:
|
||||||
|
* - stop PHY clock (PCLK)
|
||||||
|
* - gate HCLK to modules other than the AHB slave, AHB master and wakeup logic
|
||||||
|
* Internal clock un-gating:
|
||||||
|
* - un-stop PHY clock (PCLK)
|
||||||
|
* - un-gate HCLK
|
||||||
|
*
|
||||||
|
* @note This is a part of a sequence from the DWC Programming guide, chapter 14.2.2.1
|
||||||
|
* @param hal Context of the HAL layer
|
||||||
|
* @param enable Enable or disable internal clock gating
|
||||||
|
*/
|
||||||
|
static inline void usb_dwc_hal_pwr_clk_internal_clock_gate(usb_dwc_hal_context_t *hal, bool enable)
|
||||||
|
{
|
||||||
|
usb_dwc_ll_set_stoppclk(hal->dev, enable); // Enable/disable PHY clock stop
|
||||||
|
usb_dwc_ll_set_gatehclk(hal->dev, enable); // Gate/ungate HCLK
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Check if the PHY clock (PCLK) stop is enabled or disabled
|
||||||
|
*
|
||||||
|
* @param hal Context of the HAL layer
|
||||||
|
* @return true The PCLK stop is enabled
|
||||||
|
* @return false The PCLK stop is not enabled
|
||||||
|
*/
|
||||||
|
static inline bool usb_dwc_hal_pwr_clk_check_phy_clk_stopped(usb_dwc_hal_context_t *hal)
|
||||||
|
{
|
||||||
|
return usb_dwc_ll_get_stoppclk_st(hal->dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Check if the HCLK is gated or ungated
|
||||||
|
*
|
||||||
|
* @param hal Context of the HAL layer
|
||||||
|
* @return true The HCLK is gated
|
||||||
|
* @return false The HCLK is not gated
|
||||||
|
*/
|
||||||
|
static inline bool usb_dwc_hal_pwr_clk_check_hclk_gated(usb_dwc_hal_context_t *hal)
|
||||||
|
{
|
||||||
|
return usb_dwc_ll_get_gatehclk_st(hal->dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Check if PHY is in sleep state
|
||||||
|
*
|
||||||
|
* @param hal Context of the HAL layer
|
||||||
|
* @return true The USB PHY is in sleep state
|
||||||
|
* @return false The USB PHY is not in sleep state
|
||||||
|
*/
|
||||||
|
static inline bool usb_dwc_hal_pwr_clk_check_phy_sleep(usb_dwc_hal_context_t *hal)
|
||||||
|
{
|
||||||
|
return usb_dwc_ll_get_physleep_st(hal->dev);
|
||||||
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------- Channel -------------------------------------------------------
|
// ----------------------------------------------------- Channel -------------------------------------------------------
|
||||||
|
|
||||||
// ----------------- Channel Allocation --------------------
|
// ----------------- Channel Allocation --------------------
|
||||||
|
|||||||
Reference in New Issue
Block a user