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 /* GPIO/perihperal function select */ 28 #define PFC_GPSR2 0xE6060108 29 #define PFC_GPSR6 0xE6060118 30 31 static void gpio_set_value(uint32_t addr, uint8_t gpio, uint32_t val) 32 { 33 uint32_t reg; 34 35 reg = mmio_read_32(addr); 36 if (val) 37 reg |= (1 << gpio); 38 else 39 reg &= ~(1 << gpio); 40 mmio_write_32(addr, reg); 41 } 42 43 static void gpio_direction_output(uint32_t addr, uint8_t gpio) 44 { 45 uint32_t reg; 46 47 reg = mmio_read_32(addr); 48 reg |= (1 << gpio); 49 mmio_write_32(addr, reg); 50 } 51 52 static void gpio_pfc(uint32_t addr, uint8_t gpio) 53 { 54 uint32_t reg; 55 56 reg = mmio_read_32(addr); 57 reg &= ~(1 << gpio); 58 mmio_write_32(PFC_PMMR, ~reg); 59 mmio_write_32(addr, reg); 60 } 61 62 static void cpld_write(uint8_t addr, uint32_t data) 63 { 64 int i; 65 66 for (i = 0; i < 32; i++) { 67 /* MSB first */ 68 gpio_set_value(GPIO_OUTDT6, MOSI, data & (1 << 31)); 69 gpio_set_value(GPIO_OUTDT6, SCLK, 1); 70 data <<= 1; 71 gpio_set_value(GPIO_OUTDT6, SCLK, 0); 72 } 73 74 for (i = 0; i < 8; i++) { 75 /* MSB first */ 76 gpio_set_value(GPIO_OUTDT6, MOSI, addr & 0x80); 77 gpio_set_value(GPIO_OUTDT6, SCLK, 1); 78 addr <<= 1; 79 gpio_set_value(GPIO_OUTDT6, SCLK, 0); 80 } 81 82 /* WRITE */ 83 gpio_set_value(GPIO_OUTDT6, MOSI, 1); 84 gpio_set_value(GPIO_OUTDT2, SSTBZ, 0); 85 gpio_set_value(GPIO_OUTDT6, SCLK, 1); 86 gpio_set_value(GPIO_OUTDT6, SCLK, 0); 87 gpio_set_value(GPIO_OUTDT2, SSTBZ, 1); 88 } 89 90 static void cpld_init(void) 91 { 92 gpio_pfc(PFC_GPSR6, SCLK); 93 gpio_pfc(PFC_GPSR2, SSTBZ); 94 gpio_pfc(PFC_GPSR6, MOSI); 95 96 gpio_set_value(GPIO_OUTDT6, SCLK, 0); 97 gpio_set_value(GPIO_OUTDT2, SSTBZ, 1); 98 gpio_set_value(GPIO_OUTDT6, MOSI, 0); 99 100 gpio_direction_output(GPIO_INOUTSEL6, SCLK); 101 gpio_direction_output(GPIO_INOUTSEL2, SSTBZ); 102 gpio_direction_output(GPIO_INOUTSEL6, MOSI); 103 } 104 105 void rcar_cpld_reset_cpu(void) 106 { 107 cpld_init(); 108 109 cpld_write(CPLD_ADDR_RESET, 1); 110 } 111