linux/drivers/gpu/drm/msm/disp/dpu1/dpu_power_handle.c

241 lines
6.4 KiB
C
Raw Normal View History

drm/msm: Add SDM845 DPU support SDM845 SoC includes the Mobile Display Sub System (MDSS) which is a top level wrapper consisting of Display Processing Unit (DPU) and display peripheral modules such as Display Serial Interface (DSI) and DisplayPort (DP). MDSS functions essentially as a back-end composition engine. It blends video and graphic images stored in the frame buffers and scans out the composed image to a display sink (over DSI/DP). The following diagram represents hardware blocks for a simple pipeline (two planes are present on a given crtc which is connected to a DSI connector): MDSS +---------------------------------+ | +-----------------------------+ | | | DPU | | | | +--------+ +--------+ | | | | | SSPP | | SSPP | | | | | +----+---+ +----+---+ | | | | | | | | | | +----v-----------v---+ | | | | | Layer Mixer (LM) | | | | | +--------------------+ | | | | +--------------------+ | | | | | PingPong (PP) | | | | | +--------------------+ | | | | +--------------------+ | | | | | INTERFACE (VIDEO) | | | | | +---+----------------+ | | | +------|----------------------+ | | | | | +------|---------------------+ | | | | DISPLAY PERIPHERALS | | | | +---v-+ +-----+ | | | | | DSI | | DP | | | | | +-----+ +-----+ | | | +----------------------------+ | +---------------------------------+ The number of DPU sub-blocks (i.e. SSPPs, LMs, PP blocks and INTFs) depends on SoC capabilities. Overview of DPU sub-blocks: --------------------------- * Source Surface Processor (SSPP): Refers to any of hardware pipes like ViG, DMA etc. Only ViG pipes are capable of performing format conversion, scaling and quality improvement for source surfaces. * Layer Mixer (LM): Blend source surfaces together (in requested zorder) * PingPong (PP): This block controls frame done interrupt output, EOL and EOF generation, overflow/underflow control. * Display interface (INTF): Timing generator and interface connecting the display peripherals. DRM components mapping to DPU architecture: ------------------------------------------ PLANEs maps to SSPPs CRTC maps to LMs Encoder maps to PPs, INTFs Data flow setup: --------------- MDSS hardware can support various data flows (e.g.): - Dual pipe: Output from two LMs combined to single display. - Split display: Output from two LMs connected to two separate interfaces. The hardware capabilities determine the number of concurrent data paths possible. Any control path (i.e. pipeline w/i DPU) can be routed to any of the hardware data paths. A given control path can be triggered, flushed and controlled independently. Changes in v3: - Move msm_media_info.h from uapi to dpu/ subdir - Remove preclose callback dpu (it's handled in core) - Fix kbuild warnings with parent_ops - Remove unused functions from dpu_core_irq - Rename mdss_phys to mdss - Rename mdp_phys address space to mdp - Drop _phys from vbif and regdma binding names Signed-off-by: Abhinav Kumar <abhinavk@codeaurora.org> Signed-off-by: Archit Taneja <architt@codeaurora.org> Signed-off-by: Chandan Uddaraju <chandanu@codeaurora.org> Signed-off-by: Jeykumar Sankaran <jsanka@codeaurora.org> Signed-off-by: Jordan Crouse <jcrouse@codeaurora.org> Signed-off-by: Rajesh Yadav <ryadav@codeaurora.org> Signed-off-by: Sravanthi Kollukuduru <skolluku@codeaurora.org> Signed-off-by: Sean Paul <seanpaul@chromium.org> [robclark minor rebase] Signed-off-by: Rob Clark <robdclark@gmail.com>
2018-06-27 19:26:09 +00:00
/* Copyright (c) 2014-2018, 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.
*
*/
#define pr_fmt(fmt) "[drm:%s:%d]: " fmt, __func__, __LINE__
#include <linux/kernel.h>
#include <linux/of.h>
#include <linux/string.h>
#include <linux/of_address.h>
#include <linux/slab.h>
#include <linux/mutex.h>
#include <linux/of_platform.h>
#include "dpu_power_handle.h"
#include "dpu_trace.h"
static const char *data_bus_name[DPU_POWER_HANDLE_DBUS_ID_MAX] = {
[DPU_POWER_HANDLE_DBUS_ID_MNOC] = "qcom,dpu-data-bus",
[DPU_POWER_HANDLE_DBUS_ID_LLCC] = "qcom,dpu-llcc-bus",
[DPU_POWER_HANDLE_DBUS_ID_EBI] = "qcom,dpu-ebi-bus",
};
const char *dpu_power_handle_get_dbus_name(u32 bus_id)
{
if (bus_id < DPU_POWER_HANDLE_DBUS_ID_MAX)
return data_bus_name[bus_id];
return NULL;
}
static void dpu_power_event_trigger_locked(struct dpu_power_handle *phandle,
u32 event_type)
{
struct dpu_power_event *event;
list_for_each_entry(event, &phandle->event_list, list) {
if (event->event_type & event_type)
event->cb_fnc(event_type, event->usr);
}
}
struct dpu_power_client *dpu_power_client_create(
struct dpu_power_handle *phandle, char *client_name)
{
struct dpu_power_client *client;
static u32 id;
if (!client_name || !phandle) {
pr_err("client name is null or invalid power data\n");
return ERR_PTR(-EINVAL);
}
client = kzalloc(sizeof(struct dpu_power_client), GFP_KERNEL);
if (!client)
return ERR_PTR(-ENOMEM);
mutex_lock(&phandle->phandle_lock);
strlcpy(client->name, client_name, MAX_CLIENT_NAME_LEN);
client->usecase_ndx = VOTE_INDEX_DISABLE;
client->id = id;
client->active = true;
pr_debug("client %s created:%pK id :%d\n", client_name,
client, id);
id++;
list_add(&client->list, &phandle->power_client_clist);
mutex_unlock(&phandle->phandle_lock);
return client;
}
void dpu_power_client_destroy(struct dpu_power_handle *phandle,
struct dpu_power_client *client)
{
if (!client || !phandle) {
pr_err("reg bus vote: invalid client handle\n");
} else if (!client->active) {
pr_err("dpu power deinit already done\n");
kfree(client);
} else {
pr_debug("bus vote client %s destroyed:%pK id:%u\n",
client->name, client, client->id);
mutex_lock(&phandle->phandle_lock);
list_del_init(&client->list);
mutex_unlock(&phandle->phandle_lock);
kfree(client);
}
}
void dpu_power_resource_init(struct platform_device *pdev,
struct dpu_power_handle *phandle)
{
phandle->dev = &pdev->dev;
INIT_LIST_HEAD(&phandle->power_client_clist);
INIT_LIST_HEAD(&phandle->event_list);
mutex_init(&phandle->phandle_lock);
}
void dpu_power_resource_deinit(struct platform_device *pdev,
struct dpu_power_handle *phandle)
{
struct dpu_power_client *curr_client, *next_client;
struct dpu_power_event *curr_event, *next_event;
if (!phandle || !pdev) {
pr_err("invalid input param\n");
return;
}
mutex_lock(&phandle->phandle_lock);
list_for_each_entry_safe(curr_client, next_client,
&phandle->power_client_clist, list) {
pr_err("client:%s-%d still registered with refcount:%d\n",
drm/msm: Add SDM845 DPU support SDM845 SoC includes the Mobile Display Sub System (MDSS) which is a top level wrapper consisting of Display Processing Unit (DPU) and display peripheral modules such as Display Serial Interface (DSI) and DisplayPort (DP). MDSS functions essentially as a back-end composition engine. It blends video and graphic images stored in the frame buffers and scans out the composed image to a display sink (over DSI/DP). The following diagram represents hardware blocks for a simple pipeline (two planes are present on a given crtc which is connected to a DSI connector): MDSS +---------------------------------+ | +-----------------------------+ | | | DPU | | | | +--------+ +--------+ | | | | | SSPP | | SSPP | | | | | +----+---+ +----+---+ | | | | | | | | | | +----v-----------v---+ | | | | | Layer Mixer (LM) | | | | | +--------------------+ | | | | +--------------------+ | | | | | PingPong (PP) | | | | | +--------------------+ | | | | +--------------------+ | | | | | INTERFACE (VIDEO) | | | | | +---+----------------+ | | | +------|----------------------+ | | | | | +------|---------------------+ | | | | DISPLAY PERIPHERALS | | | | +---v-+ +-----+ | | | | | DSI | | DP | | | | | +-----+ +-----+ | | | +----------------------------+ | +---------------------------------+ The number of DPU sub-blocks (i.e. SSPPs, LMs, PP blocks and INTFs) depends on SoC capabilities. Overview of DPU sub-blocks: --------------------------- * Source Surface Processor (SSPP): Refers to any of hardware pipes like ViG, DMA etc. Only ViG pipes are capable of performing format conversion, scaling and quality improvement for source surfaces. * Layer Mixer (LM): Blend source surfaces together (in requested zorder) * PingPong (PP): This block controls frame done interrupt output, EOL and EOF generation, overflow/underflow control. * Display interface (INTF): Timing generator and interface connecting the display peripherals. DRM components mapping to DPU architecture: ------------------------------------------ PLANEs maps to SSPPs CRTC maps to LMs Encoder maps to PPs, INTFs Data flow setup: --------------- MDSS hardware can support various data flows (e.g.): - Dual pipe: Output from two LMs combined to single display. - Split display: Output from two LMs connected to two separate interfaces. The hardware capabilities determine the number of concurrent data paths possible. Any control path (i.e. pipeline w/i DPU) can be routed to any of the hardware data paths. A given control path can be triggered, flushed and controlled independently. Changes in v3: - Move msm_media_info.h from uapi to dpu/ subdir - Remove preclose callback dpu (it's handled in core) - Fix kbuild warnings with parent_ops - Remove unused functions from dpu_core_irq - Rename mdss_phys to mdss - Rename mdp_phys address space to mdp - Drop _phys from vbif and regdma binding names Signed-off-by: Abhinav Kumar <abhinavk@codeaurora.org> Signed-off-by: Archit Taneja <architt@codeaurora.org> Signed-off-by: Chandan Uddaraju <chandanu@codeaurora.org> Signed-off-by: Jeykumar Sankaran <jsanka@codeaurora.org> Signed-off-by: Jordan Crouse <jcrouse@codeaurora.org> Signed-off-by: Rajesh Yadav <ryadav@codeaurora.org> Signed-off-by: Sravanthi Kollukuduru <skolluku@codeaurora.org> Signed-off-by: Sean Paul <seanpaul@chromium.org> [robclark minor rebase] Signed-off-by: Rob Clark <robdclark@gmail.com>
2018-06-27 19:26:09 +00:00
curr_client->name, curr_client->id,
curr_client->refcount);
curr_client->active = false;
list_del(&curr_client->list);
}
list_for_each_entry_safe(curr_event, next_event,
&phandle->event_list, list) {
pr_err("event:%d, client:%s still registered\n",
curr_event->event_type,
curr_event->client_name);
curr_event->active = false;
list_del(&curr_event->list);
}
mutex_unlock(&phandle->phandle_lock);
}
int dpu_power_resource_enable(struct dpu_power_handle *phandle,
struct dpu_power_client *pclient, bool enable)
{
bool changed = false;
u32 max_usecase_ndx = VOTE_INDEX_DISABLE, prev_usecase_ndx;
struct dpu_power_client *client;
u32 event_type;
drm/msm: Add SDM845 DPU support SDM845 SoC includes the Mobile Display Sub System (MDSS) which is a top level wrapper consisting of Display Processing Unit (DPU) and display peripheral modules such as Display Serial Interface (DSI) and DisplayPort (DP). MDSS functions essentially as a back-end composition engine. It blends video and graphic images stored in the frame buffers and scans out the composed image to a display sink (over DSI/DP). The following diagram represents hardware blocks for a simple pipeline (two planes are present on a given crtc which is connected to a DSI connector): MDSS +---------------------------------+ | +-----------------------------+ | | | DPU | | | | +--------+ +--------+ | | | | | SSPP | | SSPP | | | | | +----+---+ +----+---+ | | | | | | | | | | +----v-----------v---+ | | | | | Layer Mixer (LM) | | | | | +--------------------+ | | | | +--------------------+ | | | | | PingPong (PP) | | | | | +--------------------+ | | | | +--------------------+ | | | | | INTERFACE (VIDEO) | | | | | +---+----------------+ | | | +------|----------------------+ | | | | | +------|---------------------+ | | | | DISPLAY PERIPHERALS | | | | +---v-+ +-----+ | | | | | DSI | | DP | | | | | +-----+ +-----+ | | | +----------------------------+ | +---------------------------------+ The number of DPU sub-blocks (i.e. SSPPs, LMs, PP blocks and INTFs) depends on SoC capabilities. Overview of DPU sub-blocks: --------------------------- * Source Surface Processor (SSPP): Refers to any of hardware pipes like ViG, DMA etc. Only ViG pipes are capable of performing format conversion, scaling and quality improvement for source surfaces. * Layer Mixer (LM): Blend source surfaces together (in requested zorder) * PingPong (PP): This block controls frame done interrupt output, EOL and EOF generation, overflow/underflow control. * Display interface (INTF): Timing generator and interface connecting the display peripherals. DRM components mapping to DPU architecture: ------------------------------------------ PLANEs maps to SSPPs CRTC maps to LMs Encoder maps to PPs, INTFs Data flow setup: --------------- MDSS hardware can support various data flows (e.g.): - Dual pipe: Output from two LMs combined to single display. - Split display: Output from two LMs connected to two separate interfaces. The hardware capabilities determine the number of concurrent data paths possible. Any control path (i.e. pipeline w/i DPU) can be routed to any of the hardware data paths. A given control path can be triggered, flushed and controlled independently. Changes in v3: - Move msm_media_info.h from uapi to dpu/ subdir - Remove preclose callback dpu (it's handled in core) - Fix kbuild warnings with parent_ops - Remove unused functions from dpu_core_irq - Rename mdss_phys to mdss - Rename mdp_phys address space to mdp - Drop _phys from vbif and regdma binding names Signed-off-by: Abhinav Kumar <abhinavk@codeaurora.org> Signed-off-by: Archit Taneja <architt@codeaurora.org> Signed-off-by: Chandan Uddaraju <chandanu@codeaurora.org> Signed-off-by: Jeykumar Sankaran <jsanka@codeaurora.org> Signed-off-by: Jordan Crouse <jcrouse@codeaurora.org> Signed-off-by: Rajesh Yadav <ryadav@codeaurora.org> Signed-off-by: Sravanthi Kollukuduru <skolluku@codeaurora.org> Signed-off-by: Sean Paul <seanpaul@chromium.org> [robclark minor rebase] Signed-off-by: Rob Clark <robdclark@gmail.com>
2018-06-27 19:26:09 +00:00
if (!phandle || !pclient) {
pr_err("invalid input argument\n");
return -EINVAL;
}
mutex_lock(&phandle->phandle_lock);
if (enable)
pclient->refcount++;
else if (pclient->refcount)
pclient->refcount--;
if (pclient->refcount)
pclient->usecase_ndx = VOTE_INDEX_LOW;
else
pclient->usecase_ndx = VOTE_INDEX_DISABLE;
list_for_each_entry(client, &phandle->power_client_clist, list) {
if (client->usecase_ndx < VOTE_INDEX_MAX &&
client->usecase_ndx > max_usecase_ndx)
max_usecase_ndx = client->usecase_ndx;
}
if (phandle->current_usecase_ndx != max_usecase_ndx) {
changed = true;
prev_usecase_ndx = phandle->current_usecase_ndx;
phandle->current_usecase_ndx = max_usecase_ndx;
}
pr_debug("%pS: changed=%d current idx=%d request client %s id:%u enable:%d refcount:%d\n",
__builtin_return_address(0), changed, max_usecase_ndx,
pclient->name, pclient->id, enable, pclient->refcount);
if (!changed)
goto end;
event_type = enable ? DPU_POWER_EVENT_ENABLE : DPU_POWER_EVENT_DISABLE;
drm/msm: Add SDM845 DPU support SDM845 SoC includes the Mobile Display Sub System (MDSS) which is a top level wrapper consisting of Display Processing Unit (DPU) and display peripheral modules such as Display Serial Interface (DSI) and DisplayPort (DP). MDSS functions essentially as a back-end composition engine. It blends video and graphic images stored in the frame buffers and scans out the composed image to a display sink (over DSI/DP). The following diagram represents hardware blocks for a simple pipeline (two planes are present on a given crtc which is connected to a DSI connector): MDSS +---------------------------------+ | +-----------------------------+ | | | DPU | | | | +--------+ +--------+ | | | | | SSPP | | SSPP | | | | | +----+---+ +----+---+ | | | | | | | | | | +----v-----------v---+ | | | | | Layer Mixer (LM) | | | | | +--------------------+ | | | | +--------------------+ | | | | | PingPong (PP) | | | | | +--------------------+ | | | | +--------------------+ | | | | | INTERFACE (VIDEO) | | | | | +---+----------------+ | | | +------|----------------------+ | | | | | +------|---------------------+ | | | | DISPLAY PERIPHERALS | | | | +---v-+ +-----+ | | | | | DSI | | DP | | | | | +-----+ +-----+ | | | +----------------------------+ | +---------------------------------+ The number of DPU sub-blocks (i.e. SSPPs, LMs, PP blocks and INTFs) depends on SoC capabilities. Overview of DPU sub-blocks: --------------------------- * Source Surface Processor (SSPP): Refers to any of hardware pipes like ViG, DMA etc. Only ViG pipes are capable of performing format conversion, scaling and quality improvement for source surfaces. * Layer Mixer (LM): Blend source surfaces together (in requested zorder) * PingPong (PP): This block controls frame done interrupt output, EOL and EOF generation, overflow/underflow control. * Display interface (INTF): Timing generator and interface connecting the display peripherals. DRM components mapping to DPU architecture: ------------------------------------------ PLANEs maps to SSPPs CRTC maps to LMs Encoder maps to PPs, INTFs Data flow setup: --------------- MDSS hardware can support various data flows (e.g.): - Dual pipe: Output from two LMs combined to single display. - Split display: Output from two LMs connected to two separate interfaces. The hardware capabilities determine the number of concurrent data paths possible. Any control path (i.e. pipeline w/i DPU) can be routed to any of the hardware data paths. A given control path can be triggered, flushed and controlled independently. Changes in v3: - Move msm_media_info.h from uapi to dpu/ subdir - Remove preclose callback dpu (it's handled in core) - Fix kbuild warnings with parent_ops - Remove unused functions from dpu_core_irq - Rename mdss_phys to mdss - Rename mdp_phys address space to mdp - Drop _phys from vbif and regdma binding names Signed-off-by: Abhinav Kumar <abhinavk@codeaurora.org> Signed-off-by: Archit Taneja <architt@codeaurora.org> Signed-off-by: Chandan Uddaraju <chandanu@codeaurora.org> Signed-off-by: Jeykumar Sankaran <jsanka@codeaurora.org> Signed-off-by: Jordan Crouse <jcrouse@codeaurora.org> Signed-off-by: Rajesh Yadav <ryadav@codeaurora.org> Signed-off-by: Sravanthi Kollukuduru <skolluku@codeaurora.org> Signed-off-by: Sean Paul <seanpaul@chromium.org> [robclark minor rebase] Signed-off-by: Rob Clark <robdclark@gmail.com>
2018-06-27 19:26:09 +00:00
dpu_power_event_trigger_locked(phandle, event_type);
drm/msm: Add SDM845 DPU support SDM845 SoC includes the Mobile Display Sub System (MDSS) which is a top level wrapper consisting of Display Processing Unit (DPU) and display peripheral modules such as Display Serial Interface (DSI) and DisplayPort (DP). MDSS functions essentially as a back-end composition engine. It blends video and graphic images stored in the frame buffers and scans out the composed image to a display sink (over DSI/DP). The following diagram represents hardware blocks for a simple pipeline (two planes are present on a given crtc which is connected to a DSI connector): MDSS +---------------------------------+ | +-----------------------------+ | | | DPU | | | | +--------+ +--------+ | | | | | SSPP | | SSPP | | | | | +----+---+ +----+---+ | | | | | | | | | | +----v-----------v---+ | | | | | Layer Mixer (LM) | | | | | +--------------------+ | | | | +--------------------+ | | | | | PingPong (PP) | | | | | +--------------------+ | | | | +--------------------+ | | | | | INTERFACE (VIDEO) | | | | | +---+----------------+ | | | +------|----------------------+ | | | | | +------|---------------------+ | | | | DISPLAY PERIPHERALS | | | | +---v-+ +-----+ | | | | | DSI | | DP | | | | | +-----+ +-----+ | | | +----------------------------+ | +---------------------------------+ The number of DPU sub-blocks (i.e. SSPPs, LMs, PP blocks and INTFs) depends on SoC capabilities. Overview of DPU sub-blocks: --------------------------- * Source Surface Processor (SSPP): Refers to any of hardware pipes like ViG, DMA etc. Only ViG pipes are capable of performing format conversion, scaling and quality improvement for source surfaces. * Layer Mixer (LM): Blend source surfaces together (in requested zorder) * PingPong (PP): This block controls frame done interrupt output, EOL and EOF generation, overflow/underflow control. * Display interface (INTF): Timing generator and interface connecting the display peripherals. DRM components mapping to DPU architecture: ------------------------------------------ PLANEs maps to SSPPs CRTC maps to LMs Encoder maps to PPs, INTFs Data flow setup: --------------- MDSS hardware can support various data flows (e.g.): - Dual pipe: Output from two LMs combined to single display. - Split display: Output from two LMs connected to two separate interfaces. The hardware capabilities determine the number of concurrent data paths possible. Any control path (i.e. pipeline w/i DPU) can be routed to any of the hardware data paths. A given control path can be triggered, flushed and controlled independently. Changes in v3: - Move msm_media_info.h from uapi to dpu/ subdir - Remove preclose callback dpu (it's handled in core) - Fix kbuild warnings with parent_ops - Remove unused functions from dpu_core_irq - Rename mdss_phys to mdss - Rename mdp_phys address space to mdp - Drop _phys from vbif and regdma binding names Signed-off-by: Abhinav Kumar <abhinavk@codeaurora.org> Signed-off-by: Archit Taneja <architt@codeaurora.org> Signed-off-by: Chandan Uddaraju <chandanu@codeaurora.org> Signed-off-by: Jeykumar Sankaran <jsanka@codeaurora.org> Signed-off-by: Jordan Crouse <jcrouse@codeaurora.org> Signed-off-by: Rajesh Yadav <ryadav@codeaurora.org> Signed-off-by: Sravanthi Kollukuduru <skolluku@codeaurora.org> Signed-off-by: Sean Paul <seanpaul@chromium.org> [robclark minor rebase] Signed-off-by: Rob Clark <robdclark@gmail.com>
2018-06-27 19:26:09 +00:00
end:
mutex_unlock(&phandle->phandle_lock);
return 0;
}
struct dpu_power_event *dpu_power_handle_register_event(
struct dpu_power_handle *phandle,
u32 event_type, void (*cb_fnc)(u32 event_type, void *usr),
void *usr, char *client_name)
{
struct dpu_power_event *event;
if (!phandle) {
pr_err("invalid power handle\n");
return ERR_PTR(-EINVAL);
} else if (!cb_fnc || !event_type) {
pr_err("no callback fnc or event type\n");
return ERR_PTR(-EINVAL);
}
event = kzalloc(sizeof(struct dpu_power_event), GFP_KERNEL);
if (!event)
return ERR_PTR(-ENOMEM);
event->event_type = event_type;
event->cb_fnc = cb_fnc;
event->usr = usr;
strlcpy(event->client_name, client_name, MAX_CLIENT_NAME_LEN);
event->active = true;
mutex_lock(&phandle->phandle_lock);
list_add(&event->list, &phandle->event_list);
mutex_unlock(&phandle->phandle_lock);
return event;
}
void dpu_power_handle_unregister_event(
struct dpu_power_handle *phandle,
struct dpu_power_event *event)
{
if (!phandle || !event) {
pr_err("invalid phandle or event\n");
} else if (!event->active) {
pr_err("power handle deinit already done\n");
kfree(event);
} else {
mutex_lock(&phandle->phandle_lock);
list_del_init(&event->list);
mutex_unlock(&phandle->phandle_lock);
kfree(event);
}
}