.. | .. |
---|
30 | 30 | #include <video/of_display_timing.h> |
---|
31 | 31 | #include <video/videomode.h> |
---|
32 | 32 | |
---|
33 | | -#include "amba-clcd-nomadik.h" |
---|
34 | | -#include "amba-clcd-versatile.h" |
---|
35 | | - |
---|
36 | 33 | #define to_clcd(info) container_of(info, struct clcd_fb, fb) |
---|
37 | 34 | |
---|
38 | 35 | /* This is limited to 16 characters when displayed by X startup */ |
---|
.. | .. |
---|
223 | 220 | var->blue.length = 4; |
---|
224 | 221 | } |
---|
225 | 222 | break; |
---|
226 | | - case 24: |
---|
227 | | - if (fb->vendor->packed_24_bit_pixels) { |
---|
228 | | - var->red.length = 8; |
---|
229 | | - var->green.length = 8; |
---|
230 | | - var->blue.length = 8; |
---|
231 | | - } else { |
---|
232 | | - ret = -EINVAL; |
---|
233 | | - } |
---|
234 | | - break; |
---|
235 | 223 | case 32: |
---|
236 | 224 | /* If we can't do 888, reject */ |
---|
237 | 225 | caps &= CLCD_CAP_888; |
---|
.. | .. |
---|
317 | 305 | fb->board->decode(fb, ®s); |
---|
318 | 306 | |
---|
319 | 307 | clcdfb_disable(fb); |
---|
320 | | - |
---|
321 | | - /* Some variants must be clocked here */ |
---|
322 | | - if (fb->vendor->clock_timregs && !fb->clk_enabled) { |
---|
323 | | - fb->clk_enabled = true; |
---|
324 | | - clk_enable(fb->clk); |
---|
325 | | - } |
---|
326 | 308 | |
---|
327 | 309 | writel(regs.tim0, fb->regs + CLCD_TIM0); |
---|
328 | 310 | writel(regs.tim1, fb->regs + CLCD_TIM1); |
---|
.. | .. |
---|
441 | 423 | return ret; |
---|
442 | 424 | } |
---|
443 | 425 | |
---|
444 | | -static struct fb_ops clcdfb_ops = { |
---|
| 426 | +static const struct fb_ops clcdfb_ops = { |
---|
445 | 427 | .owner = THIS_MODULE, |
---|
446 | 428 | .fb_check_var = clcdfb_check_var, |
---|
447 | 429 | .fb_set_par = clcdfb_set_par, |
---|
.. | .. |
---|
465 | 447 | fb->off_ienb = CLCD_PL111_IENB; |
---|
466 | 448 | fb->off_cntl = CLCD_PL111_CNTL; |
---|
467 | 449 | } else { |
---|
468 | | - if (of_machine_is_compatible("arm,versatile-ab") || |
---|
469 | | - of_machine_is_compatible("arm,versatile-pb")) { |
---|
470 | | - fb->off_ienb = CLCD_PL111_IENB; |
---|
471 | | - fb->off_cntl = CLCD_PL111_CNTL; |
---|
472 | | - } else { |
---|
473 | | - fb->off_ienb = CLCD_PL110_IENB; |
---|
474 | | - fb->off_cntl = CLCD_PL110_CNTL; |
---|
475 | | - } |
---|
| 450 | + fb->off_ienb = CLCD_PL110_IENB; |
---|
| 451 | + fb->off_cntl = CLCD_PL110_CNTL; |
---|
476 | 452 | } |
---|
477 | 453 | |
---|
478 | 454 | fb->clk = clk_get(&fb->dev->dev, NULL); |
---|
.. | .. |
---|
585 | 561 | struct videomode video; |
---|
586 | 562 | |
---|
587 | 563 | err = of_get_display_timing(node, "panel-timing", &timing); |
---|
588 | | - if (err) |
---|
| 564 | + if (err) { |
---|
| 565 | + pr_err("%pOF: problems parsing panel-timing (%d)\n", node, err); |
---|
589 | 566 | return err; |
---|
| 567 | + } |
---|
590 | 568 | |
---|
591 | 569 | videomode_from_timing(&timing, &video); |
---|
592 | 570 | |
---|
.. | .. |
---|
624 | 602 | mode->refresh); |
---|
625 | 603 | } |
---|
626 | 604 | |
---|
627 | | -static int clcdfb_of_get_backlight(struct device_node *panel, |
---|
| 605 | +static int clcdfb_of_get_backlight(struct device *dev, |
---|
628 | 606 | struct clcd_panel *clcd_panel) |
---|
629 | 607 | { |
---|
630 | | - struct device_node *backlight; |
---|
| 608 | + struct backlight_device *backlight; |
---|
631 | 609 | |
---|
632 | | - /* Look up the optional backlight phandle */ |
---|
633 | | - backlight = of_parse_phandle(panel, "backlight", 0); |
---|
634 | | - if (backlight) { |
---|
635 | | - clcd_panel->backlight = of_find_backlight_by_node(backlight); |
---|
636 | | - of_node_put(backlight); |
---|
| 610 | + /* Look up the optional backlight device */ |
---|
| 611 | + backlight = devm_of_find_backlight(dev); |
---|
| 612 | + if (IS_ERR(backlight)) |
---|
| 613 | + return PTR_ERR(backlight); |
---|
637 | 614 | |
---|
638 | | - if (!clcd_panel->backlight) |
---|
639 | | - return -EPROBE_DEFER; |
---|
640 | | - } |
---|
| 615 | + clcd_panel->backlight = backlight; |
---|
641 | 616 | return 0; |
---|
642 | 617 | } |
---|
643 | 618 | |
---|
.. | .. |
---|
713 | 688 | if (r0 != 0 && b0 == 0) |
---|
714 | 689 | fb->panel->bgr_connection = true; |
---|
715 | 690 | |
---|
716 | | - if (fb->panel->caps && fb->vendor->st_bitmux_control) { |
---|
717 | | - /* |
---|
718 | | - * Set up the special bits for the Nomadik control register |
---|
719 | | - * (other platforms tend to do this through an external |
---|
720 | | - * register). |
---|
721 | | - */ |
---|
722 | | - |
---|
723 | | - /* Offset of the highest used color */ |
---|
724 | | - int maxoff = max3(r0, g0, b0); |
---|
725 | | - /* Most significant bit out, highest used bit */ |
---|
726 | | - int msb = 0; |
---|
727 | | - |
---|
728 | | - if (fb->panel->caps & CLCD_CAP_888) { |
---|
729 | | - msb = maxoff + 8 - 1; |
---|
730 | | - } else if (fb->panel->caps & CLCD_CAP_565) { |
---|
731 | | - msb = maxoff + 5 - 1; |
---|
732 | | - fb->panel->cntl |= CNTL_ST_1XBPP_565; |
---|
733 | | - } else if (fb->panel->caps & CLCD_CAP_5551) { |
---|
734 | | - msb = maxoff + 5 - 1; |
---|
735 | | - fb->panel->cntl |= CNTL_ST_1XBPP_5551; |
---|
736 | | - } else if (fb->panel->caps & CLCD_CAP_444) { |
---|
737 | | - msb = maxoff + 4 - 1; |
---|
738 | | - fb->panel->cntl |= CNTL_ST_1XBPP_444; |
---|
739 | | - } |
---|
740 | | - |
---|
741 | | - /* Send out as many bits as we need */ |
---|
742 | | - if (msb > 17) |
---|
743 | | - fb->panel->cntl |= CNTL_ST_CDWID_24; |
---|
744 | | - else if (msb > 15) |
---|
745 | | - fb->panel->cntl |= CNTL_ST_CDWID_18; |
---|
746 | | - else if (msb > 11) |
---|
747 | | - fb->panel->cntl |= CNTL_ST_CDWID_16; |
---|
748 | | - else |
---|
749 | | - fb->panel->cntl |= CNTL_ST_CDWID_12; |
---|
750 | | - } |
---|
751 | | - |
---|
752 | 691 | return fb->panel->caps ? 0 : -EINVAL; |
---|
753 | 692 | } |
---|
754 | 693 | |
---|
.. | .. |
---|
772 | 711 | return -ENODEV; |
---|
773 | 712 | |
---|
774 | 713 | panel = of_graph_get_remote_port_parent(endpoint); |
---|
775 | | - if (!panel) |
---|
776 | | - return -ENODEV; |
---|
777 | | - |
---|
778 | | - if (fb->vendor->init_panel) { |
---|
779 | | - err = fb->vendor->init_panel(fb, panel); |
---|
780 | | - if (err) |
---|
781 | | - return err; |
---|
| 714 | + if (!panel) { |
---|
| 715 | + err = -ENODEV; |
---|
| 716 | + goto out_endpoint_put; |
---|
782 | 717 | } |
---|
783 | 718 | |
---|
784 | | - err = clcdfb_of_get_backlight(panel, fb->panel); |
---|
| 719 | + err = clcdfb_of_get_backlight(&fb->dev->dev, fb->panel); |
---|
785 | 720 | if (err) |
---|
786 | | - return err; |
---|
| 721 | + goto out_panel_put; |
---|
787 | 722 | |
---|
788 | 723 | err = clcdfb_of_get_mode(&fb->dev->dev, panel, fb->panel); |
---|
789 | 724 | if (err) |
---|
790 | | - return err; |
---|
| 725 | + goto out_panel_put; |
---|
791 | 726 | |
---|
792 | 727 | err = of_property_read_u32(fb->dev->dev.of_node, "max-memory-bandwidth", |
---|
793 | 728 | &max_bandwidth); |
---|
.. | .. |
---|
816 | 751 | |
---|
817 | 752 | if (of_property_read_u32_array(endpoint, |
---|
818 | 753 | "arm,pl11x,tft-r0g0b0-pads", |
---|
819 | | - tft_r0b0g0, ARRAY_SIZE(tft_r0b0g0)) != 0) |
---|
820 | | - return -ENOENT; |
---|
| 754 | + tft_r0b0g0, ARRAY_SIZE(tft_r0b0g0)) != 0) { |
---|
| 755 | + err = -ENOENT; |
---|
| 756 | + goto out_panel_put; |
---|
| 757 | + } |
---|
| 758 | + |
---|
| 759 | + of_node_put(panel); |
---|
| 760 | + of_node_put(endpoint); |
---|
821 | 761 | |
---|
822 | 762 | return clcdfb_of_init_tft_panel(fb, tft_r0b0g0[0], |
---|
823 | 763 | tft_r0b0g0[1], tft_r0b0g0[2]); |
---|
| 764 | +out_panel_put: |
---|
| 765 | + of_node_put(panel); |
---|
| 766 | +out_endpoint_put: |
---|
| 767 | + of_node_put(endpoint); |
---|
| 768 | + return err; |
---|
824 | 769 | } |
---|
825 | 770 | |
---|
826 | 771 | static int clcdfb_of_vram_setup(struct clcd_fb *fb) |
---|
.. | .. |
---|
838 | 783 | return -ENODEV; |
---|
839 | 784 | |
---|
840 | 785 | fb->fb.screen_base = of_iomap(memory, 0); |
---|
841 | | - if (!fb->fb.screen_base) |
---|
| 786 | + if (!fb->fb.screen_base) { |
---|
| 787 | + of_node_put(memory); |
---|
842 | 788 | return -ENOMEM; |
---|
| 789 | + } |
---|
843 | 790 | |
---|
844 | 791 | fb->fb.fix.smem_start = of_translate_address(memory, |
---|
845 | 792 | of_get_address(memory, 0, &size, NULL)); |
---|
846 | 793 | fb->fb.fix.smem_len = size; |
---|
| 794 | + of_node_put(memory); |
---|
847 | 795 | |
---|
848 | 796 | return 0; |
---|
849 | 797 | } |
---|
.. | .. |
---|
941 | 889 | static int clcdfb_probe(struct amba_device *dev, const struct amba_id *id) |
---|
942 | 890 | { |
---|
943 | 891 | struct clcd_board *board = dev_get_platdata(&dev->dev); |
---|
944 | | - struct clcd_vendor_data *vendor = id->data; |
---|
945 | 892 | struct clcd_fb *fb; |
---|
946 | 893 | int ret; |
---|
947 | 894 | |
---|
.. | .. |
---|
950 | 897 | |
---|
951 | 898 | if (!board) |
---|
952 | 899 | return -EINVAL; |
---|
953 | | - |
---|
954 | | - if (vendor->init_board) { |
---|
955 | | - ret = vendor->init_board(dev, board); |
---|
956 | | - if (ret) |
---|
957 | | - return ret; |
---|
958 | | - } |
---|
959 | 900 | |
---|
960 | 901 | ret = dma_set_mask_and_coherent(&dev->dev, DMA_BIT_MASK(32)); |
---|
961 | 902 | if (ret) |
---|
.. | .. |
---|
974 | 915 | } |
---|
975 | 916 | |
---|
976 | 917 | fb->dev = dev; |
---|
977 | | - fb->vendor = vendor; |
---|
978 | 918 | fb->board = board; |
---|
979 | 919 | |
---|
980 | 920 | dev_info(&fb->dev->dev, "PL%03x designer %02x rev%u at 0x%08llx\n", |
---|
.. | .. |
---|
1000 | 940 | return ret; |
---|
1001 | 941 | } |
---|
1002 | 942 | |
---|
1003 | | -static int clcdfb_remove(struct amba_device *dev) |
---|
| 943 | +static void clcdfb_remove(struct amba_device *dev) |
---|
1004 | 944 | { |
---|
1005 | 945 | struct clcd_fb *fb = amba_get_drvdata(dev); |
---|
1006 | 946 | |
---|
.. | .. |
---|
1017 | 957 | kfree(fb); |
---|
1018 | 958 | |
---|
1019 | 959 | amba_release_regions(dev); |
---|
1020 | | - |
---|
1021 | | - return 0; |
---|
1022 | 960 | } |
---|
1023 | | - |
---|
1024 | | -static struct clcd_vendor_data vendor_arm = { |
---|
1025 | | - /* Sets up the versatile board displays */ |
---|
1026 | | - .init_panel = versatile_clcd_init_panel, |
---|
1027 | | -}; |
---|
1028 | | - |
---|
1029 | | -static struct clcd_vendor_data vendor_nomadik = { |
---|
1030 | | - .clock_timregs = true, |
---|
1031 | | - .packed_24_bit_pixels = true, |
---|
1032 | | - .st_bitmux_control = true, |
---|
1033 | | - .init_board = nomadik_clcd_init_board, |
---|
1034 | | - .init_panel = nomadik_clcd_init_panel, |
---|
1035 | | -}; |
---|
1036 | 961 | |
---|
1037 | 962 | static const struct amba_id clcdfb_id_table[] = { |
---|
1038 | 963 | { |
---|
1039 | 964 | .id = 0x00041110, |
---|
1040 | 965 | .mask = 0x000ffffe, |
---|
1041 | | - .data = &vendor_arm, |
---|
1042 | | - }, |
---|
1043 | | - /* ST Electronics Nomadik variant */ |
---|
1044 | | - { |
---|
1045 | | - .id = 0x00180110, |
---|
1046 | | - .mask = 0x00fffffe, |
---|
1047 | | - .data = &vendor_nomadik, |
---|
1048 | 966 | }, |
---|
1049 | 967 | { 0, 0 }, |
---|
1050 | 968 | }; |
---|