Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * TI DaVinci EVM board support
0004  *
0005  * Author: Kevin Hilman, Deep Root Systems, LLC
0006  *
0007  * 2007 (c) MontaVista Software, Inc.
0008  */
0009 #include <linux/kernel.h>
0010 #include <linux/init.h>
0011 #include <linux/err.h>
0012 #include <linux/platform_device.h>
0013 #include <linux/mtd/mtd.h>
0014 #include <linux/mtd/partitions.h>
0015 #include <linux/mtd/rawnand.h>
0016 #include <linux/i2c.h>
0017 #include <linux/gpio.h>
0018 #include <linux/gpio/machine.h>
0019 #include <linux/clk.h>
0020 #include <linux/dm9000.h>
0021 #include <linux/videodev2.h>
0022 #include <media/i2c/tvp514x.h>
0023 #include <linux/spi/spi.h>
0024 #include <linux/spi/eeprom.h>
0025 #include <linux/platform_data/gpio-davinci.h>
0026 #include <linux/platform_data/i2c-davinci.h>
0027 #include <linux/platform_data/mtd-davinci.h>
0028 #include <linux/platform_data/mmc-davinci.h>
0029 #include <linux/platform_data/usb-davinci.h>
0030 
0031 #include <asm/mach-types.h>
0032 #include <asm/mach/arch.h>
0033 
0034 #include "serial.h"
0035 #include "common.h"
0036 #include "davinci.h"
0037 
0038 /* NOTE:  this is geared for the standard config, with a socketed
0039  * 2 GByte Micron NAND (MT29F16G08FAA) using 128KB sectors.  If you
0040  * swap chips, maybe with a different block size, partitioning may
0041  * need to be changed.
0042  */
0043 #define NAND_BLOCK_SIZE     SZ_128K
0044 
0045 static struct mtd_partition davinci_nand_partitions[] = {
0046     {
0047         /* UBL (a few copies) plus U-Boot */
0048         .name       = "bootloader",
0049         .offset     = 0,
0050         .size       = 15 * NAND_BLOCK_SIZE,
0051         .mask_flags = MTD_WRITEABLE, /* force read-only */
0052     }, {
0053         /* U-Boot environment */
0054         .name       = "params",
0055         .offset     = MTDPART_OFS_APPEND,
0056         .size       = 1 * NAND_BLOCK_SIZE,
0057         .mask_flags = 0,
0058     }, {
0059         .name       = "kernel",
0060         .offset     = MTDPART_OFS_APPEND,
0061         .size       = SZ_4M,
0062         .mask_flags = 0,
0063     }, {
0064         .name       = "filesystem1",
0065         .offset     = MTDPART_OFS_APPEND,
0066         .size       = SZ_512M,
0067         .mask_flags = 0,
0068     }, {
0069         .name       = "filesystem2",
0070         .offset     = MTDPART_OFS_APPEND,
0071         .size       = MTDPART_SIZ_FULL,
0072         .mask_flags = 0,
0073     }
0074     /* two blocks with bad block table (and mirror) at the end */
0075 };
0076 
0077 static struct davinci_nand_pdata davinci_nand_data = {
0078     .core_chipsel       = 0,
0079     .mask_chipsel       = BIT(14),
0080     .parts          = davinci_nand_partitions,
0081     .nr_parts       = ARRAY_SIZE(davinci_nand_partitions),
0082     .engine_type        = NAND_ECC_ENGINE_TYPE_ON_HOST,
0083     .bbt_options        = NAND_BBT_USE_FLASH,
0084     .ecc_bits       = 4,
0085 };
0086 
0087 static struct resource davinci_nand_resources[] = {
0088     {
0089         .start      = DM355_ASYNC_EMIF_DATA_CE0_BASE,
0090         .end        = DM355_ASYNC_EMIF_DATA_CE0_BASE + SZ_32M - 1,
0091         .flags      = IORESOURCE_MEM,
0092     }, {
0093         .start      = DM355_ASYNC_EMIF_CONTROL_BASE,
0094         .end        = DM355_ASYNC_EMIF_CONTROL_BASE + SZ_4K - 1,
0095         .flags      = IORESOURCE_MEM,
0096     },
0097 };
0098 
0099 static struct platform_device davinci_nand_device = {
0100     .name           = "davinci_nand",
0101     .id         = 0,
0102 
0103     .num_resources      = ARRAY_SIZE(davinci_nand_resources),
0104     .resource       = davinci_nand_resources,
0105 
0106     .dev            = {
0107         .platform_data  = &davinci_nand_data,
0108     },
0109 };
0110 
0111 #define DM355_I2C_SDA_PIN   GPIO_TO_PIN(0, 15)
0112 #define DM355_I2C_SCL_PIN   GPIO_TO_PIN(0, 14)
0113 
0114 static struct gpiod_lookup_table i2c_recovery_gpiod_table = {
0115     .dev_id = "i2c_davinci.1",
0116     .table = {
0117         GPIO_LOOKUP("davinci_gpio", DM355_I2C_SDA_PIN, "sda",
0118                 GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN),
0119         GPIO_LOOKUP("davinci_gpio", DM355_I2C_SCL_PIN, "scl",
0120                 GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN),
0121         { }
0122     },
0123 };
0124 
0125 static struct davinci_i2c_platform_data i2c_pdata = {
0126     .bus_freq   = 400   /* kHz */,
0127     .bus_delay  = 0 /* usec */,
0128     .gpio_recovery  = true,
0129 };
0130 
0131 static int dm355evm_mmc_gpios = -EINVAL;
0132 
0133 static void dm355evm_mmcsd_gpios(unsigned gpio)
0134 {
0135     gpio_request(gpio + 0, "mmc0_ro");
0136     gpio_request(gpio + 1, "mmc0_cd");
0137     gpio_request(gpio + 2, "mmc1_ro");
0138     gpio_request(gpio + 3, "mmc1_cd");
0139 
0140     /* we "know" these are input-only so we don't
0141      * need to call gpio_direction_input()
0142      */
0143 
0144     dm355evm_mmc_gpios = gpio;
0145 }
0146 
0147 static struct i2c_board_info dm355evm_i2c_info[] = {
0148     {   I2C_BOARD_INFO("dm355evm_msp", 0x25),
0149         .platform_data = dm355evm_mmcsd_gpios,
0150     },
0151     /* { plus irq  }, */
0152     { I2C_BOARD_INFO("tlv320aic33", 0x1b), },
0153 };
0154 
0155 static void __init evm_init_i2c(void)
0156 {
0157     gpiod_add_lookup_table(&i2c_recovery_gpiod_table);
0158     davinci_init_i2c(&i2c_pdata);
0159 
0160     gpio_request(5, "dm355evm_msp");
0161     gpio_direction_input(5);
0162     dm355evm_i2c_info[0].irq = gpio_to_irq(5);
0163 
0164     i2c_register_board_info(1, dm355evm_i2c_info,
0165             ARRAY_SIZE(dm355evm_i2c_info));
0166 }
0167 
0168 static struct resource dm355evm_dm9000_rsrc[] = {
0169     {
0170         /* addr */
0171         .start  = 0x04014000,
0172         .end    = 0x04014001,
0173         .flags  = IORESOURCE_MEM,
0174     }, {
0175         /* data */
0176         .start  = 0x04014002,
0177         .end    = 0x04014003,
0178         .flags  = IORESOURCE_MEM,
0179     }, {
0180         .flags  = IORESOURCE_IRQ
0181             | IORESOURCE_IRQ_HIGHEDGE /* rising (active high) */,
0182     },
0183 };
0184 
0185 static struct dm9000_plat_data dm335evm_dm9000_platdata;
0186 
0187 static struct platform_device dm355evm_dm9000 = {
0188     .name       = "dm9000",
0189     .id     = -1,
0190     .resource   = dm355evm_dm9000_rsrc,
0191     .num_resources  = ARRAY_SIZE(dm355evm_dm9000_rsrc),
0192     .dev        = {
0193         .platform_data = &dm335evm_dm9000_platdata,
0194     },
0195 };
0196 
0197 static struct tvp514x_platform_data tvp5146_pdata = {
0198     .clk_polarity = 0,
0199     .hs_polarity = 1,
0200     .vs_polarity = 1
0201 };
0202 
0203 #define TVP514X_STD_ALL (V4L2_STD_NTSC | V4L2_STD_PAL)
0204 /* Inputs available at the TVP5146 */
0205 static struct v4l2_input tvp5146_inputs[] = {
0206     {
0207         .index = 0,
0208         .name = "Composite",
0209         .type = V4L2_INPUT_TYPE_CAMERA,
0210         .std = TVP514X_STD_ALL,
0211     },
0212     {
0213         .index = 1,
0214         .name = "S-Video",
0215         .type = V4L2_INPUT_TYPE_CAMERA,
0216         .std = TVP514X_STD_ALL,
0217     },
0218 };
0219 
0220 /*
0221  * this is the route info for connecting each input to decoder
0222  * ouput that goes to vpfe. There is a one to one correspondence
0223  * with tvp5146_inputs
0224  */
0225 static struct vpfe_route tvp5146_routes[] = {
0226     {
0227         .input = INPUT_CVBS_VI2B,
0228         .output = OUTPUT_10BIT_422_EMBEDDED_SYNC,
0229     },
0230     {
0231         .input = INPUT_SVIDEO_VI2C_VI1C,
0232         .output = OUTPUT_10BIT_422_EMBEDDED_SYNC,
0233     },
0234 };
0235 
0236 static struct vpfe_subdev_info vpfe_sub_devs[] = {
0237     {
0238         .name = "tvp5146",
0239         .grp_id = 0,
0240         .num_inputs = ARRAY_SIZE(tvp5146_inputs),
0241         .inputs = tvp5146_inputs,
0242         .routes = tvp5146_routes,
0243         .can_route = 1,
0244         .ccdc_if_params = {
0245             .if_type = VPFE_BT656,
0246             .hdpol = VPFE_PINPOL_POSITIVE,
0247             .vdpol = VPFE_PINPOL_POSITIVE,
0248         },
0249         .board_info = {
0250             I2C_BOARD_INFO("tvp5146", 0x5d),
0251             .platform_data = &tvp5146_pdata,
0252         },
0253     }
0254 };
0255 
0256 static struct vpfe_config vpfe_cfg = {
0257     .num_subdevs = ARRAY_SIZE(vpfe_sub_devs),
0258     .i2c_adapter_id = 1,
0259     .sub_devs = vpfe_sub_devs,
0260     .card_name = "DM355 EVM",
0261     .ccdc = "DM355 CCDC",
0262 };
0263 
0264 /* venc standards timings */
0265 static struct vpbe_enc_mode_info dm355evm_enc_preset_timing[] = {
0266     {
0267         .name       = "ntsc",
0268         .timings_type   = VPBE_ENC_STD,
0269         .std_id     = V4L2_STD_NTSC,
0270         .interlaced = 1,
0271         .xres       = 720,
0272         .yres       = 480,
0273         .aspect     = {11, 10},
0274         .fps        = {30000, 1001},
0275         .left_margin    = 0x79,
0276         .upper_margin   = 0x10,
0277     },
0278     {
0279         .name       = "pal",
0280         .timings_type   = VPBE_ENC_STD,
0281         .std_id     = V4L2_STD_PAL,
0282         .interlaced = 1,
0283         .xres       = 720,
0284         .yres       = 576,
0285         .aspect     = {54, 59},
0286         .fps        = {25, 1},
0287         .left_margin    = 0x7E,
0288         .upper_margin   = 0x16
0289     },
0290 };
0291 
0292 #define VENC_STD_ALL    (V4L2_STD_NTSC | V4L2_STD_PAL)
0293 
0294 /*
0295  * The outputs available from VPBE + ecnoders. Keep the
0296  * the order same as that of encoders. First those from venc followed by that
0297  * from encoders. Index in the output refers to index on a particular encoder.
0298  * Driver uses this index to pass it to encoder when it supports more than
0299  * one output. Application uses index of the array to set an output.
0300  */
0301 static struct vpbe_output dm355evm_vpbe_outputs[] = {
0302     {
0303         .output     = {
0304             .index      = 0,
0305             .name       = "Composite",
0306             .type       = V4L2_OUTPUT_TYPE_ANALOG,
0307             .std        = VENC_STD_ALL,
0308             .capabilities   = V4L2_OUT_CAP_STD,
0309         },
0310         .subdev_name    = DM355_VPBE_VENC_SUBDEV_NAME,
0311         .default_mode   = "ntsc",
0312         .num_modes  = ARRAY_SIZE(dm355evm_enc_preset_timing),
0313         .modes      = dm355evm_enc_preset_timing,
0314         .if_params  = MEDIA_BUS_FMT_FIXED,
0315     },
0316 };
0317 
0318 static struct vpbe_config dm355evm_display_cfg = {
0319     .module_name    = "dm355-vpbe-display",
0320     .i2c_adapter_id = 1,
0321     .osd        = {
0322         .module_name    = DM355_VPBE_OSD_SUBDEV_NAME,
0323     },
0324     .venc       = {
0325         .module_name    = DM355_VPBE_VENC_SUBDEV_NAME,
0326     },
0327     .num_outputs    = ARRAY_SIZE(dm355evm_vpbe_outputs),
0328     .outputs    = dm355evm_vpbe_outputs,
0329 };
0330 
0331 static struct platform_device *davinci_evm_devices[] __initdata = {
0332     &dm355evm_dm9000,
0333     &davinci_nand_device,
0334 };
0335 
0336 static void __init dm355_evm_map_io(void)
0337 {
0338     dm355_init();
0339 }
0340 
0341 static int dm355evm_mmc_get_cd(int module)
0342 {
0343     if (!gpio_is_valid(dm355evm_mmc_gpios))
0344         return -ENXIO;
0345     /* low == card present */
0346     return !gpio_get_value_cansleep(dm355evm_mmc_gpios + 2 * module + 1);
0347 }
0348 
0349 static int dm355evm_mmc_get_ro(int module)
0350 {
0351     if (!gpio_is_valid(dm355evm_mmc_gpios))
0352         return -ENXIO;
0353     /* high == card's write protect switch active */
0354     return gpio_get_value_cansleep(dm355evm_mmc_gpios + 2 * module + 0);
0355 }
0356 
0357 static struct davinci_mmc_config dm355evm_mmc_config = {
0358     .get_cd     = dm355evm_mmc_get_cd,
0359     .get_ro     = dm355evm_mmc_get_ro,
0360     .wires      = 4,
0361     .max_freq       = 50000000,
0362     .caps           = MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED,
0363 };
0364 
0365 /* Don't connect anything to J10 unless you're only using USB host
0366  * mode *and* have to do so with some kind of gender-bender.  If
0367  * you have proper Mini-B or Mini-A cables (or Mini-A adapters)
0368  * the ID pin won't need any help.
0369  */
0370 #define USB_ID_VALUE    1   /* ID pulled low */
0371 
0372 static struct spi_eeprom at25640a = {
0373     .byte_len   = SZ_64K / 8,
0374     .name       = "at25640a",
0375     .page_size  = 32,
0376     .flags      = EE_ADDR2,
0377 };
0378 
0379 static const struct spi_board_info dm355_evm_spi_info[] __initconst = {
0380     {
0381         .modalias   = "at25",
0382         .platform_data  = &at25640a,
0383         .max_speed_hz   = 10 * 1000 * 1000, /* at 3v3 */
0384         .bus_num    = 0,
0385         .chip_select    = 0,
0386         .mode       = SPI_MODE_0,
0387     },
0388 };
0389 
0390 static __init void dm355_evm_init(void)
0391 {
0392     struct clk *aemif;
0393     int ret;
0394 
0395     dm355_register_clocks();
0396 
0397     ret = dm355_gpio_register();
0398     if (ret)
0399         pr_warn("%s: GPIO init failed: %d\n", __func__, ret);
0400 
0401     gpio_request(1, "dm9000");
0402     gpio_direction_input(1);
0403     dm355evm_dm9000_rsrc[2].start = gpio_to_irq(1);
0404 
0405     aemif = clk_get(&dm355evm_dm9000.dev, "aemif");
0406     if (!WARN(IS_ERR(aemif), "unable to get AEMIF clock\n"))
0407         clk_prepare_enable(aemif);
0408 
0409     platform_add_devices(davinci_evm_devices,
0410                  ARRAY_SIZE(davinci_evm_devices));
0411     evm_init_i2c();
0412     davinci_serial_init(dm355_serial_device);
0413 
0414     /* NOTE:  NAND flash timings set by the UBL are slower than
0415      * needed by MT29F16G08FAA chips ... EMIF.A1CR is 0x40400204
0416      * but could be 0x0400008c for about 25% faster page reads.
0417      */
0418 
0419     gpio_request(2, "usb_id_toggle");
0420     gpio_direction_output(2, USB_ID_VALUE);
0421     /* irlml6401 switches over 1A in under 8 msec */
0422     davinci_setup_usb(1000, 8);
0423 
0424     davinci_setup_mmc(0, &dm355evm_mmc_config);
0425     davinci_setup_mmc(1, &dm355evm_mmc_config);
0426 
0427     dm355_init_video(&vpfe_cfg, &dm355evm_display_cfg);
0428 
0429     dm355_init_spi0(BIT(0), dm355_evm_spi_info,
0430             ARRAY_SIZE(dm355_evm_spi_info));
0431 
0432     /* DM335 EVM uses ASP1; line-out is a stereo mini-jack */
0433     dm355_init_asp1(ASP1_TX_EVT_EN | ASP1_RX_EVT_EN);
0434 }
0435 
0436 MACHINE_START(DAVINCI_DM355_EVM, "DaVinci DM355 EVM")
0437     .atag_offset  = 0x100,
0438     .map_io       = dm355_evm_map_io,
0439     .init_irq     = dm355_init_irq,
0440     .init_time  = dm355_init_time,
0441     .init_machine = dm355_evm_init,
0442     .init_late  = davinci_init_late,
0443     .dma_zone_size  = SZ_128M,
0444 MACHINE_END