Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

nrfs: add GDFS service #263

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions nrfs/include/internal/nrfs_callbacks.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,16 @@ void nrfs_clock_service_notify(void *p_notification, size_t size);
*/
void nrfs_gdpwr_service_notify(void *p_notification, size_t size);

/**
* @brief Function for notifying the GDFS service about incoming message.
*
* This function is called internally by the dispatcher when the corresponding message arrives.
*
* @param[in] p_notification Pointer to the notification payload.
* @param[in] size Notification payload size.
*/
void nrfs_gdfs_service_notify(void *p_notification, size_t size);

#ifdef __cplusplus
}
#endif
Expand Down
2 changes: 1 addition & 1 deletion nrfs/include/internal/nrfs_hdr.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@
#include <internal/requests/nrfs_clock_reqs.h>
#include <internal/requests/nrfs_diag_reqs.h>
#include <internal/requests/nrfs_dvfs_reqs.h>
#include <internal/requests/nrfs_gdfs_reqs.h>
#include <internal/requests/nrfs_gdpwr_reqs.h>
#include <internal/requests/nrfs_mram_reqs.h>
#include <internal/requests/nrfs_pmic_reqs.h>
#include <internal/requests/nrfs_reset_reqs.h>
#include <internal/requests/nrfs_temp_reqs.h>
#include <internal/requests/nrfs_usb_reqs.h>


#ifdef __cplusplus
extern "C" {
#endif
Expand Down
24 changes: 24 additions & 0 deletions nrfs/include/internal/requests/nrfs_gdfs_reqs.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
* Copyright (c) 2024 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/

#ifndef NRFS_GDFS_REQS_H
#define NRFS_GDFS_REQS_H

#include "nrfs_reqs_common.h"

#ifdef __cplusplus
extern "C" {
#endif

enum {
NRFS_GDFS_REQ_FREQ = NRFS_REQUEST_ID_DEF(NRFS_SERVICE_ID_GDFS, 0x01),
};

#ifdef __cplusplus
}
#endif

#endif /* NRFS_GDFS_REQS_H */
3 changes: 2 additions & 1 deletion nrfs/include/internal/requests/nrfs_reqs_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,8 @@ enum {
NRFS_SERVICE_ID_PMIC,
NRFS_SERVICE_ID_RESET,
NRFS_SERVICE_ID_TEMP,
NRFS_SERVICE_ID_USB
NRFS_SERVICE_ID_USB,
NRFS_SERVICE_ID_GDFS
};

#ifdef __cplusplus
Expand Down
46 changes: 46 additions & 0 deletions nrfs/include/internal/services/nrfs_gdfs.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* Copyright (c) 2024 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/

#ifndef NRFS_INTERNAL_GDFS_H
#define NRFS_INTERNAL_GDFS_H

#include <internal/services/nrfs_generic.h>

#ifdef __cplusplus
extern "C" {
#endif

enum __NRFS_PACKED gdfs_frequency_setting {
GDFS_FREQ_HIGH = 0,
GDFS_FREQ_MEDHIGH = 1,
GDFS_FREQ_MEDLOW = 2,
GDFS_FREQ_LOW = 3,
GDFS_FREQ_COUNT
};

/** @brief Global Domain Frequency Scaling service request data structure. */
typedef struct __NRFS_PACKED {
enum gdfs_frequency_setting target_freq; /** Requested frequency oppoint. */
} nrfs_gdfs_req_data_t;

/** @brief Global Domain Frequency Scaling frequency change request structure. */
typedef struct __NRFS_PACKED {
nrfs_hdr_t hdr; /**< Header of the message. */
nrfs_ctx_t ctx; /**< Context of the message. */
nrfs_gdfs_req_data_t data; /**< Data of the request. */
} nrfs_gdfs_req_t;

/** @brief Global Domain Frequency Scaling service notification structure. */
typedef struct __NRFS_PACKED {
nrfs_hdr_t hdr; /**< Header of the message. */
nrfs_ctx_t ctx; /**< Context of the message. */
} nrfs_gdfs_rsp_t;

#ifdef __cplusplus
}
#endif

#endif /* NRFS_INTERNAL_GDFS_H */
78 changes: 78 additions & 0 deletions nrfs/include/services/nrfs_gdfs.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/*
* Copyright (c) 2024 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/

#ifndef NRFS_GDFS_H
#define NRFS_GDFS_H

#include <internal/services/nrfs_gdfs.h>

#ifdef __cplusplus
extern "C" {
#endif

/** @brief Global Domain Frequency Scaling service event types. */
typedef enum __NRFS_PACKED {
NRFS_GDFS_EVT_REJECT, /** General purpose event for rejected requests. */
NRFS_GDFS_EVT_FREQ_CONFIRMED, /** Frequency has been acheived. */
} nrfs_gdfs_evt_type_t;

/** @brief Global Domain Frequency Scaling service event. */
typedef struct {
nrfs_gdfs_evt_type_t type; /** Event type. */
} nrfs_gdfs_evt_t;

/** @brief Global Domain Frequency Scaling service event handler type. */
typedef void (*nrfs_gdfs_evt_handler_t)(nrfs_gdfs_evt_t const * p_evt, void * context);

/**
* @brief Function for initializing the Global Domain Frequency Scaling service.
*
* @param[in] handler Function called as a response to the request.
*
* @retval NRFS_SUCCESS Service initialized successfully.
* @retval NRFS_ERR_INVALID_STATE Service was already initialized.
*/
nrfs_err_t nrfs_gdfs_init(nrfs_gdfs_evt_handler_t handler);

/**
* @brief Function for uninitializing the Global Domain Frequency Scaling service.
*
* @warning Notifications from previous requests are dropped after service uninitialization.
*/
void nrfs_gdfs_uninit(void);

/**
* @brief Function for requesting a frequency change.
* @note The @p target_freq requirement might not be met by the system
* until the NRFS_GDFS_EVT_FREQ_CONFIRMED response is triggered.
*
* @param[in] target_freq Minimal required frequency
* @param[in] p_context Opaque user data that will be passed to registered callback.
*
* @retval NRFS_SUCCESS Request sent successfully.
* @retval NRFS_ERR_INVALID_STATE Service is uninitialized.
* @retval NRFS_ERR_IPC Backend returned error during request sending.
*/
nrfs_err_t nrfs_gdfs_request_freq(enum gdfs_frequency_setting target_freq, void * p_context);

/**
* @brief Function for requesting a frequency change.
* @note The response @p NRFS_GDFS_EVT_FREQ_CONFIRMED will not be triggered.
*
* @param[in] target_freq Minimal required frequency
* @param[in] p_context Opaque user data that will be passed to registered callback.
*
* @retval NRFS_SUCCESS Request sent successfully.
* @retval NRFS_ERR_INVALID_STATE Service is uninitialized.
* @retval NRFS_ERR_IPC Backend returned error during request sending.
*/
nrfs_err_t nrfs_gdfs_request_freq_no_rsp(enum gdfs_frequency_setting target_freq, void * p_context);

#ifdef __cplusplus
}
#endif

