162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci#include <linux/init.h> 362306a36Sopenharmony_ci#include <linux/if_ether.h> 462306a36Sopenharmony_ci#include <linux/kernel.h> 562306a36Sopenharmony_ci#include <linux/platform_device.h> 662306a36Sopenharmony_ci#include <linux/dma-mapping.h> 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci#include <asm/paccess.h> 962306a36Sopenharmony_ci#include <asm/sgi/ip22.h> 1062306a36Sopenharmony_ci#include <asm/sgi/hpc3.h> 1162306a36Sopenharmony_ci#include <asm/sgi/mc.h> 1262306a36Sopenharmony_ci#include <asm/sgi/seeq.h> 1362306a36Sopenharmony_ci#include <asm/sgi/wd.h> 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_cistatic struct resource sgiwd93_0_resources[] = { 1662306a36Sopenharmony_ci { 1762306a36Sopenharmony_ci .name = "eth0 irq", 1862306a36Sopenharmony_ci .start = SGI_WD93_0_IRQ, 1962306a36Sopenharmony_ci .end = SGI_WD93_0_IRQ, 2062306a36Sopenharmony_ci .flags = IORESOURCE_IRQ 2162306a36Sopenharmony_ci } 2262306a36Sopenharmony_ci}; 2362306a36Sopenharmony_ci 2462306a36Sopenharmony_cistatic struct sgiwd93_platform_data sgiwd93_0_pd = { 2562306a36Sopenharmony_ci .unit = 0, 2662306a36Sopenharmony_ci .irq = SGI_WD93_0_IRQ, 2762306a36Sopenharmony_ci}; 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_cistatic u64 sgiwd93_0_dma_mask = DMA_BIT_MASK(32); 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_cistatic struct platform_device sgiwd93_0_device = { 3262306a36Sopenharmony_ci .name = "sgiwd93", 3362306a36Sopenharmony_ci .id = 0, 3462306a36Sopenharmony_ci .num_resources = ARRAY_SIZE(sgiwd93_0_resources), 3562306a36Sopenharmony_ci .resource = sgiwd93_0_resources, 3662306a36Sopenharmony_ci .dev = { 3762306a36Sopenharmony_ci .platform_data = &sgiwd93_0_pd, 3862306a36Sopenharmony_ci .dma_mask = &sgiwd93_0_dma_mask, 3962306a36Sopenharmony_ci .coherent_dma_mask = DMA_BIT_MASK(32), 4062306a36Sopenharmony_ci }, 4162306a36Sopenharmony_ci}; 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_cistatic struct resource sgiwd93_1_resources[] = { 4462306a36Sopenharmony_ci { 4562306a36Sopenharmony_ci .name = "eth0 irq", 4662306a36Sopenharmony_ci .start = SGI_WD93_1_IRQ, 4762306a36Sopenharmony_ci .end = SGI_WD93_1_IRQ, 4862306a36Sopenharmony_ci .flags = IORESOURCE_IRQ 4962306a36Sopenharmony_ci } 5062306a36Sopenharmony_ci}; 5162306a36Sopenharmony_ci 5262306a36Sopenharmony_cistatic struct sgiwd93_platform_data sgiwd93_1_pd = { 5362306a36Sopenharmony_ci .unit = 1, 5462306a36Sopenharmony_ci .irq = SGI_WD93_1_IRQ, 5562306a36Sopenharmony_ci}; 5662306a36Sopenharmony_ci 5762306a36Sopenharmony_cistatic u64 sgiwd93_1_dma_mask = DMA_BIT_MASK(32); 5862306a36Sopenharmony_ci 5962306a36Sopenharmony_cistatic struct platform_device sgiwd93_1_device = { 6062306a36Sopenharmony_ci .name = "sgiwd93", 6162306a36Sopenharmony_ci .id = 1, 6262306a36Sopenharmony_ci .num_resources = ARRAY_SIZE(sgiwd93_1_resources), 6362306a36Sopenharmony_ci .resource = sgiwd93_1_resources, 6462306a36Sopenharmony_ci .dev = { 6562306a36Sopenharmony_ci .platform_data = &sgiwd93_1_pd, 6662306a36Sopenharmony_ci .dma_mask = &sgiwd93_1_dma_mask, 6762306a36Sopenharmony_ci .coherent_dma_mask = DMA_BIT_MASK(32), 6862306a36Sopenharmony_ci }, 6962306a36Sopenharmony_ci}; 7062306a36Sopenharmony_ci 7162306a36Sopenharmony_ci/* 7262306a36Sopenharmony_ci * Create a platform device for the GPI port that receives the 7362306a36Sopenharmony_ci * image data from the embedded camera. 7462306a36Sopenharmony_ci */ 7562306a36Sopenharmony_cistatic int __init sgiwd93_devinit(void) 7662306a36Sopenharmony_ci{ 7762306a36Sopenharmony_ci int res; 7862306a36Sopenharmony_ci 7962306a36Sopenharmony_ci sgiwd93_0_pd.hregs = &hpc3c0->scsi_chan0; 8062306a36Sopenharmony_ci sgiwd93_0_pd.wdregs = (unsigned char *) hpc3c0->scsi0_ext; 8162306a36Sopenharmony_ci 8262306a36Sopenharmony_ci res = platform_device_register(&sgiwd93_0_device); 8362306a36Sopenharmony_ci if (res) 8462306a36Sopenharmony_ci return res; 8562306a36Sopenharmony_ci 8662306a36Sopenharmony_ci if (!ip22_is_fullhouse()) 8762306a36Sopenharmony_ci return 0; 8862306a36Sopenharmony_ci 8962306a36Sopenharmony_ci sgiwd93_1_pd.hregs = &hpc3c0->scsi_chan1; 9062306a36Sopenharmony_ci sgiwd93_1_pd.wdregs = (unsigned char *) hpc3c0->scsi1_ext; 9162306a36Sopenharmony_ci 9262306a36Sopenharmony_ci return platform_device_register(&sgiwd93_1_device); 9362306a36Sopenharmony_ci} 9462306a36Sopenharmony_ci 9562306a36Sopenharmony_cidevice_initcall(sgiwd93_devinit); 9662306a36Sopenharmony_ci 9762306a36Sopenharmony_cistatic struct resource sgiseeq_0_resources[] = { 9862306a36Sopenharmony_ci { 9962306a36Sopenharmony_ci .name = "eth0 irq", 10062306a36Sopenharmony_ci .start = SGI_ENET_IRQ, 10162306a36Sopenharmony_ci .end = SGI_ENET_IRQ, 10262306a36Sopenharmony_ci .flags = IORESOURCE_IRQ 10362306a36Sopenharmony_ci } 10462306a36Sopenharmony_ci}; 10562306a36Sopenharmony_ci 10662306a36Sopenharmony_cistatic struct sgiseeq_platform_data eth0_pd; 10762306a36Sopenharmony_ci 10862306a36Sopenharmony_cistatic u64 sgiseeq_dma_mask = DMA_BIT_MASK(32); 10962306a36Sopenharmony_ci 11062306a36Sopenharmony_cistatic struct platform_device eth0_device = { 11162306a36Sopenharmony_ci .name = "sgiseeq", 11262306a36Sopenharmony_ci .id = 0, 11362306a36Sopenharmony_ci .num_resources = ARRAY_SIZE(sgiseeq_0_resources), 11462306a36Sopenharmony_ci .resource = sgiseeq_0_resources, 11562306a36Sopenharmony_ci .dev = { 11662306a36Sopenharmony_ci .platform_data = ð0_pd, 11762306a36Sopenharmony_ci .dma_mask = &sgiseeq_dma_mask, 11862306a36Sopenharmony_ci .coherent_dma_mask = DMA_BIT_MASK(32), 11962306a36Sopenharmony_ci }, 12062306a36Sopenharmony_ci}; 12162306a36Sopenharmony_ci 12262306a36Sopenharmony_cistatic struct resource sgiseeq_1_resources[] = { 12362306a36Sopenharmony_ci { 12462306a36Sopenharmony_ci .name = "eth1 irq", 12562306a36Sopenharmony_ci .start = SGI_GIO_0_IRQ, 12662306a36Sopenharmony_ci .end = SGI_GIO_0_IRQ, 12762306a36Sopenharmony_ci .flags = IORESOURCE_IRQ 12862306a36Sopenharmony_ci } 12962306a36Sopenharmony_ci}; 13062306a36Sopenharmony_ci 13162306a36Sopenharmony_cistatic struct sgiseeq_platform_data eth1_pd; 13262306a36Sopenharmony_ci 13362306a36Sopenharmony_cistatic struct platform_device eth1_device = { 13462306a36Sopenharmony_ci .name = "sgiseeq", 13562306a36Sopenharmony_ci .id = 1, 13662306a36Sopenharmony_ci .num_resources = ARRAY_SIZE(sgiseeq_1_resources), 13762306a36Sopenharmony_ci .resource = sgiseeq_1_resources, 13862306a36Sopenharmony_ci .dev = { 13962306a36Sopenharmony_ci .platform_data = ð1_pd, 14062306a36Sopenharmony_ci }, 14162306a36Sopenharmony_ci}; 14262306a36Sopenharmony_ci 14362306a36Sopenharmony_ci/* 14462306a36Sopenharmony_ci * Create a platform device for the GPI port that receives the 14562306a36Sopenharmony_ci * image data from the embedded camera. 14662306a36Sopenharmony_ci */ 14762306a36Sopenharmony_cistatic int __init sgiseeq_devinit(void) 14862306a36Sopenharmony_ci{ 14962306a36Sopenharmony_ci unsigned int pbdma __maybe_unused; 15062306a36Sopenharmony_ci int res, i; 15162306a36Sopenharmony_ci 15262306a36Sopenharmony_ci eth0_pd.hpc = hpc3c0; 15362306a36Sopenharmony_ci eth0_pd.irq = SGI_ENET_IRQ; 15462306a36Sopenharmony_ci#define EADDR_NVOFS 250 15562306a36Sopenharmony_ci for (i = 0; i < 3; i++) { 15662306a36Sopenharmony_ci unsigned short tmp = ip22_nvram_read(EADDR_NVOFS / 2 + i); 15762306a36Sopenharmony_ci 15862306a36Sopenharmony_ci eth0_pd.mac[2 * i] = tmp >> 8; 15962306a36Sopenharmony_ci eth0_pd.mac[2 * i + 1] = tmp & 0xff; 16062306a36Sopenharmony_ci } 16162306a36Sopenharmony_ci 16262306a36Sopenharmony_ci res = platform_device_register(ð0_device); 16362306a36Sopenharmony_ci if (res) 16462306a36Sopenharmony_ci return res; 16562306a36Sopenharmony_ci 16662306a36Sopenharmony_ci /* Second HPC is missing? */ 16762306a36Sopenharmony_ci if (ip22_is_fullhouse() || 16862306a36Sopenharmony_ci get_dbe(pbdma, (unsigned int *)&hpc3c1->pbdma[1])) 16962306a36Sopenharmony_ci return 0; 17062306a36Sopenharmony_ci 17162306a36Sopenharmony_ci sgimc->giopar |= SGIMC_GIOPAR_MASTEREXP1 | SGIMC_GIOPAR_EXP164 | 17262306a36Sopenharmony_ci SGIMC_GIOPAR_HPC264; 17362306a36Sopenharmony_ci hpc3c1->pbus_piocfg[0][0] = 0x3ffff; 17462306a36Sopenharmony_ci /* interrupt/config register on Challenge S Mezz board */ 17562306a36Sopenharmony_ci hpc3c1->pbus_extregs[0][0] = 0x30; 17662306a36Sopenharmony_ci 17762306a36Sopenharmony_ci eth1_pd.hpc = hpc3c1; 17862306a36Sopenharmony_ci eth1_pd.irq = SGI_GIO_0_IRQ; 17962306a36Sopenharmony_ci#define EADDR_NVOFS 250 18062306a36Sopenharmony_ci for (i = 0; i < 3; i++) { 18162306a36Sopenharmony_ci unsigned short tmp = ip22_eeprom_read(&hpc3c1->eeprom, 18262306a36Sopenharmony_ci EADDR_NVOFS / 2 + i); 18362306a36Sopenharmony_ci 18462306a36Sopenharmony_ci eth1_pd.mac[2 * i] = tmp >> 8; 18562306a36Sopenharmony_ci eth1_pd.mac[2 * i + 1] = tmp & 0xff; 18662306a36Sopenharmony_ci } 18762306a36Sopenharmony_ci 18862306a36Sopenharmony_ci return platform_device_register(ð1_device); 18962306a36Sopenharmony_ci} 19062306a36Sopenharmony_ci 19162306a36Sopenharmony_cidevice_initcall(sgiseeq_devinit); 19262306a36Sopenharmony_ci 19362306a36Sopenharmony_cistatic int __init sgi_hal2_devinit(void) 19462306a36Sopenharmony_ci{ 19562306a36Sopenharmony_ci return IS_ERR(platform_device_register_simple("sgihal2", 0, NULL, 0)); 19662306a36Sopenharmony_ci} 19762306a36Sopenharmony_ci 19862306a36Sopenharmony_cidevice_initcall(sgi_hal2_devinit); 19962306a36Sopenharmony_ci 20062306a36Sopenharmony_cistatic int __init sgi_button_devinit(void) 20162306a36Sopenharmony_ci{ 20262306a36Sopenharmony_ci if (ip22_is_fullhouse()) 20362306a36Sopenharmony_ci return 0; /* full house has no volume buttons */ 20462306a36Sopenharmony_ci 20562306a36Sopenharmony_ci return IS_ERR(platform_device_register_simple("sgibtns", -1, NULL, 0)); 20662306a36Sopenharmony_ci} 20762306a36Sopenharmony_ci 20862306a36Sopenharmony_cidevice_initcall(sgi_button_devinit); 20962306a36Sopenharmony_ci 21062306a36Sopenharmony_cistatic int __init sgi_ds1286_devinit(void) 21162306a36Sopenharmony_ci{ 21262306a36Sopenharmony_ci struct resource res; 21362306a36Sopenharmony_ci 21462306a36Sopenharmony_ci memset(&res, 0, sizeof(res)); 21562306a36Sopenharmony_ci res.start = HPC3_CHIP0_BASE + offsetof(struct hpc3_regs, rtcregs); 21662306a36Sopenharmony_ci res.end = res.start + sizeof(hpc3c0->rtcregs) - 1; 21762306a36Sopenharmony_ci res.flags = IORESOURCE_MEM; 21862306a36Sopenharmony_ci 21962306a36Sopenharmony_ci return IS_ERR(platform_device_register_simple("rtc-ds1286", -1, 22062306a36Sopenharmony_ci &res, 1)); 22162306a36Sopenharmony_ci} 22262306a36Sopenharmony_ci 22362306a36Sopenharmony_cidevice_initcall(sgi_ds1286_devinit); 224