diff --git a/sys/src/9/imx8/fns.h b/sys/src/9/imx8/fns.h index d6f27ea11..f518bc8ff 100644 --- a/sys/src/9/imx8/fns.h +++ b/sys/src/9/imx8/fns.h @@ -154,3 +154,8 @@ extern void lcdinit(void); /* 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); diff --git a/sys/src/9/imx8/gpio.c b/sys/src/9/imx8/gpio.c new file mode 100644 index 000000000..5c527fb3d --- /dev/null +++ b/sys/src/9/imx8/gpio.c @@ -0,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; +} diff --git a/sys/src/9/imx8/lcd.c b/sys/src/9/imx8/lcd.c index 0fa2ab65c..6053be39f 100644 --- 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 @@ struct dsi_cfg { /* 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 @@ dpiinit(struct video_mode *mode) 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<