Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

OMAPDSS: DSS: init dss ports cleanly

The init/uninit port functions are used to set up the DPI and SDI outputs under
the dss platform device. A 'reg' property is used to determine the port number
of the output. This tells us whether the port is DPI or SDI for OMAP34xx DSS
revision. For other DSS revisions, we only have DPI outputs under the dss
platform device.

For multiple DPI output instances(introduced in DRA7xx DSS), we will use the
the port number to specify which DPI output instance is being inited.

The current functions work fine if there is only one DPI output instance in
DSS. For multiple DPI instances, it would get complicated to figure out whether
port number was used to specify whether the output is SDI, or another DPI
instance.

We create a list of port types supported for each DSS rev, with the index of the
port in the list specifying the port number of the output for that DSS revision.
This allows us to have a more generic way to init/uninit ports within DSS, and
also support multiple DPI ports.

We make the uninit_port functions iterative since we will have multiple DPI
ports to uninit in the future.

Signed-off-by: Archit Taneja <archit@ti.com>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>

authored by

Archit Taneja and committed by
Tomi Valkeinen
387ce9f2 80eb6751

+92 -16
+68 -14
drivers/video/fbdev/omap2/dss/dss.c
··· 70 70 u8 fck_div_max; 71 71 u8 dss_fck_multiplier; 72 72 const char *parent_clk_name; 73 + enum omap_display_type *ports; 74 + int num_ports; 73 75 int (*dpi_select_source)(enum omap_channel channel); 74 76 }; 75 77 ··· 691 689 } 692 690 #endif 693 691 692 + 693 + static enum omap_display_type omap2plus_ports[] = { 694 + OMAP_DISPLAY_TYPE_DPI, 695 + }; 696 + 697 + static enum omap_display_type omap34xx_ports[] = { 698 + OMAP_DISPLAY_TYPE_DPI, 699 + OMAP_DISPLAY_TYPE_SDI, 700 + }; 701 + 694 702 static const struct dss_features omap24xx_dss_feats __initconst = { 695 703 /* 696 704 * fck div max is really 16, but the divider range has gaps. The range ··· 710 698 .dss_fck_multiplier = 2, 711 699 .parent_clk_name = "core_ck", 712 700 .dpi_select_source = &dss_dpi_select_source_omap2_omap3, 701 + .ports = omap2plus_ports, 702 + .num_ports = ARRAY_SIZE(omap2plus_ports), 713 703 }; 714 704 715 705 static const struct dss_features omap34xx_dss_feats __initconst = { ··· 719 705 .dss_fck_multiplier = 2, 720 706 .parent_clk_name = "dpll4_ck", 721 707 .dpi_select_source = &dss_dpi_select_source_omap2_omap3, 708 + .ports = omap34xx_ports, 709 + .num_ports = ARRAY_SIZE(omap34xx_ports), 722 710 }; 723 711 724 712 static const struct dss_features omap3630_dss_feats __initconst = { ··· 728 712 .dss_fck_multiplier = 1, 729 713 .parent_clk_name = "dpll4_ck", 730 714 .dpi_select_source = &dss_dpi_select_source_omap2_omap3, 715 + .ports = omap2plus_ports, 716 + .num_ports = ARRAY_SIZE(omap2plus_ports), 731 717 }; 732 718 733 719 static const struct dss_features omap44xx_dss_feats __initconst = { ··· 737 719 .dss_fck_multiplier = 1, 738 720 .parent_clk_name = "dpll_per_x2_ck", 739 721 .dpi_select_source = &dss_dpi_select_source_omap4, 722 + .ports = omap2plus_ports, 723 + .num_ports = ARRAY_SIZE(omap2plus_ports), 740 724 }; 741 725 742 726 static const struct dss_features omap54xx_dss_feats __initconst = { ··· 746 726 .dss_fck_multiplier = 1, 747 727 .parent_clk_name = "dpll_per_x2_ck", 748 728 .dpi_select_source = &dss_dpi_select_source_omap5, 729 + .ports = omap2plus_ports, 730 + .num_ports = ARRAY_SIZE(omap2plus_ports), 749 731 }; 750 732 751 733 static const struct dss_features am43xx_dss_feats __initconst = { ··· 755 733 .dss_fck_multiplier = 0, 756 734 .parent_clk_name = NULL, 757 735 .dpi_select_source = &dss_dpi_select_source_omap2_omap3, 736 + .ports = omap2plus_ports, 737 + .num_ports = ARRAY_SIZE(omap2plus_ports), 758 738 }; 759 739 760 740 static int __init dss_init_features(struct platform_device *pdev) ··· 822 798 if (!port) 823 799 return 0; 824 800 801 + if (dss.feat->num_ports == 0) 802 + return 0; 803 + 825 804 do { 805 + enum omap_display_type port_type; 826 806 u32 reg; 827 807 828 808 r = of_property_read_u32(port, "reg", &reg); 829 809 if (r) 830 810 reg = 0; 831 811 832 - #ifdef CONFIG_OMAP2_DSS_DPI 833 - if (reg == 0) 812 + if (reg >= dss.feat->num_ports) 813 + continue; 814 + 815 + port_type = dss.feat->ports[reg]; 816 + 817 + switch (port_type) { 818 + case OMAP_DISPLAY_TYPE_DPI: 834 819 dpi_init_port(pdev, port); 835 - #endif 836 - 837 - #ifdef CONFIG_OMAP2_DSS_SDI 838 - if (reg == 1) 820 + break; 821 + case OMAP_DISPLAY_TYPE_SDI: 839 822 sdi_init_port(pdev, port); 840 - #endif 841 - 823 + break; 824 + default: 825 + break; 826 + } 842 827 } while ((port = omapdss_of_get_next_port(parent, port)) != NULL); 843 828 844 829 return 0; ··· 865 832 if (!port) 866 833 return; 867 834 868 - #ifdef CONFIG_OMAP2_DSS_DPI 869 - dpi_uninit_port(port); 870 - #endif 835 + if (dss.feat->num_ports == 0) 836 + return; 871 837 872 - #ifdef CONFIG_OMAP2_DSS_SDI 873 - sdi_uninit_port(); 874 - #endif 838 + do { 839 + enum omap_display_type port_type; 840 + u32 reg; 841 + int r; 842 + 843 + r = of_property_read_u32(port, "reg", &reg); 844 + if (r) 845 + reg = 0; 846 + 847 + if (reg >= dss.feat->num_ports) 848 + continue; 849 + 850 + port_type = dss.feat->ports[reg]; 851 + 852 + switch (port_type) { 853 + case OMAP_DISPLAY_TYPE_DPI: 854 + dpi_uninit_port(port); 855 + break; 856 + case OMAP_DISPLAY_TYPE_SDI: 857 + sdi_uninit_port(port); 858 + break; 859 + default: 860 + break; 861 + } 862 + } while ((port = omapdss_of_get_next_port(parent, port)) != NULL); 875 863 } 876 864 877 865 /* DSS HW IP initialisation */
+23 -1
drivers/video/fbdev/omap2/dss/dss.h
··· 244 244 int sdi_init_platform_driver(void) __init; 245 245 void sdi_uninit_platform_driver(void) __exit; 246 246 247 + #ifdef CONFIG_OMAP2_DSS_SDI 247 248 int sdi_init_port(struct platform_device *pdev, struct device_node *port) __init; 248 - void sdi_uninit_port(void) __exit; 249 + void sdi_uninit_port(struct device_node *port) __exit; 250 + #else 251 + static inline int __init sdi_init_port(struct platform_device *pdev, 252 + struct device_node *port) 253 + { 254 + return 0; 255 + } 256 + static inline void __exit sdi_uninit_port(struct device_node *port) 257 + { 258 + } 259 + #endif 249 260 250 261 /* DSI */ 251 262 ··· 369 358 int dpi_init_platform_driver(void) __init; 370 359 void dpi_uninit_platform_driver(void) __exit; 371 360 361 + #ifdef CONFIG_OMAP2_DSS_DPI 372 362 int dpi_init_port(struct platform_device *pdev, struct device_node *port) __init; 373 363 void dpi_uninit_port(struct device_node *port) __exit; 364 + #else 365 + static inline int __init dpi_init_port(struct platform_device *pdev, 366 + struct device_node *port) 367 + { 368 + return 0; 369 + } 370 + static inline void __exit dpi_uninit_port(struct device_node *port) 371 + { 372 + } 373 + #endif 374 374 375 375 /* DISPC */ 376 376 int dispc_init_platform_driver(void) __init;
+1 -1
drivers/video/fbdev/omap2/dss/sdi.c
··· 425 425 return r; 426 426 } 427 427 428 - void __exit sdi_uninit_port(void) 428 + void __exit sdi_uninit_port(struct device_node *port) 429 429 { 430 430 if (!sdi.port_initialized) 431 431 return;