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