1/* 2 * Copyright 2017, Data61 3 * Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4 * ABN 41 687 119 230. 5 * 6 * This software may be distributed and modified according to the terms of 7 * the BSD 2-Clause license. Note that NO WARRANTY is provided. 8 * See "LICENSE_BSD2.txt" for details. 9 * 10 * @TAG(DATA61_BSD) 11 */ 12#include <platsupport/src.h> 13#include "../../services.h" 14 15/** PWRREG **/ 16#define PWRREG_PHY_CONTROL_OFFSET 0x708 17#define PWRREG_PHY_CONTROL_PHY_EN BIT(0) 18#define PWRREG_SWRST_OFFSET 0x400 19#define PWRREG_SWRST BIT(0) 20 21/** SYSREG **/ 22#define SYSREG_PHY_CONFIG_OFFSET 0x230 23#define SYSREG_PHY_CONFIG_PHY_EN BIT(0) 24 25struct src_priv { 26 void* sysreg_vaddr[1]; 27 void* pwrreg_vaddr[5]; 28}; 29 30struct src_priv _src_priv; 31 32static inline struct src_priv* 33src_get_priv(src_dev_t* d) { 34 return (struct src_priv*)d->priv; 35} 36 37static inline volatile uint32_t* 38sreg(struct src_priv* src, int offset) 39{ 40 void* reg = src->sysreg_vaddr[offset >> 12] + (offset & MASK(12)); 41 return (volatile uint32_t*)reg; 42} 43 44static inline volatile uint32_t* 45preg(struct src_priv* src, int offset) 46{ 47 void* reg_base; 48 reg_base = src->pwrreg_vaddr[offset >> 12]; 49 if (reg_base) { 50 return (volatile uint32_t*)(reg_base + (offset & MASK(12))); 51 } else { 52 return NULL; 53 } 54} 55 56int 57sysreg_usbphy_enable(src_dev_t* dev) 58{ 59 volatile uint32_t* a; 60 struct src_priv* priv = src_get_priv(dev); 61 a = sreg(priv, SYSREG_PHY_CONFIG_OFFSET); 62 if (a) { 63 *a |= SYSREG_PHY_CONFIG_PHY_EN; 64 } 65 a = preg(priv, PWRREG_PHY_CONTROL_OFFSET); 66 if (a) { 67 *a |= PWRREG_PHY_CONTROL_PHY_EN; 68 } 69 return 0; 70} 71 72int 73sysreg_swrst_enable(src_dev_t* dev) 74{ 75 struct src_priv* priv = src_get_priv(dev); 76 volatile uint32_t* a; 77 a = preg(priv, PWRREG_SWRST_OFFSET); 78 if (a) { 79 LOG_INFO("Software reset triggered"); 80 fflush(stdout); 81 *a = PWRREG_SWRST; 82 while (1); 83 } 84 return 0; 85} 86 87void 88reset_controller_assert_reset(src_dev_t* dev, enum src_rst_id id) 89{ 90 switch (id) { 91 case SRCRST_SW_RST: 92 sysreg_swrst_enable(dev); 93 break; 94 case SRCRST_USBPHY_EN: 95 sysreg_usbphy_enable(dev); 96 break; 97 default: 98 LOG_ERROR("Invalid option: %d", id); 99 } 100} 101 102int 103reset_controller_init(enum src_id id, ps_io_ops_t* ops, src_dev_t* dev) 104{ 105 struct src_priv* src_priv = &_src_priv; 106 int i; 107 /* Sanity check the provided ID */ 108 if (id < 0 || id >= NSRC) { 109 return -1; 110 } 111 /* Map sysreg memory */ 112 for (i = 0; i < EXYNOS_SYSREG_SIZE >> 12; i++) { 113 if (src_priv->sysreg_vaddr[i] == NULL) { 114 void *vaddr; 115 vaddr = ps_io_map(&ops->io_mapper, 116 EXYNOS_SYSREG_PADDR + i * BIT(12), 117 0x1000, 0, PS_MEM_NORMAL); 118 src_priv->sysreg_vaddr[i] = vaddr; 119 } 120 } 121 /* Map pmu memory */ 122 for (i = 0; i < EXYNOS_PMU_SIZE >> 12; i++) { 123 if (src_priv->pwrreg_vaddr[i] == NULL) { 124 void *vaddr; 125 vaddr = ps_io_map(&ops->io_mapper, 126 EXYNOS_PMU_PADDR + i * BIT(12), 127 0x1000 , 0, PS_MEM_NORMAL); 128 129 src_priv->pwrreg_vaddr[i] = vaddr; 130 } 131 } 132 /* Assign private data */ 133 dev->priv = src_priv; 134 return 0; 135} 136