Home | History | Annotate | Line # | Download | only in ingenic
apbus.c revision 1.19.26.1
      1  1.19.26.1   thorpej /*	$NetBSD: apbus.c,v 1.19.26.1 2021/03/23 07:14:49 thorpej Exp $ */
      2        1.1  macallan 
      3        1.1  macallan /*-
      4        1.1  macallan  * Copyright (c) 2014 Michael Lorenz
      5        1.1  macallan  * All rights reserved.
      6        1.1  macallan  *
      7        1.1  macallan  * Redistribution and use in source and binary forms, with or without
      8        1.1  macallan  * modification, are permitted provided that the following conditions
      9        1.1  macallan  * are met:
     10        1.1  macallan  * 1. Redistributions of source code must retain the above copyright
     11        1.1  macallan  *    notice, this list of conditions and the following disclaimer.
     12        1.1  macallan  * 2. Redistributions in binary form must reproduce the above copyright
     13        1.1  macallan  *    notice, this list of conditions and the following disclaimer in the
     14        1.1  macallan  *    documentation and/or other materials provided with the distribution.
     15        1.1  macallan  *
     16        1.1  macallan  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     17        1.1  macallan  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     18        1.1  macallan  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     19        1.1  macallan  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     20        1.1  macallan  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     21        1.1  macallan  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     22        1.1  macallan  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     23        1.1  macallan  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     24        1.1  macallan  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     25        1.1  macallan  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     26        1.1  macallan  * POSSIBILITY OF SUCH DAMAGE.
     27        1.1  macallan  */
     28       1.19     skrll 
     29        1.1  macallan /* catch-all for on-chip peripherals */
     30        1.1  macallan 
     31        1.1  macallan #include <sys/cdefs.h>
     32  1.19.26.1   thorpej __KERNEL_RCSID(0, "$NetBSD: apbus.c,v 1.19.26.1 2021/03/23 07:14:49 thorpej Exp $");
     33        1.1  macallan 
     34        1.1  macallan #include "locators.h"
     35        1.1  macallan #define	_MIPS_BUS_DMA_PRIVATE
     36        1.1  macallan 
     37        1.1  macallan #include <sys/param.h>
     38        1.1  macallan #include <sys/bus.h>
     39        1.1  macallan #include <sys/device.h>
     40        1.1  macallan #include <sys/extent.h>
     41        1.1  macallan #include <sys/systm.h>
     42        1.1  macallan 
     43        1.1  macallan #include <mips/ingenic/ingenic_var.h>
     44        1.1  macallan #include <mips/ingenic/ingenic_regs.h>
     45        1.1  macallan 
     46        1.2  macallan #include "opt_ingenic.h"
     47        1.2  macallan 
     48        1.1  macallan static int apbus_match(device_t, cfdata_t, void *);
     49        1.1  macallan static void apbus_attach(device_t, device_t, void *);
     50        1.1  macallan static int apbus_print(void *, const char *);
     51        1.1  macallan static void apbus_bus_mem_init(bus_space_tag_t, void *);
     52        1.1  macallan 
     53        1.1  macallan CFATTACH_DECL_NEW(apbus, 0, apbus_match, apbus_attach, NULL, NULL);
     54        1.1  macallan 
     55        1.1  macallan static struct mips_bus_space	apbus_mbst;
     56        1.1  macallan bus_space_tag_t	apbus_memt = NULL;
     57        1.1  macallan 
     58        1.1  macallan struct mips_bus_dma_tag	apbus_dmat = {
     59        1.6  macallan 	._bounce_alloc_hi = 0x10000000,
     60        1.1  macallan 	._dmamap_ops = _BUS_DMAMAP_OPS_INITIALIZER,
     61        1.1  macallan 	._dmamem_ops = _BUS_DMAMEM_OPS_INITIALIZER,
     62        1.1  macallan 	._dmatag_ops = _BUS_DMATAG_OPS_INITIALIZER,
     63        1.1  macallan };
     64        1.1  macallan 
     65        1.8  macallan typedef struct apbus_dev {
     66       1.12  macallan 	const char *name;	/* driver name */
     67       1.12  macallan 	bus_addr_t addr;	/* base address */
     68       1.12  macallan 	uint32_t irq;		/* interrupt */
     69       1.12  macallan 	uint32_t clk0;		/* bit(s) in CLKGR0 */
     70       1.12  macallan 	uint32_t clk1;		/* bit(s) in CLKGR1 */
     71       1.15  macallan 	uint32_t clkreg;	/* CGU register */
     72        1.8  macallan } apbus_dev_t;
     73        1.8  macallan 
     74        1.8  macallan static const apbus_dev_t apbus_devs[] = {
     75       1.18  macallan 	{ "efuse",	JZ_EFUSE,	-1, 0, 0, 0},
     76       1.16  macallan 	{ "com",	JZ_UART0,	51, CLK_UART0, 0, 0},
     77       1.16  macallan 	{ "com",	JZ_UART1,	50, CLK_UART1, 0, 0},
     78       1.16  macallan 	{ "com",	JZ_UART2,	49, CLK_UART2, 0, 0},
     79       1.16  macallan 	{ "com",	JZ_UART3,	48, CLK_UART3, 0, 0},
     80       1.16  macallan 	{ "com",	JZ_UART4,	34, 0, CLK_UART4, 0},
     81       1.15  macallan 	{ "dwctwo",	JZ_DWC2_BASE,   21, CLK_OTG0 | CLK_UHC, CLK_OTG1, 0},
     82       1.15  macallan 	{ "ohci",	JZ_OHCI_BASE,    5, CLK_UHC, 0, 0},
     83       1.15  macallan 	{ "ehci",	JZ_EHCI_BASE,   20, CLK_UHC, 0, 0},
     84       1.15  macallan 	{ "dme",	JZ_DME_BASE,    -1, 0, 0, 0},
     85       1.15  macallan 	{ "jzgpio",	JZ_GPIO_A_BASE, 17, 0, 0, 0},
     86       1.15  macallan 	{ "jzgpio",	JZ_GPIO_B_BASE, 16, 0, 0, 0},
     87       1.15  macallan 	{ "jzgpio",	JZ_GPIO_C_BASE, 15, 0, 0, 0},
     88       1.15  macallan 	{ "jzgpio",	JZ_GPIO_D_BASE, 14, 0, 0, 0},
     89       1.15  macallan 	{ "jzgpio",	JZ_GPIO_E_BASE, 13, 0, 0, 0},
     90       1.15  macallan 	{ "jzgpio",	JZ_GPIO_F_BASE, 12, 0, 0, 0},
     91       1.15  macallan 	{ "jziic",	JZ_SMB0_BASE,   60, CLK_SMB0, 0, 0},
     92       1.15  macallan 	{ "jziic",	JZ_SMB1_BASE,   59, CLK_SMB1, 0, 0},
     93       1.15  macallan 	{ "jziic",	JZ_SMB2_BASE,   58, CLK_SMB2, 0, 0},
     94       1.15  macallan 	{ "jziic",	JZ_SMB3_BASE,   57, 0, CLK_SMB3, 0},
     95       1.15  macallan 	{ "jziic",	JZ_SMB4_BASE,   56, 0, CLK_SMB4, 0},
     96       1.15  macallan 	{ "jzmmc",	JZ_MSC0_BASE,   37, CLK_MSC0, 0, JZ_MSC0CDR},
     97       1.15  macallan 	{ "jzmmc",	JZ_MSC1_BASE,   36, CLK_MSC1, 0, JZ_MSC1CDR},
     98       1.15  macallan 	{ "jzmmc",	JZ_MSC2_BASE,   35, CLK_MSC2, 0, JZ_MSC2CDR},
     99       1.15  macallan 	{ "jzfb",	JZ_LCDC0_BASE,  31, CLK_LCD, CLK_HDMI, 0},
    100       1.17  macallan 	{ "jzrng",	JZ_RNG,		-1, 0, 0, 0},
    101       1.15  macallan 	{ NULL,		-1,             -1, 0, 0, 0}
    102        1.1  macallan };
    103        1.1  macallan 
    104        1.1  macallan void
    105        1.1  macallan apbus_init(void)
    106        1.1  macallan {
    107        1.1  macallan 	static bool done = false;
    108        1.1  macallan 	if (done)
    109        1.1  macallan 		return;
    110        1.1  macallan 	done = true;
    111        1.1  macallan 
    112        1.1  macallan 	apbus_bus_mem_init(&apbus_mbst, NULL);
    113        1.1  macallan 	apbus_memt = &apbus_mbst;
    114        1.1  macallan }
    115        1.1  macallan 
    116        1.1  macallan int
    117        1.1  macallan apbus_match(device_t parent, cfdata_t match, void *aux)
    118        1.1  macallan {
    119        1.1  macallan 	struct mainbusdev {
    120        1.1  macallan 		const char *md_name;
    121        1.1  macallan 	} *aa = aux;
    122        1.1  macallan 	if (strcmp(aa->md_name, "apbus") == 0) return 1;
    123        1.1  macallan 	return 0;
    124        1.1  macallan }
    125        1.1  macallan 
    126        1.1  macallan void
    127        1.1  macallan apbus_attach(device_t parent, device_t self, void *aux)
    128        1.1  macallan {
    129       1.14  macallan 	uint32_t reg, mpll, m, n, p, mclk, pclk, pdiv, cclk, cdiv;
    130        1.1  macallan 	aprint_normal("\n");
    131        1.1  macallan 
    132        1.1  macallan 	/* should have been called early on */
    133        1.1  macallan 	apbus_init();
    134        1.1  macallan 
    135        1.2  macallan #ifdef INGENIC_DEBUG
    136        1.2  macallan 	printf("core ctrl:   %08x\n", MFC0(12, 2));
    137        1.2  macallan 	printf("core status: %08x\n", MFC0(12, 3));
    138        1.2  macallan 	printf("REIM: %08x\n", MFC0(12, 4));
    139        1.2  macallan 	printf("ID: %08x\n", MFC0(15, 1));
    140        1.2  macallan #endif
    141       1.11  macallan 	/* assuming we're using MPLL */
    142       1.11  macallan 	mpll = readreg(JZ_CPMPCR);
    143       1.11  macallan 	m = (mpll & JZ_PLLM_M) >> JZ_PLLM_S;
    144       1.11  macallan 	n = (mpll & JZ_PLLN_M) >> JZ_PLLN_S;
    145       1.11  macallan 	p = (mpll & JZ_PLLP_M) >> JZ_PLLP_S;
    146       1.11  macallan 
    147       1.11  macallan 	/* assuming 48MHz EXTCLK */
    148       1.11  macallan 	mclk = (48000 * (m + 1) / (n + 1)) / (p + 1);
    149       1.11  macallan 
    150       1.11  macallan 	reg = readreg(JZ_CPCCR);
    151       1.14  macallan 	pdiv = ((reg & JZ_PDIV_M) >> JZ_PDIV_S) + 1;
    152       1.11  macallan 	pclk = mclk / pdiv;
    153       1.14  macallan 	cdiv = (reg & JZ_CDIV_M) + 1;
    154       1.14  macallan 	cclk = mclk / cdiv;
    155       1.14  macallan 
    156       1.14  macallan 	aprint_debug_dev(self, "mclk %d kHz\n", mclk);
    157       1.14  macallan 	aprint_debug_dev(self, "pclk %d kHz\n", pclk);
    158       1.14  macallan 	aprint_debug_dev(self, "CPU clock %d kHz\n", cclk);
    159        1.2  macallan 
    160       1.11  macallan 	/* enable clocks */
    161        1.2  macallan 	reg = readreg(JZ_CLKGR1);
    162       1.12  macallan 	reg &= ~CLK_AHB_MON;	/* AHB_MON clock */
    163        1.2  macallan 	writereg(JZ_CLKGR1, reg);
    164        1.2  macallan 
    165       1.17  macallan 	/* enable RNG */
    166       1.17  macallan 	writereg(JZ_ERNG, 1);
    167       1.17  macallan 
    168        1.3  macallan 	/* wake up the USB part */
    169        1.3  macallan 	reg = readreg(JZ_OPCR);
    170        1.4  macallan 	reg |= OPCR_SPENDN0 | OPCR_SPENDN1;
    171        1.3  macallan 	writereg(JZ_OPCR, reg);
    172        1.3  macallan 
    173       1.14  macallan 	/* wire up GPIOs */
    174       1.11  macallan 	/* iic0 */
    175       1.11  macallan 	gpio_as_dev0(3, 30);
    176       1.11  macallan 	gpio_as_dev0(3, 31);
    177       1.11  macallan 	/* iic1 */
    178       1.11  macallan 	gpio_as_dev0(4, 30);
    179       1.11  macallan 	gpio_as_dev0(4, 31);
    180       1.11  macallan 	/* iic2 */
    181       1.11  macallan 	gpio_as_dev2(5, 16);
    182       1.11  macallan 	gpio_as_dev2(5, 17);
    183       1.11  macallan 	/* iic3 */
    184       1.11  macallan 	gpio_as_dev1(3, 10);
    185       1.11  macallan 	gpio_as_dev1(3, 11);
    186       1.11  macallan 	/* iic4 */
    187       1.11  macallan 	/* make sure these aren't SMB4 */
    188       1.11  macallan 	gpio_as_dev3(4, 3);
    189       1.11  macallan 	gpio_as_dev3(4, 4);
    190       1.11  macallan 	/* these are supposed to be connected to the RTC */
    191       1.11  macallan 	gpio_as_dev1(4, 12);
    192       1.11  macallan 	gpio_as_dev1(4, 13);
    193       1.15  macallan 	/* these can be DDC2 or SMB4 */
    194       1.16  macallan #if 0
    195       1.15  macallan 	/* DDC2 devices show up at SMB4 */
    196       1.15  macallan 	gpio_as_dev1(5, 24);
    197       1.15  macallan 	gpio_as_dev1(5, 25);
    198       1.15  macallan #else
    199       1.11  macallan 	gpio_as_dev0(5, 24);
    200       1.11  macallan 	gpio_as_dev0(5, 25);
    201       1.15  macallan #endif
    202       1.14  macallan 	/* MSC0 */
    203       1.14  macallan 	gpio_as_dev1(0, 4);
    204       1.14  macallan 	gpio_as_dev1(0, 5);
    205       1.14  macallan 	gpio_as_dev1(0, 6);
    206       1.14  macallan 	gpio_as_dev1(0, 7);
    207       1.14  macallan 	gpio_as_dev1(0, 18);
    208       1.14  macallan 	gpio_as_dev1(0, 19);
    209       1.14  macallan 	gpio_as_dev1(0, 20);
    210       1.14  macallan 	gpio_as_dev1(0, 21);
    211       1.14  macallan 	gpio_as_dev1(0, 22);
    212       1.14  macallan 	gpio_as_dev1(0, 23);
    213       1.14  macallan 	gpio_as_dev1(0, 24);
    214       1.14  macallan 	gpio_as_intr_level_low(5, 20);	/* card detect */
    215       1.14  macallan 
    216       1.14  macallan 	/* MSC1, for wifi/bt */
    217       1.14  macallan 	gpio_as_dev0(3, 20);
    218       1.14  macallan 	gpio_as_dev0(3, 21);
    219       1.14  macallan 	gpio_as_dev0(3, 22);
    220       1.14  macallan 	gpio_as_dev0(3, 23);
    221       1.14  macallan 	gpio_as_dev0(3, 24);
    222       1.14  macallan 	gpio_as_dev0(3, 25);
    223       1.14  macallan 
    224       1.14  macallan 	/* MSC2, on expansion header */
    225       1.14  macallan 	gpio_as_dev0(1, 20);
    226       1.14  macallan 	gpio_as_dev0(1, 21);
    227       1.14  macallan 	gpio_as_dev0(1, 28);
    228       1.14  macallan 	gpio_as_dev0(1, 29);
    229       1.14  macallan 	gpio_as_dev0(1, 30);
    230       1.14  macallan 	gpio_as_dev0(1, 31);
    231       1.14  macallan 
    232       1.16  macallan #ifndef INGENIC_DEBUG
    233        1.2  macallan 	printf("JZ_CLKGR0 %08x\n", readreg(JZ_CLKGR0));
    234        1.2  macallan 	printf("JZ_CLKGR1 %08x\n", readreg(JZ_CLKGR1));
    235        1.2  macallan 	printf("JZ_SPCR0  %08x\n", readreg(JZ_SPCR0));
    236        1.2  macallan 	printf("JZ_SPCR1  %08x\n", readreg(JZ_SPCR1));
    237        1.2  macallan 	printf("JZ_SRBC   %08x\n", readreg(JZ_SRBC));
    238        1.3  macallan 	printf("JZ_OPCR   %08x\n", readreg(JZ_OPCR));
    239        1.5  macallan 	printf("JZ_UHCCDR %08x\n", readreg(JZ_UHCCDR));
    240       1.17  macallan 	printf("JZ_ERNG   %08x\n", readreg(JZ_ERNG));
    241       1.17  macallan 	printf("JZ_RNG    %08x\n", readreg(JZ_RNG));
    242        1.2  macallan #endif
    243        1.1  macallan 
    244        1.8  macallan 	for (const apbus_dev_t *adv = apbus_devs; adv->name != NULL; adv++) {
    245        1.1  macallan 		struct apbus_attach_args aa;
    246        1.8  macallan 		aa.aa_name = adv->name;
    247        1.8  macallan 		aa.aa_addr = adv->addr;
    248        1.8  macallan 		aa.aa_irq  = adv->irq;
    249        1.1  macallan 		aa.aa_dmat = &apbus_dmat;
    250        1.1  macallan 		aa.aa_bst = apbus_memt;
    251       1.11  macallan 		aa.aa_pclk = pclk;
    252       1.14  macallan 		aa.aa_mclk = mclk;
    253       1.15  macallan 		aa.aa_clockreg = adv->clkreg;
    254        1.1  macallan 
    255       1.12  macallan 		/* enable clocks as needed */
    256       1.12  macallan 		if (adv->clk0 != 0) {
    257       1.12  macallan 			reg = readreg(JZ_CLKGR0);
    258       1.12  macallan 			reg &= ~adv->clk0;
    259       1.12  macallan 			writereg(JZ_CLKGR0, reg);
    260       1.12  macallan 		}
    261       1.12  macallan 
    262       1.12  macallan 		if (adv->clk1 != 0) {
    263       1.12  macallan 			reg = readreg(JZ_CLKGR1);
    264       1.12  macallan 			reg &= ~adv->clk1;
    265       1.12  macallan 			writereg(JZ_CLKGR1, reg);
    266       1.12  macallan 		}
    267       1.19     skrll 
    268  1.19.26.1   thorpej 		config_found(self, &aa, apbus_print, CFARG_EOL);
    269        1.1  macallan 	}
    270        1.1  macallan }
    271        1.1  macallan 
    272        1.1  macallan int
    273        1.1  macallan apbus_print(void *aux, const char *pnp)
    274        1.1  macallan {
    275        1.1  macallan 	struct apbus_attach_args *aa = aux;
    276        1.1  macallan 
    277        1.8  macallan 	if (pnp) {
    278        1.1  macallan 		aprint_normal("%s at %s", aa->aa_name, pnp);
    279        1.8  macallan 	}
    280        1.9  macallan 	if (aa->aa_addr != -1)
    281        1.9  macallan 		aprint_normal(" addr 0x%" PRIxBUSADDR, aa->aa_addr);
    282        1.9  macallan 	if ((pnp == NULL) && (aa->aa_irq != -1))
    283        1.9  macallan 		aprint_normal(" irq %d", aa->aa_irq);
    284        1.1  macallan 	return (UNCONF);
    285        1.1  macallan }
    286        1.1  macallan 
    287        1.1  macallan #define CHIP	   		apbus
    288        1.1  macallan #define	CHIP_MEM		/* defined */
    289        1.1  macallan #define	CHIP_W1_BUS_START(v)	0x10000000UL
    290        1.1  macallan #define CHIP_W1_BUS_END(v)	0x20000000UL
    291        1.1  macallan #define	CHIP_W1_SYS_START(v)	0x10000000UL
    292        1.1  macallan #define	CHIP_W1_SYS_END(v)	0x20000000UL
    293        1.1  macallan 
    294        1.1  macallan #include <mips/mips/bus_space_alignstride_chipdep.c>
    295