1*91f16700Schasinglulu /* 2*91f16700Schasinglulu * Copyright (c) 2018, Renesas Electronics Corporation. All rights reserved. 3*91f16700Schasinglulu * 4*91f16700Schasinglulu * SPDX-License-Identifier: BSD-3-Clause 5*91f16700Schasinglulu */ 6*91f16700Schasinglulu 7*91f16700Schasinglulu #include <lib/mmio.h> 8*91f16700Schasinglulu #include "ulcb_cpld.h" 9*91f16700Schasinglulu 10*91f16700Schasinglulu #define SCLK 8 /* GP_6_8 */ 11*91f16700Schasinglulu #define SSTBZ 3 /* GP_2_3 */ 12*91f16700Schasinglulu #define MOSI 7 /* GP_6_7 */ 13*91f16700Schasinglulu 14*91f16700Schasinglulu #define CPLD_ADDR_RESET 0x80 /* RW */ 15*91f16700Schasinglulu 16*91f16700Schasinglulu /* LSI Multiplexed Pin Setting Mask Register */ 17*91f16700Schasinglulu #define PFC_PMMR 0xE6060000 18*91f16700Schasinglulu 19*91f16700Schasinglulu /* General output registers */ 20*91f16700Schasinglulu #define GPIO_OUTDT2 0xE6052008 21*91f16700Schasinglulu #define GPIO_OUTDT6 0xE6055408 22*91f16700Schasinglulu 23*91f16700Schasinglulu /* General input/output switching registers */ 24*91f16700Schasinglulu #define GPIO_INOUTSEL2 0xE6052004 25*91f16700Schasinglulu #define GPIO_INOUTSEL6 0xE6055404 26*91f16700Schasinglulu 27*91f16700Schasinglulu /* General IO/Interrupt Switching Register */ 28*91f16700Schasinglulu #define GPIO_IOINTSEL6 0xE6055400 29*91f16700Schasinglulu 30*91f16700Schasinglulu /* GPIO/perihperal function select */ 31*91f16700Schasinglulu #define PFC_GPSR2 0xE6060108 32*91f16700Schasinglulu #define PFC_GPSR6 0xE6060118 33*91f16700Schasinglulu 34*91f16700Schasinglulu static void gpio_set_value(uint32_t addr, uint8_t gpio, uint32_t val) 35*91f16700Schasinglulu { 36*91f16700Schasinglulu uint32_t reg; 37*91f16700Schasinglulu 38*91f16700Schasinglulu reg = mmio_read_32(addr); 39*91f16700Schasinglulu if (val) 40*91f16700Schasinglulu reg |= (1 << gpio); 41*91f16700Schasinglulu else 42*91f16700Schasinglulu reg &= ~(1 << gpio); 43*91f16700Schasinglulu mmio_write_32(addr, reg); 44*91f16700Schasinglulu } 45*91f16700Schasinglulu 46*91f16700Schasinglulu static void gpio_direction_output(uint32_t addr, uint8_t gpio) 47*91f16700Schasinglulu { 48*91f16700Schasinglulu uint32_t reg; 49*91f16700Schasinglulu 50*91f16700Schasinglulu reg = mmio_read_32(addr); 51*91f16700Schasinglulu reg |= (1 << gpio); 52*91f16700Schasinglulu mmio_write_32(addr, reg); 53*91f16700Schasinglulu } 54*91f16700Schasinglulu 55*91f16700Schasinglulu static void gpio_pfc(uint32_t addr, uint8_t gpio) 56*91f16700Schasinglulu { 57*91f16700Schasinglulu uint32_t reg; 58*91f16700Schasinglulu 59*91f16700Schasinglulu reg = mmio_read_32(addr); 60*91f16700Schasinglulu reg &= ~(1 << gpio); 61*91f16700Schasinglulu mmio_write_32(PFC_PMMR, ~reg); 62*91f16700Schasinglulu mmio_write_32(addr, reg); 63*91f16700Schasinglulu } 64*91f16700Schasinglulu 65*91f16700Schasinglulu static void cpld_write(uint8_t addr, uint32_t data) 66*91f16700Schasinglulu { 67*91f16700Schasinglulu int i; 68*91f16700Schasinglulu 69*91f16700Schasinglulu for (i = 0; i < 32; i++) { 70*91f16700Schasinglulu /* MSB first */ 71*91f16700Schasinglulu gpio_set_value(GPIO_OUTDT6, MOSI, data & (1U << 31)); 72*91f16700Schasinglulu gpio_set_value(GPIO_OUTDT6, SCLK, 1); 73*91f16700Schasinglulu data <<= 1; 74*91f16700Schasinglulu gpio_set_value(GPIO_OUTDT6, SCLK, 0); 75*91f16700Schasinglulu } 76*91f16700Schasinglulu 77*91f16700Schasinglulu for (i = 0; i < 8; i++) { 78*91f16700Schasinglulu /* MSB first */ 79*91f16700Schasinglulu gpio_set_value(GPIO_OUTDT6, MOSI, addr & 0x80); 80*91f16700Schasinglulu gpio_set_value(GPIO_OUTDT6, SCLK, 1); 81*91f16700Schasinglulu addr <<= 1; 82*91f16700Schasinglulu gpio_set_value(GPIO_OUTDT6, SCLK, 0); 83*91f16700Schasinglulu } 84*91f16700Schasinglulu 85*91f16700Schasinglulu /* WRITE */ 86*91f16700Schasinglulu gpio_set_value(GPIO_OUTDT6, MOSI, 1); 87*91f16700Schasinglulu gpio_set_value(GPIO_OUTDT2, SSTBZ, 0); 88*91f16700Schasinglulu gpio_set_value(GPIO_OUTDT6, SCLK, 1); 89*91f16700Schasinglulu gpio_set_value(GPIO_OUTDT6, SCLK, 0); 90*91f16700Schasinglulu gpio_set_value(GPIO_OUTDT2, SSTBZ, 1); 91*91f16700Schasinglulu } 92*91f16700Schasinglulu 93*91f16700Schasinglulu static void cpld_init(void) 94*91f16700Schasinglulu { 95*91f16700Schasinglulu gpio_pfc(PFC_GPSR6, SCLK); 96*91f16700Schasinglulu gpio_pfc(PFC_GPSR2, SSTBZ); 97*91f16700Schasinglulu gpio_pfc(PFC_GPSR6, MOSI); 98*91f16700Schasinglulu 99*91f16700Schasinglulu gpio_set_value(GPIO_IOINTSEL6, SCLK, 0); 100*91f16700Schasinglulu gpio_set_value(GPIO_OUTDT6, SCLK, 0); 101*91f16700Schasinglulu gpio_set_value(GPIO_OUTDT2, SSTBZ, 1); 102*91f16700Schasinglulu gpio_set_value(GPIO_OUTDT6, MOSI, 0); 103*91f16700Schasinglulu 104*91f16700Schasinglulu gpio_direction_output(GPIO_INOUTSEL6, SCLK); 105*91f16700Schasinglulu gpio_direction_output(GPIO_INOUTSEL2, SSTBZ); 106*91f16700Schasinglulu gpio_direction_output(GPIO_INOUTSEL6, MOSI); 107*91f16700Schasinglulu } 108*91f16700Schasinglulu 109*91f16700Schasinglulu void rcar_cpld_reset_cpu(void) 110*91f16700Schasinglulu { 111*91f16700Schasinglulu cpld_init(); 112*91f16700Schasinglulu 113*91f16700Schasinglulu cpld_write(CPLD_ADDR_RESET, 1); 114*91f16700Schasinglulu } 115