diff options
Diffstat (limited to 'drivers/video/fsl-diu-fb.c')
-rw-r--r-- | drivers/video/fsl-diu-fb.c | 64 |
1 files changed, 36 insertions, 28 deletions
diff --git a/drivers/video/fsl-diu-fb.c b/drivers/video/fsl-diu-fb.c index 19cfd7a92563..41fbd9453c5f 100644 --- a/drivers/video/fsl-diu-fb.c +++ b/drivers/video/fsl-diu-fb.c | |||
@@ -944,7 +944,7 @@ static u32 fsl_diu_get_pixel_format(unsigned int bits_per_pixel) | |||
944 | #define PF_COMP_0_MASK 0x0000000F | 944 | #define PF_COMP_0_MASK 0x0000000F |
945 | #define PF_COMP_0_SHIFT 0 | 945 | #define PF_COMP_0_SHIFT 0 |
946 | 946 | ||
947 | #define MAKE_PF(alpha, red, blue, green, size, c0, c1, c2, c3) \ | 947 | #define MAKE_PF(alpha, red, green, blue, size, c0, c1, c2, c3) \ |
948 | cpu_to_le32(PF_BYTE_F | (alpha << PF_ALPHA_C_SHIFT) | \ | 948 | cpu_to_le32(PF_BYTE_F | (alpha << PF_ALPHA_C_SHIFT) | \ |
949 | (blue << PF_BLUE_C_SHIFT) | (green << PF_GREEN_C_SHIFT) | \ | 949 | (blue << PF_BLUE_C_SHIFT) | (green << PF_GREEN_C_SHIFT) | \ |
950 | (red << PF_RED_C_SHIFT) | (c3 << PF_COMP_3_SHIFT) | \ | 950 | (red << PF_RED_C_SHIFT) | (c3 << PF_COMP_3_SHIFT) | \ |
@@ -954,10 +954,10 @@ static u32 fsl_diu_get_pixel_format(unsigned int bits_per_pixel) | |||
954 | switch (bits_per_pixel) { | 954 | switch (bits_per_pixel) { |
955 | case 32: | 955 | case 32: |
956 | /* 0x88883316 */ | 956 | /* 0x88883316 */ |
957 | return MAKE_PF(3, 2, 0, 1, 3, 8, 8, 8, 8); | 957 | return MAKE_PF(3, 2, 1, 0, 3, 8, 8, 8, 8); |
958 | case 24: | 958 | case 24: |
959 | /* 0x88082219 */ | 959 | /* 0x88082219 */ |
960 | return MAKE_PF(4, 0, 1, 2, 2, 0, 8, 8, 8); | 960 | return MAKE_PF(4, 0, 1, 2, 2, 8, 8, 8, 0); |
961 | case 16: | 961 | case 16: |
962 | /* 0x65053118 */ | 962 | /* 0x65053118 */ |
963 | return MAKE_PF(4, 2, 1, 0, 1, 5, 6, 5, 0); | 963 | return MAKE_PF(4, 2, 1, 0, 1, 5, 6, 5, 0); |
@@ -1232,6 +1232,16 @@ static int fsl_diu_ioctl(struct fb_info *info, unsigned int cmd, | |||
1232 | return 0; | 1232 | return 0; |
1233 | } | 1233 | } |
1234 | 1234 | ||
1235 | static inline void fsl_diu_enable_interrupts(struct fsl_diu_data *data) | ||
1236 | { | ||
1237 | u32 int_mask = INT_UNDRUN; /* enable underrun detection */ | ||
1238 | |||
1239 | if (IS_ENABLED(CONFIG_NOT_COHERENT_CACHE)) | ||
1240 | int_mask |= INT_VSYNC; /* enable vertical sync */ | ||
1241 | |||
1242 | clrbits32(&data->diu_reg->int_mask, int_mask); | ||
1243 | } | ||
1244 | |||
1235 | /* turn on fb if count == 1 | 1245 | /* turn on fb if count == 1 |
1236 | */ | 1246 | */ |
1237 | static int fsl_diu_open(struct fb_info *info, int user) | 1247 | static int fsl_diu_open(struct fb_info *info, int user) |
@@ -1251,19 +1261,7 @@ static int fsl_diu_open(struct fb_info *info, int user) | |||
1251 | if (res < 0) | 1261 | if (res < 0) |
1252 | mfbi->count--; | 1262 | mfbi->count--; |
1253 | else { | 1263 | else { |
1254 | struct fsl_diu_data *data = mfbi->parent; | 1264 | fsl_diu_enable_interrupts(mfbi->parent); |
1255 | |||
1256 | #ifdef CONFIG_NOT_COHERENT_CACHE | ||
1257 | /* | ||
1258 | * Enable underrun detection and vertical sync | ||
1259 | * interrupts. | ||
1260 | */ | ||
1261 | clrbits32(&data->diu_reg->int_mask, | ||
1262 | INT_UNDRUN | INT_VSYNC); | ||
1263 | #else | ||
1264 | /* Enable underrun detection */ | ||
1265 | clrbits32(&data->diu_reg->int_mask, INT_UNDRUN); | ||
1266 | #endif | ||
1267 | fsl_diu_enable_panel(info); | 1265 | fsl_diu_enable_panel(info); |
1268 | } | 1266 | } |
1269 | } | 1267 | } |
@@ -1283,9 +1281,18 @@ static int fsl_diu_release(struct fb_info *info, int user) | |||
1283 | mfbi->count--; | 1281 | mfbi->count--; |
1284 | if (mfbi->count == 0) { | 1282 | if (mfbi->count == 0) { |
1285 | struct fsl_diu_data *data = mfbi->parent; | 1283 | struct fsl_diu_data *data = mfbi->parent; |
1284 | bool disable = true; | ||
1285 | int i; | ||
1286 | 1286 | ||
1287 | /* Disable interrupts */ | 1287 | /* Disable interrupts only if all AOIs are closed */ |
1288 | out_be32(&data->diu_reg->int_mask, 0xffffffff); | 1288 | for (i = 0; i < NUM_AOIS; i++) { |
1289 | struct mfb_info *mi = data->fsl_diu_info[i].par; | ||
1290 | |||
1291 | if (mi->count) | ||
1292 | disable = false; | ||
1293 | } | ||
1294 | if (disable) | ||
1295 | out_be32(&data->diu_reg->int_mask, 0xffffffff); | ||
1289 | fsl_diu_disable_panel(info); | 1296 | fsl_diu_disable_panel(info); |
1290 | } | 1297 | } |
1291 | 1298 | ||
@@ -1614,14 +1621,6 @@ static int fsl_diu_probe(struct platform_device *pdev) | |||
1614 | out_be32(&data->diu_reg->desc[1], data->dummy_ad.paddr); | 1621 | out_be32(&data->diu_reg->desc[1], data->dummy_ad.paddr); |
1615 | out_be32(&data->diu_reg->desc[2], data->dummy_ad.paddr); | 1622 | out_be32(&data->diu_reg->desc[2], data->dummy_ad.paddr); |
1616 | 1623 | ||
1617 | for (i = 0; i < NUM_AOIS; i++) { | ||
1618 | ret = install_fb(&data->fsl_diu_info[i]); | ||
1619 | if (ret) { | ||
1620 | dev_err(&pdev->dev, "could not register fb %d\n", i); | ||
1621 | goto error; | ||
1622 | } | ||
1623 | } | ||
1624 | |||
1625 | /* | 1624 | /* |
1626 | * Older versions of U-Boot leave interrupts enabled, so disable | 1625 | * Older versions of U-Boot leave interrupts enabled, so disable |
1627 | * all of them and clear the status register. | 1626 | * all of them and clear the status register. |
@@ -1630,12 +1629,21 @@ static int fsl_diu_probe(struct platform_device *pdev) | |||
1630 | in_be32(&data->diu_reg->int_status); | 1629 | in_be32(&data->diu_reg->int_status); |
1631 | 1630 | ||
1632 | ret = request_irq(data->irq, fsl_diu_isr, 0, "fsl-diu-fb", | 1631 | ret = request_irq(data->irq, fsl_diu_isr, 0, "fsl-diu-fb", |
1633 | &data->diu_reg); | 1632 | data->diu_reg); |
1634 | if (ret) { | 1633 | if (ret) { |
1635 | dev_err(&pdev->dev, "could not claim irq\n"); | 1634 | dev_err(&pdev->dev, "could not claim irq\n"); |
1636 | goto error; | 1635 | goto error; |
1637 | } | 1636 | } |
1638 | 1637 | ||
1638 | for (i = 0; i < NUM_AOIS; i++) { | ||
1639 | ret = install_fb(&data->fsl_diu_info[i]); | ||
1640 | if (ret) { | ||
1641 | dev_err(&pdev->dev, "could not register fb %d\n", i); | ||
1642 | free_irq(data->irq, data->diu_reg); | ||
1643 | goto error; | ||
1644 | } | ||
1645 | } | ||
1646 | |||
1639 | sysfs_attr_init(&data->dev_attr.attr); | 1647 | sysfs_attr_init(&data->dev_attr.attr); |
1640 | data->dev_attr.attr.name = "monitor"; | 1648 | data->dev_attr.attr.name = "monitor"; |
1641 | data->dev_attr.attr.mode = S_IRUGO|S_IWUSR; | 1649 | data->dev_attr.attr.mode = S_IRUGO|S_IWUSR; |
@@ -1667,7 +1675,7 @@ static int fsl_diu_remove(struct platform_device *pdev) | |||
1667 | data = dev_get_drvdata(&pdev->dev); | 1675 | data = dev_get_drvdata(&pdev->dev); |
1668 | disable_lcdc(&data->fsl_diu_info[0]); | 1676 | disable_lcdc(&data->fsl_diu_info[0]); |
1669 | 1677 | ||
1670 | free_irq(data->irq, &data->diu_reg); | 1678 | free_irq(data->irq, data->diu_reg); |
1671 | 1679 | ||
1672 | for (i = 0; i < NUM_AOIS; i++) | 1680 | for (i = 0; i < NUM_AOIS; i++) |
1673 | uninstall_fb(&data->fsl_diu_info[i]); | 1681 | uninstall_fb(&data->fsl_diu_info[i]); |