Home | History | Annotate | Download | only in kmp204x
      1 // SPDX-License-Identifier: GPL-2.0+
      2 /*
      3  * (C) Copyright 2013 Keymile AG
      4  * Valentin Longchamp <valentin.longchamp (at) keymile.com>
      5  */
      6 
      7 #include <common.h>
      8 
      9 #include "../common/common.h"
     10 #include "kmp204x.h"
     11 
     12 /* QRIO GPIO register offsets */
     13 #define DIRECT_OFF		0x18
     14 #define GPRT_OFF		0x1c
     15 
     16 int qrio_get_gpio(u8 port_off, u8 gpio_nr)
     17 {
     18 	u32 gprt;
     19 
     20 	void __iomem *qrio_base = (void *)CONFIG_SYS_QRIO_BASE;
     21 
     22 	gprt = in_be32(qrio_base + port_off + GPRT_OFF);
     23 
     24 	return (gprt >> gpio_nr) & 1U;
     25 }
     26 
     27 void qrio_set_gpio(u8 port_off, u8 gpio_nr, bool value)
     28 {
     29 	u32 gprt, mask;
     30 
     31 	void __iomem *qrio_base = (void *)CONFIG_SYS_QRIO_BASE;
     32 
     33 	mask = 1U << gpio_nr;
     34 
     35 	gprt = in_be32(qrio_base + port_off + GPRT_OFF);
     36 	if (value)
     37 		gprt |= mask;
     38 	else
     39 		gprt &= ~mask;
     40 
     41 	out_be32(qrio_base + port_off + GPRT_OFF, gprt);
     42 }
     43 
     44 void qrio_gpio_direction_output(u8 port_off, u8 gpio_nr, bool value)
     45 {
     46 	u32 direct, mask;
     47 
     48 	void __iomem *qrio_base = (void *)CONFIG_SYS_QRIO_BASE;
     49 
     50 	mask = 1U << gpio_nr;
     51 
     52 	direct = in_be32(qrio_base + port_off + DIRECT_OFF);
     53 	direct |= mask;
     54 	out_be32(qrio_base + port_off + DIRECT_OFF, direct);
     55 
     56 	qrio_set_gpio(port_off, gpio_nr, value);
     57 }
     58 
     59 void qrio_gpio_direction_input(u8 port_off, u8 gpio_nr)
     60 {
     61 	u32 direct, mask;
     62 
     63 	void __iomem *qrio_base = (void *)CONFIG_SYS_QRIO_BASE;
     64 
     65 	mask = 1U << gpio_nr;
     66 
     67 	direct = in_be32(qrio_base + port_off + DIRECT_OFF);
     68 	direct &= ~mask;
     69 	out_be32(qrio_base + port_off + DIRECT_OFF, direct);
     70 }
     71 
     72 void qrio_set_opendrain_gpio(u8 port_off, u8 gpio_nr, u8 val)
     73 {
     74 	u32 direct, mask;
     75 
     76 	void __iomem *qrio_base = (void *)CONFIG_SYS_QRIO_BASE;
     77 
     78 	mask = 1U << gpio_nr;
     79 
     80 	direct = in_be32(qrio_base + port_off + DIRECT_OFF);
     81 	if (val == 0)
     82 		/* set to output -> GPIO drives low */
     83 		direct |= mask;
     84 	else
     85 		/* set to input -> GPIO floating */
     86 		direct &= ~mask;
     87 
     88 	out_be32(qrio_base + port_off + DIRECT_OFF, direct);
     89 }
     90 
     91 #define WDMASK_OFF	0x16
     92 
     93 void qrio_wdmask(u8 bit, bool wden)
     94 {
     95 	u16 wdmask;
     96 	void __iomem *qrio_base = (void *)CONFIG_SYS_QRIO_BASE;
     97 
     98 	wdmask = in_be16(qrio_base + WDMASK_OFF);
     99 
    100 	if (wden)
    101 		wdmask |= (1 << bit);
    102 	else
    103 		wdmask &= ~(1 << bit);
    104 
    105 	out_be16(qrio_base + WDMASK_OFF, wdmask);
    106 }
    107 
    108 #define PRST_OFF	0x1a
    109 
    110 void qrio_prst(u8 bit, bool en, bool wden)
    111 {
    112 	u16 prst;
    113 	void __iomem *qrio_base = (void *)CONFIG_SYS_QRIO_BASE;
    114 
    115 	qrio_wdmask(bit, wden);
    116 
    117 	prst = in_be16(qrio_base + PRST_OFF);
    118 
    119 	if (en)
    120 		prst &= ~(1 << bit);
    121 	else
    122 		prst |= (1 << bit);
    123 
    124 	out_be16(qrio_base + PRST_OFF, prst);
    125 }
    126 
    127 #define PRSTCFG_OFF	0x1c
    128 
    129 void qrio_prstcfg(u8 bit, u8 mode)
    130 {
    131 	u32 prstcfg;
    132 	u8 i;
    133 	void __iomem *qrio_base = (void *)CONFIG_SYS_QRIO_BASE;
    134 
    135 	prstcfg = in_be32(qrio_base + PRSTCFG_OFF);
    136 
    137 	for (i = 0; i < 2; i++) {
    138 		if (mode & (1<<i))
    139 			set_bit(2*bit+i, &prstcfg);
    140 		else
    141 			clear_bit(2*bit+i, &prstcfg);
    142 	}
    143 
    144 	out_be32(qrio_base + PRSTCFG_OFF, prstcfg);
    145 }
    146 
    147 #define CTRLH_OFF		0x02
    148 #define CTRLH_WRL_BOOT		0x01
    149 #define CTRLH_WRL_UNITRUN	0x02
    150 
    151 void qrio_set_leds(void)
    152 {
    153 	u8 ctrlh;
    154 	void __iomem *qrio_base = (void *)CONFIG_SYS_QRIO_BASE;
    155 
    156 	/* set UNIT LED to RED and BOOT LED to ON */
    157 	ctrlh = in_8(qrio_base + CTRLH_OFF);
    158 	ctrlh |= (CTRLH_WRL_BOOT | CTRLH_WRL_UNITRUN);
    159 	out_8(qrio_base + CTRLH_OFF, ctrlh);
    160 }
    161 
    162 #define CTRLL_OFF		0x03
    163 #define CTRLL_WRB_BUFENA	0x20
    164 
    165 void qrio_enable_app_buffer(void)
    166 {
    167 	u8 ctrll;
    168 	void __iomem *qrio_base = (void *)CONFIG_SYS_QRIO_BASE;
    169 
    170 	/* enable application buffer */
    171 	ctrll = in_8(qrio_base + CTRLL_OFF);
    172 	ctrll |= (CTRLL_WRB_BUFENA);
    173 	out_8(qrio_base + CTRLL_OFF, ctrll);
    174 }
    175 
    176 #define REASON1_OFF	0x12
    177 #define REASON1_CPUWD	0x01
    178 
    179 void qrio_cpuwd_flag(bool flag)
    180 {
    181 	u8 reason1;
    182 	void __iomem *qrio_base = (void *)CONFIG_SYS_QRIO_BASE;
    183 	reason1 = in_8(qrio_base + REASON1_OFF);
    184 	if (flag)
    185 		reason1 |= REASON1_CPUWD;
    186 	else
    187 		reason1 &= ~REASON1_CPUWD;
    188 	out_8(qrio_base + REASON1_OFF, reason1);
    189 }
    190 
    191 #define RSTCFG_OFF	0x11
    192 
    193 void qrio_uprstreq(u8 mode)
    194 {
    195 	u32 rstcfg;
    196 	void __iomem *qrio_base = (void *)CONFIG_SYS_QRIO_BASE;
    197 
    198 	rstcfg = in_8(qrio_base + RSTCFG_OFF);
    199 
    200 	if (mode & UPREQ_CORE_RST)
    201 		rstcfg |= UPREQ_CORE_RST;
    202 	else
    203 		rstcfg &= ~UPREQ_CORE_RST;
    204 
    205 	out_8(qrio_base + RSTCFG_OFF, rstcfg);
    206 }
    207