; Copyright 2010 Castle Technology Ltd
;
; Licensed under the Apache License, Version 2.0 (the "License");
; you may not use this file except in compliance with the License.
; You may obtain a copy of the License at
;
;     http://www.apache.org/licenses/LICENSE-2.0
;
; Unless required by applicable law or agreed to in writing, software
; distributed under the License is distributed on an "AS IS" BASIS,
; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
; See the License for the specific language governing permissions and
; limitations under the License.
;

        GET     Hdr:ListOpts
        GET     Hdr:Macros
        GET     Hdr:System
        GET     Hdr:Machine.<Machine>
        GET     Hdr:ImageSize.<ImageSize>
        $GetIO

        GET     Hdr:OSEntries
        GET     Hdr:HALEntries
        GET     Hdr:Proc

        GET     hdr.omap3530
        GET     hdr.StaticWS
        GET     hdr.GPIO

        AREA    |Asm$$Code|, CODE, READONLY, PIC


        EXPORT  NIC_Init
        EXPORT  NIC_GPMC_Config_IGEP
        EXPORT  NIC_GPMC_Config_DevKit
        EXPORT  NIC_SMSC
        EXPORT  NIC_DM9000

        IMPORT  GPMC_Enable
        IMPORT  memcpy
        IMPORT  GPIOx_SetAndEnableIRQ

NIC_Init
        ; a1 = GPMC CS
        ; a2 = GPMC configuration
        ; a3 = GPIO IRQ
        ; a4 = HAL device template
        ; v1 = amount of memory to map in
        Entry   "v2"
        ; First copy the HAL device template into our workspace
        Push    "a1-a3"
        ADRL    v2, NICWS
        MOV     a1, v2
        MOV     a2, a4
        MOV     a3, #NIC_DeviceSize
        BL      memcpy
        STR     sb, [v2, #:INDEX:NICWorkspace]
        Pull    "a1-a3"
        STRB    a1, [v2, #HALDevice_Location+1] ; Might as well fill in the GPMC CS #
        STR     a3, [v2, #:INDEX:NICGPIO]
        ; Work out what IRQ that GPIO corresponds to
        GPIO_GetIRQR a3, a3
        ORR     a3, a3, #1:SHL:31
        STR     a3, [v2, #HALDevice_Device]
        ; Set up the GPMC bus
        BL      GPMC_Enable
        ; We now have a2=base addr, a3=size
        ; Map it in, but using the supplied size (v1), since no NIC is going to need 16MB of address space
        MOV     a1, #0
        MOV     a3, v1
        CallOS  OS_MapInIO
        STR     a1, [v2, #HALDevice_Address]
        ; Now register the HAL device
        MOV     a1, #0
        MOV     a2, v2
        CallOS  OS_AddDevice
        EXIT

; These boards use the same GPMC config values
NIC_GPMC_Config_IGEP
NIC_GPMC_Config_DevKit
        DCD     &00001000 ; GPMC_CONFIG1
        DCD     &001E1E01 ; GPMC_CONFIG2 note - DevKit version of u-boot has CSONTIME of 0, but DevKit code in mainline u-boot has CSONTIME of 1.
        DCD     &00080300 ; GPMC_CONFIG3
        DCD     &1C091C09 ; GPMC_CONFIG4
        DCD     &04181F1F ; GPMC_CONFIG5
        DCD     &00000FCF ; GPMC_CONFIG6
        DCD     &00000F6C ; GPMC_CONFIG7 (16mb CS @ &26000000)

; HAL device template for SMSC NIC
NIC_SMSC
        DCW     HALDeviceType_Comms + HALDeviceComms_EtherNIC
        DCW     HALDeviceID_EtherNIC_SMSC9221
        DCD     HALDeviceBus_Exp + HALDeviceExpBus_GPMC
        DCD     0               ; API version
        DCD     SMSCDesc        ; Description
        DCD     0               ; Address - filled in later
        %       12              ; Reserved
        DCD     NICActivate
        DCD     NICDeactivate
        DCD     NICReset
        DCD     NICSleep
        DCD     0               ; Device - filled in later
        DCD     NICTestIRQ      ; TestIRQ
        DCD     NICClearIRQ     ; ClearIRQ
        %       4
        ASSERT  (.-NIC_SMSC) = HALDeviceSize
        DCD     0               ; HAL workspace
        DCD     0               ; GPIO IRQ #
        DCD     GPIO_LEVELDETECT0_FLAG ; SMSC9221 uses active-low IRQ by default
        ASSERT  (.-NIC_SMSC) = NIC_DeviceSize

; HAL device template for DM9000 NIC
NIC_DM9000
        DCW     HALDeviceType_Comms + HALDeviceComms_EtherNIC
        DCW     HALDeviceID_EtherNIC_DM9000
        DCD     HALDeviceBus_Exp + HALDeviceExpBus_GPMC
        DCD     0               ; API version
        DCD     DM9000Desc      ; Description
        DCD     0               ; Address - filled in later
        %       12              ; Reserved
        DCD     NICActivate
        DCD     NICDeactivate
        DCD     NICReset
        DCD     NICSleep
        DCD     0               ; Device - filled in later
        DCD     NICTestIRQ      ; TestIRQ
        DCD     NICClearIRQ     ; ClearIRQ
        %       4
        ASSERT  (.-NIC_DM9000) = HALDeviceSize
        DCD     0               ; HAL workspace
        DCD     0               ; GPIO IRQ #
        DCD     GPIO_LEVELDETECT0_FLAG ; DM9000 uses active-low IRQ by default
        ASSERT  (.-NIC_DM9000) = NIC_DeviceSize

SMSCDesc
        =       "SMSC LAN9221 NIC", 0
DM9000Desc
        =       "DAVICOM DM9000 NIC", 0
        ALIGN

NICActivate
        ; Configure GPIO IRQ
        Entry   "sb"
        LDR     sb, NICWorkspace
        LDR     a2, NICGPIO_Mode
        LDR     a1, NICGPIO
        BL      GPIOx_SetAndEnableIRQ
        MOV     a1, #1
        EXIT

NICDeactivate
        ; Disable GPIO IRQ
        Entry   "sb"
        LDR     sb, NICWorkspace
        LDR     ip, NICGPIO
        GPIO_PrepareR a2, a3, ip
        STR     a3, [a2, #GPIO_CLEARIRQENABLE1]
        EXIT

NICReset
        ; What should we do here?
        MOV     pc, lr

NICSleep
        ; Nothing we can do
        MOV     a1, #0
        MOV     pc, lr

NICTestIRQ
        LDR     ip, NICGPIO
        MOV     a3, #1
        LDR     a4, NICWorkspace
        MOV     a2, ip, LSR #5
        ADD     a2, a4, a2, LSL #2
        LDR     a2, [a2, #:INDEX:L4_GPIO_Table]
        LDR     a1, [a2, #GPIO_IRQSTATUS1]
        AND     a1, a3, a1, ROR ip
        MOV     pc, lr

NICClearIRQ
        Entry   "sb"
        LDR     ip, NICGPIO
        LDR     sb, NICWorkspace
        GPIO_PrepareR a1, a2, ip
        STR     a2, [a1, #GPIO_IRQSTATUS1]
        EXIT

        END