You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
404 lines
12 KiB
404 lines
12 KiB
/* Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License version 2 and
|
|
* only version 2 as published by the Free Software Foundation.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
*/
|
|
|
|
#ifndef _SDE_RSC_H_
|
|
#define _SDE_RSC_H_
|
|
|
|
#include <linux/kernel.h>
|
|
|
|
/* primary display rsc index */
|
|
#define SDE_RSC_INDEX 0
|
|
|
|
#define MAX_RSC_CLIENT_NAME_LEN 128
|
|
|
|
/* DRM Object IDs are numbered excluding 0, use 0 to indicate invalid CRTC */
|
|
#define SDE_RSC_INVALID_CRTC_ID 0
|
|
|
|
/**
|
|
* event will be triggered before sde core power collapse,
|
|
* mdss gdsc is still on
|
|
*/
|
|
#define SDE_RSC_EVENT_PRE_CORE_PC 0x1
|
|
/**
|
|
* event will be triggered after sde core collapse complete,
|
|
* mdss gdsc is off now
|
|
*/
|
|
#define SDE_RSC_EVENT_POST_CORE_PC 0x2
|
|
/**
|
|
* event will be triggered before restoring the sde core from power collapse,
|
|
* mdss gdsc is still off
|
|
*/
|
|
#define SDE_RSC_EVENT_PRE_CORE_RESTORE 0x4
|
|
/**
|
|
* event will be triggered after restoring the sde core from power collapse,
|
|
* mdss gdsc is on now
|
|
*/
|
|
#define SDE_RSC_EVENT_POST_CORE_RESTORE 0x8
|
|
/**
|
|
* event attached with solver state enabled
|
|
* all clients in clk_state or cmd_state
|
|
*/
|
|
#define SDE_RSC_EVENT_SOLVER_ENABLED 0x10
|
|
/**
|
|
* event attached with solver state disabled
|
|
* one of the client requested for vid state
|
|
*/
|
|
#define SDE_RSC_EVENT_SOLVER_DISABLED 0x20
|
|
|
|
#define SDE_RSC_REV_1 0x1
|
|
#define SDE_RSC_REV_2 0x2
|
|
#define SDE_RSC_REV_3 0x3
|
|
|
|
/**
|
|
* sde_rsc_client_type: sde rsc client type information
|
|
* SDE_RSC_PRIMARY_DISP_CLIENT: A primary display client which can request
|
|
* vid or cmd state switch.
|
|
* SDE_RSC_EXTERNAL_DISPLAY_CLIENT:An external display client which can
|
|
* request only clk state switch.
|
|
* SDE_RSC_CLK_CLIENT: A clk client request for only rsc clocks
|
|
* enabled and mode_2 exit state.
|
|
*/
|
|
enum sde_rsc_client_type {
|
|
SDE_RSC_PRIMARY_DISP_CLIENT,
|
|
SDE_RSC_EXTERNAL_DISP_CLIENT,
|
|
SDE_RSC_CLK_CLIENT,
|
|
SDE_RSC_INVALID_CLIENT,
|
|
};
|
|
|
|
/**
|
|
* sde_rsc_state: sde rsc state information
|
|
* SDE_RSC_IDLE_STATE: A client requests for idle state when there is no
|
|
* pixel or cmd transfer expected. An idle vote from
|
|
* all clients lead to power collapse state.
|
|
* SDE_RSC_CLK_STATE: A client requests for clk state when it wants to
|
|
* only avoid mode-2 entry/exit. For ex: V4L2 driver,
|
|
* sde power handle, etc.
|
|
* SDE_RSC_CMD_STATE: A client requests for cmd state when it wants to
|
|
* enable the solver mode.
|
|
* SDE_RSC_VID_STATE: A client requests for vid state it wants to avoid
|
|
* solver enable because client is fetching data from
|
|
* continuously.
|
|
*/
|
|
enum sde_rsc_state {
|
|
SDE_RSC_IDLE_STATE,
|
|
SDE_RSC_CLK_STATE,
|
|
SDE_RSC_CMD_STATE,
|
|
SDE_RSC_VID_STATE,
|
|
};
|
|
|
|
/**
|
|
* struct sde_rsc_client: stores the rsc client for sde driver
|
|
* @name: name of the client
|
|
* @current_state: current client state
|
|
* @crtc_id: crtc_id associated with this rsc client.
|
|
* @rsc_index: rsc index of a client - only index "0" valid.
|
|
* @id: Index of client. It will be assigned during client_create call
|
|
* @client_type: check sde_rsc_client_type information
|
|
* @list: list to attach client master list
|
|
*/
|
|
struct sde_rsc_client {
|
|
char name[MAX_RSC_CLIENT_NAME_LEN];
|
|
short current_state;
|
|
int crtc_id;
|
|
u32 rsc_index;
|
|
u32 id;
|
|
enum sde_rsc_client_type client_type;
|
|
struct list_head list;
|
|
};
|
|
|
|
/**
|
|
* struct sde_rsc_event: local event registration entry structure
|
|
* @cb_func: Pointer to desired callback function
|
|
* @usr: User pointer to pass to callback on event trigger
|
|
* @rsc_index: rsc index of a client - only index "0" valid.
|
|
* @event_type: refer comments in event_register
|
|
* @list: list to attach event master list
|
|
*/
|
|
struct sde_rsc_event {
|
|
void (*cb_func)(uint32_t event_type, void *usr);
|
|
void *usr;
|
|
u32 rsc_index;
|
|
uint32_t event_type;
|
|
struct list_head list;
|
|
};
|
|
|
|
/**
|
|
* struct sde_rsc_cmd_config: provides panel configuration to rsc
|
|
* when client is command mode. It is not required to set it during
|
|
* video mode.
|
|
*
|
|
* @fps: panel te interval
|
|
* @vtotal: current vertical total (height + vbp + vfp)
|
|
* @jitter_numer: panel jitter numerator value. This config causes rsc/solver
|
|
* early before te. Default is 0.8% jitter.
|
|
* @jitter_denom: panel jitter denominator.
|
|
* @prefill_lines: max prefill lines based on panel
|
|
*/
|
|
struct sde_rsc_cmd_config {
|
|
u32 fps;
|
|
u32 vtotal;
|
|
u32 jitter_numer;
|
|
u32 jitter_denom;
|
|
u32 prefill_lines;
|
|
};
|
|
|
|
#ifdef CONFIG_DRM_SDE_RSC
|
|
/**
|
|
* sde_rsc_client_create() - create the client for sde rsc.
|
|
* Different displays like DSI, HDMI, DP, WB, etc should call this
|
|
* api to register their vote for rpmh. They still need to vote for
|
|
* power handle to get the clocks.
|
|
|
|
* @rsc_index: A client will be created on this RSC. As of now only
|
|
* SDE_RSC_INDEX is valid rsc index.
|
|
* @name: Caller needs to provide some valid string to identify
|
|
* the client. "primary", "dp", "hdmi" are suggested name.
|
|
* @is_primary: Caller needs to provide information if client is primary
|
|
* or not. Primary client votes will be redirected to
|
|
* display rsc.
|
|
* @config: fps, vtotal, porches, etc configuration for command mode
|
|
* panel
|
|
* @client_type: check client_type enum for information
|
|
* @vsync_source: This parameter is only valid for primary display. It provides
|
|
* vsync source information
|
|
*
|
|
* Return: client node pointer.
|
|
*/
|
|
struct sde_rsc_client *sde_rsc_client_create(u32 rsc_index, char *name,
|
|
enum sde_rsc_client_type client_type, u32 vsync_source);
|
|
|
|
/**
|
|
* sde_rsc_client_destroy() - Destroy the sde rsc client.
|
|
*
|
|
* @client: Client pointer provided by sde_rsc_client_create().
|
|
*
|
|
* Return: none
|
|
*/
|
|
void sde_rsc_client_destroy(struct sde_rsc_client *client);
|
|
|
|
/**
|
|
* sde_rsc_client_state_update() - rsc client state update
|
|
* Video mode, cmd mode and clk state are supported as modes. A client need to
|
|
* set this property during panel time. A switching client can set the
|
|
* property to change the state
|
|
*
|
|
* @client: Client pointer provided by sde_rsc_client_create().
|
|
* @state: Client state - video/cmd
|
|
* @config: fps, vtotal, porches, etc configuration for command mode
|
|
* panel
|
|
* @crtc_id: current client's crtc id
|
|
* @wait_vblank_crtc_id: Output parameter. If set to non-zero, rsc hw
|
|
* state update requires a wait for one vblank on
|
|
* the primary crtc. In that case, this output
|
|
* param will be set to the crtc on which to wait.
|
|
* If SDE_RSC_INVALID_CRTC_ID, no wait necessary
|
|
*
|
|
* Return: error code.
|
|
*/
|
|
int sde_rsc_client_state_update(struct sde_rsc_client *client,
|
|
enum sde_rsc_state state,
|
|
struct sde_rsc_cmd_config *config, int crtc_id,
|
|
int *wait_vblank_crtc_id);
|
|
|
|
/**
|
|
* sde_rsc_client_get_vsync_refcount() - returns the status of the vsync
|
|
* refcount, to signal if the client needs to reset the refcounting logic
|
|
* @client: Client pointer provided by sde_rsc_client_create().
|
|
*
|
|
* Return: true if the state update has completed.
|
|
*/
|
|
int sde_rsc_client_get_vsync_refcount(
|
|
struct sde_rsc_client *caller_client);
|
|
|
|
/**
|
|
* sde_rsc_client_reset_vsync_refcount() - reduces the refcounting
|
|
* logic that waits for the vsync.
|
|
* @client: Client pointer provided by sde_rsc_client_create().
|
|
*
|
|
* Return: true if the state update has completed.
|
|
*/
|
|
int sde_rsc_client_reset_vsync_refcount(
|
|
struct sde_rsc_client *caller_client);
|
|
|
|
/**
|
|
* sde_rsc_client_is_state_update_complete() - check if state update is complete
|
|
* RSC state transition is not complete until HW receives VBLANK signal. This
|
|
* function checks RSC HW to determine whether that signal has been received.
|
|
* @client: Client pointer provided by sde_rsc_client_create().
|
|
*
|
|
* Return: true if the state update has completed.
|
|
*/
|
|
bool sde_rsc_client_is_state_update_complete(
|
|
struct sde_rsc_client *caller_client);
|
|
|
|
/**
|
|
* sde_rsc_client_vote() - stores ab/ib vote for rsc client
|
|
*
|
|
* @client: Client pointer provided by sde_rsc_client_create().
|
|
* @bus_id: data bus identifier
|
|
* @ab: aggregated bandwidth vote from client.
|
|
* @ib: instant bandwidth vote from client.
|
|
*
|
|
* Return: error code.
|
|
*/
|
|
int sde_rsc_client_vote(struct sde_rsc_client *caller_client,
|
|
u32 bus_id, u64 ab_vote, u64 ib_vote);
|
|
|
|
/**
|
|
* sde_rsc_register_event - register a callback function for an event
|
|
* @rsc_index: A client will be created on this RSC. As of now only
|
|
* SDE_RSC_INDEX is valid rsc index.
|
|
* @event_type: event type to register; client sets 0x3 if it wants
|
|
* to register for CORE_PC and CORE_RESTORE - both events.
|
|
* @cb_func: Pointer to desired callback function
|
|
* @usr: User pointer to pass to callback on event trigger
|
|
* Returns: sde_rsc_event pointer on success
|
|
*/
|
|
struct sde_rsc_event *sde_rsc_register_event(int rsc_index, uint32_t event_type,
|
|
void (*cb_func)(uint32_t event_type, void *usr), void *usr);
|
|
|
|
/**
|
|
* sde_rsc_unregister_event - unregister callback for an event
|
|
* @sde_rsc_event: event returned by sde_rsc_register_event
|
|
*/
|
|
void sde_rsc_unregister_event(struct sde_rsc_event *event);
|
|
|
|
/**
|
|
* is_sde_rsc_available - check if display rsc available.
|
|
* @rsc_index: A client will be created on this RSC. As of now only
|
|
* SDE_RSC_INDEX is valid rsc index.
|
|
* Returns: true if rsc is available; false in all other cases
|
|
*/
|
|
bool is_sde_rsc_available(int rsc_index);
|
|
|
|
/**
|
|
* get_sde_rsc_current_state - gets the current state of sde rsc.
|
|
* @rsc_index: A client will be created on this RSC. As of now only
|
|
* SDE_RSC_INDEX is valid rsc index.
|
|
* Returns: current state if rsc available; SDE_RSC_IDLE_STATE for
|
|
* all other cases
|
|
*/
|
|
enum sde_rsc_state get_sde_rsc_current_state(int rsc_index);
|
|
|
|
/**
|
|
* get_sde_rsc_primary_crtc - gets the primary crtc for the sde rsc.
|
|
* @rsc_index: A client will be created on this RSC. As of now only
|
|
* SDE_RSC_INDEX is valid rsc index.
|
|
* Returns: crtc id of primary crtc ; 0 for all other cases.
|
|
*/
|
|
int get_sde_rsc_primary_crtc(int rsc_index);
|
|
|
|
/**
|
|
* sde_rsc_client_trigger_vote() - triggers ab/ib vote for rsc client
|
|
*
|
|
* @client: Client pointer provided by sde_rsc_client_create().
|
|
* @delta_vote: if bw vote is increased or decreased
|
|
*
|
|
* Return: error code.
|
|
*/
|
|
int sde_rsc_client_trigger_vote(struct sde_rsc_client *caller_client,
|
|
bool delta_vote);
|
|
|
|
/**
|
|
* get_sde_rsc_version - get the supported rsc version
|
|
*
|
|
* @rsc_index: A client will be created on this RSC. As of now only
|
|
* SDE_RSC_INDEX is valid rsc index.
|
|
* Return the rsc version.
|
|
*/
|
|
u32 get_sde_rsc_version(int rsc_index);
|
|
|
|
#else
|
|
|
|
static inline struct sde_rsc_client *sde_rsc_client_create(u32 rsc_index,
|
|
char *name, enum sde_rsc_client_type client_type, u32 vsync_source)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
static inline void sde_rsc_client_destroy(struct sde_rsc_client *client)
|
|
{
|
|
}
|
|
|
|
static inline int sde_rsc_client_state_update(struct sde_rsc_client *client,
|
|
enum sde_rsc_state state,
|
|
struct sde_rsc_cmd_config *config, int crtc_id,
|
|
int *wait_vblank_crtc_id)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
static inline int sde_rsc_client_get_vsync_refcount(
|
|
struct sde_rsc_client *caller_client)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
static inline int sde_rsc_client_reset_vsync_refcount(
|
|
struct sde_rsc_client *caller_client)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
static inline bool sde_rsc_client_is_state_update_complete(
|
|
struct sde_rsc_client *caller_client)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
static inline int sde_rsc_client_vote(struct sde_rsc_client *caller_client,
|
|
u32 bus_id, u64 ab_vote, u64 ib_vote)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
static inline struct sde_rsc_event *sde_rsc_register_event(int rsc_index,
|
|
uint32_t event_type,
|
|
void (*cb_func)(uint32_t event_type, void *usr), void *usr)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
static inline void sde_rsc_unregister_event(struct sde_rsc_event *event)
|
|
{
|
|
}
|
|
|
|
static inline bool is_sde_rsc_available(int rsc_index)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
static inline enum sde_rsc_state get_sde_rsc_current_state(int rsc_index)
|
|
{
|
|
return SDE_RSC_IDLE_STATE;
|
|
}
|
|
|
|
static inline int get_sde_rsc_primary_crtc(int rsc_index)
|
|
{
|
|
return 0;
|
|
}
|
|
static inline int sde_rsc_client_trigger_vote(
|
|
struct sde_rsc_client *caller_client, bool delta_vote)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
|
|
static inline u32 get_sde_rsc_version(int rsc_index)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
#endif /* CONFIG_DRM_SDE_RSC */
|
|
|
|
#endif /* _SDE_RSC_H_ */
|
|
|