root/drivers/video/fbdev/mmp/core.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. path_get_overlay
  2. path_check_status
  3. path_get_modelist
  4. mmp_register_panel
  5. mmp_unregister_panel
  6. mmp_get_path
  7. mmp_register_path
  8. mmp_unregister_path

   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 
  16 static 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 
  24 static 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  */
  41 static 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  */
  59 static LIST_HEAD(panel_list);
  60 static LIST_HEAD(path_list);
  61 static 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  */
  72 void 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 }
  93 EXPORT_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  */
 102 void 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 }
 119 EXPORT_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  */
 128 struct mmp_path *mmp_get_path(const char *name)
 129 {
 130         struct mmp_path *path;
 131         int found = 0;
 132 
 133         mutex_lock(&disp_lock);
 134         list_for_each_entry(path, &path_list, node) {
 135                 if (!strcmp(name, path->name)) {
 136                         found = 1;
 137                         break;
 138                 }
 139         }
 140         mutex_unlock(&disp_lock);
 141 
 142         return found ? path : NULL;
 143 }
 144 EXPORT_SYMBOL_GPL(mmp_get_path);
 145 
 146 /*
 147  * mmp_register_path - init and register path by path_info
 148  * @p: path info provided by display controller
 149  *
 150  * this function init by path info and register path to path_list
 151  * this function also try to connect path with panel by name
 152  */
 153 struct mmp_path *mmp_register_path(struct mmp_path_info *info)
 154 {
 155         int i;
 156         struct mmp_path *path = NULL;
 157         struct mmp_panel *panel;
 158 
 159         path = kzalloc(struct_size(path, overlays, info->overlay_num),
 160                        GFP_KERNEL);
 161         if (!path)
 162                 return NULL;
 163 
 164         /* path set */
 165         mutex_init(&path->access_ok);
 166         path->dev = info->dev;
 167         path->id = info->id;
 168         path->name = info->name;
 169         path->output_type = info->output_type;
 170         path->overlay_num = info->overlay_num;
 171         path->plat_data = info->plat_data;
 172         path->ops.set_mode = info->set_mode;
 173 
 174         mutex_lock(&disp_lock);
 175         /* get panel */
 176         list_for_each_entry(panel, &panel_list, node) {
 177                 if (!strcmp(info->name, panel->plat_path_name)) {
 178                         dev_info(path->dev, "get panel %s\n", panel->name);
 179                         path->panel = panel;
 180                         break;
 181                 }
 182         }
 183 
 184         dev_info(path->dev, "register %s, overlay_num %d\n",
 185                         path->name, path->overlay_num);
 186 
 187         /* default op set: if already set by driver, never cover it */
 188         if (!path->ops.check_status)
 189                 path->ops.check_status = path_check_status;
 190         if (!path->ops.get_overlay)
 191                 path->ops.get_overlay = path_get_overlay;
 192         if (!path->ops.get_modelist)
 193                 path->ops.get_modelist = path_get_modelist;
 194 
 195         /* step3: init overlays */
 196         for (i = 0; i < path->overlay_num; i++) {
 197                 path->overlays[i].path = path;
 198                 path->overlays[i].id = i;
 199                 mutex_init(&path->overlays[i].access_ok);
 200                 path->overlays[i].ops = info->overlay_ops;
 201         }
 202 
 203         /* add to pathlist */
 204         list_add_tail(&path->node, &path_list);
 205 
 206         mutex_unlock(&disp_lock);
 207         return path;
 208 }
 209 EXPORT_SYMBOL_GPL(mmp_register_path);
 210 
 211 /*
 212  * mmp_unregister_path - unregister and destroy path
 213  * @p: path to be destroyed.
 214  *
 215  * this function registers path and destroys it.
 216  */
 217 void mmp_unregister_path(struct mmp_path *path)
 218 {
 219         int i;
 220 
 221         if (!path)
 222                 return;
 223 
 224         mutex_lock(&disp_lock);
 225         /* del from pathlist */
 226         list_del(&path->node);
 227 
 228         /* deinit overlays */
 229         for (i = 0; i < path->overlay_num; i++)
 230                 mutex_destroy(&path->overlays[i].access_ok);
 231 
 232         mutex_destroy(&path->access_ok);
 233 
 234         kfree(path);
 235         mutex_unlock(&disp_lock);
 236 }
 237 EXPORT_SYMBOL_GPL(mmp_unregister_path);
 238 
 239 MODULE_AUTHOR("Zhou Zhu <zzhu3@marvell.com>");
 240 MODULE_DESCRIPTION("Marvell MMP display framework");
 241 MODULE_LICENSE("GPL");

/* [<][>][^][v][top][bottom][index][help] */