287 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * linux/drivers/video/omap2/dss/core.c4 *5 * Copyright (C) 2009 Nokia Corporation6 * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>7 *8 * Some code and ideas taken from drivers/video/omap/ driver9 * by Imre Deak.10 */11 12#define DSS_SUBSYS_NAME "CORE"13 14#include <linux/kernel.h>15#include <linux/module.h>16#include <linux/clk.h>17#include <linux/err.h>18#include <linux/platform_device.h>19#include <linux/seq_file.h>20#include <linux/debugfs.h>21#include <linux/io.h>22#include <linux/device.h>23#include <linux/regulator/consumer.h>24#include <linux/suspend.h>25#include <linux/slab.h>26 27#include <video/omapfb_dss.h>28 29#include "dss.h"30#include "dss_features.h"31 32static struct {33 struct platform_device *pdev;34 35 const char *default_display_name;36} core;37 38static char *def_disp_name;39module_param_named(def_disp, def_disp_name, charp, 0);40MODULE_PARM_DESC(def_disp, "default display name");41 42const char *omapdss_get_default_display_name(void)43{44 return core.default_display_name;45}46EXPORT_SYMBOL(omapdss_get_default_display_name);47 48enum omapdss_version omapdss_get_version(void)49{50 struct omap_dss_board_info *pdata = core.pdev->dev.platform_data;51 return pdata->version;52}53EXPORT_SYMBOL(omapdss_get_version);54 55struct platform_device *dss_get_core_pdev(void)56{57 return core.pdev;58}59 60int dss_dsi_enable_pads(int dsi_id, unsigned lane_mask)61{62 struct omap_dss_board_info *board_data = core.pdev->dev.platform_data;63 64 if (!board_data->dsi_enable_pads)65 return -ENOENT;66 67 return board_data->dsi_enable_pads(dsi_id, lane_mask);68}69 70void dss_dsi_disable_pads(int dsi_id, unsigned lane_mask)71{72 struct omap_dss_board_info *board_data = core.pdev->dev.platform_data;73 74 if (!board_data->dsi_disable_pads)75 return;76 77 return board_data->dsi_disable_pads(dsi_id, lane_mask);78}79 80int dss_set_min_bus_tput(struct device *dev, unsigned long tput)81{82 struct omap_dss_board_info *pdata = core.pdev->dev.platform_data;83 84 if (pdata->set_min_bus_tput)85 return pdata->set_min_bus_tput(dev, tput);86 else87 return 0;88}89 90#if defined(CONFIG_FB_OMAP2_DSS_DEBUGFS)91static int dss_show(struct seq_file *s, void *unused)92{93 void (*func)(struct seq_file *) = s->private;94 func(s);95 return 0;96}97 98DEFINE_SHOW_ATTRIBUTE(dss);99 100static struct dentry *dss_debugfs_dir;101 102static void dss_initialize_debugfs(void)103{104 dss_debugfs_dir = debugfs_create_dir("omapdss", NULL);105 106 debugfs_create_file("clk", S_IRUGO, dss_debugfs_dir,107 &dss_debug_dump_clocks, &dss_fops);108}109 110static void dss_uninitialize_debugfs(void)111{112 debugfs_remove_recursive(dss_debugfs_dir);113}114 115void dss_debugfs_create_file(const char *name, void (*write)(struct seq_file *))116{117 debugfs_create_file(name, S_IRUGO, dss_debugfs_dir, write, &dss_fops);118}119#else /* CONFIG_FB_OMAP2_DSS_DEBUGFS */120static inline void dss_initialize_debugfs(void)121{122}123static inline void dss_uninitialize_debugfs(void)124{125}126void dss_debugfs_create_file(const char *name, void (*write)(struct seq_file *))127{128}129#endif /* CONFIG_FB_OMAP2_DSS_DEBUGFS */130 131/* PLATFORM DEVICE */132static int omap_dss_pm_notif(struct notifier_block *b, unsigned long v, void *d)133{134 DSSDBG("pm notif %lu\n", v);135 136 switch (v) {137 case PM_SUSPEND_PREPARE:138 case PM_HIBERNATION_PREPARE:139 case PM_RESTORE_PREPARE:140 DSSDBG("suspending displays\n");141 return dss_suspend_all_devices();142 143 case PM_POST_SUSPEND:144 case PM_POST_HIBERNATION:145 case PM_POST_RESTORE:146 DSSDBG("resuming displays\n");147 return dss_resume_all_devices();148 149 default:150 return 0;151 }152}153 154static struct notifier_block omap_dss_pm_notif_block = {155 .notifier_call = omap_dss_pm_notif,156};157 158static int __init omap_dss_probe(struct platform_device *pdev)159{160 core.pdev = pdev;161 162 dss_features_init(omapdss_get_version());163 164 dss_initialize_debugfs();165 166 if (def_disp_name)167 core.default_display_name = def_disp_name;168 169 register_pm_notifier(&omap_dss_pm_notif_block);170 171 return 0;172}173 174static void omap_dss_remove(struct platform_device *pdev)175{176 unregister_pm_notifier(&omap_dss_pm_notif_block);177 178 dss_uninitialize_debugfs();179}180 181static void omap_dss_shutdown(struct platform_device *pdev)182{183 DSSDBG("shutdown\n");184 dss_disable_all_devices();185}186 187static struct platform_driver omap_dss_driver = {188 .remove = omap_dss_remove,189 .shutdown = omap_dss_shutdown,190 .driver = {191 .name = "omapdss",192 },193};194 195/* INIT */196static int (*dss_output_drv_reg_funcs[])(void) __initdata = {197 dss_init_platform_driver,198 dispc_init_platform_driver,199#ifdef CONFIG_FB_OMAP2_DSS_DSI200 dsi_init_platform_driver,201#endif202#ifdef CONFIG_FB_OMAP2_DSS_DPI203 dpi_init_platform_driver,204#endif205#ifdef CONFIG_FB_OMAP2_DSS_SDI206 sdi_init_platform_driver,207#endif208#ifdef CONFIG_FB_OMAP2_DSS_VENC209 venc_init_platform_driver,210#endif211#ifdef CONFIG_FB_OMAP4_DSS_HDMI212 hdmi4_init_platform_driver,213#endif214#ifdef CONFIG_FB_OMAP5_DSS_HDMI215 hdmi5_init_platform_driver,216#endif217};218 219static void (*dss_output_drv_unreg_funcs[])(void) = {220#ifdef CONFIG_FB_OMAP5_DSS_HDMI221 hdmi5_uninit_platform_driver,222#endif223#ifdef CONFIG_FB_OMAP4_DSS_HDMI224 hdmi4_uninit_platform_driver,225#endif226#ifdef CONFIG_FB_OMAP2_DSS_VENC227 venc_uninit_platform_driver,228#endif229#ifdef CONFIG_FB_OMAP2_DSS_SDI230 sdi_uninit_platform_driver,231#endif232#ifdef CONFIG_FB_OMAP2_DSS_DPI233 dpi_uninit_platform_driver,234#endif235#ifdef CONFIG_FB_OMAP2_DSS_DSI236 dsi_uninit_platform_driver,237#endif238 dispc_uninit_platform_driver,239 dss_uninit_platform_driver,240};241 242static int __init omap_dss_init(void)243{244 int r;245 int i;246 247 r = platform_driver_probe(&omap_dss_driver, omap_dss_probe);248 if (r)249 return r;250 251 for (i = 0; i < ARRAY_SIZE(dss_output_drv_reg_funcs); ++i) {252 r = dss_output_drv_reg_funcs[i]();253 if (r)254 goto err_reg;255 }256 257 return 0;258 259err_reg:260 for (i = ARRAY_SIZE(dss_output_drv_reg_funcs) - i;261 i < ARRAY_SIZE(dss_output_drv_reg_funcs);262 ++i)263 dss_output_drv_unreg_funcs[i]();264 265 platform_driver_unregister(&omap_dss_driver);266 267 return r;268}269 270static void __exit omap_dss_exit(void)271{272 int i;273 274 for (i = 0; i < ARRAY_SIZE(dss_output_drv_unreg_funcs); ++i)275 dss_output_drv_unreg_funcs[i]();276 277 platform_driver_unregister(&omap_dss_driver);278}279 280module_init(omap_dss_init);281module_exit(omap_dss_exit);282 283MODULE_AUTHOR("Tomi Valkeinen <tomi.valkeinen@nokia.com>");284MODULE_DESCRIPTION("OMAP2/3 Display Subsystem");285MODULE_LICENSE("GPL v2");286 287