0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/string.h>
0011 #include <linux/kernel.h>
0012 #include <linux/init.h>
0013 #include <linux/platform_device.h>
0014 #include <linux/io.h>
0015 #include <linux/clk.h>
0016 #include <linux/err.h>
0017 #include <linux/delay.h>
0018 #include <linux/of.h>
0019 #include <linux/of_platform.h>
0020 #include <linux/slab.h>
0021 #include <linux/mfd/syscon.h>
0022 #include <linux/regmap.h>
0023
0024 #include <linux/platform_data/omapdss.h>
0025 #include "omap_hwmod.h"
0026 #include "omap_device.h"
0027 #include "common.h"
0028
0029 #include "soc.h"
0030 #include "iomap.h"
0031 #include "control.h"
0032 #include "display.h"
0033 #include "prm.h"
0034
0035 #define DISPC_CONTROL 0x0040
0036 #define DISPC_CONTROL2 0x0238
0037 #define DISPC_CONTROL3 0x0848
0038 #define DISPC_IRQSTATUS 0x0018
0039
0040 #define DSS_CONTROL 0x40
0041 #define DSS_SDI_CONTROL 0x44
0042 #define DSS_PLL_CONTROL 0x48
0043
0044 #define LCD_EN_MASK (0x1 << 0)
0045 #define DIGIT_EN_MASK (0x1 << 1)
0046
0047 #define FRAMEDONE_IRQ_SHIFT 0
0048 #define EVSYNC_EVEN_IRQ_SHIFT 2
0049 #define EVSYNC_ODD_IRQ_SHIFT 3
0050 #define FRAMEDONE2_IRQ_SHIFT 22
0051 #define FRAMEDONE3_IRQ_SHIFT 30
0052 #define FRAMEDONETV_IRQ_SHIFT 24
0053
0054
0055
0056
0057
0058 #define FRAMEDONE_IRQ_TIMEOUT 100
0059
0060 #if defined(CONFIG_FB_OMAP2)
0061 static struct platform_device omap_display_device = {
0062 .name = "omapdss",
0063 .id = -1,
0064 .dev = {
0065 .platform_data = NULL,
0066 },
0067 };
0068
0069 #define OMAP4_DSIPHY_SYSCON_OFFSET 0x78
0070
0071 static struct regmap *omap4_dsi_mux_syscon;
0072
0073 static int omap4_dsi_mux_pads(int dsi_id, unsigned lanes)
0074 {
0075 u32 enable_mask, enable_shift;
0076 u32 pipd_mask, pipd_shift;
0077 u32 reg;
0078 int ret;
0079
0080 if (dsi_id == 0) {
0081 enable_mask = OMAP4_DSI1_LANEENABLE_MASK;
0082 enable_shift = OMAP4_DSI1_LANEENABLE_SHIFT;
0083 pipd_mask = OMAP4_DSI1_PIPD_MASK;
0084 pipd_shift = OMAP4_DSI1_PIPD_SHIFT;
0085 } else if (dsi_id == 1) {
0086 enable_mask = OMAP4_DSI2_LANEENABLE_MASK;
0087 enable_shift = OMAP4_DSI2_LANEENABLE_SHIFT;
0088 pipd_mask = OMAP4_DSI2_PIPD_MASK;
0089 pipd_shift = OMAP4_DSI2_PIPD_SHIFT;
0090 } else {
0091 return -ENODEV;
0092 }
0093
0094 ret = regmap_read(omap4_dsi_mux_syscon,
0095 OMAP4_DSIPHY_SYSCON_OFFSET,
0096 ®);
0097 if (ret)
0098 return ret;
0099
0100 reg &= ~enable_mask;
0101 reg &= ~pipd_mask;
0102
0103 reg |= (lanes << enable_shift) & enable_mask;
0104 reg |= (lanes << pipd_shift) & pipd_mask;
0105
0106 regmap_write(omap4_dsi_mux_syscon, OMAP4_DSIPHY_SYSCON_OFFSET, reg);
0107
0108 return 0;
0109 }
0110
0111 static int omap_dsi_enable_pads(int dsi_id, unsigned lane_mask)
0112 {
0113 if (cpu_is_omap44xx())
0114 return omap4_dsi_mux_pads(dsi_id, lane_mask);
0115
0116 return 0;
0117 }
0118
0119 static void omap_dsi_disable_pads(int dsi_id, unsigned lane_mask)
0120 {
0121 if (cpu_is_omap44xx())
0122 omap4_dsi_mux_pads(dsi_id, 0);
0123 }
0124
0125 static enum omapdss_version __init omap_display_get_version(void)
0126 {
0127 if (cpu_is_omap24xx())
0128 return OMAPDSS_VER_OMAP24xx;
0129 else if (cpu_is_omap3630())
0130 return OMAPDSS_VER_OMAP3630;
0131 else if (cpu_is_omap34xx()) {
0132 if (soc_is_am35xx()) {
0133 return OMAPDSS_VER_AM35xx;
0134 } else {
0135 if (omap_rev() < OMAP3430_REV_ES3_0)
0136 return OMAPDSS_VER_OMAP34xx_ES1;
0137 else
0138 return OMAPDSS_VER_OMAP34xx_ES3;
0139 }
0140 } else if (omap_rev() == OMAP4430_REV_ES1_0)
0141 return OMAPDSS_VER_OMAP4430_ES1;
0142 else if (omap_rev() == OMAP4430_REV_ES2_0 ||
0143 omap_rev() == OMAP4430_REV_ES2_1 ||
0144 omap_rev() == OMAP4430_REV_ES2_2)
0145 return OMAPDSS_VER_OMAP4430_ES2;
0146 else if (cpu_is_omap44xx())
0147 return OMAPDSS_VER_OMAP4;
0148 else if (soc_is_omap54xx())
0149 return OMAPDSS_VER_OMAP5;
0150 else if (soc_is_am43xx())
0151 return OMAPDSS_VER_AM43xx;
0152 else if (soc_is_dra7xx())
0153 return OMAPDSS_VER_DRA7xx;
0154 else
0155 return OMAPDSS_VER_UNKNOWN;
0156 }
0157
0158 static int __init omapdss_init_fbdev(void)
0159 {
0160 static struct omap_dss_board_info board_data = {
0161 .dsi_enable_pads = omap_dsi_enable_pads,
0162 .dsi_disable_pads = omap_dsi_disable_pads,
0163 };
0164 struct device_node *node;
0165 int r;
0166
0167 board_data.version = omap_display_get_version();
0168 if (board_data.version == OMAPDSS_VER_UNKNOWN) {
0169 pr_err("DSS not supported on this SoC\n");
0170 return -ENODEV;
0171 }
0172
0173 omap_display_device.dev.platform_data = &board_data;
0174
0175 r = platform_device_register(&omap_display_device);
0176 if (r < 0) {
0177 pr_err("Unable to register omapdss device\n");
0178 return r;
0179 }
0180
0181
0182 r = omap_init_vrfb();
0183 if (r < 0) {
0184 pr_err("Unable to register omapvrfb device\n");
0185 return r;
0186 }
0187
0188
0189 r = omap_init_fb();
0190 if (r < 0) {
0191 pr_err("Unable to register omapfb device\n");
0192 return r;
0193 }
0194
0195
0196 r = omap_init_vout();
0197 if (r < 0) {
0198 pr_err("Unable to register omap_vout device\n");
0199 return r;
0200 }
0201
0202
0203 node = of_find_node_by_name(NULL, "omap4_padconf_global");
0204 if (node)
0205 omap4_dsi_mux_syscon = syscon_node_to_regmap(node);
0206 of_node_put(node);
0207
0208 return 0;
0209 }
0210
0211 static const char * const omapdss_compat_names[] __initconst = {
0212 "ti,omap2-dss",
0213 "ti,omap3-dss",
0214 "ti,omap4-dss",
0215 "ti,omap5-dss",
0216 "ti,dra7-dss",
0217 };
0218
0219 static struct device_node * __init omapdss_find_dss_of_node(void)
0220 {
0221 struct device_node *node;
0222 int i;
0223
0224 for (i = 0; i < ARRAY_SIZE(omapdss_compat_names); ++i) {
0225 node = of_find_compatible_node(NULL, NULL,
0226 omapdss_compat_names[i]);
0227 if (node)
0228 return node;
0229 }
0230
0231 return NULL;
0232 }
0233
0234 static int __init omapdss_init_of(void)
0235 {
0236 int r;
0237 struct device_node *node;
0238 struct platform_device *pdev;
0239
0240
0241
0242 node = omapdss_find_dss_of_node();
0243 if (!node)
0244 return 0;
0245
0246 if (!of_device_is_available(node)) {
0247 of_node_put(node);
0248 return 0;
0249 }
0250
0251 pdev = of_find_device_by_node(node);
0252
0253 if (!pdev) {
0254 pr_err("Unable to find DSS platform device\n");
0255 of_node_put(node);
0256 return -ENODEV;
0257 }
0258
0259 r = of_platform_populate(node, NULL, NULL, &pdev->dev);
0260 put_device(&pdev->dev);
0261 of_node_put(node);
0262 if (r) {
0263 pr_err("Unable to populate DSS submodule devices\n");
0264 return r;
0265 }
0266
0267 return omapdss_init_fbdev();
0268 }
0269 omap_device_initcall(omapdss_init_of);
0270 #endif
0271
0272 static void dispc_disable_outputs(void)
0273 {
0274 u32 v, irq_mask = 0;
0275 bool lcd_en, digit_en, lcd2_en = false, lcd3_en = false;
0276 int i;
0277 struct omap_dss_dispc_dev_attr *da;
0278 struct omap_hwmod *oh;
0279
0280 oh = omap_hwmod_lookup("dss_dispc");
0281 if (!oh) {
0282 WARN(1, "display: could not disable outputs during reset - could not find dss_dispc hwmod\n");
0283 return;
0284 }
0285
0286 if (!oh->dev_attr) {
0287 pr_err("display: could not disable outputs during reset due to missing dev_attr\n");
0288 return;
0289 }
0290
0291 da = (struct omap_dss_dispc_dev_attr *)oh->dev_attr;
0292
0293
0294 v = omap_hwmod_read(oh, DISPC_CONTROL);
0295 lcd_en = v & LCD_EN_MASK;
0296 digit_en = v & DIGIT_EN_MASK;
0297
0298
0299 if (da->manager_count > 2) {
0300 v = omap_hwmod_read(oh, DISPC_CONTROL2);
0301 lcd2_en = v & LCD_EN_MASK;
0302 }
0303
0304
0305 if (da->manager_count > 3) {
0306 v = omap_hwmod_read(oh, DISPC_CONTROL3);
0307 lcd3_en = v & LCD_EN_MASK;
0308 }
0309
0310 if (!(lcd_en | digit_en | lcd2_en | lcd3_en))
0311 return;
0312
0313
0314
0315
0316
0317 if (lcd_en)
0318 irq_mask |= 1 << FRAMEDONE_IRQ_SHIFT;
0319
0320 if (digit_en) {
0321 if (da->has_framedonetv_irq) {
0322 irq_mask |= 1 << FRAMEDONETV_IRQ_SHIFT;
0323 } else {
0324 irq_mask |= 1 << EVSYNC_EVEN_IRQ_SHIFT |
0325 1 << EVSYNC_ODD_IRQ_SHIFT;
0326 }
0327 }
0328
0329 if (lcd2_en)
0330 irq_mask |= 1 << FRAMEDONE2_IRQ_SHIFT;
0331 if (lcd3_en)
0332 irq_mask |= 1 << FRAMEDONE3_IRQ_SHIFT;
0333
0334
0335
0336
0337
0338 omap_hwmod_write(irq_mask, oh, DISPC_IRQSTATUS);
0339
0340
0341 v = omap_hwmod_read(oh, DISPC_CONTROL);
0342 v &= ~(LCD_EN_MASK | DIGIT_EN_MASK);
0343 omap_hwmod_write(v, oh, DISPC_CONTROL);
0344
0345
0346 if (da->manager_count > 2) {
0347 v = omap_hwmod_read(oh, DISPC_CONTROL2);
0348 v &= ~LCD_EN_MASK;
0349 omap_hwmod_write(v, oh, DISPC_CONTROL2);
0350 }
0351
0352
0353 if (da->manager_count > 3) {
0354 v = omap_hwmod_read(oh, DISPC_CONTROL3);
0355 v &= ~LCD_EN_MASK;
0356 omap_hwmod_write(v, oh, DISPC_CONTROL3);
0357 }
0358
0359 i = 0;
0360 while ((omap_hwmod_read(oh, DISPC_IRQSTATUS) & irq_mask) !=
0361 irq_mask) {
0362 i++;
0363 if (i > FRAMEDONE_IRQ_TIMEOUT) {
0364 pr_err("didn't get FRAMEDONE1/2/3 or TV interrupt\n");
0365 break;
0366 }
0367 mdelay(1);
0368 }
0369 }
0370
0371 int omap_dss_reset(struct omap_hwmod *oh)
0372 {
0373 struct omap_hwmod_opt_clk *oc;
0374 int c = 0;
0375 int i, r;
0376
0377 if (!(oh->class->sysc->sysc_flags & SYSS_HAS_RESET_STATUS)) {
0378 pr_err("dss_core: hwmod data doesn't contain reset data\n");
0379 return -EINVAL;
0380 }
0381
0382 for (i = oh->opt_clks_cnt, oc = oh->opt_clks; i > 0; i--, oc++)
0383 clk_prepare_enable(oc->_clk);
0384
0385 dispc_disable_outputs();
0386
0387
0388 if (cpu_is_omap3430()) {
0389 omap_hwmod_write(0x0, oh, DSS_SDI_CONTROL);
0390 omap_hwmod_write(0x0, oh, DSS_PLL_CONTROL);
0391 }
0392
0393
0394
0395
0396
0397 omap_hwmod_write(0x0, oh, DSS_CONTROL);
0398
0399 omap_test_timeout((omap_hwmod_read(oh, oh->class->sysc->syss_offs)
0400 & SYSS_RESETDONE_MASK),
0401 MAX_MODULE_SOFTRESET_WAIT, c);
0402
0403 if (c == MAX_MODULE_SOFTRESET_WAIT)
0404 pr_warn("dss_core: waiting for reset to finish failed\n");
0405 else
0406 pr_debug("dss_core: softreset done\n");
0407
0408 for (i = oh->opt_clks_cnt, oc = oh->opt_clks; i > 0; i--, oc++)
0409 clk_disable_unprepare(oc->_clk);
0410
0411 r = (c == MAX_MODULE_SOFTRESET_WAIT) ? -ETIMEDOUT : 0;
0412
0413 return r;
0414 }