diff options
author | Liu Ying <Ying.Liu@freescale.com> | 2014-03-10 05:30:15 -0400 |
---|---|---|
committer | Nitin Garg <nitin.garg@freescale.com> | 2014-04-16 09:57:56 -0400 |
commit | 76d39a3901c9fb63d554137c23b10be76c6118f6 (patch) | |
tree | 692e1e1864958907e13da4cf3598c1f620c41be6 | |
parent | 839479a02802a4d3493bb01790f812f01f898a38 (diff) |
ENGR00302472-3 video: mxc: Introduce CRTC concept
As the mxc display system is getting more and more complex, various
CRTCs(CRT controllers), such as IPUx DIy and LCDIFz, may drive
various encoders. For example, imx6sx/imx6dl LCDIF may drive LDB
while imx6dl IPU0 DI0/1 may drive LDB as well. This patch introduces
CRTC concept to the display framework so that the core logic could be
less IPU specific.
Signed-off-by: Liu Ying <Ying.Liu@freescale.com>
-rw-r--r-- | drivers/video/mxc/crtc.h | 57 | ||||
-rw-r--r-- | drivers/video/mxc/ldb.c | 69 | ||||
-rw-r--r-- | drivers/video/mxc/mipi_dsi.c | 9 | ||||
-rw-r--r-- | drivers/video/mxc/mipi_dsi.h | 3 | ||||
-rw-r--r-- | drivers/video/mxc/mxc_dispdrv.c | 6 | ||||
-rw-r--r-- | drivers/video/mxc/mxc_dispdrv.h | 8 | ||||
-rw-r--r-- | drivers/video/mxc/mxc_hdmi.c | 7 | ||||
-rw-r--r-- | drivers/video/mxc/mxc_ipuv3_fb.c | 27 | ||||
-rw-r--r-- | drivers/video/mxc/mxc_lcdif.c | 12 |
9 files changed, 142 insertions, 56 deletions
diff --git a/drivers/video/mxc/crtc.h b/drivers/video/mxc/crtc.h new file mode 100644 index 000000000000..8bd1c1b95bd1 --- /dev/null +++ b/drivers/video/mxc/crtc.h | |||
@@ -0,0 +1,57 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2014 Freescale Semiconductor, Inc. All Rights Reserved. | ||
3 | */ | ||
4 | |||
5 | /* | ||
6 | * The code contained herein is licensed under the GNU General Public | ||
7 | * License. You may obtain a copy of the GNU General Public License | ||
8 | * Version 2 or later at the following locations: | ||
9 | * | ||
10 | * http://www.opensource.org/licenses/gpl-license.html | ||
11 | * http://www.gnu.org/copyleft/gpl.html | ||
12 | */ | ||
13 | #ifndef __CRTC__ | ||
14 | #define __CRTC__ | ||
15 | |||
16 | enum crtc { | ||
17 | CRTC_IPU_DI0, | ||
18 | CRTC_IPU_DI1, | ||
19 | CRTC_IPU1_DI0, | ||
20 | CRTC_IPU1_DI1, | ||
21 | CRTC_IPU2_DI0, | ||
22 | CRTC_IPU2_DI1, | ||
23 | CRTC_LCDIF, | ||
24 | CRTC_LCDIF1, | ||
25 | CRTC_LCDIF2, | ||
26 | CRTC_MAX, | ||
27 | }; | ||
28 | |||
29 | struct ipu_di_crtc_map { | ||
30 | enum crtc crtc; | ||
31 | int ipu_id; | ||
32 | int ipu_di; | ||
33 | }; | ||
34 | |||
35 | static const struct ipu_di_crtc_map ipu_di_crtc_maps[] = { | ||
36 | {CRTC_IPU1_DI0, 0 , 0}, {CRTC_IPU1_DI1, 0 , 1}, | ||
37 | {CRTC_IPU2_DI0, 1 , 0}, {CRTC_IPU2_DI1, 1 , 1}, | ||
38 | }; | ||
39 | |||
40 | static inline int ipu_di_to_crtc(struct device *dev, int ipu_id, | ||
41 | int ipu_di, enum crtc *crtc) | ||
42 | { | ||
43 | int i = 0; | ||
44 | |||
45 | for (; i < ARRAY_SIZE(ipu_di_crtc_maps); i++) | ||
46 | if (ipu_di_crtc_maps[i].ipu_id == ipu_id && | ||
47 | ipu_di_crtc_maps[i].ipu_di == ipu_di) { | ||
48 | *crtc = ipu_di_crtc_maps[i].crtc; | ||
49 | return 0; | ||
50 | } | ||
51 | |||
52 | dev_err(dev, "failed to get valid ipu di crtc " | ||
53 | "ipu_id %d, ipu_di %d\n", ipu_id, ipu_di); | ||
54 | return -EINVAL; | ||
55 | } | ||
56 | |||
57 | #endif | ||
diff --git a/drivers/video/mxc/ldb.c b/drivers/video/mxc/ldb.c index 2c7d647cc89c..8e9f26011146 100644 --- a/drivers/video/mxc/ldb.c +++ b/drivers/video/mxc/ldb.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2012-2013 Freescale Semiconductor, Inc. All Rights Reserved. | 2 | * Copyright (C) 2012-2014 Freescale Semiconductor, Inc. All Rights Reserved. |
3 | */ | 3 | */ |
4 | 4 | ||
5 | /* | 5 | /* |
@@ -529,7 +529,7 @@ static int ldb_ipu_ldb_route(int ipu, int di, struct ldb_data *ldb) | |||
529 | static int ldb_disp_init(struct mxc_dispdrv_handle *disp, | 529 | static int ldb_disp_init(struct mxc_dispdrv_handle *disp, |
530 | struct mxc_dispdrv_setting *setting) | 530 | struct mxc_dispdrv_setting *setting) |
531 | { | 531 | { |
532 | int ret = 0, i, lvds_channel = 0; | 532 | int ret = 0, i, lvds_channel = 0, dev_id, ipu_di; |
533 | struct ldb_data *ldb = mxc_dispdrv_getdata(disp); | 533 | struct ldb_data *ldb = mxc_dispdrv_getdata(disp); |
534 | struct fsl_mxc_ldb_platform_data *plat_data = ldb->pdev->dev.platform_data; | 534 | struct fsl_mxc_ldb_platform_data *plat_data = ldb->pdev->dev.platform_data; |
535 | struct resource *res; | 535 | struct resource *res; |
@@ -563,7 +563,7 @@ static int ldb_disp_init(struct mxc_dispdrv_handle *disp, | |||
563 | ldb->gpr3_reg = ldb->reg + 3; | 563 | ldb->gpr3_reg = ldb->reg + 3; |
564 | 564 | ||
565 | /* ipu selected by platform data setting */ | 565 | /* ipu selected by platform data setting */ |
566 | setting->dev_id = plat_data->ipu_id; | 566 | dev_id = plat_data->ipu_id; |
567 | 567 | ||
568 | reg = readl(ldb->control_reg); | 568 | reg = readl(ldb->control_reg); |
569 | 569 | ||
@@ -628,23 +628,23 @@ static int ldb_disp_init(struct mxc_dispdrv_handle *disp, | |||
628 | if (ldb->mode == LDB_SPL_DI0) { | 628 | if (ldb->mode == LDB_SPL_DI0) { |
629 | reg |= LDB_SPLIT_MODE_EN | LDB_CH0_MODE_EN_TO_DI0 | 629 | reg |= LDB_SPLIT_MODE_EN | LDB_CH0_MODE_EN_TO_DI0 |
630 | | LDB_CH1_MODE_EN_TO_DI0; | 630 | | LDB_CH1_MODE_EN_TO_DI0; |
631 | setting->disp_id = 0; | 631 | ipu_di = 0; |
632 | } else if (ldb->mode == LDB_SPL_DI1) { | 632 | } else if (ldb->mode == LDB_SPL_DI1) { |
633 | reg |= LDB_SPLIT_MODE_EN | LDB_CH0_MODE_EN_TO_DI1 | 633 | reg |= LDB_SPLIT_MODE_EN | LDB_CH0_MODE_EN_TO_DI1 |
634 | | LDB_CH1_MODE_EN_TO_DI1; | 634 | | LDB_CH1_MODE_EN_TO_DI1; |
635 | setting->disp_id = 1; | 635 | ipu_di = 1; |
636 | } else if (ldb->mode == LDB_DUL_DI0) { | 636 | } else if (ldb->mode == LDB_DUL_DI0) { |
637 | reg &= ~LDB_SPLIT_MODE_EN; | 637 | reg &= ~LDB_SPLIT_MODE_EN; |
638 | reg |= LDB_CH0_MODE_EN_TO_DI0 | LDB_CH1_MODE_EN_TO_DI0; | 638 | reg |= LDB_CH0_MODE_EN_TO_DI0 | LDB_CH1_MODE_EN_TO_DI0; |
639 | setting->disp_id = 0; | 639 | ipu_di = 0; |
640 | } else if (ldb->mode == LDB_DUL_DI1) { | 640 | } else if (ldb->mode == LDB_DUL_DI1) { |
641 | reg &= ~LDB_SPLIT_MODE_EN; | 641 | reg &= ~LDB_SPLIT_MODE_EN; |
642 | reg |= LDB_CH0_MODE_EN_TO_DI1 | LDB_CH1_MODE_EN_TO_DI1; | 642 | reg |= LDB_CH0_MODE_EN_TO_DI1 | LDB_CH1_MODE_EN_TO_DI1; |
643 | setting->disp_id = 1; | 643 | ipu_di = 1; |
644 | } else if (ldb->mode == LDB_SIN0) { | 644 | } else if (ldb->mode == LDB_SIN0) { |
645 | reg &= ~LDB_SPLIT_MODE_EN; | 645 | reg &= ~LDB_SPLIT_MODE_EN; |
646 | setting->disp_id = plat_data->disp_id; | 646 | ipu_di = plat_data->disp_id; |
647 | if (setting->disp_id == 0) | 647 | if (ipu_di == 0) |
648 | reg |= LDB_CH0_MODE_EN_TO_DI0; | 648 | reg |= LDB_CH0_MODE_EN_TO_DI0; |
649 | else | 649 | else |
650 | reg |= LDB_CH0_MODE_EN_TO_DI1; | 650 | reg |= LDB_CH0_MODE_EN_TO_DI1; |
@@ -652,15 +652,15 @@ static int ldb_disp_init(struct mxc_dispdrv_handle *disp, | |||
652 | ch_val = reg & LDB_CH0_MODE_MASK; | 652 | ch_val = reg & LDB_CH0_MODE_MASK; |
653 | } else if (ldb->mode == LDB_SIN1) { | 653 | } else if (ldb->mode == LDB_SIN1) { |
654 | reg &= ~LDB_SPLIT_MODE_EN; | 654 | reg &= ~LDB_SPLIT_MODE_EN; |
655 | setting->disp_id = plat_data->disp_id; | 655 | ipu_di = plat_data->disp_id; |
656 | if (setting->disp_id == 0) | 656 | if (ipu_di == 0) |
657 | reg |= LDB_CH1_MODE_EN_TO_DI0; | 657 | reg |= LDB_CH1_MODE_EN_TO_DI0; |
658 | else | 658 | else |
659 | reg |= LDB_CH1_MODE_EN_TO_DI1; | 659 | reg |= LDB_CH1_MODE_EN_TO_DI1; |
660 | ch_mask = LDB_CH1_MODE_MASK; | 660 | ch_mask = LDB_CH1_MODE_MASK; |
661 | ch_val = reg & LDB_CH1_MODE_MASK; | 661 | ch_val = reg & LDB_CH1_MODE_MASK; |
662 | } else { /* separate mode*/ | 662 | } else { /* separate mode*/ |
663 | setting->disp_id = plat_data->disp_id; | 663 | ipu_di = plat_data->disp_id; |
664 | 664 | ||
665 | /* first output is LVDS0 or LVDS1 */ | 665 | /* first output is LVDS0 or LVDS1 */ |
666 | if (ldb->mode == LDB_SEP0) | 666 | if (ldb->mode == LDB_SEP0) |
@@ -670,11 +670,11 @@ static int ldb_disp_init(struct mxc_dispdrv_handle *disp, | |||
670 | 670 | ||
671 | reg &= ~LDB_SPLIT_MODE_EN; | 671 | reg &= ~LDB_SPLIT_MODE_EN; |
672 | 672 | ||
673 | if ((lvds_channel == 0) && (setting->disp_id == 0)) | 673 | if ((lvds_channel == 0) && (ipu_di == 0)) |
674 | reg |= LDB_CH0_MODE_EN_TO_DI0; | 674 | reg |= LDB_CH0_MODE_EN_TO_DI0; |
675 | else if ((lvds_channel == 0) && (setting->disp_id == 1)) | 675 | else if ((lvds_channel == 0) && (ipu_di == 1)) |
676 | reg |= LDB_CH0_MODE_EN_TO_DI1; | 676 | reg |= LDB_CH0_MODE_EN_TO_DI1; |
677 | else if ((lvds_channel == 1) && (setting->disp_id == 0)) | 677 | else if ((lvds_channel == 1) && (ipu_di == 0)) |
678 | reg |= LDB_CH1_MODE_EN_TO_DI0; | 678 | reg |= LDB_CH1_MODE_EN_TO_DI0; |
679 | else | 679 | else |
680 | reg |= LDB_CH1_MODE_EN_TO_DI1; | 680 | reg |= LDB_CH1_MODE_EN_TO_DI1; |
@@ -714,13 +714,13 @@ static int ldb_disp_init(struct mxc_dispdrv_handle *disp, | |||
714 | 714 | ||
715 | setting_idx = 1; | 715 | setting_idx = 1; |
716 | if (is_imx6_ldb(plat_data)) { | 716 | if (is_imx6_ldb(plat_data)) { |
717 | setting->dev_id = plat_data->sec_ipu_id; | 717 | dev_id = plat_data->sec_ipu_id; |
718 | setting->disp_id = plat_data->sec_disp_id; | 718 | ipu_di = plat_data->sec_disp_id; |
719 | } else { | 719 | } else { |
720 | setting->dev_id = plat_data->ipu_id; | 720 | dev_id = plat_data->ipu_id; |
721 | setting->disp_id = !plat_data->disp_id; | 721 | ipu_di = !plat_data->disp_id; |
722 | } | 722 | } |
723 | if (setting->disp_id == ldb->setting[0].di) { | 723 | if (ipu_di == ldb->setting[0].di) { |
724 | dev_err(&ldb->pdev->dev, "Err: for second ldb disp in" | 724 | dev_err(&ldb->pdev->dev, "Err: for second ldb disp in" |
725 | "separate mode, DI should be different!\n"); | 725 | "separate mode, DI should be different!\n"); |
726 | return -EINVAL; | 726 | return -EINVAL; |
@@ -733,11 +733,11 @@ static int ldb_disp_init(struct mxc_dispdrv_handle *disp, | |||
733 | lvds_channel = 0; | 733 | lvds_channel = 0; |
734 | 734 | ||
735 | reg = readl(ldb->control_reg); | 735 | reg = readl(ldb->control_reg); |
736 | if ((lvds_channel == 0) && (setting->disp_id == 0)) | 736 | if ((lvds_channel == 0) && (ipu_di == 0)) |
737 | reg |= LDB_CH0_MODE_EN_TO_DI0; | 737 | reg |= LDB_CH0_MODE_EN_TO_DI0; |
738 | else if ((lvds_channel == 0) && (setting->disp_id == 1)) | 738 | else if ((lvds_channel == 0) && (ipu_di == 1)) |
739 | reg |= LDB_CH0_MODE_EN_TO_DI1; | 739 | reg |= LDB_CH0_MODE_EN_TO_DI1; |
740 | else if ((lvds_channel == 1) && (setting->disp_id == 0)) | 740 | else if ((lvds_channel == 1) && (ipu_di == 0)) |
741 | reg |= LDB_CH1_MODE_EN_TO_DI0; | 741 | reg |= LDB_CH1_MODE_EN_TO_DI0; |
742 | else | 742 | else |
743 | reg |= LDB_CH1_MODE_EN_TO_DI1; | 743 | reg |= LDB_CH1_MODE_EN_TO_DI1; |
@@ -767,10 +767,10 @@ static int ldb_disp_init(struct mxc_dispdrv_handle *disp, | |||
767 | div_7_clk[2] += lvds_channel; | 767 | div_7_clk[2] += lvds_channel; |
768 | div_sel_clk[2] += lvds_channel; | 768 | div_sel_clk[2] += lvds_channel; |
769 | } else { | 769 | } else { |
770 | ldb_clk[6] += setting->disp_id; | 770 | ldb_clk[6] += ipu_di; |
771 | div_3_5_clk[2] += setting->disp_id; | 771 | div_3_5_clk[2] += ipu_di; |
772 | div_7_clk[2] += setting->disp_id; | 772 | div_7_clk[2] += ipu_di; |
773 | div_sel_clk[2] += setting->disp_id; | 773 | div_sel_clk[2] += ipu_di; |
774 | } | 774 | } |
775 | ldb->setting[setting_idx].ldb_di_clk = clk_get(&ldb->pdev->dev, | 775 | ldb->setting[setting_idx].ldb_di_clk = clk_get(&ldb->pdev->dev, |
776 | ldb_clk); | 776 | ldb_clk); |
@@ -799,8 +799,8 @@ static int ldb_disp_init(struct mxc_dispdrv_handle *disp, | |||
799 | return PTR_ERR(ldb->setting[setting_idx].div_sel_clk); | 799 | return PTR_ERR(ldb->setting[setting_idx].div_sel_clk); |
800 | } | 800 | } |
801 | 801 | ||
802 | di_clk[3] += setting->dev_id; | 802 | di_clk[3] += dev_id; |
803 | di_clk[7] += setting->disp_id; | 803 | di_clk[7] += ipu_di; |
804 | ldb->setting[setting_idx].di_clk = clk_get(&ldb->pdev->dev, | 804 | ldb->setting[setting_idx].di_clk = clk_get(&ldb->pdev->dev, |
805 | di_clk); | 805 | di_clk); |
806 | if (IS_ERR(ldb->setting[setting_idx].di_clk)) { | 806 | if (IS_ERR(ldb->setting[setting_idx].di_clk)) { |
@@ -812,7 +812,7 @@ static int ldb_disp_init(struct mxc_dispdrv_handle *disp, | |||
812 | ldb->setting[setting_idx].ch_val = ch_val; | 812 | ldb->setting[setting_idx].ch_val = ch_val; |
813 | 813 | ||
814 | if (is_imx6_ldb(plat_data)) | 814 | if (is_imx6_ldb(plat_data)) |
815 | ldb_ipu_ldb_route(setting->dev_id, setting->disp_id, ldb); | 815 | ldb_ipu_ldb_route(dev_id, ipu_di, ldb); |
816 | 816 | ||
817 | /* must use spec video mode defined by driver */ | 817 | /* must use spec video mode defined by driver */ |
818 | ret = fb_find_mode(&setting->fbi->var, setting->fbi, setting->dft_mode_str, | 818 | ret = fb_find_mode(&setting->fbi->var, setting->fbi, setting->dft_mode_str, |
@@ -831,8 +831,13 @@ static int ldb_disp_init(struct mxc_dispdrv_handle *disp, | |||
831 | } | 831 | } |
832 | } | 832 | } |
833 | 833 | ||
834 | ldb->setting[setting_idx].ipu = setting->dev_id; | 834 | ret = ipu_di_to_crtc(&ldb->pdev->dev, dev_id, |
835 | ldb->setting[setting_idx].di = setting->disp_id; | 835 | ipu_di, &setting->crtc); |
836 | if (ret < 0) | ||
837 | return ret; | ||
838 | |||
839 | ldb->setting[setting_idx].ipu = dev_id; | ||
840 | ldb->setting[setting_idx].di = ipu_di; | ||
836 | 841 | ||
837 | return ret; | 842 | return ret; |
838 | } | 843 | } |
diff --git a/drivers/video/mxc/mipi_dsi.c b/drivers/video/mxc/mipi_dsi.c index 8517d2ff7302..53741c31e711 100644 --- a/drivers/video/mxc/mipi_dsi.c +++ b/drivers/video/mxc/mipi_dsi.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved. | 2 | * Copyright (C) 2011-2014 Freescale Semiconductor, Inc. All Rights Reserved. |
3 | * | 3 | * |
4 | * This program is free software; you can redistribute it and/or modify | 4 | * This program is free software; you can redistribute it and/or modify |
5 | * it under the terms of the GNU General Public License as published by | 5 | * it under the terms of the GNU General Public License as published by |
@@ -38,7 +38,6 @@ | |||
38 | #include <linux/delay.h> | 38 | #include <linux/delay.h> |
39 | #include <video/mipi_display.h> | 39 | #include <video/mipi_display.h> |
40 | 40 | ||
41 | #include "mxc_dispdrv.h" | ||
42 | #include "mipi_dsi.h" | 41 | #include "mipi_dsi.h" |
43 | 42 | ||
44 | #define DISPDRV_MIPI "mipi_dsi" | 43 | #define DISPDRV_MIPI "mipi_dsi" |
@@ -666,8 +665,10 @@ static int mipi_dsi_disp_init(struct mxc_dispdrv_handle *disp, | |||
666 | setting->if_fmt = IPU_PIX_FMT_RGB24; | 665 | setting->if_fmt = IPU_PIX_FMT_RGB24; |
667 | } | 666 | } |
668 | 667 | ||
669 | setting->dev_id = mipi_dsi->dev_id; | 668 | ret = ipu_di_to_crtc(dev, mipi_dsi->dev_id, |
670 | setting->disp_id = mipi_dsi->disp_id; | 669 | mipi_dsi->disp_id, &setting->crtc); |
670 | if (ret < 0) | ||
671 | return ret; | ||
671 | 672 | ||
672 | ret = mipi_dsi_lcd_init(mipi_dsi, setting); | 673 | ret = mipi_dsi_lcd_init(mipi_dsi, setting); |
673 | if (ret) { | 674 | if (ret) { |
diff --git a/drivers/video/mxc/mipi_dsi.h b/drivers/video/mxc/mipi_dsi.h index 098dea8f6d7f..a7145a583718 100644 --- a/drivers/video/mxc/mipi_dsi.h +++ b/drivers/video/mxc/mipi_dsi.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved. | 2 | * Copyright (C) 2011-2014 Freescale Semiconductor, Inc. All Rights Reserved. |
3 | * | 3 | * |
4 | * This program is free software; you can redistribute it and/or modify | 4 | * This program is free software; you can redistribute it and/or modify |
5 | * it under the terms of the GNU General Public License as published by | 5 | * it under the terms of the GNU General Public License as published by |
@@ -20,6 +20,7 @@ | |||
20 | #define __MIPI_DSI_H__ | 20 | #define __MIPI_DSI_H__ |
21 | 21 | ||
22 | #include <linux/regmap.h> | 22 | #include <linux/regmap.h> |
23 | #include "mxc_dispdrv.h" | ||
23 | 24 | ||
24 | #ifdef DEBUG | 25 | #ifdef DEBUG |
25 | #define mipi_dbg(fmt, ...) printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__) | 26 | #define mipi_dbg(fmt, ...) printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__) |
diff --git a/drivers/video/mxc/mxc_dispdrv.c b/drivers/video/mxc/mxc_dispdrv.c index 5193c7deef00..def260f7841b 100644 --- a/drivers/video/mxc/mxc_dispdrv.c +++ b/drivers/video/mxc/mxc_dispdrv.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved. | 2 | * Copyright (C) 2011-2014 Freescale Semiconductor, Inc. All Rights Reserved. |
3 | */ | 3 | */ |
4 | 4 | ||
5 | /* | 5 | /* |
@@ -24,10 +24,10 @@ | |||
24 | * Move all dev_suspend() things into fb_notifier for SUSPEND, if there is; | 24 | * Move all dev_suspend() things into fb_notifier for SUSPEND, if there is; |
25 | * Move all dev_resume() things into fb_notifier for RESUME, if there is; | 25 | * Move all dev_resume() things into fb_notifier for RESUME, if there is; |
26 | * | 26 | * |
27 | * ipuv3 fb driver could call mxc_dispdrv_gethandle(name, setting) before a fb | 27 | * mxc fb driver could call mxc_dispdrv_gethandle(name, setting) before a fb |
28 | * need be added, with fbi param passing by setting, after | 28 | * need be added, with fbi param passing by setting, after |
29 | * mxc_dispdrv_gethandle() return, FB driver should get the basic setting | 29 | * mxc_dispdrv_gethandle() return, FB driver should get the basic setting |
30 | * about fbi info and ipuv3-hw (ipu_id and disp_id). | 30 | * about fbi info and crtc. |
31 | * | 31 | * |
32 | * @ingroup Framebuffer | 32 | * @ingroup Framebuffer |
33 | */ | 33 | */ |
diff --git a/drivers/video/mxc/mxc_dispdrv.h b/drivers/video/mxc/mxc_dispdrv.h index 127fd08ea391..c2ee2ca0f01e 100644 --- a/drivers/video/mxc/mxc_dispdrv.h +++ b/drivers/video/mxc/mxc_dispdrv.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved. | 2 | * Copyright (C) 2011-2014 Freescale Semiconductor, Inc. All Rights Reserved. |
3 | */ | 3 | */ |
4 | 4 | ||
5 | /* | 5 | /* |
@@ -13,6 +13,7 @@ | |||
13 | #ifndef __MXC_DISPDRV_H__ | 13 | #ifndef __MXC_DISPDRV_H__ |
14 | #define __MXC_DISPDRV_H__ | 14 | #define __MXC_DISPDRV_H__ |
15 | #include <linux/fb.h> | 15 | #include <linux/fb.h> |
16 | #include "crtc.h" | ||
16 | 17 | ||
17 | struct mxc_dispdrv_handle { | 18 | struct mxc_dispdrv_handle { |
18 | struct mxc_dispdrv_driver *drv; | 19 | struct mxc_dispdrv_driver *drv; |
@@ -25,9 +26,8 @@ struct mxc_dispdrv_setting { | |||
25 | int default_bpp; | 26 | int default_bpp; |
26 | char *dft_mode_str; | 27 | char *dft_mode_str; |
27 | 28 | ||
28 | /*feedback parameter*/ | 29 | /* feedback parameter */ |
29 | int dev_id; | 30 | enum crtc crtc; |
30 | int disp_id; | ||
31 | }; | 31 | }; |
32 | 32 | ||
33 | struct mxc_dispdrv_driver { | 33 | struct mxc_dispdrv_driver { |
diff --git a/drivers/video/mxc/mxc_hdmi.c b/drivers/video/mxc/mxc_hdmi.c index bf20720d1452..2c072bdacda8 100644 --- a/drivers/video/mxc/mxc_hdmi.c +++ b/drivers/video/mxc/mxc_hdmi.c | |||
@@ -2473,8 +2473,11 @@ static int mxc_hdmi_disp_init(struct mxc_dispdrv_handle *disp, | |||
2473 | /* Setting HDMI default to blank state */ | 2473 | /* Setting HDMI default to blank state */ |
2474 | hdmi->blank = FB_BLANK_POWERDOWN; | 2474 | hdmi->blank = FB_BLANK_POWERDOWN; |
2475 | 2475 | ||
2476 | setting->dev_id = mxc_hdmi_ipu_id; | 2476 | ret = ipu_di_to_crtc(&hdmi->pdev->dev, mxc_hdmi_ipu_id, |
2477 | setting->disp_id = mxc_hdmi_disp_id; | 2477 | mxc_hdmi_disp_id, &setting->crtc); |
2478 | if (ret < 0) | ||
2479 | return ret; | ||
2480 | |||
2478 | setting->if_fmt = IPU_PIX_FMT_RGB24; | 2481 | setting->if_fmt = IPU_PIX_FMT_RGB24; |
2479 | 2482 | ||
2480 | hdmi->dft_mode_str = setting->dft_mode_str; | 2483 | hdmi->dft_mode_str = setting->dft_mode_str; |
diff --git a/drivers/video/mxc/mxc_ipuv3_fb.c b/drivers/video/mxc/mxc_ipuv3_fb.c index 49abe8c284fc..954cbf1e3d52 100644 --- a/drivers/video/mxc/mxc_ipuv3_fb.c +++ b/drivers/video/mxc/mxc_ipuv3_fb.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright 2004-2013 Freescale Semiconductor, Inc. All Rights Reserved. | 2 | * Copyright 2004-2014 Freescale Semiconductor, Inc. All Rights Reserved. |
3 | */ | 3 | */ |
4 | 4 | ||
5 | /* | 5 | /* |
@@ -1889,6 +1889,22 @@ static ssize_t show_disp_dev(struct device *dev, | |||
1889 | } | 1889 | } |
1890 | static DEVICE_ATTR(fsl_disp_dev_property, S_IRUGO, show_disp_dev, NULL); | 1890 | static DEVICE_ATTR(fsl_disp_dev_property, S_IRUGO, show_disp_dev, NULL); |
1891 | 1891 | ||
1892 | static int mxcfb_get_crtc(struct device *dev, struct mxcfb_info *mxcfbi, | ||
1893 | enum crtc crtc) | ||
1894 | { | ||
1895 | int i = 0; | ||
1896 | |||
1897 | for (; i < ARRAY_SIZE(ipu_di_crtc_maps); i++) | ||
1898 | if (ipu_di_crtc_maps[i].crtc == crtc) { | ||
1899 | mxcfbi->ipu_id = ipu_di_crtc_maps[i].ipu_id; | ||
1900 | mxcfbi->ipu_di = ipu_di_crtc_maps[i].ipu_di; | ||
1901 | return 0; | ||
1902 | } | ||
1903 | |||
1904 | dev_err(dev, "failed to get valid crtc\n"); | ||
1905 | return -EINVAL; | ||
1906 | } | ||
1907 | |||
1892 | static int mxcfb_dispdrv_init(struct platform_device *pdev, | 1908 | static int mxcfb_dispdrv_init(struct platform_device *pdev, |
1893 | struct fb_info *fbi) | 1909 | struct fb_info *fbi) |
1894 | { | 1910 | { |
@@ -1925,12 +1941,13 @@ static int mxcfb_dispdrv_init(struct platform_device *pdev, | |||
1925 | mxcfbi->ipu_di_pix_fmt = setting.if_fmt; | 1941 | mxcfbi->ipu_di_pix_fmt = setting.if_fmt; |
1926 | mxcfbi->default_bpp = setting.default_bpp; | 1942 | mxcfbi->default_bpp = setting.default_bpp; |
1927 | 1943 | ||
1928 | /* setting */ | 1944 | ret = mxcfb_get_crtc(&pdev->dev, mxcfbi, setting.crtc); |
1929 | mxcfbi->ipu_id = setting.dev_id; | 1945 | if (ret) |
1930 | mxcfbi->ipu_di = setting.disp_id; | 1946 | return ret; |
1947 | |||
1931 | dev_dbg(&pdev->dev, "di_pixfmt:0x%x, bpp:0x%x, di:%d, ipu:%d\n", | 1948 | dev_dbg(&pdev->dev, "di_pixfmt:0x%x, bpp:0x%x, di:%d, ipu:%d\n", |
1932 | setting.if_fmt, setting.default_bpp, | 1949 | setting.if_fmt, setting.default_bpp, |
1933 | setting.disp_id, setting.dev_id); | 1950 | mxcfbi->ipu_di, mxcfbi->ipu_id); |
1934 | } | 1951 | } |
1935 | 1952 | ||
1936 | return ret; | 1953 | return ret; |
diff --git a/drivers/video/mxc/mxc_lcdif.c b/drivers/video/mxc/mxc_lcdif.c index a0cca1c347fb..d635eddbef70 100644 --- a/drivers/video/mxc/mxc_lcdif.c +++ b/drivers/video/mxc/mxc_lcdif.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved. | 2 | * Copyright (C) 2011-2014 Freescale Semiconductor, Inc. All Rights Reserved. |
3 | */ | 3 | */ |
4 | 4 | ||
5 | /* | 5 | /* |
@@ -56,14 +56,16 @@ static int lcdif_init(struct mxc_dispdrv_handle *disp, | |||
56 | { | 56 | { |
57 | int ret, i; | 57 | int ret, i; |
58 | struct mxc_lcdif_data *lcdif = mxc_dispdrv_getdata(disp); | 58 | struct mxc_lcdif_data *lcdif = mxc_dispdrv_getdata(disp); |
59 | struct mxc_lcd_platform_data *plat_data | 59 | struct device *dev = &lcdif->pdev->dev; |
60 | = lcdif->pdev->dev.platform_data; | 60 | struct mxc_lcd_platform_data *plat_data = dev->platform_data; |
61 | struct fb_videomode *modedb = lcdif_modedb; | 61 | struct fb_videomode *modedb = lcdif_modedb; |
62 | int modedb_sz = lcdif_modedb_sz; | 62 | int modedb_sz = lcdif_modedb_sz; |
63 | 63 | ||
64 | /* use platform defined ipu/di */ | 64 | /* use platform defined ipu/di */ |
65 | setting->dev_id = plat_data->ipu_id; | 65 | ret = ipu_di_to_crtc(dev, plat_data->ipu_id, |
66 | setting->disp_id = plat_data->disp_id; | 66 | plat_data->disp_id, &setting->crtc); |
67 | if (ret < 0) | ||
68 | return ret; | ||
67 | 69 | ||
68 | ret = fb_find_mode(&setting->fbi->var, setting->fbi, setting->dft_mode_str, | 70 | ret = fb_find_mode(&setting->fbi->var, setting->fbi, setting->dft_mode_str, |
69 | modedb, modedb_sz, NULL, setting->default_bpp); | 71 | modedb, modedb_sz, NULL, setting->default_bpp); |