uboot/board/microchip/mpfs_icicle/mpfs_icicle.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Copyright (C) 2019 Microchip Technology Inc.
   4 * Padmarao Begari <padmarao.begari@microchip.com>
   5 */
   6
   7#include <common.h>
   8#include <dm.h>
   9#include <env.h>
  10#include <init.h>
  11#include <asm/global_data.h>
  12#include <asm/io.h>
  13
  14DECLARE_GLOBAL_DATA_PTR;
  15
  16#define MPFS_SYSREG_SOFT_RESET          ((unsigned int *)0x20002088)
  17#define MPFS_SYS_SERVICE_CR             ((unsigned int *)0x37020050)
  18#define MPFS_SYS_SERVICE_SR             ((unsigned int *)0x37020054)
  19#define MPFS_SYS_SERVICE_MAILBOX        ((unsigned char *)0x37020800)
  20
  21#define PERIPH_RESET_VALUE              0x1e8u
  22#define SERVICE_CR_REQ                  0x1u
  23#define SERVICE_SR_BUSY                 0x2u
  24
  25static void read_device_serial_number(u8 *response, u8 response_size)
  26{
  27        u8 idx;
  28        u8 *response_buf;
  29        unsigned int val;
  30
  31        response_buf = (u8 *)response;
  32
  33        writel(SERVICE_CR_REQ, MPFS_SYS_SERVICE_CR);
  34        /*
  35         * REQ bit will remain set till the system controller starts
  36         * processing.
  37         */
  38        do {
  39                val = readl(MPFS_SYS_SERVICE_CR);
  40        } while (SERVICE_CR_REQ == (val & SERVICE_CR_REQ));
  41
  42        /*
  43         * Once system controller starts processing the busy bit will
  44         * go high and service is completed when busy bit is gone low
  45         */
  46        do {
  47                val = readl(MPFS_SYS_SERVICE_SR);
  48        } while (SERVICE_SR_BUSY == (val & SERVICE_SR_BUSY));
  49
  50        for (idx = 0; idx < response_size; idx++)
  51                response_buf[idx] = readb(MPFS_SYS_SERVICE_MAILBOX + idx);
  52}
  53
  54int board_init(void)
  55{
  56        /* For now nothing to do here. */
  57
  58        return 0;
  59}
  60
  61int board_early_init_f(void)
  62{
  63        unsigned int val;
  64
  65        /* Reset uart, mmc peripheral */
  66        val = readl(MPFS_SYSREG_SOFT_RESET);
  67        val = (val & ~(PERIPH_RESET_VALUE));
  68        writel(val, MPFS_SYSREG_SOFT_RESET);
  69
  70        return 0;
  71}
  72
  73int board_late_init(void)
  74{
  75        u32 ret;
  76        u32 node;
  77        u8 idx;
  78        u8 device_serial_number[16] = { 0 };
  79        unsigned char mac_addr[6];
  80        char icicle_mac_addr[20];
  81        void *blob = (void *)gd->fdt_blob;
  82
  83        node = fdt_path_offset(blob, "ethernet0");
  84        if (node < 0) {
  85                printf("No ethernet0 path offset\n");
  86                return -ENODEV;
  87        }
  88
  89        ret = fdtdec_get_byte_array(blob, node, "local-mac-address", mac_addr, 6);
  90        if (ret) {
  91                printf("No local-mac-address property\n");
  92                return -EINVAL;
  93        }
  94
  95        read_device_serial_number(device_serial_number, 16);
  96
  97        /* Update MAC address with device serial number */
  98        mac_addr[0] = 0x00;
  99        mac_addr[1] = 0x04;
 100        mac_addr[2] = 0xA3;
 101        mac_addr[3] = device_serial_number[2];
 102        mac_addr[4] = device_serial_number[1];
 103        mac_addr[5] = device_serial_number[0];
 104
 105        ret = fdt_setprop(blob, node, "local-mac-address", mac_addr, 6);
 106        if (ret) {
 107                printf("Error setting local-mac-address property\n");
 108                return -ENODEV;
 109        }
 110
 111        icicle_mac_addr[0] = '[';
 112
 113        sprintf(&icicle_mac_addr[1], "%pM", mac_addr);
 114
 115        icicle_mac_addr[18] = ']';
 116        icicle_mac_addr[19] = '\0';
 117
 118        for (idx = 0; idx < 20; idx++) {
 119                if (icicle_mac_addr[idx] == ':')
 120                        icicle_mac_addr[idx] = ' ';
 121        }
 122        env_set("icicle_mac_addr0", icicle_mac_addr);
 123
 124        mac_addr[5] = device_serial_number[0] + 1;
 125
 126        icicle_mac_addr[0] = '[';
 127
 128        sprintf(&icicle_mac_addr[1], "%pM", mac_addr);
 129
 130        icicle_mac_addr[18] = ']';
 131        icicle_mac_addr[19] = '\0';
 132
 133        for (idx = 0; idx < 20; idx++) {
 134                if (icicle_mac_addr[idx] == ':')
 135                        icicle_mac_addr[idx] = ' ';
 136        }
 137        env_set("icicle_mac_addr1", icicle_mac_addr);
 138
 139        return 0;
 140}
 141