cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

core.c (5888B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * linux/drivers/video/mmp/common.c
      4 * This driver is a common framework for Marvell Display Controller
      5 *
      6 * Copyright (C) 2012 Marvell Technology Group Ltd.
      7 * Authors: Zhou Zhu <zzhu3@marvell.com>
      8 */
      9
     10#include <linux/slab.h>
     11#include <linux/dma-mapping.h>
     12#include <linux/export.h>
     13#include <linux/module.h>
     14#include <video/mmp_disp.h>
     15
     16static struct mmp_overlay *path_get_overlay(struct mmp_path *path,
     17		int overlay_id)
     18{
     19	if (path && overlay_id < path->overlay_num)
     20		return &path->overlays[overlay_id];
     21	return NULL;
     22}
     23
     24static int path_check_status(struct mmp_path *path)
     25{
     26	int i;
     27	for (i = 0; i < path->overlay_num; i++)
     28		if (path->overlays[i].status)
     29			return 1;
     30
     31	return 0;
     32}
     33
     34/*
     35 * Get modelist write pointer of modelist.
     36 * It also returns modelist number
     37 * this function fetches modelist from phy/panel:
     38 *   for HDMI/parallel or dsi to hdmi cases, get from phy
     39 *   or get from panel
     40 */
     41static int path_get_modelist(struct mmp_path *path,
     42		struct mmp_mode **modelist)
     43{
     44	BUG_ON(!path || !modelist);
     45
     46	if (path->panel && path->panel->get_modelist)
     47		return path->panel->get_modelist(path->panel, modelist);
     48
     49	return 0;
     50}
     51
     52/*
     53 * panel list is used to pair panel/path when path/panel registered
     54 * path list is used for both buffer driver and platdriver
     55 * plat driver do path register/unregister
     56 * panel driver do panel register/unregister
     57 * buffer driver get registered path
     58 */
     59static LIST_HEAD(panel_list);
     60static LIST_HEAD(path_list);
     61static DEFINE_MUTEX(disp_lock);
     62
     63/*
     64 * mmp_register_panel - register panel to panel_list and connect to path
     65 * @p: panel to be registered
     66 *
     67 * this function provides interface for panel drivers to register panel
     68 * to panel_list and connect to path which matchs panel->plat_path_name.
     69 * no error returns when no matching path is found as path register after
     70 * panel register is permitted.
     71 */
     72void mmp_register_panel(struct mmp_panel *panel)
     73{
     74	struct mmp_path *path;
     75
     76	mutex_lock(&disp_lock);
     77
     78	/* add */
     79	list_add_tail(&panel->node, &panel_list);
     80
     81	/* try to register to path */
     82	list_for_each_entry(path, &path_list, node) {
     83		if (!strcmp(panel->plat_path_name, path->name)) {
     84			dev_info(panel->dev, "connect to path %s\n",
     85				path->name);
     86			path->panel = panel;
     87			break;
     88		}
     89	}
     90
     91	mutex_unlock(&disp_lock);
     92}
     93EXPORT_SYMBOL_GPL(mmp_register_panel);
     94
     95/*
     96 * mmp_unregister_panel - unregister panel from panel_list and disconnect
     97 * @p: panel to be unregistered
     98 *
     99 * this function provides interface for panel drivers to unregister panel
    100 * from panel_list and disconnect from path.
    101 */
    102void mmp_unregister_panel(struct mmp_panel *panel)
    103{
    104	struct mmp_path *path;
    105
    106	mutex_lock(&disp_lock);
    107	list_del(&panel->node);
    108
    109	list_for_each_entry(path, &path_list, node) {
    110		if (path->panel && path->panel == panel) {
    111			dev_info(panel->dev, "disconnect from path %s\n",
    112				path->name);
    113			path->panel = NULL;
    114			break;
    115		}
    116	}
    117	mutex_unlock(&disp_lock);
    118}
    119EXPORT_SYMBOL_GPL(mmp_unregister_panel);
    120
    121/*
    122 * mmp_get_path - get path by name
    123 * @p: path name
    124 *
    125 * this function checks path name in path_list and return matching path
    126 * return NULL if no matching path
    127 */
    128struct mmp_path *mmp_get_path(const char *name)
    129{
    130	struct mmp_path *path = NULL, *iter;
    131
    132	mutex_lock(&disp_lock);
    133	list_for_each_entry(iter, &path_list, node) {
    134		if (!strcmp(name, iter->name)) {
    135			path = iter;
    136			break;
    137		}
    138	}
    139	mutex_unlock(&disp_lock);
    140
    141	return path;
    142}
    143EXPORT_SYMBOL_GPL(mmp_get_path);
    144
    145/*
    146 * mmp_register_path - init and register path by path_info
    147 * @p: path info provided by display controller
    148 *
    149 * this function init by path info and register path to path_list
    150 * this function also try to connect path with panel by name
    151 */
    152struct mmp_path *mmp_register_path(struct mmp_path_info *info)
    153{
    154	int i;
    155	struct mmp_path *path = NULL;
    156	struct mmp_panel *panel;
    157
    158	path = kzalloc(struct_size(path, overlays, info->overlay_num),
    159		       GFP_KERNEL);
    160	if (!path)
    161		return NULL;
    162
    163	/* path set */
    164	mutex_init(&path->access_ok);
    165	path->dev = info->dev;
    166	path->id = info->id;
    167	path->name = info->name;
    168	path->output_type = info->output_type;
    169	path->overlay_num = info->overlay_num;
    170	path->plat_data = info->plat_data;
    171	path->ops.set_mode = info->set_mode;
    172
    173	mutex_lock(&disp_lock);
    174	/* get panel */
    175	list_for_each_entry(panel, &panel_list, node) {
    176		if (!strcmp(info->name, panel->plat_path_name)) {
    177			dev_info(path->dev, "get panel %s\n", panel->name);
    178			path->panel = panel;
    179			break;
    180		}
    181	}
    182
    183	dev_info(path->dev, "register %s, overlay_num %d\n",
    184			path->name, path->overlay_num);
    185
    186	/* default op set: if already set by driver, never cover it */
    187	if (!path->ops.check_status)
    188		path->ops.check_status = path_check_status;
    189	if (!path->ops.get_overlay)
    190		path->ops.get_overlay = path_get_overlay;
    191	if (!path->ops.get_modelist)
    192		path->ops.get_modelist = path_get_modelist;
    193
    194	/* step3: init overlays */
    195	for (i = 0; i < path->overlay_num; i++) {
    196		path->overlays[i].path = path;
    197		path->overlays[i].id = i;
    198		mutex_init(&path->overlays[i].access_ok);
    199		path->overlays[i].ops = info->overlay_ops;
    200	}
    201
    202	/* add to pathlist */
    203	list_add_tail(&path->node, &path_list);
    204
    205	mutex_unlock(&disp_lock);
    206	return path;
    207}
    208EXPORT_SYMBOL_GPL(mmp_register_path);
    209
    210/*
    211 * mmp_unregister_path - unregister and destroy path
    212 * @p: path to be destroyed.
    213 *
    214 * this function registers path and destroys it.
    215 */
    216void mmp_unregister_path(struct mmp_path *path)
    217{
    218	int i;
    219
    220	if (!path)
    221		return;
    222
    223	mutex_lock(&disp_lock);
    224	/* del from pathlist */
    225	list_del(&path->node);
    226
    227	/* deinit overlays */
    228	for (i = 0; i < path->overlay_num; i++)
    229		mutex_destroy(&path->overlays[i].access_ok);
    230
    231	mutex_destroy(&path->access_ok);
    232
    233	kfree(path);
    234	mutex_unlock(&disp_lock);
    235}
    236EXPORT_SYMBOL_GPL(mmp_unregister_path);
    237
    238MODULE_AUTHOR("Zhou Zhu <zzhu3@marvell.com>");
    239MODULE_DESCRIPTION("Marvell MMP display framework");
    240MODULE_LICENSE("GPL");