#endif /* NRFS_GDFS_H */
5 changes: 5 additions & 0 deletions nrfs/src/internal/nrfs_dispatcher.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,11 @@ static const nrfs_service_cb_t services_callbacks[] = {
#else
[NRFS_SERVICE_ID_GDPWR] = NULL,
#endif
#ifdef NRFS_GDFS_SERVICE_ENABLED
[NRFS_SERVICE_ID_GDFS] = nrfs_gdfs_service_notify,
#else
[NRFS_SERVICE_ID_GDFS] = NULL,
#endif
};

/* Warning! All "UNSOLICITED" features are not supported. This is intended for possible future use. */
Expand Down
89 changes: 89 additions & 0 deletions nrfs/src/services/nrfs_gdfs.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
/*
* Copyright (c) 2024 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/

#include <internal/nrfs_backend.h>
#include <internal/nrfs_callbacks.h>
#include <nrfs_gdfs.h>

typedef struct {
nrfs_gdfs_evt_handler_t handler;
bool is_initialized;
} nrfs_gdfs_cb_t;
static nrfs_gdfs_cb_t m_cb;

void nrfs_gdfs_service_notify(void *p_notification, size_t size)
{
if (!m_cb.handler || !m_cb.is_initialized) {
return;
}

nrfs_gdfs_evt_t evt;
nrfs_generic_t *p_data = (nrfs_generic_t *)p_notification;
if (NRFS_HDR_FILTER_ERR_GET(&p_data->hdr)) {
evt.type = NRFS_GDFS_EVT_REJECT;
m_cb.handler(&evt, (void *)p_data->ctx.ctx);
return;
}

nrfs_gdfs_rsp_t *p_rsp = (nrfs_gdfs_rsp_t *)p_notification;
switch (p_data->hdr.req) {
case NRFS_GDFS_REQ_FREQ:
evt.type = NRFS_GDFS_EVT_FREQ_CONFIRMED;
m_cb.handler(&evt, (void *)p_rsp->ctx.ctx);
break;

default:
break;
}
}

nrfs_err_t nrfs_gdfs_init(nrfs_gdfs_evt_handler_t handler)
{
if (m_cb.is_initialized) {
return NRFS_ERR_INVALID_STATE;
}

m_cb.handler = handler;
m_cb.is_initialized = true;
return NRFS_SUCCESS;
}

void nrfs_gdfs_uninit(void)
{
m_cb.is_initialized = false;
}

nrfs_err_t nrfs_gdfs_request_freq(enum gdfs_frequency_setting target_freq, void *p_context)
{
if (!m_cb.is_initialized) {
return NRFS_ERR_INVALID_STATE;
}

nrfs_gdfs_req_t req;

NRFS_SERVICE_HDR_FILL(&req, NRFS_GDFS_REQ_FREQ);
req.ctx.ctx = (uint32_t)p_context;
req.data.target_freq = target_freq;

return nrfs_backend_send(&req, sizeof(req));
}

nrfs_err_t nrfs_gdfs_request_freq_no_rsp(enum gdfs_frequency_setting target_freq,
void *p_context)
{
if (!m_cb.is_initialized) {
return NRFS_ERR_INVALID_STATE;
}

nrfs_gdfs_req_t req;

NRFS_SERVICE_HDR_FILL(&req, NRFS_GDFS_REQ_FREQ);
NRFS_HDR_NO_RSP_SET(&req.hdr);
req.ctx.ctx = (uint32_t)p_context;
req.data.target_freq = target_freq;

return nrfs_backend_send(&req, sizeof(req));
}