linux/drivers/video/fbdev/omap2/omapfb/dss/core.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * linux/drivers/video/omap2/dss/core.c
   4 *
   5 * Copyright (C) 2009 Nokia Corporation
   6 * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
   7 *
   8 * Some code and ideas taken from drivers/video/omap/ driver
   9 * 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        else
  87                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 int omap_dss_remove(struct platform_device *pdev)
 175{
 176        unregister_pm_notifier(&omap_dss_pm_notif_block);
 177
 178        dss_uninitialize_debugfs();
 179
 180        return 0;
 181}
 182
 183static void omap_dss_shutdown(struct platform_device *pdev)
 184{
 185        DSSDBG("shutdown\n");
 186        dss_disable_all_devices();
 187}
 188
 189static struct platform_driver omap_dss_driver = {
 190        .remove         = omap_dss_remove,
 191        .shutdown       = omap_dss_shutdown,
 192        .driver         = {
 193                .name   = "omapdss",
 194        },
 195};
 196
 197/* INIT */
 198static int (*dss_output_drv_reg_funcs[])(void) __initdata = {
 199        dss_init_platform_driver,
 200        dispc_init_platform_driver,
 201#ifdef CONFIG_FB_OMAP2_DSS_DSI
 202        dsi_init_platform_driver,
 203#endif
 204#ifdef CONFIG_FB_OMAP2_DSS_DPI
 205        dpi_init_platform_driver,
 206#endif
 207#ifdef CONFIG_FB_OMAP2_DSS_SDI
 208        sdi_init_platform_driver,
 209#endif
 210#ifdef CONFIG_FB_OMAP2_DSS_VENC
 211        venc_init_platform_driver,
 212#endif
 213#ifdef CONFIG_FB_OMAP4_DSS_HDMI
 214        hdmi4_init_platform_driver,
 215#endif
 216#ifdef CONFIG_FB_OMAP5_DSS_HDMI
 217        hdmi5_init_platform_driver,
 218#endif
 219};
 220
 221static void (*dss_output_drv_unreg_funcs[])(void) = {
 222#ifdef CONFIG_FB_OMAP5_DSS_HDMI
 223        hdmi5_uninit_platform_driver,
 224#endif
 225#ifdef CONFIG_FB_OMAP4_DSS_HDMI
 226        hdmi4_uninit_platform_driver,
 227#endif
 228#ifdef CONFIG_FB_OMAP2_DSS_VENC
 229        venc_uninit_platform_driver,
 230#endif
 231#ifdef CONFIG_FB_OMAP2_DSS_SDI
 232        sdi_uninit_platform_driver,
 233#endif
 234#ifdef CONFIG_FB_OMAP2_DSS_DPI
 235        dpi_uninit_platform_driver,
 236#endif
 237#ifdef CONFIG_FB_OMAP2_DSS_DSI
 238        dsi_uninit_platform_driver,
 239#endif
 240        dispc_uninit_platform_driver,
 241        dss_uninit_platform_driver,
 242};
 243
 244static int __init omap_dss_init(void)
 245{
 246        int r;
 247        int i;
 248
 249        r = platform_driver_probe(&omap_dss_driver, omap_dss_probe);
 250        if (r)
 251                return r;
 252
 253        for (i = 0; i < ARRAY_SIZE(dss_output_drv_reg_funcs); ++i) {
 254                r = dss_output_drv_reg_funcs[i]();
 255                if (r)
 256                        goto err_reg;
 257        }
 258
 259        return 0;
 260
 261err_reg:
 262        for (i = ARRAY_SIZE(dss_output_drv_reg_funcs) - i;
 263                        i < ARRAY_SIZE(dss_output_drv_reg_funcs);
 264                        ++i)
 265                dss_output_drv_unreg_funcs[i]();
 266
 267        platform_driver_unregister(&omap_dss_driver);
 268
 269        return r;
 270}
 271
 272static void __exit omap_dss_exit(void)
 273{
 274        int i;
 275
 276        for (i = 0; i < ARRAY_SIZE(dss_output_drv_unreg_funcs); ++i)
 277                dss_output_drv_unreg_funcs[i]();
 278
 279        platform_driver_unregister(&omap_dss_driver);
 280}
 281
 282module_init(omap_dss_init);
 283module_exit(omap_dss_exit);
 284
 285MODULE_AUTHOR("Tomi Valkeinen <tomi.valkeinen@nokia.com>");
 286MODULE_DESCRIPTION("OMAP2/3 Display Subsystem");
 287MODULE_LICENSE("GPL v2");
 288
 289