0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #define DSS_SUBSYS_NAME "DISPLAY"
0013
0014 #include <linux/kernel.h>
0015 #include <linux/module.h>
0016 #include <linux/jiffies.h>
0017 #include <linux/platform_device.h>
0018 #include <linux/of.h>
0019
0020 #include <video/omapfb_dss.h>
0021 #include "dss.h"
0022 #include "dss_features.h"
0023
0024 void omapdss_default_get_resolution(struct omap_dss_device *dssdev,
0025 u16 *xres, u16 *yres)
0026 {
0027 *xres = dssdev->panel.timings.x_res;
0028 *yres = dssdev->panel.timings.y_res;
0029 }
0030 EXPORT_SYMBOL(omapdss_default_get_resolution);
0031
0032 int omapdss_default_get_recommended_bpp(struct omap_dss_device *dssdev)
0033 {
0034 switch (dssdev->type) {
0035 case OMAP_DISPLAY_TYPE_DPI:
0036 if (dssdev->phy.dpi.data_lines == 24)
0037 return 24;
0038 else
0039 return 16;
0040
0041 case OMAP_DISPLAY_TYPE_DBI:
0042 if (dssdev->ctrl.pixel_size == 24)
0043 return 24;
0044 else
0045 return 16;
0046 case OMAP_DISPLAY_TYPE_DSI:
0047 if (dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt) > 16)
0048 return 24;
0049 else
0050 return 16;
0051 case OMAP_DISPLAY_TYPE_VENC:
0052 case OMAP_DISPLAY_TYPE_SDI:
0053 case OMAP_DISPLAY_TYPE_HDMI:
0054 case OMAP_DISPLAY_TYPE_DVI:
0055 return 24;
0056 default:
0057 BUG();
0058 return 0;
0059 }
0060 }
0061 EXPORT_SYMBOL(omapdss_default_get_recommended_bpp);
0062
0063 void omapdss_default_get_timings(struct omap_dss_device *dssdev,
0064 struct omap_video_timings *timings)
0065 {
0066 *timings = dssdev->panel.timings;
0067 }
0068 EXPORT_SYMBOL(omapdss_default_get_timings);
0069
0070 int dss_suspend_all_devices(void)
0071 {
0072 struct omap_dss_device *dssdev = NULL;
0073
0074 for_each_dss_dev(dssdev) {
0075 if (!dssdev->driver)
0076 continue;
0077
0078 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
0079 dssdev->driver->disable(dssdev);
0080 dssdev->activate_after_resume = true;
0081 } else {
0082 dssdev->activate_after_resume = false;
0083 }
0084 }
0085
0086 return 0;
0087 }
0088
0089 int dss_resume_all_devices(void)
0090 {
0091 struct omap_dss_device *dssdev = NULL;
0092
0093 for_each_dss_dev(dssdev) {
0094 if (!dssdev->driver)
0095 continue;
0096
0097 if (dssdev->activate_after_resume) {
0098 dssdev->driver->enable(dssdev);
0099 dssdev->activate_after_resume = false;
0100 }
0101 }
0102
0103 return 0;
0104 }
0105
0106 void dss_disable_all_devices(void)
0107 {
0108 struct omap_dss_device *dssdev = NULL;
0109
0110 for_each_dss_dev(dssdev) {
0111 if (!dssdev->driver)
0112 continue;
0113
0114 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
0115 dssdev->driver->disable(dssdev);
0116 }
0117 }
0118
0119 static LIST_HEAD(panel_list);
0120 static DEFINE_MUTEX(panel_list_mutex);
0121 static int disp_num_counter;
0122
0123 int omapdss_register_display(struct omap_dss_device *dssdev)
0124 {
0125 struct omap_dss_driver *drv = dssdev->driver;
0126 int id;
0127
0128
0129
0130
0131
0132
0133
0134 if (dssdev->dev->of_node) {
0135 id = of_alias_get_id(dssdev->dev->of_node, "display");
0136
0137 if (id < 0)
0138 id = disp_num_counter++;
0139 } else {
0140 id = disp_num_counter++;
0141 }
0142
0143 snprintf(dssdev->alias, sizeof(dssdev->alias), "display%d", id);
0144
0145
0146 if (dssdev->dev->of_node)
0147 of_property_read_string(dssdev->dev->of_node, "label",
0148 &dssdev->name);
0149
0150 if (dssdev->name == NULL)
0151 dssdev->name = dssdev->alias;
0152
0153 if (drv && drv->get_resolution == NULL)
0154 drv->get_resolution = omapdss_default_get_resolution;
0155 if (drv && drv->get_recommended_bpp == NULL)
0156 drv->get_recommended_bpp = omapdss_default_get_recommended_bpp;
0157 if (drv && drv->get_timings == NULL)
0158 drv->get_timings = omapdss_default_get_timings;
0159
0160 mutex_lock(&panel_list_mutex);
0161 list_add_tail(&dssdev->panel_list, &panel_list);
0162 mutex_unlock(&panel_list_mutex);
0163 return 0;
0164 }
0165 EXPORT_SYMBOL(omapdss_register_display);
0166
0167 void omapdss_unregister_display(struct omap_dss_device *dssdev)
0168 {
0169 mutex_lock(&panel_list_mutex);
0170 list_del(&dssdev->panel_list);
0171 mutex_unlock(&panel_list_mutex);
0172 }
0173 EXPORT_SYMBOL(omapdss_unregister_display);
0174
0175 struct omap_dss_device *omap_dss_get_device(struct omap_dss_device *dssdev)
0176 {
0177 if (!try_module_get(dssdev->owner))
0178 return NULL;
0179
0180 if (get_device(dssdev->dev) == NULL) {
0181 module_put(dssdev->owner);
0182 return NULL;
0183 }
0184
0185 return dssdev;
0186 }
0187 EXPORT_SYMBOL(omap_dss_get_device);
0188
0189 void omap_dss_put_device(struct omap_dss_device *dssdev)
0190 {
0191 put_device(dssdev->dev);
0192 module_put(dssdev->owner);
0193 }
0194 EXPORT_SYMBOL(omap_dss_put_device);
0195
0196
0197
0198
0199
0200 struct omap_dss_device *omap_dss_get_next_device(struct omap_dss_device *from)
0201 {
0202 struct list_head *l;
0203 struct omap_dss_device *dssdev;
0204
0205 mutex_lock(&panel_list_mutex);
0206
0207 if (list_empty(&panel_list)) {
0208 dssdev = NULL;
0209 goto out;
0210 }
0211
0212 if (from == NULL) {
0213 dssdev = list_first_entry(&panel_list, struct omap_dss_device,
0214 panel_list);
0215 omap_dss_get_device(dssdev);
0216 goto out;
0217 }
0218
0219 omap_dss_put_device(from);
0220
0221 list_for_each(l, &panel_list) {
0222 dssdev = list_entry(l, struct omap_dss_device, panel_list);
0223 if (dssdev == from) {
0224 if (list_is_last(l, &panel_list)) {
0225 dssdev = NULL;
0226 goto out;
0227 }
0228
0229 dssdev = list_entry(l->next, struct omap_dss_device,
0230 panel_list);
0231 omap_dss_get_device(dssdev);
0232 goto out;
0233 }
0234 }
0235
0236 WARN(1, "'from' dssdev not found\n");
0237
0238 dssdev = NULL;
0239 out:
0240 mutex_unlock(&panel_list_mutex);
0241 return dssdev;
0242 }
0243 EXPORT_SYMBOL(omap_dss_get_next_device);
0244
0245 struct omap_dss_device *omap_dss_find_device(void *data,
0246 int (*match)(struct omap_dss_device *dssdev, void *data))
0247 {
0248 struct omap_dss_device *dssdev = NULL;
0249
0250 while ((dssdev = omap_dss_get_next_device(dssdev)) != NULL) {
0251 if (match(dssdev, data))
0252 return dssdev;
0253 }
0254
0255 return NULL;
0256 }
0257 EXPORT_SYMBOL(omap_dss_find_device);
0258
0259 void videomode_to_omap_video_timings(const struct videomode *vm,
0260 struct omap_video_timings *ovt)
0261 {
0262 memset(ovt, 0, sizeof(*ovt));
0263
0264 ovt->pixelclock = vm->pixelclock;
0265 ovt->x_res = vm->hactive;
0266 ovt->hbp = vm->hback_porch;
0267 ovt->hfp = vm->hfront_porch;
0268 ovt->hsw = vm->hsync_len;
0269 ovt->y_res = vm->vactive;
0270 ovt->vbp = vm->vback_porch;
0271 ovt->vfp = vm->vfront_porch;
0272 ovt->vsw = vm->vsync_len;
0273
0274 ovt->vsync_level = vm->flags & DISPLAY_FLAGS_VSYNC_HIGH ?
0275 OMAPDSS_SIG_ACTIVE_HIGH :
0276 OMAPDSS_SIG_ACTIVE_LOW;
0277 ovt->hsync_level = vm->flags & DISPLAY_FLAGS_HSYNC_HIGH ?
0278 OMAPDSS_SIG_ACTIVE_HIGH :
0279 OMAPDSS_SIG_ACTIVE_LOW;
0280 ovt->de_level = vm->flags & DISPLAY_FLAGS_DE_HIGH ?
0281 OMAPDSS_SIG_ACTIVE_HIGH :
0282 OMAPDSS_SIG_ACTIVE_LOW;
0283 ovt->data_pclk_edge = vm->flags & DISPLAY_FLAGS_PIXDATA_POSEDGE ?
0284 OMAPDSS_DRIVE_SIG_RISING_EDGE :
0285 OMAPDSS_DRIVE_SIG_FALLING_EDGE;
0286
0287 ovt->sync_pclk_edge = ovt->data_pclk_edge;
0288 }
0289 EXPORT_SYMBOL(videomode_to_omap_video_timings);
0290
0291 void omap_video_timings_to_videomode(const struct omap_video_timings *ovt,
0292 struct videomode *vm)
0293 {
0294 memset(vm, 0, sizeof(*vm));
0295
0296 vm->pixelclock = ovt->pixelclock;
0297
0298 vm->hactive = ovt->x_res;
0299 vm->hback_porch = ovt->hbp;
0300 vm->hfront_porch = ovt->hfp;
0301 vm->hsync_len = ovt->hsw;
0302 vm->vactive = ovt->y_res;
0303 vm->vback_porch = ovt->vbp;
0304 vm->vfront_porch = ovt->vfp;
0305 vm->vsync_len = ovt->vsw;
0306
0307 if (ovt->hsync_level == OMAPDSS_SIG_ACTIVE_HIGH)
0308 vm->flags |= DISPLAY_FLAGS_HSYNC_HIGH;
0309 else
0310 vm->flags |= DISPLAY_FLAGS_HSYNC_LOW;
0311
0312 if (ovt->vsync_level == OMAPDSS_SIG_ACTIVE_HIGH)
0313 vm->flags |= DISPLAY_FLAGS_VSYNC_HIGH;
0314 else
0315 vm->flags |= DISPLAY_FLAGS_VSYNC_LOW;
0316
0317 if (ovt->de_level == OMAPDSS_SIG_ACTIVE_HIGH)
0318 vm->flags |= DISPLAY_FLAGS_DE_HIGH;
0319 else
0320 vm->flags |= DISPLAY_FLAGS_DE_LOW;
0321
0322 if (ovt->data_pclk_edge == OMAPDSS_DRIVE_SIG_RISING_EDGE)
0323 vm->flags |= DISPLAY_FLAGS_PIXDATA_POSEDGE;
0324 else
0325 vm->flags |= DISPLAY_FLAGS_PIXDATA_NEGEDGE;
0326 }
0327 EXPORT_SYMBOL(omap_video_timings_to_videomode);