coresight: add clk control for coresight system

Signed-off-by: liaoao <liaoao@xiaomi.com>
This commit is contained in:
liaoao 2023-12-27 21:42:51 +08:00 committed by Xiang Xiao
parent df33c392ae
commit 8a57dafdcf
13 changed files with 314 additions and 195 deletions

View File

@ -56,20 +56,151 @@ static struct list_node g_csdev_list = LIST_INITIAL_VALUE(g_csdev_list);
* Private Functions
****************************************************************************/
#ifdef CONFIG_PM
/****************************************************************************
* Name: coresight_notify_pm
****************************************************************************/
static void coresight_notify_pm(struct pm_callback_s *cb, int domain,
enum pm_state_e pmstate)
{
FAR struct coresight_dev_s *csdev =
container_of(cb, struct coresight_dev_s, pmcb);
enum pm_state_e oldstate;
if (csdev->refcnt == 0 || domain != PM_IDLE_DOMAIN)
{
return;
}
oldstate = pm_querystate(PM_IDLE_DOMAIN);
switch (oldstate)
{
case PM_NORMAL:
case PM_IDLE:
case PM_STANDBY:
if (pmstate == PM_SLEEP)
{
clk_disable(csdev->clk);
}
break;
case PM_SLEEP:
if (pmstate == PM_NORMAL || pmstate == PM_IDLE ||
pmstate == PM_STANDBY)
{
if (clk_enable(csdev->clk) <= 0)
{
cserr("clk enable failed when pm state change\n");
}
}
break;
default:
break;
}
}
#endif
#ifdef CONFIG_CLK
/****************************************************************************
* Name: coresight_enable_clk
****************************************************************************/
static int coresight_enable_clk(FAR struct coresight_dev_s *csdev)
{
int ret;
if (csdev->clk == NULL)
{
return 0;
}
ret = clk_enable(csdev->clk);
if (ret < 0)
{
cserr("%s clk enable failed\n", csdev->name);
return ret;
}
#ifdef CONFIG_PM
if (csdev->pmcb.notify == NULL)
{
csdev->pmcb.notify = coresight_notify_pm;
}
ret = pm_register(&csdev->pmcb);
if (ret < 0)
{
clk_disable(csdev->clk);
cserr("%s register pm failed\n", csdev->name);
return ret;
}
#endif
return ret;
}
/****************************************************************************
* Name: coresight_disable_clk
****************************************************************************/
static void coresight_disable_clk(FAR struct coresight_dev_s *csdev)
{
if (csdev->clk == NULL)
{
return;
}
#ifdef CONFIG_PM
pm_unregister(&csdev->pmcb);
#endif
clk_disable(csdev->clk);
}
#else
# define coresight_enable_clk(csdev) (0)
# define coresight_disable_clk(csdev)
#endif
/****************************************************************************
* Name: coresight_enable_sink
****************************************************************************/
static int coresight_enable_sink(FAR struct coresight_dev_s *csdev)
{
if (csdev->ops->sink_ops->enable != NULL)
{
return csdev->ops->sink_ops->enable(csdev);
}
else
int ret;
if (csdev->ops->sink_ops->enable == NULL)
{
return -EINVAL;
}
if (csdev->refcnt++ != 0)
{
return 0;
}
ret = coresight_enable_clk(csdev);
if (ret < 0)
{
csdev->refcnt--;
return ret;
}
ret = csdev->ops->sink_ops->enable(csdev);
if (ret >= 0)
{
return ret;
}
csdev->refcnt--;
coresight_disable_clk(csdev);
cserr("%s enable failed\n", csdev->name);
return ret;
}
/****************************************************************************
@ -78,10 +209,18 @@ static int coresight_enable_sink(FAR struct coresight_dev_s *csdev)
static void coresight_disable_sink(FAR struct coresight_dev_s *csdev)
{
if (csdev->ops->sink_ops->disable != NULL)
if (csdev->ops->sink_ops->disable == NULL)
{
csdev->ops->sink_ops->disable(csdev);
return;
}
if (--csdev->refcnt != 0)
{
return;
}
csdev->ops->sink_ops->disable(csdev);
coresight_disable_clk(csdev);
}
/****************************************************************************
@ -138,6 +277,7 @@ static int coresight_enable_link(FAR struct coresight_dev_s *csdev,
{
int inport = 0;
int outport = 0;
int ret;
if (csdev->ops->link_ops->enable == NULL)
{
@ -162,7 +302,28 @@ static int coresight_enable_link(FAR struct coresight_dev_s *csdev,
}
}
return csdev->ops->link_ops->enable(csdev, inport, outport);
if (csdev->refcnt++ == 0)
{
ret = coresight_enable_clk(csdev);
if (ret < 0)
{
csdev->refcnt--;
return ret;
}
}
ret = csdev->ops->link_ops->enable(csdev, inport, outport);
if (ret < 0)
{
if (--csdev->refcnt == 0)
{
coresight_disable_clk(csdev);
}
return ret;
}
return ret;
}
/****************************************************************************
@ -173,11 +334,21 @@ static void coresight_disable_link(FAR struct coresight_dev_s *csdev,
FAR struct coresight_dev_s *prev,
FAR struct coresight_dev_s *next)
{
if (csdev->ops->sink_ops->disable != NULL)
int inport;
int outport;
if (csdev->ops->sink_ops->disable == NULL)
{
int inport = coresight_find_link_inport(csdev, prev);
int outport = coresight_find_link_outport(csdev, next);
csdev->ops->link_ops->disable(csdev, inport, outport);
return;
}
inport = coresight_find_link_inport(csdev, prev);
outport = coresight_find_link_outport(csdev, next);
csdev->ops->link_ops->disable(csdev, inport, outport);
if (--csdev->refcnt == 0)
{
coresight_disable_clk(csdev);
}
}
@ -187,14 +358,35 @@ static void coresight_disable_link(FAR struct coresight_dev_s *csdev,
static int coresight_enable_source(FAR struct coresight_dev_s *csdev)
{
if (csdev->ops->source_ops->enable != NULL)
{
return csdev->ops->source_ops->enable(csdev);
}
else
int ret;
if (csdev->ops->source_ops->enable == NULL)
{
return -EINVAL;
}
if (csdev->refcnt++ != 0)
{
return 0;
}
ret = coresight_enable_clk(csdev);
if (ret < 0)
{
csdev->refcnt--;
return ret;
}
ret = csdev->ops->source_ops->enable(csdev);
if (ret >= 0)
{
return ret;
}
csdev->refcnt--;
coresight_disable_clk(csdev);
cserr("%s enable failed\n", csdev->name);
return ret;
}
/****************************************************************************
@ -203,10 +395,18 @@ static int coresight_enable_source(FAR struct coresight_dev_s *csdev)
static void coresight_disable_source(FAR struct coresight_dev_s *csdev)
{
if (csdev->ops->source_ops->disable != NULL)
if (csdev->ops->source_ops->disable == NULL)
{
csdev->ops->source_ops->disable(csdev);
return;
}
if (--csdev->refcnt != 0)
{
return;
}
csdev->ops->source_ops->disable(csdev);
coresight_disable_clk(csdev);
}
/****************************************************************************
@ -494,6 +694,18 @@ int coresight_register(FAR struct coresight_dev_s *csdev,
csdev->outport_num = desc->outport_num;
list_initialize(&csdev->path);
#ifdef CONFIG_CLK
if (desc->clkname != NULL)
{
csdev->clk = clk_get(desc->clkname);
if (csdev->clk == NULL)
{
cserr("get device clk failed\n");
return -ENODEV;
}
}
#endif
if (csdev->outport_num > 0)
{
csdev->outconns =
@ -684,4 +896,3 @@ void coresight_disable(FAR struct coresight_dev_s *srcdev)
leave_critical_section(flags);
}

View File

@ -272,21 +272,15 @@ static int etb_enable(FAR struct coresight_dev_s *csdev)
{
FAR struct coresight_etb_dev_s *etbdev =
(FAR struct coresight_etb_dev_s *)csdev;
int ret = 0;
int ret;
if (etbdev->refcnt++ == 0)
ret = coresight_claim_device(etbdev->csdev.addr);
if (ret < 0)
{
ret = coresight_claim_device(etbdev->csdev.addr);
if (ret < 0)
{
etbdev->refcnt--;
cserr("%s enable failed\n", csdev->name);
return ret;
}
etb_hw_enable(etbdev);
return ret;
}
etb_hw_enable(etbdev);
return ret;
}
@ -299,12 +293,8 @@ static void etb_disable(FAR struct coresight_dev_s *csdev)
FAR struct coresight_etb_dev_s *etbdev =
(FAR struct coresight_etb_dev_s *)csdev;
if (--etbdev->refcnt == 0)
{
etb_hw_disable(etbdev);
coresight_disclaim_device(etbdev->csdev.addr);
csinfo("%s disabled\n", csdev->name);
}
etb_hw_disable(etbdev);
coresight_disclaim_device(etbdev->csdev.addr);
}
/****************************************************************************
@ -342,13 +332,13 @@ static int etb_open(FAR struct file *filep)
irqstate_t flags;
flags = enter_critical_section();
if (etbdev->refcnt > 0)
if (etbdev->csdev.refcnt > 0)
{
etb_hw_disable(etbdev);
}
etb_hw_read(etbdev);
if (etbdev->refcnt > 0)
if (etbdev->csdev.refcnt > 0)
{
etb_hw_enable(etbdev);
}

View File

@ -436,7 +436,7 @@ static bool etm_arch_supported(uint8_t arch)
*
****************************************************************************/
void etm_set_default(struct etm_config_s *config)
static void etm_set_default(struct etm_config_s *config)
{
int i;
@ -470,19 +470,12 @@ void etm_set_default(struct etm_config_s *config)
* Name: etm_hw_enable
****************************************************************************/
static int etm_hw_enable(FAR struct coresight_etm_dev_s *etmdev)
static void etm_hw_enable(FAR struct coresight_etm_dev_s *etmdev)
{
FAR struct etm_config_s *config = &etmdev->cfg;
uint32_t etmcr;
int ret;
int i;
ret = coresight_claim_device(etmdev->csdev.addr);
if (ret < 0)
{
return ret;
}
coresight_unlock(etmdev->csdev.addr);
etm_os_unlock(etmdev);
etm_set_pwrup(etmdev);
@ -549,8 +542,6 @@ static int etm_hw_enable(FAR struct coresight_etm_dev_s *etmdev)
etm_clr_program(etmdev);
coresight_lock(etmdev->csdev.addr);
return ret;
}
/****************************************************************************
@ -575,8 +566,6 @@ static void etm_hw_disable(FAR struct coresight_etm_dev_s *etmdev)
etm_set_pwrdwn(etmdev);
coresight_lock(etmdev->csdev.addr);
coresight_disclaim_device(etmdev->csdev.addr);
}
/****************************************************************************
@ -587,18 +576,15 @@ static int etm_enable(FAR struct coresight_dev_s *csdev)
{
FAR struct coresight_etm_dev_s *etmdev =
(FAR struct coresight_etm_dev_s *)csdev;
int ret = 0;
int ret;
if (etmdev->refcnt++ == 0)
ret = coresight_claim_device(etmdev->csdev.addr);
if (ret < 0)
{
ret = etm_hw_enable(etmdev);
if (ret < 0)
{
etmdev->refcnt--;
cserr("%s enabled\n", csdev->name);
}
return ret;
}
etm_hw_enable(etmdev);
return ret;
}
@ -611,11 +597,8 @@ static void etm_disable(FAR struct coresight_dev_s *csdev)
FAR struct coresight_etm_dev_s *etmdev =
(FAR struct coresight_etm_dev_s *)csdev;
if (--etmdev->refcnt == 0)
{
etm_hw_disable(etmdev);
csinfo("etm %s disabled\n", csdev->name);
}
etm_hw_disable(etmdev);
coresight_disclaim_device(etmdev->csdev.addr);
}
/****************************************************************************
@ -692,7 +675,6 @@ etm_register(FAR const struct coresight_desc_s *desc)
etmdev->cpu = desc->cpu;
etmdev->csdev.addr = desc->addr;
etm_init_arch_data(etmdev);
if (!etm_arch_supported(etmdev->arch))

View File

@ -157,24 +157,14 @@ static void stm_hw_disable(FAR struct coresight_stm_dev_s *stmdev)
}
coresight_lock(stmdev->csdev.addr);
coresight_disclaim_device(stmdev->csdev.addr);
}
/****************************************************************************
* Name: stm_hw_enable
****************************************************************************/
static int stm_hw_enable(FAR struct coresight_stm_dev_s *stmdev)
static void stm_hw_enable(FAR struct coresight_stm_dev_s *stmdev)
{
int ret;
ret = coresight_claim_device(stmdev->csdev.addr);
if (ret < 0)
{
cserr("stm %s claim failed\n", stmdev->csdev.name);
return ret;
}
coresight_unlock(stmdev->csdev.addr);
if (stmdev->stmheer != 0)
{
@ -196,7 +186,6 @@ static int stm_hw_enable(FAR struct coresight_stm_dev_s *stmdev)
stmdev->csdev.addr + STM_TCSR);
coresight_lock(stmdev->csdev.addr);
return ret;
}
/****************************************************************************
@ -208,11 +197,8 @@ static void stm_disable(FAR struct coresight_dev_s *csdev)
FAR struct coresight_stm_dev_s *stmdev =
(FAR struct coresight_stm_dev_s *)csdev;
if (--stmdev->refcnt == 0)
{
stm_hw_disable(stmdev);
csinfo("%s disabled\n", csdev->name);
}
stm_hw_disable(stmdev);
coresight_disclaim_device(stmdev->csdev.addr);
}
/****************************************************************************
@ -223,18 +209,15 @@ static int stm_enable(FAR struct coresight_dev_s *csdev)
{
FAR struct coresight_stm_dev_s *stmdev =
(FAR struct coresight_stm_dev_s *)csdev;
int ret = 0;
int ret;
if (stmdev->refcnt++ == 0)
ret = coresight_claim_device(stmdev->csdev.addr);
if (ret < 0)
{
ret = stm_hw_enable(stmdev);
if (ret < 0)
{
stmdev->refcnt--;
cserr("%s enabled failed\n", csdev->name);
}
return ret;
}
stm_hw_enable(stmdev);
return ret;
}

View File

@ -277,25 +277,19 @@ static int tmc_etf_sink_enable(FAR struct coresight_dev_s *csdev)
{
FAR struct coresight_tmc_dev_s *tmcdev =
(FAR struct coresight_tmc_dev_s *)csdev;
int ret = 0;
int ret;
if (tmcdev->refcnt++ == 0)
ret = coresight_claim_device(tmcdev->csdev.addr);
if (ret < 0)
{
ret = coresight_claim_device(tmcdev->csdev.addr);
if (ret < 0)
{
tmcdev->refcnt--;
cserr("%s claimed failed\n", csdev->name);
return ret;
}
cserr("%s claimed failed\n", csdev->name);
return ret;
}
ret = tmc_etf_sink_hw_enable(tmcdev);
if (ret < 0)
{
tmcdev->refcnt--;
coresight_disclaim_device(tmcdev->csdev.addr);
cserr("%s enable failed\n", csdev->name);
}
ret = tmc_etf_sink_hw_enable(tmcdev);
if (ret < 0)
{
coresight_disclaim_device(tmcdev->csdev.addr);
}
return ret;
@ -310,12 +304,8 @@ static void tmc_etf_sink_disable(FAR struct coresight_dev_s *csdev)
FAR struct coresight_tmc_dev_s *tmcdev =
(FAR struct coresight_tmc_dev_s *)csdev;
if (--tmcdev->refcnt == 0)
{
tmc_etf_hw_disable(tmcdev);
coresight_disclaim_device(tmcdev->csdev.addr);
csinfo("%s disabled\n", csdev->name);
}
tmc_etf_hw_disable(tmcdev);
coresight_disclaim_device(tmcdev->csdev.addr);
}
/****************************************************************************
@ -327,25 +317,19 @@ static int tmc_etf_link_enable(FAR struct coresight_dev_s *csdev,
{
FAR struct coresight_tmc_dev_s *tmcdev =
(FAR struct coresight_tmc_dev_s *)csdev;
int ret = 0;
int ret;
if (tmcdev->refcnt++ == 0)
ret = coresight_claim_device(tmcdev->csdev.addr);
if (ret < 0)
{
ret = coresight_claim_device(tmcdev->csdev.addr);
if (ret < 0)
{
tmcdev->refcnt--;
cserr("%s claimed failed\n", csdev->name);
return ret;
}
cserr("%s claimed failed\n", csdev->name);
return ret;
}
ret = tmc_etf_link_hw_enable(tmcdev);
if (ret < 0)
{
tmcdev->refcnt--;
coresight_disclaim_device(tmcdev->csdev.addr);
cserr("%s enable failed\n", csdev->name);
}
ret = tmc_etf_link_hw_enable(tmcdev);
if (ret < 0)
{
coresight_disclaim_device(tmcdev->csdev.addr);
}
return ret;
@ -361,12 +345,8 @@ static void tmc_etf_link_disable(FAR struct coresight_dev_s *csdev,
FAR struct coresight_tmc_dev_s *tmcdev =
(FAR struct coresight_tmc_dev_s *)csdev;
if (--tmcdev->refcnt == 0)
{
tmc_etf_hw_disable(tmcdev);
coresight_disclaim_device(tmcdev->csdev.addr);
csinfo("%s disabled\n", csdev->name);
}
tmc_etf_hw_disable(tmcdev);
coresight_disclaim_device(tmcdev->csdev.addr);
}
/****************************************************************************
@ -402,7 +382,7 @@ static int tmc_etf_open(FAR struct file *filep)
irqstate_t flags;
flags = enter_critical_section();
if (tmcdev->refcnt > 0)
if (tmcdev->csdev.refcnt > 0)
{
tmc_etf_hw_disable_and_read(tmcdev);
tmc_etf_sink_hw_enable(tmcdev);

View File

@ -270,25 +270,19 @@ static int tmc_etr_enable(FAR struct coresight_dev_s *csdev)
{
FAR struct coresight_tmc_dev_s *tmcdev =
(FAR struct coresight_tmc_dev_s *)csdev;
int ret = 0;
int ret;
if (tmcdev->refcnt++ == 0)
ret = coresight_claim_device(tmcdev->csdev.addr);
if (ret < 0)
{
ret = coresight_claim_device(tmcdev->csdev.addr);
if (ret < 0)
{
tmcdev->refcnt--;
cserr("%s claimed failed\n", csdev->name);
return ret;
}
cserr("%s claimed failed\n", csdev->name);
return ret;
}
ret = tmc_etr_hw_enable(tmcdev);
if (ret < 0)
{
tmcdev->refcnt--;
coresight_disclaim_device(tmcdev->csdev.addr);
cserr("%s enabled failed\n", csdev->name);
}
ret = tmc_etr_hw_enable(tmcdev);
if (ret < 0)
{
coresight_disclaim_device(tmcdev->csdev.addr);
}
return ret;
@ -303,12 +297,8 @@ static void tmc_etr_disable(FAR struct coresight_dev_s *csdev)
FAR struct coresight_tmc_dev_s *tmcdev =
(FAR struct coresight_tmc_dev_s *)csdev;
if (--tmcdev->refcnt == 0)
{
tmc_etr_hw_disable(tmcdev);
coresight_disclaim_device(tmcdev->csdev.addr);
csinfo("%s disabled\n", csdev->name);
}
tmc_etr_hw_disable(tmcdev);
coresight_disclaim_device(tmcdev->csdev.addr);
}
/****************************************************************************
@ -340,7 +330,7 @@ static int tmc_etr_open(FAR struct file *filep)
irqstate_t flags;
flags = enter_critical_section();
if (tmcdev->refcnt > 0)
if (tmcdev->csdev.refcnt > 0)
{
tmc_etr_hw_disable_and_read(tmcdev);
}
@ -387,7 +377,7 @@ static int tmc_etr_close(FAR struct file *filep)
irqstate_t flags;
flags = enter_critical_section();
if (tmcdev->refcnt > 0)
if (tmcdev->csdev.refcnt > 0)
{
if (tmc_etr_hw_enable(tmcdev) < 0)
{

View File

@ -92,15 +92,6 @@ static const struct coresight_ops_s g_tpiu_ops =
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: tpiu_hw_enable
****************************************************************************/
static int tpiu_hw_enable(FAR struct coresight_tpiu_dev_s *tpiudev)
{
return coresight_claim_device(tpiudev->csdev.addr);
}
/****************************************************************************
* Name: tpiu_hw_disable
****************************************************************************/
@ -128,7 +119,6 @@ static void tpiu_hw_disable(FAR struct coresight_tpiu_dev_s *tpiudev)
}
coresight_lock(tpiudev->csdev.addr);
coresight_disclaim_device(tpiudev->csdev.addr);
}
/****************************************************************************
@ -137,21 +127,7 @@ static void tpiu_hw_disable(FAR struct coresight_tpiu_dev_s *tpiudev)
static int tpiu_enable(FAR struct coresight_dev_s *csdev)
{
FAR struct coresight_tpiu_dev_s *tpiudev =
(FAR struct coresight_tpiu_dev_s *)csdev;
int ret = 0;
if (tpiudev->refcnt++ == 0)
{
ret = tpiu_hw_enable(tpiudev);
if (ret < 0)
{
tpiudev->refcnt--;
cserr("tpiu %s enabled failed\n", csdev->name);
}
}
return ret;
return coresight_claim_device(csdev->addr);
}
/****************************************************************************
@ -163,11 +139,8 @@ static void tpiu_disable(FAR struct coresight_dev_s *csdev)
FAR struct coresight_tpiu_dev_s *tpiudev =
(FAR struct coresight_tpiu_dev_s *)csdev;
if (--tpiudev->refcnt == 0)
{
tpiu_hw_disable(tpiudev);
csinfo("tpiu %s disabled\n", csdev->name);
}
tpiu_hw_disable(tpiudev);
coresight_disclaim_device(tpiudev->csdev.addr);
}
/****************************************************************************

View File

@ -26,7 +26,9 @@
****************************************************************************/
#include <stdint.h>
#include <nuttx/clk/clk.h>
#include <nuttx/list.h>
#include <nuttx/power/pm.h>
/****************************************************************************
* Pre-processor Definitions
@ -121,6 +123,9 @@ struct coresight_portdesc_s
struct coresight_desc_s
{
FAR const char *name;
#ifdef CONFIG_CLK
FAR const char *clkname;
#endif
uintptr_t addr;
enum coresight_dev_type_e type;
union coresight_dev_subtype_u subtype;
@ -168,6 +173,16 @@ struct coresight_connect_s
struct coresight_dev_s
{
FAR const char *name;
#ifdef CONFIG_CLK
FAR struct clk_s *clk;
#endif
#ifdef CONFIG_PM
struct pm_callback_s pmcb;
#endif
/* Coresight device's enable count. */
uint8_t refcnt;
/* Memory-mapped base address of current coresight device. */

