shithub: riscv

Download patch

ref: fe033ae81611a7a98d51b38ca5a8e9bc5638b996
parent: 8dd05d041ed65e8c74c23baccaf99ba6ad424c39
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Mon Jun 13 19:00:06 EDT 2022

imx8: add gpio helper gpioout()/gpioin()

--- a/sys/src/9/imx8/fns.h
+++ b/sys/src/9/imx8/fns.h
@@ -154,3 +154,8 @@
 /* iomux */
 extern void iomuxpad(char *pads, char *sel, char *cfg);
 extern uint iomuxgpr(int gpr, uint set, uint mask);
+
+/* gpio */
+#define GPIO_PIN(n, m)	(((n)-1)<<5 | (m))
+extern void gpioout(uint pin, int set);
+extern int gpioin(uint pin);
--- /dev/null
+++ b/sys/src/9/imx8/gpio.c
@@ -1,0 +1,78 @@
+#include "u.h"
+#include "../port/lib.h"
+#include "../port/error.h"
+#include "mem.h"
+#include "dat.h"
+#include "fns.h"
+#include "io.h"
+
+/* gpio registers */
+enum {
+	GPIO_DR = 0x00/4,
+	GPIO_GDIR = 0x04/4,
+	GPIO_PSR = 0x08/4,
+	GPIO_ICR1 = 0x0C/4,
+	GPIO_ICR2 = 0x10/4,
+	GPIO_IMR = 0x14/4,
+	GPIO_ISR = 0x18/4,
+	GPIO_EDGE_SEL = 0x1C/4,
+};
+
+typedef struct Ctlr Ctlr;
+struct Ctlr
+{
+	u32int	*reg;
+	char	*clk;
+	u32int	dir;
+	int	enabled;
+};
+
+static Ctlr ctlrs[5] = {
+	{(u32int*)(VIRTIO + 0x200000),	"gpio1.ipg_clk_s" },
+	{(u32int*)(VIRTIO + 0x210000),	"gpio2.ipg_clk_s" },
+	{(u32int*)(VIRTIO + 0x220000),	"gpio3.ipg_clk_s" },
+	{(u32int*)(VIRTIO + 0x230000),	"gpio4.ipg_clk_s" },
+	{(u32int*)(VIRTIO + 0x240000),	"gpio5.ipg_clk_s" },
+};
+
+static Ctlr*
+enable(uint pin)
+{
+	Ctlr *ctlr = &ctlrs[pin/32];
+
+	assert(ctlr < &ctlrs[nelem(ctlrs)]);
+
+	if(!ctlr->enabled){
+		setclkgate(ctlr->clk, 1);
+		ctlr->reg[GPIO_IMR] = 0;
+		ctlr->dir = ctlr->reg[GPIO_GDIR];
+		ctlr->enabled = 1;
+	}
+
+	return ctlr;
+}
+
+void
+gpioout(uint pin, int set)
+{
+	int bit = 1 << (pin % 32);
+	Ctlr *ctlr = enable(pin);
+
+	if((ctlr->dir & bit) == 0)
+		ctlr->reg[GPIO_GDIR] = ctlr->dir |= bit;
+	if(set)
+		ctlr->reg[GPIO_DR] |= bit;
+	else
+		ctlr->reg[GPIO_DR] &= ~bit;
+}
+
+int
+gpioin(uint pin)
+{
+	int bit = 1 << (pin % 32);
+	Ctlr *ctlr = enable(pin);
+
+	if(ctlr->dir & bit)
+		ctlr->reg[GPIO_GDIR] = ctlr->dir &= ~bit;
+	return (ctlr->reg[GPIO_DR] & bit) != 0;
+}
--- a/sys/src/9/imx8/lcd.c
+++ b/sys/src/9/imx8/lcd.c
@@ -14,18 +14,6 @@
 
 extern Memimage *gscreen;
 
-/* gpio registers */
-enum {
-	GPIO_DR = 0x00/4,
-	GPIO_GDIR = 0x04/4,
-	GPIO_PSR = 0x08/4,
-	GPIO_ICR1 = 0x0C/4,
-	GPIO_ICR2 = 0x10/4,
-	GPIO_IMR = 0x14/4,
-	GPIO_ISR = 0x18/4,
-	GPIO_EDGE_SEL = 0x1C/4,
-};
-
 /* system reset controller registers */
 enum {
 	SRC_MIPIPHY_RCR = 0x28/4,
@@ -359,9 +347,6 @@
 
 /* base addresses, VIRTIO is at 0x30000000 physical */
 
-static u32int *gpio1 = (u32int*)(VIRTIO + 0x200000);
-static u32int *gpio3 = (u32int*)(VIRTIO + 0x220000);
-
 static u32int *pwm2 = (u32int*)(VIRTIO + 0x670000);
 
 static u32int *resetc= (u32int*)(VIRTIO + 0x390000);
@@ -802,6 +787,22 @@
 	wr(dsi, DSI_HOST_CFG_DPI_VFP, mode->vso); 
 }
 
