1 /** @file
2 *
3 * Copyright (c) 2016, Hisilicon Limited. All rights reserved.
4 * Copyright (c) 2016, Linaro Limited. All rights reserved.
5 *
6 * This program and the accompanying materials
7 * are licensed and made available under the terms and conditions of the BSD License
8 * which accompanies this distribution. The full text of the license may be found at
9 * http://opensource.org/licenses/bsd-license.php
10 *
11 * THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13 *
14 **/
15
16
17 #include <Library/BaseLib.h>
18 #include <Library/BaseMemoryLib.h>
19 #include <Library/DebugLib.h>
20 #include <Library/IoLib.h>
21 #include <Library/TimerLib.h>
22 #include <Library/UefiBootServicesTableLib.h>
23 #include <Library/UefiLib.h>
24
25 #include <Protocol/PlatformSasProtocol.h>
26
27 #define SAS0_BASE 0xc0000000
28 #define SAS0_RESET 0xa60
29 #define SAS0_DISABLE_CLK 0x33c
30 #define SAS0_DERESET 0xa64
31 #define SAS0_ENABLE_CLK 0x338
32
33 #define SAS1_BASE 0xb0000000
34 #define SAS1_RESET 0xa18
35 #define SAS1_DISABLE_CLK 0x31c
36 #define SAS1_DERESET 0xa1c
37 #define SAS1_ENABLE_CLK 0x318
38
39 #define SAS_RESET_VALUE 0x7ffff
40
41 STATIC
42 VOID
SasInit_0(IN PLATFORM_SAS_PROTOCOL * This)43 SasInit_0 (
44 IN PLATFORM_SAS_PROTOCOL *This
45 )
46 {
47 // Apply reset and disable clock
48 MmioWrite32(SAS0_BASE + SAS0_RESET, SAS_RESET_VALUE);
49 MmioWrite32(SAS0_BASE + SAS0_DISABLE_CLK, SAS_RESET_VALUE);
50 // Wait 1ms for reset takes effect, refer drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
51 MicroSecondDelay(1000);
52 // De-reset and enable clock
53 MmioWrite32(SAS0_BASE + SAS0_DERESET, SAS_RESET_VALUE);
54 MmioWrite32(SAS0_BASE + SAS0_ENABLE_CLK, SAS_RESET_VALUE);
55 // Wait 1ms for de-reset takes effect, refer drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
56 MicroSecondDelay(1000);
57 }
58
59 PLATFORM_SAS_PROTOCOL Sas0 = {
60 0xc1000000,
61 SasInit_0
62 };
63
64 STATIC
65 VOID
SasInit_1(IN PLATFORM_SAS_PROTOCOL * This)66 SasInit_1 (
67 IN PLATFORM_SAS_PROTOCOL *This
68 )
69 {
70 // Apply reset and disable clock
71 MmioWrite32(SAS1_BASE + SAS1_RESET, SAS_RESET_VALUE);
72 MmioWrite32(SAS1_BASE + SAS1_DISABLE_CLK, SAS_RESET_VALUE);
73 // Wait 1ms for reset takes effect, refer drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
74 MicroSecondDelay(1000);
75 // De-reset and enable clock
76 MmioWrite32(SAS1_BASE + SAS1_DERESET, SAS_RESET_VALUE);
77 MmioWrite32(SAS1_BASE + SAS1_ENABLE_CLK, SAS_RESET_VALUE);
78 // Wait 1ms for de-reset takes effect, refer drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
79 MicroSecondDelay(1000);
80 }
81
82 PLATFORM_SAS_PROTOCOL Sas1 = {
83 0xb1000000,
84 SasInit_1
85 };
86
87 EFI_STATUS
88 EFIAPI
SasV1InitEntry(IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE * SystemTable)89 SasV1InitEntry (
90 IN EFI_HANDLE ImageHandle,
91 IN EFI_SYSTEM_TABLE *SystemTable
92 )
93 {
94 EFI_HANDLE Handle;
95 EFI_STATUS Status;
96
97 Handle = NULL;
98 Status = gBS->InstallMultipleProtocolInterfaces(
99 &Handle,
100 &gPlatformSasProtocolGuid, &Sas0,
101 NULL
102 );
103 if (EFI_ERROR(Status)) {
104 return Status;
105 }
106
107 Handle = NULL;
108 Status = gBS->InstallMultipleProtocolInterfaces(
109 &Handle,
110 &gPlatformSasProtocolGuid, &Sas1,
111 NULL
112 );
113 return Status;
114 }
115