I can see two concerns in this question
How to create an array with non-default prefilled values?
There is no clean way to fill a generic array with custom default value, except for creating it manually.    
You might want to read this StackOverflow question too, because it is related to this topic:
What is the equivalent of memset in C#?
Taking this into account, you can define your Grid class as the following:
public class Grid<T>
{
    private T[] _gridArray;  
    public Grid(int size)
    {
        _gridArray = new T[size];
    }            
    public Grid(int size, T initialValue)
    {
        _gridArray = new T[size];
        for (int i = 0; i < size; i++)
            _gridArray[i] = initialValue;
        // or it can be rewritten with LINQ, if you like:
        // _gridArray = Enumerable.Repeat(initialValue, size).ToArray();
    }    
}
Now, you can use it to create default arrays:
var grid = new Grid<int>(3); // [0, 0, 0]
var grid = new Grid<object>(3); // [null, null, null]
var grid = new Grid<bool>(4); // [false, false, false, false]
but you can also provide a value which you would like to be as a default:
var grid = new Grid<int>(3, -1); // [-1, -1, -1]
var grid = new Grid<bool>(4, true); // [true, true, true, true]
How to set custom default values per generic T
If you want -1 to be default value for all Grid<int>, you can create a factory, which will know about it and create this according to this logic. This factory can store default values for each type and validate your T against them.
Of course, you could put this logic into constructor just like you initially wanted it to be:
public class Grid<T>
{
    private static readonly Dictionary<Type, object> _customDefaultValues = new Dictionary<Type, object>
    {
        [typeof(int)] = -1,
        [typeof(long)] = long.MaxValue
    };
    public T[] _gridArray;  
    public Grid(int size)
    {
        _gridArray = new T[size];
        if (_customDefaultValues.TryGetValue(typeof(T), out object defaultValue))
        {
            T defaultValueUnboxed = (T)defaultValue;
            for (int i = 0; i < size; i++)
                _gridArray[i] = defaultValueUnboxed;
        }
    }  
}
var grid = new Grid<int>(4); // [-1, -1, -1, -1]
var grid = new Grid<long>(2); // [long.MaxValue, long.MaxValue]
var grid = new Grid<bool>(3); // [false, false, false]
but for me it looks a little bit sloppy and non-transparent. Also, it creates new instance of static _customDefaultValues for each create closed generic type. That's why it would be better to extract it to a factory class. 
public class Grid<T>
{
    private T[] _gridArray;  
    public Grid(int size)
    {
        _gridArray = new T[size];
    }            
    public Grid(int size, T initialValue)
    {
        _gridArray = new T[size];
        for (int i = 0; i < size; i++)
            _gridArray[i] = initialValue;
    }    
}
public static class GridFactory
{
    private static readonly Dictionary<Type, object> _customDefaultValues = new Dictionary<Type, object>
    {
        [typeof(int)] = -1,
        [typeof(long)] = long.MaxValue
    };
    public static Grid<T> Create<T>(int size)
    {
        if (_customDefaultValues.TryGetValue(typeof(T), out object defaultValue))
            return new Grid<T>(size, (T)defaultValue);
        return new Grid<T>(size);
    }        
}
It results into more code, but this way it looks more clear:
var grid = GridFactory.Create<int>(3); // [-1, -1, -1]
var grid = GridFactory.Create<long>(4); // [long.MaxValue, long.MaxValue, long.MaxValue, long.MaxValue]
var grid = GridFactory.Create<object>(3); // [null, null, null] by default