1*2d48caa4SMike Looijmans /* 2*2d48caa4SMike Looijmans * (c) Copyright 2010-2014 Xilinx, Inc. All rights reserved. 3*2d48caa4SMike Looijmans * (c) Copyright 2016 Topic Embedded Products. 4*2d48caa4SMike Looijmans * 5*2d48caa4SMike Looijmans * SPDX-License-Identifier: GPL-2.0+ 6*2d48caa4SMike Looijmans */ 7*2d48caa4SMike Looijmans 8*2d48caa4SMike Looijmans #include "ps7_init_gpl.h" 9*2d48caa4SMike Looijmans #include <asm/io.h> 10*2d48caa4SMike Looijmans 11*2d48caa4SMike Looijmans /* For delay calculation using global registers*/ 12*2d48caa4SMike Looijmans #define SCU_GLOBAL_TIMER_COUNT_L32 0xF8F00200 13*2d48caa4SMike Looijmans #define SCU_GLOBAL_TIMER_COUNT_U32 0xF8F00204 14*2d48caa4SMike Looijmans #define SCU_GLOBAL_TIMER_CONTROL 0xF8F00208 15*2d48caa4SMike Looijmans #define SCU_GLOBAL_TIMER_AUTO_INC 0xF8F00218 16*2d48caa4SMike Looijmans #define APU_FREQ 666666666 17*2d48caa4SMike Looijmans 18*2d48caa4SMike Looijmans #define PS7_MASK_POLL_TIME 100000000 19*2d48caa4SMike Looijmans 20*2d48caa4SMike Looijmans /* IO accessors. No memory barriers desired. */ iowrite(unsigned long val,unsigned long addr)21*2d48caa4SMike Looijmansstatic inline void iowrite(unsigned long val, unsigned long addr) 22*2d48caa4SMike Looijmans { 23*2d48caa4SMike Looijmans __raw_writel(val, addr); 24*2d48caa4SMike Looijmans } 25*2d48caa4SMike Looijmans ioread(unsigned long addr)26*2d48caa4SMike Looijmansstatic inline unsigned long ioread(unsigned long addr) 27*2d48caa4SMike Looijmans { 28*2d48caa4SMike Looijmans return __raw_readl(addr); 29*2d48caa4SMike Looijmans } 30*2d48caa4SMike Looijmans 31*2d48caa4SMike Looijmans /* start timer */ perf_start_clock(void)32*2d48caa4SMike Looijmansstatic void perf_start_clock(void) 33*2d48caa4SMike Looijmans { 34*2d48caa4SMike Looijmans iowrite((1 << 0) | /* Timer Enable */ 35*2d48caa4SMike Looijmans (1 << 3) | /* Auto-increment */ 36*2d48caa4SMike Looijmans (0 << 8), /* Pre-scale */ 37*2d48caa4SMike Looijmans SCU_GLOBAL_TIMER_CONTROL); 38*2d48caa4SMike Looijmans } 39*2d48caa4SMike Looijmans 40*2d48caa4SMike Looijmans /* Compute mask for given delay in miliseconds*/ get_number_of_cycles_for_delay(unsigned int delay)41*2d48caa4SMike Looijmansstatic int get_number_of_cycles_for_delay(unsigned int delay) 42*2d48caa4SMike Looijmans { 43*2d48caa4SMike Looijmans return (APU_FREQ / (2 * 1000)) * delay; 44*2d48caa4SMike Looijmans } 45*2d48caa4SMike Looijmans 46*2d48caa4SMike Looijmans /* stop timer */ perf_disable_clock(void)47*2d48caa4SMike Looijmansstatic void perf_disable_clock(void) 48*2d48caa4SMike Looijmans { 49*2d48caa4SMike Looijmans iowrite(0, SCU_GLOBAL_TIMER_CONTROL); 50*2d48caa4SMike Looijmans } 51*2d48caa4SMike Looijmans 52*2d48caa4SMike Looijmans /* stop timer and reset timer count regs */ perf_reset_clock(void)53*2d48caa4SMike Looijmansstatic void perf_reset_clock(void) 54*2d48caa4SMike Looijmans { 55*2d48caa4SMike Looijmans perf_disable_clock(); 56*2d48caa4SMike Looijmans iowrite(0, SCU_GLOBAL_TIMER_COUNT_L32); 57*2d48caa4SMike Looijmans iowrite(0, SCU_GLOBAL_TIMER_COUNT_U32); 58*2d48caa4SMike Looijmans } 59*2d48caa4SMike Looijmans perf_reset_and_start_timer(void)60*2d48caa4SMike Looijmansstatic void perf_reset_and_start_timer(void) 61*2d48caa4SMike Looijmans { 62*2d48caa4SMike Looijmans perf_reset_clock(); 63*2d48caa4SMike Looijmans perf_start_clock(); 64*2d48caa4SMike Looijmans } 65*2d48caa4SMike Looijmans ps7_config(unsigned long * ps7_config_init)66*2d48caa4SMike Looijmansint ps7_config(unsigned long *ps7_config_init) 67*2d48caa4SMike Looijmans { 68*2d48caa4SMike Looijmans unsigned long *ptr = ps7_config_init; 69*2d48caa4SMike Looijmans unsigned long opcode; 70*2d48caa4SMike Looijmans unsigned long addr; 71*2d48caa4SMike Looijmans unsigned long val; 72*2d48caa4SMike Looijmans unsigned long mask; 73*2d48caa4SMike Looijmans unsigned int numargs; 74*2d48caa4SMike Looijmans int i; 75*2d48caa4SMike Looijmans int delay; 76*2d48caa4SMike Looijmans 77*2d48caa4SMike Looijmans for (;;) { 78*2d48caa4SMike Looijmans opcode = ptr[0]; 79*2d48caa4SMike Looijmans if (opcode == OPCODE_EXIT) 80*2d48caa4SMike Looijmans return PS7_INIT_SUCCESS; 81*2d48caa4SMike Looijmans addr = (opcode & OPCODE_ADDRESS_MASK); 82*2d48caa4SMike Looijmans 83*2d48caa4SMike Looijmans switch (opcode & ~OPCODE_ADDRESS_MASK) { 84*2d48caa4SMike Looijmans case OPCODE_MASKWRITE: 85*2d48caa4SMike Looijmans numargs = 3; 86*2d48caa4SMike Looijmans mask = ptr[1]; 87*2d48caa4SMike Looijmans val = ptr[2]; 88*2d48caa4SMike Looijmans iowrite((ioread(addr) & ~mask) | (val & mask), addr); 89*2d48caa4SMike Looijmans break; 90*2d48caa4SMike Looijmans 91*2d48caa4SMike Looijmans case OPCODE_MASKPOLL: 92*2d48caa4SMike Looijmans numargs = 2; 93*2d48caa4SMike Looijmans mask = ptr[1]; 94*2d48caa4SMike Looijmans i = 0; 95*2d48caa4SMike Looijmans while (!(ioread(addr) & mask)) { 96*2d48caa4SMike Looijmans if (i == PS7_MASK_POLL_TIME) 97*2d48caa4SMike Looijmans return PS7_INIT_TIMEOUT; 98*2d48caa4SMike Looijmans i++; 99*2d48caa4SMike Looijmans } 100*2d48caa4SMike Looijmans break; 101*2d48caa4SMike Looijmans 102*2d48caa4SMike Looijmans case OPCODE_MASKDELAY: 103*2d48caa4SMike Looijmans numargs = 2; 104*2d48caa4SMike Looijmans mask = ptr[1]; 105*2d48caa4SMike Looijmans delay = get_number_of_cycles_for_delay(mask); 106*2d48caa4SMike Looijmans perf_reset_and_start_timer(); 107*2d48caa4SMike Looijmans while (ioread(addr) < delay) 108*2d48caa4SMike Looijmans ; 109*2d48caa4SMike Looijmans break; 110*2d48caa4SMike Looijmans 111*2d48caa4SMike Looijmans default: 112*2d48caa4SMike Looijmans return PS7_INIT_CORRUPT; 113*2d48caa4SMike Looijmans } 114*2d48caa4SMike Looijmans 115*2d48caa4SMike Looijmans ptr += numargs; 116*2d48caa4SMike Looijmans } 117*2d48caa4SMike Looijmans } 118