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