View File

@ -39,7 +39,6 @@ struct coresight_etb_dev_s
uint32_t buffer_depth; /* ETB buffer depth. */
FAR uint32_t *bufptr; /* Buffer that ETB content sends to. */
mutex_t lock; /* Mutex for driver's open/close. */
uint8_t refcnt; /* ETB coresight device's enable count. */
uint8_t opencnt; /* ETB device's open count. */
};

View File

@ -75,7 +75,6 @@ struct coresight_etm_dev_s
{
struct coresight_dev_s csdev;
struct etm_config_s cfg;
uint8_t refcnt;
int cpu; /* The cpu this component is affined to */
int port_size; /* Out port size */
int traceid; /* Trace id */

View File

@ -63,7 +63,6 @@ enum stp_packet_flags_e
struct coresight_stm_dev_s
{
struct coresight_dev_s csdev;
uint8_t refcnt;
int traceid; /* Trace id. */
/* Used in STM device: start address of extend stimulus port, this memory

View File

@ -68,7 +68,6 @@ struct coresight_tmc_dev_s
uint32_t caps; /* Capalilities current etr device has. */
enum tmc_etr_mode_e mode; /* ETR buffer mode. */
uint32_t offset; /* Data offset in ETR buffer. */
uint8_t refcnt; /* TMC coresight device's enable count */
uint8_t opencnt; /* TMC device's open count. */
};

View File

@ -34,7 +34,6 @@
struct coresight_tpiu_dev_s
{
struct coresight_dev_s csdev;
uint8_t refcnt;
};
/****************************************************************************