+static void
+backlighton(void)
+{
+	/* pwm2_out: for panel backlight */
+	iomuxpad("pad_spdif_rx", "pwm2_out", nil);
+
+	setclkrate("pwm2.ipg_clk_high_freq", "osc_25m_ref_clk", Pwmsrcclk);
+	setclkgate("pwm2.ipg_clk_high_freq", 1);
+
+	wr(pwm2, PWMIR, 0);	
+	wr(pwm2, PWMCR, CR_STOPEN | CR_DOZEN | CR_WAITEN | CR_DBGEN | CR_CLKSRC_HIGHFREQ | 0<<CR_PRESCALER_SHIFT);
+	wr(pwm2, PWMSAR, Pwmsrcclk/150000);
+	wr(pwm2, PWMPR, (Pwmsrcclk/100000)-2);
+	mr(pwm2, PWMCR, CR_EN, CR_EN);
+}
+
 void
 lcdinit(void)
 {
@@ -810,37 +811,25 @@
 	I2Cdev *bridge;
 	char *err;
 
+	/* GPR13[MIPI_MUX_SEL]: 0 = LCDIF, 1 = DCSS */
+	iomuxgpr(13, 0, 1<<2);
+
 	/* gpio3_io20: sn65dsi86 bridge */
 	iomuxpad("pad_sai5_rxc", "gpio3_io20", nil);
 
 	/* gpio1_io10: for panel */
 	iomuxpad("pad_gpio1_io10", "gpio1_io10", nil);	
-
-	/* pwm2_out: for panel backlight */
-	iomuxpad("pad_spdif_rx", "pwm2_out", nil);
 	
-	/* GPR13[MIPI_MUX_SEL]: 0 = LCDIF, 1 = DCSS */
-	iomuxgpr(13, 0, 1<<2);
+	/* gpio1_io10 low: panel off */
+	gpioout(GPIO_PIN(1, 10), 0);
 
-	setclkgate("gpio1.ipg_clk_s", 1);
-	setclkgate("gpio3.ipg_clk_s", 1);
+	backlighton();
 
-	setclkrate("pwm2.ipg_clk_high_freq", "osc_25m_ref_clk", Pwmsrcclk);
-	setclkgate("pwm2.ipg_clk_high_freq", 1);
+	/* gpio1_io10 high: panel on */
+	gpioout(GPIO_PIN(1, 10), 1);
 
-	mr(gpio1, GPIO_GDIR, 1<<10, 1<<10);	/* gpio1 10 output */
-	mr(gpio1, GPIO_DR, 0<<10, 1<<10);	/* gpio1 10 low: panel off */
-
-	wr(pwm2, PWMIR, 0);	
-	wr(pwm2, PWMCR, CR_STOPEN | CR_DOZEN | CR_WAITEN | CR_DBGEN | CR_CLKSRC_HIGHFREQ | 0<<CR_PRESCALER_SHIFT);
-	wr(pwm2, PWMSAR, Pwmsrcclk/150000);
-	wr(pwm2, PWMPR, (Pwmsrcclk/100000)-2);
-	mr(pwm2, PWMCR, CR_EN, CR_EN);
-
-	mr(gpio1, GPIO_DR, 1<<10, 1<<10);	/* gpio1 10 high: panel on */
-
-	mr(gpio3, GPIO_GDIR, 1<<20, 1<<20);	/* gpio3 20 output */
-	mr(gpio3, GPIO_DR, 1<<20, 1<<20);	/* gpio3 20 high: bridge on */
+	/* gpio3_io20 high: bridge on */
+	gpioout(GPIO_PIN(3, 20), 1);
 
 	bridge = i2cdev(i2cbus("i2c4"), 0x2C);
 	if(bridge == nil)
--- a/sys/src/9/imx8/reform
+++ b/sys/src/9/imx8/reform
@@ -37,6 +37,7 @@
 misc
 	ccm
 	gpc
+	gpio
 	gic
 	uartimx
 	lcd
--- a/sys/src/9/imx8/usbxhciimx.c
+++ b/sys/src/9/imx8/usbxhciimx.c
@@ -1786,29 +1786,6 @@
 }
 
 static void
-hubreset(int on)
-{
-	/* gpio registers */
-	enum {
-		GPIO_DR = 0x00/4,
-		GPIO_GDIR = 0x04/4,
-		GPIO_PSR = 0x08/4,
-		GPIO_ICR1 = 0x0C/4,
-		GPIO_ICR2 = 0x10/4,
-		GPIO_IMR = 0x14/4,
-		GPIO_ISR = 0x18/4,
-		GPIO_EDGE_SEL = 0x1C/4,
-	};
-	static u32int *gpio1 = (u32int*)(VIRTIO + 0x200000);
-
-	gpio1[GPIO_GDIR] |= 1<<14;	/* output */
-	if(on)
-		gpio1[GPIO_DR] |= 1<<14;
-	else
-		gpio1[GPIO_DR] &= ~(1<<14);
-}
-
-static void
 phyinit(u32int *reg)
 {
 	enum {
@@ -1878,9 +1855,10 @@
 		iomuxpad("pad_gpio1_io13", "usb1_otg_oc", nil);
 		iomuxpad("pad_gpio1_io14", "gpio1_io14", "FAST 45_OHM");
 
-		hubreset(0);
+		/* gpio1_io14: hub reset */
+		gpioout(GPIO_PIN(1, 14), 0);
 		microdelay(500);
-		hubreset(1);
+		gpioout(GPIO_PIN(1, 14), 1);
 
 		for(i = 0; i < nelem(ctlrs); i++) clkenable(i, 0);
 		setclkrate("ccm_usb_bus_clk_root", "system_pll2_div2", 500*Mhz);