Commit 752126a05a73303192d704250a0e68156241784d
Committed by
Jaehoon Chung
1 parent
036a803e1b
Exists in
smarc_8mq_lf_v2020.04
and in
17 other branches
dm: sata: dw_sata: Set up common versions of operations
Driver model wants to use the core functions in this file but accesses the uclass-private data in a different way. Move the code into new 'common' functions and set up stubs to call these. Signed-off-by: Simon Glass <sjg@chromium.org>
Showing 1 changed file with 131 additions and 105 deletions Side-by-side Diff
drivers/ata/dwc_ahsata.c
... | ... | @@ -10,6 +10,7 @@ |
10 | 10 | #include <fis.h> |
11 | 11 | #include <libata.h> |
12 | 12 | #include <malloc.h> |
13 | +#include <memalign.h> | |
13 | 14 | #include <sata.h> |
14 | 15 | #include <asm/io.h> |
15 | 16 | #include <asm/arch/clock.h> |
... | ... | @@ -720,6 +721,130 @@ |
720 | 721 | return blkcnt; |
721 | 722 | } |
722 | 723 | |
724 | +static int dwc_ahci_start_ports(struct ahci_uc_priv *uc_priv) | |
725 | +{ | |
726 | + u32 linkmap; | |
727 | + int i; | |
728 | + | |
729 | + linkmap = uc_priv->link_port_map; | |
730 | + | |
731 | + if (0 == linkmap) { | |
732 | + printf("No port device detected!\n"); | |
733 | + return -ENXIO; | |
734 | + } | |
735 | + | |
736 | + for (i = 0; i < uc_priv->n_ports; i++) { | |
737 | + if ((linkmap >> i) && ((linkmap >> i) & 0x01)) { | |
738 | + if (ahci_port_start(uc_priv, (u8)i)) { | |
739 | + printf("Can not start port %d\n", i); | |
740 | + return 1; | |
741 | + } | |
742 | + uc_priv->hard_port_no = i; | |
743 | + break; | |
744 | + } | |
745 | + } | |
746 | + | |
747 | + return 0; | |
748 | +} | |
749 | + | |
750 | +static int dwc_ahsata_scan_common(struct ahci_uc_priv *uc_priv, | |
751 | + struct blk_desc *pdev) | |
752 | +{ | |
753 | + u8 serial[ATA_ID_SERNO_LEN + 1] = { 0 }; | |
754 | + u8 firmware[ATA_ID_FW_REV_LEN + 1] = { 0 }; | |
755 | + u8 product[ATA_ID_PROD_LEN + 1] = { 0 }; | |
756 | + u64 n_sectors; | |
757 | + u8 port = uc_priv->hard_port_no; | |
758 | + ALLOC_CACHE_ALIGN_BUFFER(u16, id, ATA_ID_WORDS); | |
759 | + | |
760 | + /* Identify device to get information */ | |
761 | + dwc_ahsata_identify(uc_priv, id); | |
762 | + | |
763 | + /* Serial number */ | |
764 | + ata_id_c_string(id, serial, ATA_ID_SERNO, sizeof(serial)); | |
765 | + memcpy(pdev->product, serial, sizeof(serial)); | |
766 | + | |
767 | + /* Firmware version */ | |
768 | + ata_id_c_string(id, firmware, ATA_ID_FW_REV, sizeof(firmware)); | |
769 | + memcpy(pdev->revision, firmware, sizeof(firmware)); | |
770 | + | |
771 | + /* Product model */ | |
772 | + ata_id_c_string(id, product, ATA_ID_PROD, sizeof(product)); | |
773 | + memcpy(pdev->vendor, product, sizeof(product)); | |
774 | + | |
775 | + /* Totoal sectors */ | |
776 | + n_sectors = ata_id_n_sectors(id); | |
777 | + pdev->lba = (u32)n_sectors; | |
778 | + | |
779 | + pdev->type = DEV_TYPE_HARDDISK; | |
780 | + pdev->blksz = ATA_SECT_SIZE; | |
781 | + pdev->lun = 0; | |
782 | + | |
783 | + /* Check if support LBA48 */ | |
784 | + if (ata_id_has_lba48(id)) { | |
785 | + pdev->lba48 = 1; | |
786 | + debug("Device support LBA48\n\r"); | |
787 | + } | |
788 | + | |
789 | + /* Get the NCQ queue depth from device */ | |
790 | + uc_priv->flags &= (~SATA_FLAG_Q_DEP_MASK); | |
791 | + uc_priv->flags |= ata_id_queue_depth(id); | |
792 | + | |
793 | + /* Get the xfer mode from device */ | |
794 | + dwc_ahsata_xfer_mode(uc_priv, id); | |
795 | + | |
796 | + /* Get the write cache status from device */ | |
797 | + dwc_ahsata_init_wcache(uc_priv, id); | |
798 | + | |
799 | + /* Set the xfer mode to highest speed */ | |
800 | + ahci_set_feature(uc_priv, port); | |
801 | + | |
802 | + dwc_ahsata_print_info(pdev); | |
803 | + | |
804 | + return 0; | |
805 | +} | |
806 | + | |
807 | +/* | |
808 | + * SATA interface between low level driver and command layer | |
809 | + */ | |
810 | +static ulong sata_read_common(struct ahci_uc_priv *uc_priv, | |
811 | + struct blk_desc *desc, ulong blknr, | |
812 | + lbaint_t blkcnt, void *buffer) | |
813 | +{ | |
814 | + u32 rc; | |
815 | + | |
816 | + if (desc->lba48) | |
817 | + rc = ata_low_level_rw_lba48(uc_priv, blknr, blkcnt, buffer, | |
818 | + READ_CMD); | |
819 | + else | |
820 | + rc = ata_low_level_rw_lba28(uc_priv, blknr, blkcnt, buffer, | |
821 | + READ_CMD); | |
822 | + | |
823 | + return rc; | |
824 | +} | |
825 | + | |
826 | +static ulong sata_write_common(struct ahci_uc_priv *uc_priv, | |
827 | + struct blk_desc *desc, ulong blknr, | |
828 | + lbaint_t blkcnt, const void *buffer) | |
829 | +{ | |
830 | + u32 rc; | |
831 | + u32 flags = uc_priv->flags; | |
832 | + | |
833 | + if (desc->lba48) { | |
834 | + rc = ata_low_level_rw_lba48(uc_priv, blknr, blkcnt, buffer, | |
835 | + WRITE_CMD); | |
836 | + if ((flags & SATA_FLAG_WCACHE) && (flags & SATA_FLAG_FLUSH_EXT)) | |
837 | + dwc_ahsata_flush_cache_ext(uc_priv); | |
838 | + } else { | |
839 | + rc = ata_low_level_rw_lba28(uc_priv, blknr, blkcnt, buffer, | |
840 | + WRITE_CMD); | |
841 | + if ((flags & SATA_FLAG_WCACHE) && (flags & SATA_FLAG_FLUSH)) | |
842 | + dwc_ahsata_flush_cache(uc_priv); | |
843 | + } | |
844 | + | |
845 | + return rc; | |
846 | +} | |
847 | + | |
723 | 848 | static int ahci_init_one(int pdev) |
724 | 849 | { |
725 | 850 | int rc; |
... | ... | @@ -755,8 +880,6 @@ |
755 | 880 | |
756 | 881 | int init_sata(int dev) |
757 | 882 | { |
758 | - int i; | |
759 | - u32 linkmap; | |
760 | 883 | struct ahci_uc_priv *uc_priv = NULL; |
761 | 884 | |
762 | 885 | #if defined(CONFIG_MX6) |
763 | 886 | |
... | ... | @@ -771,25 +894,8 @@ |
771 | 894 | ahci_init_one(dev); |
772 | 895 | |
773 | 896 | uc_priv = sata_dev_desc[dev].priv; |
774 | - linkmap = uc_priv->link_port_map; | |
775 | 897 | |
776 | - if (0 == linkmap) { | |
777 | - printf("No port device detected!\n"); | |
778 | - return 1; | |
779 | - } | |
780 | - | |
781 | - for (i = 0; i < uc_priv->n_ports; i++) { | |
782 | - if ((linkmap >> i) && ((linkmap >> i) & 0x01)) { | |
783 | - if (ahci_port_start(uc_priv, (u8)i)) { | |
784 | - printf("Can not start port %d\n", i); | |
785 | - return 1; | |
786 | - } | |
787 | - uc_priv->hard_port_no = i; | |
788 | - break; | |
789 | - } | |
790 | - } | |
791 | - | |
792 | - return 0; | |
898 | + return dwc_ahci_start_ports(uc_priv) ? 1 : 0; | |
793 | 899 | } |
794 | 900 | |
795 | 901 | int reset_sata(int dev) |
796 | 902 | |
797 | 903 | |
798 | 904 | |
799 | 905 | |
800 | 906 | |
801 | 907 | |
802 | 908 | |
... | ... | @@ -838,104 +944,24 @@ |
838 | 944 | ulong sata_read(int dev, ulong blknr, lbaint_t blkcnt, void *buffer) |
839 | 945 | { |
840 | 946 | struct ahci_uc_priv *uc_priv = sata_dev_desc[dev].priv; |
841 | - u32 rc; | |
842 | 947 | |
843 | - if (sata_dev_desc[dev].lba48) | |
844 | - rc = ata_low_level_rw_lba48(uc_priv, blknr, blkcnt, | |
845 | - buffer, READ_CMD); | |
846 | - else | |
847 | - rc = ata_low_level_rw_lba28(uc_priv, blknr, blkcnt, | |
848 | - buffer, READ_CMD); | |
849 | - return rc; | |
948 | + return sata_read_common(uc_priv, &sata_dev_desc[dev], blknr, blkcnt, | |
949 | + buffer); | |
850 | 950 | } |
851 | 951 | |
852 | 952 | ulong sata_write(int dev, ulong blknr, lbaint_t blkcnt, const void *buffer) |
853 | 953 | { |
854 | - u32 rc; | |
855 | 954 | struct ahci_uc_priv *uc_priv = sata_dev_desc[dev].priv; |
856 | - u32 flags = uc_priv->flags; | |
857 | 955 | |
858 | - if (sata_dev_desc[dev].lba48) { | |
859 | - rc = ata_low_level_rw_lba48(uc_priv, blknr, blkcnt, buffer, | |
860 | - WRITE_CMD); | |
861 | - if ((flags & SATA_FLAG_WCACHE) && | |
862 | - (flags & SATA_FLAG_FLUSH_EXT)) | |
863 | - dwc_ahsata_flush_cache_ext(uc_priv); | |
864 | - } else { | |
865 | - rc = ata_low_level_rw_lba28(uc_priv, blknr, blkcnt, buffer, | |
866 | - WRITE_CMD); | |
867 | - if ((flags & SATA_FLAG_WCACHE) && | |
868 | - (flags & SATA_FLAG_FLUSH)) | |
869 | - dwc_ahsata_flush_cache(uc_priv); | |
870 | - } | |
871 | - return rc; | |
956 | + return sata_write_common(uc_priv, &sata_dev_desc[dev], blknr, blkcnt, | |
957 | + buffer); | |
872 | 958 | } |
873 | 959 | |
874 | 960 | int scan_sata(int dev) |
875 | 961 | { |
876 | - u8 serial[ATA_ID_SERNO_LEN + 1] = { 0 }; | |
877 | - u8 firmware[ATA_ID_FW_REV_LEN + 1] = { 0 }; | |
878 | - u8 product[ATA_ID_PROD_LEN + 1] = { 0 }; | |
879 | - u16 *id; | |
880 | - u64 n_sectors; | |
881 | 962 | struct ahci_uc_priv *uc_priv = sata_dev_desc[dev].priv; |
882 | - u8 port = uc_priv->hard_port_no; | |
883 | 963 | struct blk_desc *pdev = &sata_dev_desc[dev]; |
884 | 964 | |
885 | - id = (u16 *)memalign(ARCH_DMA_MINALIGN, | |
886 | - roundup(ARCH_DMA_MINALIGN, | |
887 | - (ATA_ID_WORDS * 2))); | |
888 | - if (!id) { | |
889 | - printf("id malloc failed\n\r"); | |
890 | - return -1; | |
891 | - } | |
892 | - | |
893 | - /* Identify device to get information */ | |
894 | - dwc_ahsata_identify(uc_priv, id); | |
895 | - | |
896 | - /* Serial number */ | |
897 | - ata_id_c_string(id, serial, ATA_ID_SERNO, sizeof(serial)); | |
898 | - memcpy(pdev->product, serial, sizeof(serial)); | |
899 | - | |
900 | - /* Firmware version */ | |
901 | - ata_id_c_string(id, firmware, ATA_ID_FW_REV, sizeof(firmware)); | |
902 | - memcpy(pdev->revision, firmware, sizeof(firmware)); | |
903 | - | |
904 | - /* Product model */ | |
905 | - ata_id_c_string(id, product, ATA_ID_PROD, sizeof(product)); | |
906 | - memcpy(pdev->vendor, product, sizeof(product)); | |
907 | - | |
908 | - /* Totoal sectors */ | |
909 | - n_sectors = ata_id_n_sectors(id); | |
910 | - pdev->lba = (u32)n_sectors; | |
911 | - | |
912 | - pdev->type = DEV_TYPE_HARDDISK; | |
913 | - pdev->blksz = ATA_SECT_SIZE; | |
914 | - pdev->lun = 0 ; | |
915 | - | |
916 | - /* Check if support LBA48 */ | |
917 | - if (ata_id_has_lba48(id)) { | |
918 | - pdev->lba48 = 1; | |
919 | - debug("Device support LBA48\n\r"); | |
920 | - } | |
921 | - | |
922 | - /* Get the NCQ queue depth from device */ | |
923 | - uc_priv->flags &= (~SATA_FLAG_Q_DEP_MASK); | |
924 | - uc_priv->flags |= ata_id_queue_depth(id); | |
925 | - | |
926 | - /* Get the xfer mode from device */ | |
927 | - dwc_ahsata_xfer_mode(uc_priv, id); | |
928 | - | |
929 | - /* Get the write cache status from device */ | |
930 | - dwc_ahsata_init_wcache(uc_priv, id); | |
931 | - | |
932 | - /* Set the xfer mode to highest speed */ | |
933 | - ahci_set_feature(uc_priv, port); | |
934 | - | |
935 | - free((void *)id); | |
936 | - | |
937 | - dwc_ahsata_print_info(&sata_dev_desc[dev]); | |
938 | - | |
939 | - return 0; | |
965 | + return dwc_ahsata_scan_common(uc_priv, pdev); | |
940 | 966 | } |