brintos

brintos / linux-shallow public Read only

0
0
Text · 5.8 KiB · 0370746 Raw
241 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * linux/drivers/video/mmp/common.c4 * This driver is a common framework for Marvell Display Controller5 *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 number37 * this function fetches modelist from phy/panel:38 *   for HDMI/parallel or dsi to hdmi cases, get from phy39 *   or get from panel40 */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 registered54 * path list is used for both buffer driver and platdriver55 * plat driver do path register/unregister56 * panel driver do panel register/unregister57 * buffer driver get registered path58 */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 path65 * @p: panel to be registered66 *67 * this function provides interface for panel drivers to register panel68 * 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 after70 * 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 disconnect97 * @p: panel to be unregistered98 *99 * this function provides interface for panel drivers to unregister panel100 * 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 name123 * @p: path name124 *125 * this function checks path name in path_list and return matching path126 * return NULL if no matching path127 */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_info147 * @p: path info provided by display controller148 *149 * this function init by path info and register path to path_list150 * this function also try to connect path with panel by name151 */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 path212 * @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");241